Просмотр исходного кода

chore: 移除项目中依赖的three.js及其相关文件

1. 从package.json中删除three.js依赖项
2. 删除整个node_modules/three目录下的所有文件
3. 更新dist/index.html中的资源引用路径
4.补充双击地形聚焦
5.补充调试函数
wenhongquan 1 месяц назад
Родитель
Сommit
022a09055c
100 измененных файлов с 2 добавлено и 150871 удалено
  1. 0 0
      dist/assets/index-Co3HZtGW.css
  2. 0 0
      dist/assets/index-DCNMMEJK.js
  3. 2 2
      dist/index.html
  4. 0 21
      node_modules/three/LICENSE
  5. 0 85
      node_modules/three/README.md
  6. 0 60025
      node_modules/three/build/three.cjs
  7. 0 59731
      node_modules/three/build/three.core.js
  8. 0 5
      node_modules/three/build/three.core.min.js
  9. 0 5
      node_modules/three/build/three.module.js
  10. 0 5
      node_modules/three/build/three.module.min.js
  11. 0 653
      node_modules/three/build/three.tsl.js
  12. 0 5
      node_modules/three/build/three.tsl.min.js
  13. 0 5
      node_modules/three/build/three.webgpu.js
  14. 0 5
      node_modules/three/build/three.webgpu.min.js
  15. 0 5
      node_modules/three/build/three.webgpu.nodes.js
  16. 0 5
      node_modules/three/build/three.webgpu.nodes.min.js
  17. 0 13
      node_modules/three/examples/fonts/LICENSE
  18. BIN
      node_modules/three/examples/fonts/MPLUSRounded1c/MPLUSRounded1c-Regular.typeface.json.zip
  19. 0 91
      node_modules/three/examples/fonts/MPLUSRounded1c/OFL.txt
  20. 0 11
      node_modules/three/examples/fonts/README.md
  21. 0 190
      node_modules/three/examples/fonts/droid/NOTICE
  22. 0 18
      node_modules/three/examples/fonts/droid/README.txt
  23. 0 0
      node_modules/three/examples/fonts/droid/droid_sans_bold.typeface.json
  24. 0 0
      node_modules/three/examples/fonts/droid/droid_sans_mono_regular.typeface.json
  25. 0 0
      node_modules/three/examples/fonts/droid/droid_sans_regular.typeface.json
  26. 0 0
      node_modules/three/examples/fonts/droid/droid_serif_bold.typeface.json
  27. 0 0
      node_modules/three/examples/fonts/droid/droid_serif_regular.typeface.json
  28. 0 0
      node_modules/three/examples/fonts/gentilis_bold.typeface.json
  29. 0 0
      node_modules/three/examples/fonts/gentilis_regular.typeface.json
  30. 0 0
      node_modules/three/examples/fonts/helvetiker_bold.typeface.json
  31. 0 0
      node_modules/three/examples/fonts/helvetiker_regular.typeface.json
  32. 0 0
      node_modules/three/examples/fonts/optimer_bold.typeface.json
  33. 0 0
      node_modules/three/examples/fonts/optimer_regular.typeface.json
  34. 0 9
      node_modules/three/examples/fonts/ttf/README.md
  35. BIN
      node_modules/three/examples/fonts/ttf/kenpixel.ttf
  36. 0 293
      node_modules/three/examples/jsm/Addons.js
  37. 0 168
      node_modules/three/examples/jsm/animation/AnimationClipCreator.js
  38. 0 595
      node_modules/three/examples/jsm/animation/CCDIKSolver.js
  39. 0 113
      node_modules/three/examples/jsm/capabilities/WebGL.js
  40. 0 59
      node_modules/three/examples/jsm/capabilities/WebGPU.js
  41. 0 3539
      node_modules/three/examples/jsm/controls/ArcballControls.js
  42. 0 452
      node_modules/three/examples/jsm/controls/DragControls.js
  43. 0 451
      node_modules/three/examples/jsm/controls/FirstPersonControls.js
  44. 0 384
      node_modules/three/examples/jsm/controls/FlyControls.js
  45. 0 116
      node_modules/three/examples/jsm/controls/MapControls.js
  46. 0 1963
      node_modules/three/examples/jsm/controls/OrbitControls.js
  47. 0 264
      node_modules/three/examples/jsm/controls/PointerLockControls.js
  48. 0 1001
      node_modules/three/examples/jsm/controls/TrackballControls.js
  49. 0 1950
      node_modules/three/examples/jsm/controls/TransformControls.js
  50. 0 598
      node_modules/three/examples/jsm/csm/CSM.js
  51. 0 209
      node_modules/three/examples/jsm/csm/CSMFrustum.js
  52. 0 243
      node_modules/three/examples/jsm/csm/CSMHelper.js
  53. 0 307
      node_modules/three/examples/jsm/csm/CSMShader.js
  54. 0 603
      node_modules/three/examples/jsm/csm/CSMShadowNode.js
  55. 0 694
      node_modules/three/examples/jsm/curves/CurveExtras.js
  56. 0 155
      node_modules/three/examples/jsm/curves/NURBSCurve.js
  57. 0 98
      node_modules/three/examples/jsm/curves/NURBSSurface.js
  58. 0 532
      node_modules/three/examples/jsm/curves/NURBSUtils.js
  59. 0 82
      node_modules/three/examples/jsm/curves/NURBSVolume.js
  60. 0 274
      node_modules/three/examples/jsm/effects/AnaglyphEffect.js
  61. 0 310
      node_modules/three/examples/jsm/effects/AsciiEffect.js
  62. 0 489
      node_modules/three/examples/jsm/effects/OutlineEffect.js
  63. 0 155
      node_modules/three/examples/jsm/effects/ParallaxBarrierEffect.js
  64. 0 91
      node_modules/three/examples/jsm/effects/StereoEffect.js
  65. 0 59
      node_modules/three/examples/jsm/environments/ColorEnvironment.js
  66. 0 102
      node_modules/three/examples/jsm/environments/DebugEnvironment.js
  67. 0 185
      node_modules/three/examples/jsm/environments/RoomEnvironment.js
  68. 0 311
      node_modules/three/examples/jsm/exporters/DRACOExporter.js
  69. 0 618
      node_modules/three/examples/jsm/exporters/EXRExporter.js
  70. 0 3738
      node_modules/three/examples/jsm/exporters/GLTFExporter.js
  71. 0 347
      node_modules/three/examples/jsm/exporters/KTX2Exporter.js
  72. 0 308
      node_modules/three/examples/jsm/exporters/OBJExporter.js
  73. 0 562
      node_modules/three/examples/jsm/exporters/PLYExporter.js
  74. 0 221
      node_modules/three/examples/jsm/exporters/STLExporter.js
  75. 0 1254
      node_modules/three/examples/jsm/exporters/USDZExporter.js
  76. 0 92
      node_modules/three/examples/jsm/geometries/BoxLineGeometry.js
  77. 0 72
      node_modules/three/examples/jsm/geometries/ConvexGeometry.js
  78. 0 420
      node_modules/three/examples/jsm/geometries/DecalGeometry.js
  79. 0 100
      node_modules/three/examples/jsm/geometries/ParametricFunctions.js
  80. 0 172
      node_modules/three/examples/jsm/geometries/ParametricGeometry.js
  81. 0 216
      node_modules/three/examples/jsm/geometries/RoundedBoxGeometry.js
  82. 0 689
      node_modules/three/examples/jsm/geometries/TeapotGeometry.js
  83. 0 102
      node_modules/three/examples/jsm/geometries/TextGeometry.js
  84. 0 715
      node_modules/three/examples/jsm/gpgpu/BitonicSort.js
  85. 0 302
      node_modules/three/examples/jsm/helpers/AnimationPathHelper.js
  86. 0 221
      node_modules/three/examples/jsm/helpers/LightProbeGridHelper.js
  87. 0 165
      node_modules/three/examples/jsm/helpers/LightProbeHelper.js
  88. 0 102
      node_modules/three/examples/jsm/helpers/LightProbeHelperGPU.js
  89. 0 109
      node_modules/three/examples/jsm/helpers/OctreeHelper.js
  90. 0 169
      node_modules/three/examples/jsm/helpers/PositionalAudioHelper.js
  91. 0 59
      node_modules/three/examples/jsm/helpers/RapierHelper.js
  92. 0 118
      node_modules/three/examples/jsm/helpers/RectAreaLightHelper.js
  93. 0 265
      node_modules/three/examples/jsm/helpers/TextureHelper.js
  94. 0 214
      node_modules/three/examples/jsm/helpers/TextureHelperGPU.js
  95. 0 155
      node_modules/three/examples/jsm/helpers/VertexNormalsHelper.js
  96. 0 133
      node_modules/three/examples/jsm/helpers/VertexTangentsHelper.js
  97. 0 519
      node_modules/three/examples/jsm/helpers/ViewHelper.js
  98. 0 13
      node_modules/three/examples/jsm/inspector/Extension.js
  99. 0 542
      node_modules/three/examples/jsm/inspector/Inspector.js
  100. 0 425
      node_modules/three/examples/jsm/inspector/RendererInspector.js

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
dist/assets/index-Co3HZtGW.css


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
dist/assets/index-DCNMMEJK.js


+ 2 - 2
dist/index.html

@@ -7,8 +7,8 @@
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>3D 大屏 - 倾斜摄影</title>
-    <script type="module" crossorigin src="/assets/index-D8IoQj9E.js"></script>
-    <link rel="stylesheet" crossorigin href="/assets/index-C9fPZ9Zl.css">
+    <script type="module" crossorigin src="/assets/index-DCNMMEJK.js"></script>
+    <link rel="stylesheet" crossorigin href="/assets/index-Co3HZtGW.css">
   </head>
   <body>
     <div id="app"></div>

+ 0 - 21
node_modules/three/LICENSE

@@ -1,21 +0,0 @@
-The MIT License
-
-Copyright © 2010-2026 three.js authors
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.

+ 0 - 85
node_modules/three/README.md

@@ -1,85 +0,0 @@
-# three.js
-
-[![NPM Package][npm]][npm-url]
-[![Build Size][build-size]][build-size-url]
-[![NPM Downloads][npm-downloads]][npmtrends-url]
-[![jsDelivr Downloads][jsdelivr-downloads]][jsdelivr-url]
-[![Discord][discord]][discord-url]
-
-#### JavaScript 3D library
-
-The aim of the project is to create an easy-to-use, lightweight, cross-browser, general-purpose 3D library. The current builds only include WebGL and WebGPU renderers but SVG and CSS3D renderers are also available as addons.
-
-[Examples](https://threejs.org/examples/) &mdash;
-[Docs](https://threejs.org/docs/) &mdash;
-[Manual](https://threejs.org/manual/) &mdash;
-[Wiki](https://github.com/mrdoob/three.js/wiki) &mdash;
-[Migrating](https://github.com/mrdoob/three.js/wiki/Migration-Guide) &mdash;
-[Questions](https://stackoverflow.com/questions/tagged/three.js) &mdash;
-[Forum](https://discourse.threejs.org/) &mdash;
-[Discord](https://discord.gg/56GBJwAnUS)
-
-### Usage
-
-This code creates a scene, a camera, and a geometric cube, and it adds the cube to the scene. It then creates a `WebGL` renderer for the scene and camera, and it adds that viewport to the `document.body` element. Finally, it animates the cube within the scene for the camera.
-
-```javascript
-import * as THREE from 'three';
-
-const width = window.innerWidth, height = window.innerHeight;
-
-// init
-
-const camera = new THREE.PerspectiveCamera( 70, width / height, 0.01, 10 );
-camera.position.z = 1;
-
-const scene = new THREE.Scene();
-
-const geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
-const material = new THREE.MeshNormalMaterial();
-
-const mesh = new THREE.Mesh( geometry, material );
-scene.add( mesh );
-
-const renderer = new THREE.WebGLRenderer( { antialias: true } );
-renderer.setSize( width, height );
-renderer.setAnimationLoop( animate );
-document.body.appendChild( renderer.domElement );
-
-// animation
-
-function animate( time ) {
-
-	mesh.rotation.x = time / 2000;
-	mesh.rotation.y = time / 1000;
-
-	renderer.render( scene, camera );
-
-}
-```
-
-If everything goes well, you should see [this](https://jsfiddle.net/w43x5Lgh/).
-
-### Cloning this repository
-
-Cloning the repo with all its history results in a ~2 GB download. If you don't need the whole history you can use the `depth` parameter to significantly reduce download size.
-
-```sh
-git clone --depth=1 https://github.com/mrdoob/three.js.git
-```
-
-### Change log
-
-[Releases](https://github.com/mrdoob/three.js/releases)
-
-
-[npm]: https://img.shields.io/npm/v/three
-[npm-url]: https://www.npmjs.com/package/three
-[build-size]: https://badgen.net/bundlephobia/minzip/three
-[build-size-url]: https://bundlephobia.com/result?p=three
-[npm-downloads]: https://img.shields.io/npm/dw/three
-[npmtrends-url]: https://www.npmtrends.com/three
-[jsdelivr-downloads]: https://data.jsdelivr.com/v1/package/npm/three/badge?style=rounded
-[jsdelivr-url]: https://www.jsdelivr.com/package/npm/three
-[discord]: https://img.shields.io/discord/685241246557667386
-[discord-url]: https://discord.gg/56GBJwAnUS

Разница между файлами не показана из-за своего большого размера
+ 0 - 60025
node_modules/three/build/three.cjs


Разница между файлами не показана из-за своего большого размера
+ 0 - 59731
node_modules/three/build/three.core.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 5
node_modules/three/build/three.core.min.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 5
node_modules/three/build/three.module.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 5
node_modules/three/build/three.module.min.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 653
node_modules/three/build/three.tsl.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 5
node_modules/three/build/three.tsl.min.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 5
node_modules/three/build/three.webgpu.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 5
node_modules/three/build/three.webgpu.min.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 5
node_modules/three/build/three.webgpu.nodes.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 5
node_modules/three/build/three.webgpu.nodes.min.js


+ 0 - 13
node_modules/three/examples/fonts/LICENSE

@@ -1,13 +0,0 @@
-Copyright @ 2004 by MAGENTA Ltd. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions:
-
-The above copyright and this permission notice shall be included in all copies of one or more of the Font Software typefaces.
-
-The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing the word "MgOpen", or if the modifications are accepted for inclusion in the Font Software itself by the each appointed Administrator.
-
-This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "MgOpen" name.
-
-The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself.
-
-THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL MAGENTA OR PERSONS OR BODIES IN CHARGE OF ADMINISTRATION AND MAINTENANCE OF THE FONT SOFTWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.

BIN
node_modules/three/examples/fonts/MPLUSRounded1c/MPLUSRounded1c-Regular.typeface.json.zip


+ 0 - 91
node_modules/three/examples/fonts/MPLUSRounded1c/OFL.txt

@@ -1,91 +0,0 @@
-This Font Software is licensed under the SIL Open Font License, Version 1.1.
-This license is copied below, and is also available with a FAQ at:
-https://openfontlicense.org
-
-
------------------------------------------------------------
-SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
------------------------------------------------------------
-
-PREAMBLE
-The goals of the Open Font License (OFL) are to stimulate worldwide
-development of collaborative font projects, to support the font creation
-efforts of academic and linguistic communities, and to provide a free and
-open framework in which fonts may be shared and improved in partnership
-with others.
-
-The OFL allows the licensed fonts to be used, studied, modified and
-redistributed freely as long as they are not sold by themselves. The
-fonts, including any derivative works, can be bundled, embedded, 
-redistributed and/or sold with any software provided that any reserved
-names are not used by derivative works. The fonts and derivatives,
-however, cannot be released under any other type of license. The
-requirement for fonts to remain under this license does not apply
-to any document created using the fonts or their derivatives.
-
-DEFINITIONS
-"Font Software" refers to the set of files released by the Copyright
-Holder(s) under this license and clearly marked as such. This may
-include source files, build scripts and documentation.
-
-"Reserved Font Name" refers to any names specified as such after the
-copyright statement(s).
-
-"Original Version" refers to the collection of Font Software components as
-distributed by the Copyright Holder(s).
-
-"Modified Version" refers to any derivative made by adding to, deleting,
-or substituting -- in part or in whole -- any of the components of the
-Original Version, by changing formats or by porting the Font Software to a
-new environment.
-
-"Author" refers to any designer, engineer, programmer, technical
-writer or other person who contributed to the Font Software.
-
-PERMISSION & CONDITIONS
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of the Font Software, to use, study, copy, merge, embed, modify,
-redistribute, and sell modified and unmodified copies of the Font
-Software, subject to the following conditions:
-
-1) Neither the Font Software nor any of its individual components,
-in Original or Modified Versions, may be sold by itself.
-
-2) Original or Modified Versions of the Font Software may be bundled,
-redistributed and/or sold with any software, provided that each copy
-contains the above copyright notice and this license. These can be
-included either as stand-alone text files, human-readable headers or
-in the appropriate machine-readable metadata fields within text or
-binary files as long as those fields can be easily viewed by the user.
-
-3) No Modified Version of the Font Software may use the Reserved Font
-Name(s) unless explicit written permission is granted by the corresponding
-Copyright Holder. This restriction only applies to the primary font name as
-presented to the users.
-
-4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
-Software shall not be used to promote, endorse or advertise any
-Modified Version, except to acknowledge the contribution(s) of the
-Copyright Holder(s) and the Author(s) or with their explicit written
-permission.
-
-5) The Font Software, modified or unmodified, in part or in whole,
-must be distributed entirely under this license, and must not be
-distributed under any other license. The requirement for fonts to
-remain under this license does not apply to any document created
-using the Font Software.
-
-TERMINATION
-This license becomes null and void if any of the above conditions are
-not met.
-
-DISCLAIMER
-THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
-OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
-COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
-DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
-OTHER DEALINGS IN THE FONT SOFTWARE.

+ 0 - 11
node_modules/three/examples/fonts/README.md

@@ -1,11 +0,0 @@
-## MgOpen typefaces
-
-# Source and License
-
-https://web.archive.org/web/20050528114140/https://ellak.gr/fonts/mgopen/index.en
-
-# Usage
-
-Use Facetype.js to generate typeface.json fonts: https://gero3.github.io/facetype.js/
-
-Collection of Google fonts as typeface data for usage with three.js: https://github.com/components-ai/typefaces

+ 0 - 190
node_modules/three/examples/fonts/droid/NOTICE

@@ -1,190 +0,0 @@
-
-   Copyright (c) 2005-2008, The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-

+ 0 - 18
node_modules/three/examples/fonts/droid/README.txt

@@ -1,18 +0,0 @@
-Copyright (C) 2008 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-  
-     http://www.apache.org/licenses/LICENSE-2.0
-  
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-##########
-
-This directory contains the fonts for the platform. They are licensed
-under the Apache 2 license.

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
node_modules/three/examples/fonts/droid/droid_sans_bold.typeface.json


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
node_modules/three/examples/fonts/droid/droid_sans_mono_regular.typeface.json


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
node_modules/three/examples/fonts/droid/droid_sans_regular.typeface.json


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
node_modules/three/examples/fonts/droid/droid_serif_bold.typeface.json


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
node_modules/three/examples/fonts/droid/droid_serif_regular.typeface.json


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
node_modules/three/examples/fonts/gentilis_bold.typeface.json


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
node_modules/three/examples/fonts/gentilis_regular.typeface.json


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
node_modules/three/examples/fonts/helvetiker_bold.typeface.json


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
node_modules/three/examples/fonts/helvetiker_regular.typeface.json


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
node_modules/three/examples/fonts/optimer_bold.typeface.json


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
node_modules/three/examples/fonts/optimer_regular.typeface.json


+ 0 - 9
node_modules/three/examples/fonts/ttf/README.md

@@ -1,9 +0,0 @@
-# Kenney Fonts
-
-## Source
-
-https://www.kenney.nl/assets/kenney-fonts
-
-## License
-
-CC0 1.0 Universal (CC0 1.0) Public Domain Dedication (https://creativecommons.org/publicdomain/zero/1.0/)

BIN
node_modules/three/examples/fonts/ttf/kenpixel.ttf


+ 0 - 293
node_modules/three/examples/jsm/Addons.js

@@ -1,293 +0,0 @@
-export * from './animation/AnimationClipCreator.js';
-export * from './animation/CCDIKSolver.js';
-
-export { default as WebGL } from './capabilities/WebGL.js';
-
-export * from './controls/ArcballControls.js';
-export * from './controls/DragControls.js';
-export * from './controls/FirstPersonControls.js';
-export * from './controls/FlyControls.js';
-export * from './controls/MapControls.js';
-export * from './controls/OrbitControls.js';
-export * from './controls/PointerLockControls.js';
-export * from './controls/TrackballControls.js';
-export * from './controls/TransformControls.js';
-
-export * from './csm/CSM.js';
-export * from './csm/CSMFrustum.js';
-export * from './csm/CSMHelper.js';
-export * from './csm/CSMShader.js';
-
-export * as Curves from './curves/CurveExtras.js';
-export * from './curves/NURBSCurve.js';
-export * from './curves/NURBSSurface.js';
-export * from './curves/NURBSVolume.js';
-export * as NURBSUtils from './curves/NURBSUtils.js';
-
-export * from './effects/AnaglyphEffect.js';
-export * from './effects/AsciiEffect.js';
-export * from './effects/OutlineEffect.js';
-export * from './effects/ParallaxBarrierEffect.js';
-export * from './effects/StereoEffect.js';
-
-export * from './environments/ColorEnvironment.js';
-export * from './environments/DebugEnvironment.js';
-export * from './environments/RoomEnvironment.js';
-
-export * from './exporters/DRACOExporter.js';
-export * from './exporters/EXRExporter.js';
-export * from './exporters/GLTFExporter.js';
-export * from './exporters/KTX2Exporter.js';
-export * from './exporters/OBJExporter.js';
-export * from './exporters/PLYExporter.js';
-export * from './exporters/STLExporter.js';
-export * from './exporters/USDZExporter.js';
-
-export * from './geometries/BoxLineGeometry.js';
-export * from './geometries/ConvexGeometry.js';
-export * from './geometries/DecalGeometry.js';
-export * from './geometries/ParametricFunctions.js';
-export * from './geometries/ParametricGeometry.js';
-export * from './geometries/RoundedBoxGeometry.js';
-export * from './geometries/TeapotGeometry.js';
-export * from './geometries/TextGeometry.js';
-
-export * from './helpers/AnimationPathHelper.js';
-export * from './helpers/LightProbeHelper.js';
-export * from './helpers/OctreeHelper.js';
-export * from './helpers/PositionalAudioHelper.js';
-export * from './helpers/RapierHelper.js';
-export * from './helpers/RectAreaLightHelper.js';
-export * from './helpers/TextureHelper.js';
-export * from './helpers/VertexNormalsHelper.js';
-export * from './helpers/VertexTangentsHelper.js';
-export * from './helpers/ViewHelper.js';
-
-export * from './interactive/HTMLMesh.js';
-export * from './interactive/InteractiveGroup.js';
-export * from './interactive/SelectionBox.js';
-export * from './interactive/SelectionHelper.js';
-
-export * from './lights/LightProbeGenerator.js';
-export * from './lights/RectAreaLightTexturesLib.js';
-export * from './lights/RectAreaLightUniformsLib.js';
-
-export * from './lines/Line2.js';
-export * from './lines/LineGeometry.js';
-export * from './lines/LineMaterial.js';
-export * from './lines/LineSegments2.js';
-export * from './lines/LineSegmentsGeometry.js';
-export * from './lines/Wireframe.js';
-export * from './lines/WireframeGeometry2.js';
-
-export * from './loaders/3DMLoader.js';
-export * from './loaders/3MFLoader.js';
-export * from './loaders/AMFLoader.js';
-export * from './loaders/BVHLoader.js';
-export * from './loaders/ColladaLoader.js';
-export * from './loaders/DDSLoader.js';
-export * from './loaders/DRACOLoader.js';
-export * from './loaders/EXRLoader.js';
-export * from './loaders/FBXLoader.js';
-export * from './loaders/FontLoader.js';
-export * from './loaders/GCodeLoader.js';
-export * from './loaders/GLTFLoader.js';
-export * from './loaders/HDRLoader.js';
-export * from './loaders/HDRCubeTextureLoader.js';
-export * from './loaders/IESLoader.js';
-export * from './loaders/KMZLoader.js';
-export * from './loaders/KTX2Loader.js';
-export * from './loaders/KTXLoader.js';
-export * from './loaders/LDrawLoader.js';
-export * from './loaders/LUT3dlLoader.js';
-export * from './loaders/LUTCubeLoader.js';
-export * from './loaders/LUTImageLoader.js';
-export * from './loaders/LWOLoader.js';
-export * from './loaders/LottieLoader.js';
-export * from './loaders/MD2Loader.js';
-export * from './loaders/MDDLoader.js';
-export * from './loaders/MTLLoader.js';
-export * from './loaders/NRRDLoader.js';
-export * from './loaders/OBJLoader.js';
-export * from './loaders/PCDLoader.js';
-export * from './loaders/PDBLoader.js';
-export * from './loaders/PLYLoader.js';
-export * from './loaders/PVRLoader.js';
-export * from './loaders/RGBELoader.js';
-export * from './loaders/UltraHDRLoader.js';
-export * from './loaders/STLLoader.js';
-export * from './loaders/SVGLoader.js';
-export * from './loaders/TDSLoader.js';
-export * from './loaders/TGALoader.js';
-export * from './loaders/TIFFLoader.js';
-export * from './loaders/TTFLoader.js';
-export * from './loaders/USDLoader.js';
-export * from './loaders/VOXLoader.js';
-export * from './loaders/VRMLLoader.js';
-export * from './loaders/VTKLoader.js';
-export * from './loaders/XYZLoader.js';
-
-export * from './materials/LDrawConditionalLineMaterial.js';
-
-export * from './math/Capsule.js';
-export * from './math/ColorConverter.js';
-export * as ColorSpaces from './math/ColorSpaces.js';
-export * from './math/ConvexHull.js';
-export * from './math/ImprovedNoise.js';
-export * from './math/Lut.js';
-export * from './math/MeshSurfaceSampler.js';
-export * from './math/OBB.js';
-export * from './math/Octree.js';
-export * from './math/SimplexNoise.js';
-
-export * from './misc/ConvexObjectBreaker.js';
-export * from './misc/GPUComputationRenderer.js';
-export * from './misc/Gyroscope.js';
-export * from './misc/MD2Character.js';
-export * from './misc/MD2CharacterComplex.js';
-export * from './misc/MorphAnimMesh.js';
-export * from './misc/MorphBlendMesh.js';
-export * from './misc/ProgressiveLightMap.js';
-export * from './misc/RollerCoaster.js';
-export * from './misc/TubePainter.js';
-export * from './misc/Volume.js';
-export * from './misc/VolumeSlice.js';
-
-export * from './modifiers/CurveModifier.js';
-export * from './modifiers/EdgeSplitModifier.js';
-export * from './modifiers/SimplifyModifier.js';
-export * from './modifiers/TessellateModifier.js';
-
-export * from './objects/GroundedSkybox.js';
-export * from './objects/Lensflare.js';
-export * from './objects/MarchingCubes.js';
-export * from './objects/Reflector.js';
-export * from './objects/ReflectorForSSRPass.js';
-export * from './objects/Refractor.js';
-export * from './objects/ShadowMesh.js';
-export * from './objects/Sky.js';
-export * from './objects/Water.js';
-export { Water as Water2 } from './objects/Water2.js';
-
-export * from './physics/AmmoPhysics.js';
-export * from './physics/JoltPhysics.js';
-export * from './physics/RapierPhysics.js';
-
-export * from './postprocessing/AfterimagePass.js';
-export * from './postprocessing/BloomPass.js';
-export * from './postprocessing/BokehPass.js';
-export * from './postprocessing/ClearPass.js';
-export * from './postprocessing/CubeTexturePass.js';
-export * from './postprocessing/DotScreenPass.js';
-export * from './postprocessing/EffectComposer.js';
-export * from './postprocessing/FXAAPass.js';
-export * from './postprocessing/FilmPass.js';
-export * from './postprocessing/GlitchPass.js';
-export * from './postprocessing/GTAOPass.js';
-export * from './postprocessing/HalftonePass.js';
-export * from './postprocessing/LUTPass.js';
-export * from './postprocessing/MaskPass.js';
-export * from './postprocessing/OutlinePass.js';
-export * from './postprocessing/OutputPass.js';
-export * from './postprocessing/Pass.js';
-export * from './postprocessing/RenderPass.js';
-export * from './postprocessing/RenderPixelatedPass.js';
-export * from './postprocessing/RenderTransitionPass.js';
-export * from './postprocessing/SAOPass.js';
-export * from './postprocessing/SMAAPass.js';
-export * from './postprocessing/SSAARenderPass.js';
-export * from './postprocessing/SSAOPass.js';
-export * from './postprocessing/SSRPass.js';
-export * from './postprocessing/SavePass.js';
-export * from './postprocessing/ShaderPass.js';
-export * from './postprocessing/TAARenderPass.js';
-export * from './postprocessing/TexturePass.js';
-export * from './postprocessing/UnrealBloomPass.js';
-
-export * from './renderers/CSS2DRenderer.js';
-export * from './renderers/CSS3DRenderer.js';
-export * from './renderers/Projector.js';
-export * from './renderers/SVGRenderer.js';
-
-export * from './shaders/ACESFilmicToneMappingShader.js';
-export * from './shaders/AfterimageShader.js';
-export * from './shaders/BasicShader.js';
-export * from './shaders/BleachBypassShader.js';
-export * from './shaders/BlendShader.js';
-export * from './shaders/BokehShader.js';
-export { BokehShader as BokehShader2 } from './shaders/BokehShader2.js';
-export * from './shaders/BrightnessContrastShader.js';
-export * from './shaders/ColorCorrectionShader.js';
-export * from './shaders/ColorifyShader.js';
-export * from './shaders/ConvolutionShader.js';
-export * from './shaders/CopyShader.js';
-export * from './shaders/DOFMipMapShader.js';
-export * from './shaders/DepthLimitedBlurShader.js';
-export * from './shaders/DigitalGlitch.js';
-export * from './shaders/DotScreenShader.js';
-export * from './shaders/ExposureShader.js';
-export * from './shaders/FXAAShader.js';
-export * from './shaders/FilmShader.js';
-export * from './shaders/FocusShader.js';
-export * from './shaders/FreiChenShader.js';
-export * from './shaders/GammaCorrectionShader.js';
-export * from './shaders/GTAOShader.js';
-export * from './shaders/HalftoneShader.js';
-export * from './shaders/HorizontalBlurShader.js';
-export * from './shaders/HorizontalTiltShiftShader.js';
-export * from './shaders/HueSaturationShader.js';
-export * from './shaders/KaleidoShader.js';
-export * from './shaders/LuminosityHighPassShader.js';
-export * from './shaders/LuminosityShader.js';
-export * from './shaders/MirrorShader.js';
-export * from './shaders/NormalMapShader.js';
-export * from './shaders/OutputShader.js';
-export * from './shaders/PoissonDenoiseShader.js';
-export * from './shaders/RGBShiftShader.js';
-export * from './shaders/SAOShader.js';
-export * from './shaders/SMAAShader.js';
-export * from './shaders/SSAOShader.js';
-export * from './shaders/SSRShader.js';
-export * from './shaders/SepiaShader.js';
-export * from './shaders/SobelOperatorShader.js';
-export * from './shaders/SubsurfaceScatteringShader.js';
-export * from './shaders/TechnicolorShader.js';
-export * from './shaders/ToonShader.js';
-export * from './shaders/TriangleBlurShader.js';
-export * from './shaders/UnpackDepthRGBAShader.js';
-export * from './shaders/VelocityShader.js';
-export * from './shaders/VerticalBlurShader.js';
-export * from './shaders/VerticalTiltShiftShader.js';
-export * from './shaders/VignetteShader.js';
-export * from './shaders/VolumeShader.js';
-export * from './shaders/WaterRefractionShader.js';
-
-export * from './textures/FlakesTexture.js';
-
-export * as BufferGeometryUtils from './utils/BufferGeometryUtils.js';
-export * as CameraUtils from './utils/CameraUtils.js';
-export * as ColorUtils from './utils/ColorUtils.js';
-export * as GeometryCompressionUtils from './utils/GeometryCompressionUtils.js';
-export * as GeometryUtils from './utils/GeometryUtils.js';
-export * from './utils/LDrawUtils.js';
-export * from './utils/SceneOptimizer.js';
-export * as SceneUtils from './utils/SceneUtils.js';
-export * from './utils/ShadowMapViewer.js';
-export * as SkeletonUtils from './utils/SkeletonUtils.js';
-export * as SortUtils from './utils/SortUtils.js';
-export * from './utils/WebGLTextureUtils.js';
-export * from './utils/UVsDebug.js';
-export * from './utils/WorkerPool.js';
-
-export * from './webxr/ARButton.js';
-export * from './webxr/OculusHandModel.js';
-export * from './webxr/OculusHandPointerModel.js';
-export * from './webxr/Text2D.js';
-export * from './webxr/VRButton.js';
-export * from './webxr/XRButton.js';
-export * from './webxr/XRControllerModelFactory.js';
-export * from './webxr/XREstimatedLight.js';
-export * from './webxr/XRHandMeshModel.js';
-export * from './webxr/XRHandModelFactory.js';
-export * from './webxr/XRHandPrimitiveModel.js';
-export * from './webxr/XRPlanes.js';

+ 0 - 168
node_modules/three/examples/jsm/animation/AnimationClipCreator.js

@@ -1,168 +0,0 @@
-import {
-	AnimationClip,
-	BooleanKeyframeTrack,
-	ColorKeyframeTrack,
-	NumberKeyframeTrack,
-	Vector3,
-	VectorKeyframeTrack
-} from 'three';
-
-/**
- * A utility class with factory methods for creating basic animation clips.
- *
- * @hideconstructor
- * @three_import import { AnimationClipCreator } from 'three/addons/animation/AnimationClipCreator.js';
- */
-class AnimationClipCreator {
-
-	/**
-	 * Creates an animation clip that rotates a 3D object 360 degrees
-	 * in the given period of time around the given axis.
-	 *
-	 * @param {number} period - The duration of the animation.
-	 * @param {('x'|'y'|'z')} [axis='x'] - The axis of rotation.
-	 * @return {AnimationClip} The created animation clip.
-	 */
-	static CreateRotationAnimation( period, axis = 'x' ) {
-
-		const times = [ 0, period ], values = [ 0, 360 ];
-
-		const trackName = '.rotation[' + axis + ']';
-
-		const track = new NumberKeyframeTrack( trackName, times, values );
-
-		return new AnimationClip( '', period, [ track ] );
-
-	}
-
-	/**
-	 * Creates an animation clip that scales a 3D object from `0` to `1`
-	 * in the given period of time along the given axis.
-	 *
-	 * @param {number} period - The duration of the animation.
-	 * @param {('x'|'y'|'z')} [axis='x'] - The axis to scale the 3D object along.
-	 * @return {AnimationClip} The created animation clip.
-	 */
-	static CreateScaleAxisAnimation( period, axis = 'x' ) {
-
-		const times = [ 0, period ], values = [ 0, 1 ];
-
-		const trackName = '.scale[' + axis + ']';
-
-		const track = new NumberKeyframeTrack( trackName, times, values );
-
-		return new AnimationClip( '', period, [ track ] );
-
-	}
-
-	/**
-	 * Creates an animation clip that translates a 3D object in a shake pattern
-	 * in the given period.
-	 *
-	 * @param {number} duration - The duration of the animation.
-	 * @param {Vector3} shakeScale - The scale of the shake.
-	 * @return {AnimationClip} The created animation clip.
-	 */
-	static CreateShakeAnimation( duration, shakeScale ) {
-
-		const times = [], values = [], tmp = new Vector3();
-
-		for ( let i = 0; i < duration * 10; i ++ ) {
-
-			times.push( i / 10 );
-
-			tmp.set( Math.random() * 2.0 - 1.0, Math.random() * 2.0 - 1.0, Math.random() * 2.0 - 1.0 ).
-				multiply( shakeScale ).
-				toArray( values, values.length );
-
-		}
-
-		const trackName = '.position';
-
-		const track = new VectorKeyframeTrack( trackName, times, values );
-
-		return new AnimationClip( '', duration, [ track ] );
-
-	}
-
-	/**
-	 * Creates an animation clip that scales a 3D object in a pulse pattern
-	 * in the given period.
-	 *
-	 * @param {number} duration - The duration of the animation.
-	 * @param {number} pulseScale - The scale of the pulse.
-	 * @return {AnimationClip} The created animation clip.
-	 */
-	static CreatePulsationAnimation( duration, pulseScale ) {
-
-		const times = [], values = [], tmp = new Vector3();
-
-		for ( let i = 0; i < duration * 10; i ++ ) {
-
-			times.push( i / 10 );
-
-			const scaleFactor = Math.random() * pulseScale;
-			tmp.set( scaleFactor, scaleFactor, scaleFactor ).
-				toArray( values, values.length );
-
-		}
-
-		const trackName = '.scale';
-
-		const track = new VectorKeyframeTrack( trackName, times, values );
-
-		return new AnimationClip( '', duration, [ track ] );
-
-	}
-
-	/**
-	 * Creates an animation clip that toggles the visibility of a 3D object.
-	 *
-	 * @param {number} duration - The duration of the animation.
-	 * @return {AnimationClip} The created animation clip.
-	 */
-	static CreateVisibilityAnimation( duration ) {
-
-		const times = [ 0, duration / 2, duration ], values = [ true, false, true ];
-
-		const trackName = '.visible';
-
-		const track = new BooleanKeyframeTrack( trackName, times, values );
-
-		return new AnimationClip( '', duration, [ track ] );
-
-	}
-
-	/**
-	 * Creates an animation clip that animates the `color` property of a 3D object's
-	 * material.
-	 *
-	 * @param {number} duration - The duration of the animation.
-	 * @param {Array<Color>} colors - An array of colors that should be sequentially animated.
-	 * @return {AnimationClip} The created animation clip.
-	 */
-	static CreateMaterialColorAnimation( duration, colors ) {
-
-		const times = [], values = [],
-			timeStep = ( colors.length > 1 ) ? duration / ( colors.length - 1 ) : 0;
-
-		for ( let i = 0; i < colors.length; i ++ ) {
-
-			times.push( i * timeStep );
-
-			const color = colors[ i ];
-			values.push( color.r, color.g, color.b );
-
-		}
-
-		const trackName = '.material.color';
-
-		const track = new ColorKeyframeTrack( trackName, times, values );
-
-		return new AnimationClip( '', duration, [ track ] );
-
-	}
-
-}
-
-export { AnimationClipCreator };

+ 0 - 595
node_modules/three/examples/jsm/animation/CCDIKSolver.js

@@ -1,595 +0,0 @@
-import {
-	BufferAttribute,
-	BufferGeometry,
-	Color,
-	Line,
-	LineBasicMaterial,
-	Matrix4,
-	Mesh,
-	MeshBasicMaterial,
-	Object3D,
-	Quaternion,
-	SphereGeometry,
-	Vector3
-} from 'three';
-
-const _quaternion = new Quaternion();
-const _targetPos = new Vector3();
-const _targetVec = new Vector3();
-const _effectorPos = new Vector3();
-const _effectorVec = new Vector3();
-const _linkPos = new Vector3();
-const _invLinkQ = new Quaternion();
-const _linkScale = new Vector3();
-const _axis = new Vector3();
-const _vector = new Vector3();
-const _matrix = new Matrix4();
-
-/**
- * This class solves the Inverse Kinematics Problem with a [CCD Algorithm](https://web.archive.org/web/20221206080850/https://sites.google.com/site/auraliusproject/ccd-algorithm).
- *
- * `CCDIKSolver` is designed to work with instances of {@link SkinnedMesh}.
- *
- * @three_import import { CCDIKSolver } from 'three/addons/animation/CCDIKSolver.js';
- */
-class CCDIKSolver {
-
-	/**
-	 * @param {SkinnedMesh} mesh - The skinned mesh.
-	 * @param {Array<CCDIKSolver~IK>} [iks=[]] - The IK objects.
-	 */
-	constructor( mesh, iks = [] ) {
-
-		/**
-		 * The skinned mesh.
-		 *
-		 * @type {SkinnedMesh}
-		 */
-		this.mesh = mesh;
-
-		/**
-		 * The IK objects.
-		 *
-		 * @type {Array<CCDIKSolver~IK>}
-		 */
-		this.iks = iks;
-
-		this._initialQuaternions = [];
-		this._workingQuaternion = new Quaternion();
-
-		for ( const ik of iks ) {
-
-			const chainQuats = [];
-			for ( let i = 0; i < ik.links.length; i ++ ) {
-
-			  chainQuats.push( new Quaternion() );
-
-			}
-
-			this._initialQuaternions.push( chainQuats );
-
-		}
-
-		this._valid();
-
-	}
-
-	/**
-	 * Updates all IK bones by solving the CCD algorithm.
-	 *
-	 * @param {number} [globalBlendFactor=1.0] - Blend factor applied if an IK chain doesn't have its own .blendFactor.
-	 * @return {CCDIKSolver} A reference to this instance.
-	 */
-	update( globalBlendFactor = 1.0 ) {
-
-		const iks = this.iks;
-
-		for ( let i = 0, il = iks.length; i < il; i ++ ) {
-
-			this.updateOne( iks[ i ], globalBlendFactor );
-
-		}
-
-		return this;
-
-	}
-
-	/**
-	 * Updates one IK bone solving the CCD algorithm.
-	 *
-	 * @param {CCDIKSolver~IK} ik - The IK to update.
-	 * @param {number} [overrideBlend=1.0] - If the IK object does not define `blendFactor`, this value is used.
-	 * @return {CCDIKSolver} A reference to this instance.
-	 */
-	updateOne( ik, overrideBlend = 1.0 ) {
-
-		const chainBlend = ik.blendFactor !== undefined ? ik.blendFactor : overrideBlend;
-		const bones = this.mesh.skeleton.bones;
-		const chainIndex = this.iks.indexOf( ik );
-		const initialQuaternions = this._initialQuaternions[ chainIndex ];
-
-		// for reference overhead reduction in loop
-		const math = Math;
-
-		const effector = bones[ ik.effector ];
-		const target = bones[ ik.target ];
-
-		// don't use getWorldPosition() here for the performance
-		// because it calls updateMatrixWorld( true ) inside.
-		_targetPos.setFromMatrixPosition( target.matrixWorld );
-
-		const links = ik.links;
-		const iteration = ik.iteration !== undefined ? ik.iteration : 1;
-
-		if ( chainBlend < 1.0 ) {
-
-			for ( let j = 0; j < links.length; j ++ ) {
-
-			  const linkIndex = links[ j ].index;
-			  initialQuaternions[ j ].copy( bones[ linkIndex ].quaternion );
-
-			}
-
-		}
-
-		for ( let i = 0; i < iteration; i ++ ) {
-
-			let rotated = false;
-
-			for ( let j = 0, jl = links.length; j < jl; j ++ ) {
-
-				const link = bones[ links[ j ].index ];
-
-				// skip this link and following links
-				if ( links[ j ].enabled === false ) break;
-
-				const limitation = links[ j ].limitation;
-				const rotationMin = links[ j ].rotationMin;
-				const rotationMax = links[ j ].rotationMax;
-
-				// don't use getWorldPosition/Quaternion() here for the performance
-				// because they call updateMatrixWorld( true ) inside.
-				link.matrixWorld.decompose( _linkPos, _invLinkQ, _linkScale );
-				_invLinkQ.invert();
-				_effectorPos.setFromMatrixPosition( effector.matrixWorld );
-
-				// work in link world
-				_effectorVec.subVectors( _effectorPos, _linkPos );
-				_effectorVec.applyQuaternion( _invLinkQ );
-				_effectorVec.normalize();
-
-				_targetVec.subVectors( _targetPos, _linkPos );
-				_targetVec.applyQuaternion( _invLinkQ );
-				_targetVec.normalize();
-
-				let angle = _targetVec.dot( _effectorVec );
-
-				if ( angle > 1.0 ) {
-
-					angle = 1.0;
-
-				} else if ( angle < - 1.0 ) {
-
-					angle = - 1.0;
-
-				}
-
-				angle = math.acos( angle );
-
-				// skip if changing angle is too small to prevent vibration of bone
-				if ( angle < 1e-5 ) continue;
-
-				if ( ik.minAngle !== undefined && angle < ik.minAngle ) {
-
-					angle = ik.minAngle;
-
-				}
-
-				if ( ik.maxAngle !== undefined && angle > ik.maxAngle ) {
-
-					angle = ik.maxAngle;
-
-				}
-
-				_axis.crossVectors( _effectorVec, _targetVec );
-				_axis.normalize();
-
-				_quaternion.setFromAxisAngle( _axis, angle );
-				link.quaternion.multiply( _quaternion );
-
-				// TODO: re-consider the limitation specification
-				if ( limitation !== undefined ) {
-
-					let c = link.quaternion.w;
-
-					if ( c > 1.0 ) c = 1.0;
-
-					// preserve sign of the rotation along the limitation axis,
-					// otherwise negative rotations get mirrored to positive
-					const dot = link.quaternion.x * limitation.x + link.quaternion.y * limitation.y + link.quaternion.z * limitation.z;
-					const sign = dot < 0 ? - 1 : 1;
-					const c2 = sign * math.sqrt( 1 - c * c );
-					link.quaternion.set( limitation.x * c2,
-					                     limitation.y * c2,
-					                     limitation.z * c2,
-					                     c );
-
-				}
-
-				if ( rotationMin !== undefined ) {
-
-					link.rotation.setFromVector3( _vector.setFromEuler( link.rotation ).max( rotationMin ) );
-
-				}
-
-				if ( rotationMax !== undefined ) {
-
-					link.rotation.setFromVector3( _vector.setFromEuler( link.rotation ).min( rotationMax ) );
-
-				}
-
-				link.updateMatrixWorld( true );
-
-				rotated = true;
-
-			}
-
-			if ( ! rotated ) break;
-
-		}
-
-		if ( chainBlend < 1.0 ) {
-
-			for ( let j = 0; j < links.length; j ++ ) {
-
-			  const linkIndex = links[ j ].index;
-			  const link = bones[ linkIndex ];
-
-			  this._workingQuaternion.copy( initialQuaternions[ j ] ).slerp( link.quaternion, chainBlend );
-
-			  link.quaternion.copy( this._workingQuaternion );
-			  link.updateMatrixWorld( true );
-
-			}
-
-		}
-
-		  return this;
-
-	}
-
-	/**
-	 * Creates a helper for visualizing the CCDIK.
-	 *
-	 * @param {number} sphereSize - The sphere size.
-	 * @return {CCDIKHelper} The created helper.
-	 */
-	createHelper( sphereSize ) {
-
-		return new CCDIKHelper( this.mesh, this.iks, sphereSize );
-
-	}
-
-	// private methods
-
-	_valid() {
-
-		const iks = this.iks;
-		const bones = this.mesh.skeleton.bones;
-
-		for ( let i = 0, il = iks.length; i < il; i ++ ) {
-
-			const ik = iks[ i ];
-			const effector = bones[ ik.effector ];
-			const links = ik.links;
-			let link0, link1;
-
-			link0 = effector;
-
-			for ( let j = 0, jl = links.length; j < jl; j ++ ) {
-
-				link1 = bones[ links[ j ].index ];
-
-				if ( link0.parent !== link1 ) {
-
-					console.warn( 'THREE.CCDIKSolver: bone ' + link0.name + ' is not the child of bone ' + link1.name );
-
-				}
-
-				link0 = link1;
-
-			}
-
-		}
-
-	}
-
-}
-
-function getPosition( bone, matrixWorldInv ) {
-
-	return _vector
-		.setFromMatrixPosition( bone.matrixWorld )
-		.applyMatrix4( matrixWorldInv );
-
-}
-
-function setPositionOfBoneToAttributeArray( array, index, bone, matrixWorldInv ) {
-
-	const v = getPosition( bone, matrixWorldInv );
-
-	array[ index * 3 + 0 ] = v.x;
-	array[ index * 3 + 1 ] = v.y;
-	array[ index * 3 + 2 ] = v.z;
-
-}
-
-/**
- * Helper for visualizing IK bones.
- *
- * @augments Object3D
- * @three_import import { CCDIKHelper } from 'three/addons/animation/CCDIKSolver.js';
- */
-class CCDIKHelper extends Object3D {
-
-	/**
-	 * @param {SkinnedMesh} mesh - The skinned mesh.
- 	 * @param {Array<CCDIKSolver~IK>} [iks=[]] - The IK objects.
- 	 * @param {number} [sphereSize=0.25] - The sphere size.
-	 */
-	constructor( mesh, iks = [], sphereSize = 0.25 ) {
-
-		super();
-
-		/**
-		 * The skinned mesh this helper refers to.
-		 *
-		 * @type {SkinnedMesh}
-		 */
-		this.root = mesh;
-
-		/**
-		 * The IK objects.
-		 *
-		 * @type {Array<CCDIKSolver~IK>}
-		 */
-		this.iks = iks;
-
-		this.matrix.copy( mesh.matrixWorld );
-		this.matrixAutoUpdate = false;
-
-		/**
-		 * The helpers sphere geometry.
-		 *
-		 * @type {SphereGeometry}
-		 */
-		this.sphereGeometry = new SphereGeometry( sphereSize, 16, 8 );
-
-		/**
-		 * The material for the target spheres.
-		 *
-		 * @type {MeshBasicMaterial}
-		 */
-		this.targetSphereMaterial = new MeshBasicMaterial( {
-			color: new Color( 0xff8888 ),
-			depthTest: false,
-			depthWrite: false,
-			transparent: true
-		} );
-
-		/**
-		 * The material for the effector spheres.
-		 *
-		 * @type {MeshBasicMaterial}
-		 */
-		this.effectorSphereMaterial = new MeshBasicMaterial( {
-			color: new Color( 0x88ff88 ),
-			depthTest: false,
-			depthWrite: false,
-			transparent: true
-		} );
-
-		/**
-		 * The material for the link spheres.
-		 *
-		 * @type {MeshBasicMaterial}
-		 */
-		this.linkSphereMaterial = new MeshBasicMaterial( {
-			color: new Color( 0x8888ff ),
-			depthTest: false,
-			depthWrite: false,
-			transparent: true
-		} );
-
-		/**
-		 * A global line material.
-		 *
-		 * @type {LineBasicMaterial}
-		 */
-		this.lineMaterial = new LineBasicMaterial( {
-			color: new Color( 0xff0000 ),
-			depthTest: false,
-			depthWrite: false,
-			transparent: true
-		} );
-
-		this._init();
-
-	}
-
-	updateMatrixWorld( force ) {
-
-		const mesh = this.root;
-
-		if ( this.visible ) {
-
-			let offset = 0;
-
-			const iks = this.iks;
-			const bones = mesh.skeleton.bones;
-
-			_matrix.copy( mesh.matrixWorld ).invert();
-
-			for ( let i = 0, il = iks.length; i < il; i ++ ) {
-
-				const ik = iks[ i ];
-
-				const targetBone = bones[ ik.target ];
-				const effectorBone = bones[ ik.effector ];
-
-				const targetMesh = this.children[ offset ++ ];
-				const effectorMesh = this.children[ offset ++ ];
-
-				targetMesh.position.copy( getPosition( targetBone, _matrix ) );
-				effectorMesh.position.copy( getPosition( effectorBone, _matrix ) );
-
-				for ( let j = 0, jl = ik.links.length; j < jl; j ++ ) {
-
-					const link = ik.links[ j ];
-					const linkBone = bones[ link.index ];
-
-					const linkMesh = this.children[ offset ++ ];
-
-					linkMesh.position.copy( getPosition( linkBone, _matrix ) );
-
-				}
-
-				const line = this.children[ offset ++ ];
-				const array = line.geometry.attributes.position.array;
-
-				setPositionOfBoneToAttributeArray( array, 0, targetBone, _matrix );
-				setPositionOfBoneToAttributeArray( array, 1, effectorBone, _matrix );
-
-				for ( let j = 0, jl = ik.links.length; j < jl; j ++ ) {
-
-					const link = ik.links[ j ];
-					const linkBone = bones[ link.index ];
-					setPositionOfBoneToAttributeArray( array, j + 2, linkBone, _matrix );
-
-				}
-
-				line.geometry.attributes.position.needsUpdate = true;
-
-			}
-
-		}
-
-		this.matrix.copy( mesh.matrixWorld );
-
-		super.updateMatrixWorld( force );
-
-	}
-
-	/**
-	 * Frees the GPU-related resources allocated by this instance.
-	 * Call this method whenever this instance is no longer used in your app.
-	 */
-	dispose() {
-
-		this.sphereGeometry.dispose();
-
-		this.targetSphereMaterial.dispose();
-		this.effectorSphereMaterial.dispose();
-		this.linkSphereMaterial.dispose();
-		this.lineMaterial.dispose();
-
-		const children = this.children;
-
-		for ( let i = 0; i < children.length; i ++ ) {
-
-			const child = children[ i ];
-
-			if ( child.isLine ) child.geometry.dispose();
-
-		}
-
-	}
-
-	// private method
-
-	_init() {
-
-		const scope = this;
-		const iks = this.iks;
-
-		function createLineGeometry( ik ) {
-
-			const geometry = new BufferGeometry();
-			const vertices = new Float32Array( ( 2 + ik.links.length ) * 3 );
-			geometry.setAttribute( 'position', new BufferAttribute( vertices, 3 ) );
-
-			return geometry;
-
-		}
-
-		function createTargetMesh() {
-
-			return new Mesh( scope.sphereGeometry, scope.targetSphereMaterial );
-
-		}
-
-		function createEffectorMesh() {
-
-			return new Mesh( scope.sphereGeometry, scope.effectorSphereMaterial );
-
-		}
-
-		function createLinkMesh() {
-
-			return new Mesh( scope.sphereGeometry, scope.linkSphereMaterial );
-
-		}
-
-		function createLine( ik ) {
-
-			return new Line( createLineGeometry( ik ), scope.lineMaterial );
-
-		}
-
-		for ( let i = 0, il = iks.length; i < il; i ++ ) {
-
-			const ik = iks[ i ];
-
-			this.add( createTargetMesh() );
-			this.add( createEffectorMesh() );
-
-			for ( let j = 0, jl = ik.links.length; j < jl; j ++ ) {
-
-				this.add( createLinkMesh() );
-
-			}
-
-			this.add( createLine( ik ) );
-
-		}
-
-	}
-
-}
-
-/**
- * This type represents IK configuration objects.
- *
- * @typedef {Object} CCDIKSolver~IK
- * @property {number} target - The target bone index which refers to a bone in the `Skeleton.bones` array.
- * @property {number} effector - The effector bone index which refers to a bone in the `Skeleton.bones` array.
- * @property {Array<CCDIKSolver~BoneLink>} links - An array of bone links.
- * @property {number} [iteration=1] - Iteration number of calculation. Smaller is faster but less precise.
- * @property {number} [minAngle] - Minimum rotation angle in a step in radians.
- * @property {number} [maxAngle] - Minimum rotation angle in a step in radians.
- * @property {number} [blendFactor] - The blend factor.
- **/
-
-/**
- * This type represents bone links.
- *
- * @typedef {Object} CCDIKSolver~BoneLink
- * @property {number} index - The index of a linked bone which refers to a bone in the `Skeleton.bones` array.
- * @property {number} [limitation] - Rotation axis.
- * @property {number} [rotationMin] - Rotation minimum limit.
- * @property {number} [rotationMax] - Rotation maximum limit.
- * @property {boolean} [enabled=true] - Whether the link is enabled or not.
- **/
-
-
-export { CCDIKSolver, CCDIKHelper };

+ 0 - 113
node_modules/three/examples/jsm/capabilities/WebGL.js

@@ -1,113 +0,0 @@
-/**
- * A utility module with basic WebGL 2 capability testing.
- *
- * @hideconstructor
- * @three_import import WebGL from 'three/addons/capabilities/WebGL.js';
- */
-class WebGL {
-
-	/**
-	 * Returns `true` if WebGL 2 is available.
-	 *
-	 * @return {boolean} Whether WebGL 2 is available or not.
-	 */
-	static isWebGL2Available() {
-
-		try {
-
-			const canvas = document.createElement( 'canvas' );
-			return !! ( window.WebGL2RenderingContext && canvas.getContext( 'webgl2' ) );
-
-		} catch ( e ) {
-
-			return false;
-
-		}
-
-	}
-
-	/**
-	 * Returns `true` if the given color space is available. This method can only be used
-	 * if WebGL 2 is supported.
-	 *
-	 * @param {string} colorSpace - The color space to test.
-	 * @return {boolean} Whether the given color space is available or not.
-	 */
-	static isColorSpaceAvailable( colorSpace ) {
-
-		try {
-
-			const canvas = document.createElement( 'canvas' );
-			const ctx = window.WebGL2RenderingContext && canvas.getContext( 'webgl2' );
-			ctx.drawingBufferColorSpace = colorSpace;
-			return ctx.drawingBufferColorSpace === colorSpace; // deepscan-disable-line SAME_OPERAND_VALUE
-
-		} catch ( e ) {
-
-			return false;
-
-		}
-
-	}
-
-	/**
-	 * Returns a `div` element representing a formatted error message that can be appended in
-	 * web sites if WebGL 2 isn't supported.
-	 *
-	 * @return {HTMLDivElement} A `div` element representing a formatted error message that WebGL 2 isn't supported.
-	 */
-	static getWebGL2ErrorMessage() {
-
-		return this._getErrorMessage( 2 );
-
-	}
-
-	// private
-
-	static _getErrorMessage( version ) {
-
-		const names = {
-			1: 'WebGL',
-			2: 'WebGL 2'
-		};
-
-		const contexts = {
-			1: window.WebGLRenderingContext,
-			2: window.WebGL2RenderingContext
-		};
-
-		let message = 'Your $0 does not seem to support <a href="http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation" style="color:#000">$1</a>';
-
-		const element = document.createElement( 'div' );
-		element.id = 'webglmessage';
-		element.style.fontFamily = 'monospace';
-		element.style.fontSize = '13px';
-		element.style.fontWeight = 'normal';
-		element.style.textAlign = 'center';
-		element.style.background = '#fff';
-		element.style.color = '#000';
-		element.style.padding = '1.5em';
-		element.style.width = '400px';
-		element.style.margin = '5em auto 0';
-
-		if ( contexts[ version ] ) {
-
-			message = message.replace( '$0', 'graphics card' );
-
-		} else {
-
-			message = message.replace( '$0', 'browser' );
-
-		}
-
-		message = message.replace( '$1', names[ version ] );
-
-		element.innerHTML = message;
-
-		return element;
-
-	}
-
-}
-
-export default WebGL;

+ 0 - 59
node_modules/three/examples/jsm/capabilities/WebGPU.js

@@ -1,59 +0,0 @@
-let isAvailable = ( typeof navigator !== 'undefined' && navigator.gpu !== undefined );
-
-if ( typeof window !== 'undefined' && isAvailable ) {
-
-	isAvailable = Boolean( await navigator.gpu.requestAdapter() );
-
-}
-
-/**
- * A utility module with basic WebGPU capability testing.
- *
- * @hideconstructor
- * @three_import import WebGPU from 'three/addons/capabilities/WebGPU.js';
- */
-class WebGPU {
-
-	/**
-	 * Returns `true` if WebGPU is available.
-	 *
-	 * @return {boolean} Whether WebGPU is available or not.
-	 */
-	static isAvailable() {
-
-		return Boolean( isAvailable );
-
-	}
-
-	/**
-	 * Returns a `div` element representing a formatted error message that can be appended in
-	 * web sites if WebGPU isn't supported.
-	 *
-	 * @return {HTMLDivElement} A `div` element representing a formatted error message that WebGPU isn't supported.
-	 */
-	static getErrorMessage() {
-
-		const message = 'Your browser does not support <a href="https://gpuweb.github.io/gpuweb/" style="color:blue">WebGPU</a> yet';
-
-		const element = document.createElement( 'div' );
-		element.id = 'webgpumessage';
-		element.style.fontFamily = 'monospace';
-		element.style.fontSize = '13px';
-		element.style.fontWeight = 'normal';
-		element.style.textAlign = 'center';
-		element.style.background = '#fff';
-		element.style.color = '#000';
-		element.style.padding = '1.5em';
-		element.style.maxWidth = '400px';
-		element.style.margin = '5em auto 0';
-
-		element.innerHTML = message;
-
-		return element;
-
-	}
-
-}
-
-
-export default WebGPU;

+ 0 - 3539
node_modules/three/examples/jsm/controls/ArcballControls.js

@@ -1,3539 +0,0 @@
-import {
-	Controls,
-	GridHelper,
-	EllipseCurve,
-	BufferGeometry,
-	Line,
-	LineBasicMaterial,
-	Raycaster,
-	Group,
-	Box3,
-	Sphere,
-	Quaternion,
-	Vector2,
-	Vector3,
-	Matrix4,
-	MathUtils
-} from 'three';
-
-//trackball state
-const STATE = {
-
-	IDLE: Symbol(),
-	ROTATE: Symbol(),
-	PAN: Symbol(),
-	SCALE: Symbol(),
-	FOV: Symbol(),
-	FOCUS: Symbol(),
-	ZROTATE: Symbol(),
-	TOUCH_MULTI: Symbol(),
-	ANIMATION_FOCUS: Symbol(),
-	ANIMATION_ROTATE: Symbol()
-
-};
-
-const INPUT = {
-
-	NONE: Symbol(),
-	ONE_FINGER: Symbol(),
-	ONE_FINGER_SWITCHED: Symbol(),
-	TWO_FINGER: Symbol(),
-	MULT_FINGER: Symbol(),
-	CURSOR: Symbol()
-
-};
-
-//cursor center coordinates
-const _center = {
-
-	x: 0,
-	y: 0
-
-};
-
-//transformation matrices for gizmos and camera
-const _transformation = {
-
-	camera: new Matrix4(),
-	gizmos: new Matrix4()
-
-};
-
-/**
- * Fires when the camera has been transformed by the controls.
- *
- * @event ArcballControls#change
- * @type {Object}
- */
-const _changeEvent = { type: 'change' };
-
-/**
- * Fires when an interaction was initiated.
- *
- * @event ArcballControls#start
- * @type {Object}
- */
-const _startEvent = { type: 'start' };
-
-/**
- * Fires when an interaction has finished.
- *
- * @event ArcballControls#end
- * @type {Object}
- */
-const _endEvent = { type: 'end' };
-
-const _raycaster = new Raycaster();
-const _offset = new Vector3();
-
-const _gizmoMatrixStateTemp = new Matrix4();
-const _cameraMatrixStateTemp = new Matrix4();
-const _scalePointTemp = new Vector3();
-
-const _EPS = 0.000001;
-
-/**
- * Arcball controls allow the camera to be controlled by a virtual trackball with full touch support and advanced navigation functionality.
- * Cursor/finger positions and movements are mapped over a virtual trackball surface represented by a gizmo and mapped in intuitive and
- * consistent camera movements. Dragging cursor/fingers will cause camera to orbit around the center of the trackball in a conservative
- * way (returning to the starting point will make the camera return to its starting orientation).
- *
- * In addition to supporting pan, zoom and pinch gestures, double clicking/tapping focuses on a point, intuitively moving the object's
- * point of interest to the center of the virtual trackball. Focus allows a much better inspection and navigation in complex environment.
- * Moreover Arcball controls allow FOV manipulation (in a vertigo-style method) and z-rotation. Saving and restoring of Camera State
- * is supported also through clipboard (use ctrl+c and ctrl+v shortcuts for copy and paste the state).
- *
- * Unlike {@link OrbitControls} and {@link TrackballControls}, `ArcballControls` doesn't require `update()` to be called externally in an
- * animation loop when animations are on.
- *
- * @augments Controls
- * @three_import import { ArcballControls } from 'three/addons/controls/ArcballControls.js';
- */
-class ArcballControls extends Controls {
-
-	/**
-	 * Constructs a new controls instance.
-	 *
-	 * @param {Camera} camera - The camera to be controlled. The camera must not be a child of another object, unless that object is the scene itself.
-	 * @param {?HTMLElement} [domElement=null] - The HTML element used for event listeners.
-	 * @param {?Scene} [scene=null] The scene rendered by the camera. If not given, gizmos cannot be shown.
-	 */
-	constructor( camera, domElement = null, scene = null ) {
-
-		super( camera, domElement );
-
-		/**
-		 * The scene rendered by the camera. If not given, gizmos cannot be shown.
-		 *
-		 * @type {?Scene}
-		 * @default null
-		 */
-		this.scene = scene;
-
-		/**
-		 * The control's focus point.
-		 *
-		 * @type {Vector3}
-		 */
-		this.target = new Vector3();
-		this._currentTarget = new Vector3();
-
-		/**
-		 * The size of the gizmo relative to the screen width and height.
-		 *
-		 * @type {number}
-		 * @default 0.67
-		 */
-		this.radiusFactor = 0.67;
-
-		/**
-		 * Holds the mouse actions of this controls. This property is maintained by the methods
-		 * `setMouseAction()` and `unsetMouseAction()`.
-		 *
-		 * @type {Array<Object>}
-		 */
-		this.mouseActions = [];
-		this._mouseOp = null;
-
-
-		//global vectors and matrices that are used in some operations to avoid creating new objects every time (e.g. every time cursor moves)
-		this._v2_1 = new Vector2();
-		this._v3_1 = new Vector3();
-		this._v3_2 = new Vector3();
-
-		this._m4_1 = new Matrix4();
-		this._m4_2 = new Matrix4();
-
-		this._quat = new Quaternion();
-
-		//transformation matrices
-		this._translationMatrix = new Matrix4(); //matrix for translation operation
-		this._rotationMatrix = new Matrix4(); //matrix for rotation operation
-		this._scaleMatrix = new Matrix4(); //matrix for scaling operation
-
-		this._rotationAxis = new Vector3(); //axis for rotate operation
-
-
-		//camera state
-		this._cameraMatrixState = new Matrix4();
-		this._cameraProjectionState = new Matrix4();
-
-		this._fovState = 1;
-		this._upState = new Vector3();
-		this._zoomState = 1;
-		this._nearPos = 0;
-		this._farPos = 0;
-
-		this._gizmoMatrixState = new Matrix4();
-
-		//initial values
-		this._up0 = new Vector3();
-		this._zoom0 = 1;
-		this._fov0 = 0;
-		this._initialNear = 0;
-		this._nearPos0 = 0;
-		this._initialFar = 0;
-		this._farPos0 = 0;
-		this._cameraMatrixState0 = new Matrix4();
-		this._gizmoMatrixState0 = new Matrix4();
-		this._target0 = new Vector3();
-
-		//pointers array
-		this._button = - 1;
-		this._touchStart = [];
-		this._touchCurrent = [];
-		this._input = INPUT.NONE;
-
-		//two fingers touch interaction
-		this._switchSensibility = 32;	//minimum movement to be performed to fire single pan start after the second finger has been released
-		this._startFingerDistance = 0; //distance between two fingers
-		this._currentFingerDistance = 0;
-		this._startFingerRotation = 0; //amount of rotation performed with two fingers
-		this._currentFingerRotation = 0;
-
-		//double tap
-		this._devPxRatio = 0;
-		this._downValid = true;
-		this._nclicks = 0;
-		this._downEvents = [];
-		this._downStart = 0;	//pointerDown time
-		this._clickStart = 0;	//first click time
-		this._maxDownTime = 250;
-		this._maxInterval = 300;
-		this._posThreshold = 24;
-		this._movementThreshold = 24;
-
-		//cursor positions
-		this._currentCursorPosition = new Vector3();
-		this._startCursorPosition = new Vector3();
-
-		//grid
-		this._grid = null; //grid to be visualized during pan operation
-		this._gridPosition = new Vector3();
-
-		//gizmos
-		this._gizmos = new Group();
-		this._curvePts = 128;
-
-
-		//animations
-		this._timeStart = - 1; //initial time
-		this._animationId = - 1;
-
-		/**
-		 * Duration of focus animations in ms.
-		 *
-		 * @type {number}
-		 * @default 500
-		 */
-		this.focusAnimationTime = 500;
-
-		//rotate animation
-		this._timePrev = 0; //time at which previous rotate operation has been detected
-		this._timeCurrent = 0; //time at which current rotate operation has been detected
-		this._anglePrev = 0; //angle of previous rotation
-		this._angleCurrent = 0; //angle of current rotation
-		this._cursorPosPrev = new Vector3();	//cursor position when previous rotate operation has been detected
-		this._cursorPosCurr = new Vector3();//cursor position when current rotate operation has been detected
-		this._wPrev = 0; //angular velocity of the previous rotate operation
-		this._wCurr = 0; //angular velocity of the current rotate operation
-
-		//parameters
-
-		/**
-		 * If set to `true`, the camera's near and far values will be adjusted every time zoom is
-		 * performed trying to maintain the same visible portion given by initial near and far
-		 * values. Only works with perspective cameras.
-		 *
-		 * @type {boolean}
-		 * @default false
-		 */
-		this.adjustNearFar = false;
-
-		/**
-		 * The scaling factor used when performing zoom operation.
-		 *
-		 * @type {number}
-		 * @default 1.1
-		 */
-		this.scaleFactor = 1.1;
-
-		/**
-		 * The damping inertia used if 'enableAnimations` is set to `true`.
-		 *
-		 * @type {number}
-		 * @default 25
-		 */
-		this.dampingFactor = 25;
-
-		/**
-		 * Maximum angular velocity allowed on rotation animation start.
-		 *
-		 * @type {number}
-		 * @default 20
-		 */
-		this.wMax = 20;
-
-		/**
-		 * Set to `true` to enable animations for rotation (damping) and focus operation.
-		 *
-		 * @type {boolean}
-		 * @default true
-		 */
-		this.enableAnimations = true;
-
-		/**
-		 * If set to `true`, a grid will appear when panning operation is being performed
-		 * (desktop interaction only).
-		 *
-		 * @type {boolean}
-		 * @default false
-		 */
-		this.enableGrid = false;
-
-		/**
-		 * Set to `true` to make zoom become cursor centered.
-		 *
-		 * @type {boolean}
-		 * @default false
-		 */
-		this.cursorZoom = false;
-
-		/**
-		 * The minimum FOV in degrees.
-		 *
-		 * @type {number}
-		 * @default 5
-		 */
-		this.minFov = 5;
-
-		/**
-		 * The maximum FOV in degrees.
-		 *
-		 * @type {number}
-		 * @default 90
-		 */
-		this.maxFov = 90;
-
-		/**
-		 * Speed of rotation.
-		 *
-		 * @type {number}
-		 * @default 1
-		 */
-		this.rotateSpeed = 1;
-
-		/**
-		 * Enable or disable camera panning.
-		 *
-		 * @type {boolean}
-		 * @default true
-		 */
-		this.enablePan = true;
-
-		/**
-		 * Enable or disable camera rotation.
-		 *
-		 * @type {boolean}
-		 * @default true
-		 */
-		this.enableRotate = true;
-
-		/**
-		 * Enable or disable camera zoom.
-		 *
-		 * @type {boolean}
-		 * @default true
-		 */
-		this.enableZoom = true;
-
-		/**
-		 * Enable or disable gizmos.
-		 *
-		 * @type {boolean}
-		 * @default true
-		 */
-		this.enableGizmos = true;
-
-		/**
-		 * Enable or disable camera focusing on double-tap (or click) operations.
-		 *
-		 * @type {boolean}
-		 * @default true
-		 */
-		this.enableFocus = true;
-
-		/**
-		 * How far you can dolly in. For perspective cameras only.
-		 *
-		 * @type {number}
-		 * @default 0
-		 */
-		this.minDistance = 0;
-
-		/**
-		 * How far you can dolly out. For perspective cameras only.
-		 *
-		 * @type {number}
-		 * @default Infinity
-		 */
-		this.maxDistance = Infinity;
-
-		/**
-		 * How far you can zoom in. For orthographic cameras only.
-		 *
-		 * @type {number}
-		 * @default 0
-		 */
-		this.minZoom = 0;
-
-		/**
-		 * How far you can zoom out. For orthographic cameras only.
-		 *
-		 * @type {number}
-		 * @default Infinity
-		 */
-		this.maxZoom = Infinity;
-
-		//trackball parameters
-		this._tbRadius = 1;
-
-		//FSA
-		this._state = STATE.IDLE;
-
-		this.setCamera( camera );
-
-		if ( this.scene != null ) {
-
-			this.scene.add( this._gizmos );
-
-		}
-
-		this.initializeMouseActions();
-
-		// event listeners
-
-		this._onContextMenu = onContextMenu.bind( this );
-		this._onWheel = onWheel.bind( this );
-		this._onPointerUp = onPointerUp.bind( this );
-		this._onPointerMove = onPointerMove.bind( this );
-		this._onPointerDown = onPointerDown.bind( this );
-		this._onPointerCancel = onPointerCancel.bind( this );
-		this._onWindowResize = onWindowResize.bind( this );
-
-		if ( domElement !== null ) {
-
-			this.connect( domElement );
-
-		}
-
-	}
-
-	connect( element ) {
-
-		super.connect( element );
-
-		this._devPxRatio = window.devicePixelRatio;
-
-		this.domElement.addEventListener( 'contextmenu', this._onContextMenu );
-		this.domElement.addEventListener( 'wheel', this._onWheel, { passive: false } );
-		this.domElement.addEventListener( 'pointerdown', this._onPointerDown );
-		this.domElement.addEventListener( 'pointercancel', this._onPointerCancel );
-
-		window.addEventListener( 'resize', this._onWindowResize );
-
-		this.domElement.style.touchAction = 'none'; // Disable touch scroll
-
-	}
-
-	disconnect() {
-
-		this.domElement.removeEventListener( 'pointerdown', this._onPointerDown );
-		this.domElement.removeEventListener( 'pointercancel', this._onPointerCancel );
-		this.domElement.removeEventListener( 'wheel', this._onWheel );
-		this.domElement.removeEventListener( 'contextmenu', this._onContextMenu );
-
-		window.removeEventListener( 'pointermove', this._onPointerMove );
-		window.removeEventListener( 'pointerup', this._onPointerUp );
-
-		window.removeEventListener( 'resize', this._onWindowResize );
-
-		this.domElement.style.touchAction = ''; // Restore touch scroll
-
-	}
-
-	onSinglePanStart( event, operation ) {
-
-		if ( this.enabled ) {
-
-			this.dispatchEvent( _startEvent );
-
-			this.setCenter( event.clientX, event.clientY );
-
-			switch ( operation ) {
-
-				case 'PAN':
-
-					if ( ! this.enablePan ) {
-
-						return;
-
-					}
-
-					if ( this._animationId != - 1 ) {
-
-						cancelAnimationFrame( this._animationId );
-						this._animationId = - 1;
-						this._timeStart = - 1;
-
-						this.activateGizmos( false );
-						this.dispatchEvent( _changeEvent );
-
-					}
-
-					this.updateTbState( STATE.PAN, true );
-					this._startCursorPosition.copy( this.unprojectOnTbPlane( this.object, _center.x, _center.y, this.domElement ) );
-					if ( this.enableGrid ) {
-
-						this.drawGrid();
-						this.dispatchEvent( _changeEvent );
-
-					}
-
-					break;
-
-				case 'ROTATE':
-
-					if ( ! this.enableRotate ) {
-
-						return;
-
-					}
-
-					if ( this._animationId != - 1 ) {
-
-						cancelAnimationFrame( this._animationId );
-						this._animationId = - 1;
-						this._timeStart = - 1;
-
-					}
-
-					this.updateTbState( STATE.ROTATE, true );
-					this._startCursorPosition.copy( this.unprojectOnTbSurface( this.object, _center.x, _center.y, this.domElement, this._tbRadius ) );
-					this.activateGizmos( true );
-					if ( this.enableAnimations ) {
-
-						this._timePrev = this._timeCurrent = performance.now();
-						this._angleCurrent = this._anglePrev = 0;
-						this._cursorPosPrev.copy( this._startCursorPosition );
-						this._cursorPosCurr.copy( this._cursorPosPrev );
-						this._wCurr = 0;
-						this._wPrev = this._wCurr;
-
-					}
-
-					this.dispatchEvent( _changeEvent );
-					break;
-
-				case 'FOV':
-
-					if ( ! this.object.isPerspectiveCamera || ! this.enableZoom ) {
-
-						return;
-
-					}
-
-					if ( this._animationId != - 1 ) {
-
-						cancelAnimationFrame( this._animationId );
-						this._animationId = - 1;
-						this._timeStart = - 1;
-
-						this.activateGizmos( false );
-						this.dispatchEvent( _changeEvent );
-
-					}
-
-					this.updateTbState( STATE.FOV, true );
-					this._startCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 );
-					this._currentCursorPosition.copy( this._startCursorPosition );
-					break;
-
-				case 'ZOOM':
-
-					if ( ! this.enableZoom ) {
-
-						return;
-
-					}
-
-					if ( this._animationId != - 1 ) {
-
-						cancelAnimationFrame( this._animationId );
-						this._animationId = - 1;
-						this._timeStart = - 1;
-
-						this.activateGizmos( false );
-						this.dispatchEvent( _changeEvent );
-
-					}
-
-					this.updateTbState( STATE.SCALE, true );
-					this._startCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 );
-					this._currentCursorPosition.copy( this._startCursorPosition );
-					break;
-
-			}
-
-		}
-
-	}
-
-	onSinglePanMove( event, opState ) {
-
-		if ( this.enabled ) {
-
-			const restart = opState != this._state;
-			this.setCenter( event.clientX, event.clientY );
-
-			switch ( opState ) {
-
-				case STATE.PAN:
-
-					if ( this.enablePan ) {
-
-						if ( restart ) {
-
-							//switch to pan operation
-
-							this.dispatchEvent( _endEvent );
-							this.dispatchEvent( _startEvent );
-
-							this.updateTbState( opState, true );
-							this._startCursorPosition.copy( this.unprojectOnTbPlane( this.object, _center.x, _center.y, this.domElement ) );
-							if ( this.enableGrid ) {
-
-								this.drawGrid();
-
-							}
-
-							this.activateGizmos( false );
-
-						} else {
-
-							//continue with pan operation
-							this._currentCursorPosition.copy( this.unprojectOnTbPlane( this.object, _center.x, _center.y, this.domElement ) );
-							this.applyTransformMatrix( this.pan( this._startCursorPosition, this._currentCursorPosition ) );
-
-						}
-
-					}
-
-					break;
-
-				case STATE.ROTATE:
-
-					if ( this.enableRotate ) {
-
-						if ( restart ) {
-
-							//switch to rotate operation
-
-							this.dispatchEvent( _endEvent );
-							this.dispatchEvent( _startEvent );
-
-							this.updateTbState( opState, true );
-							this._startCursorPosition.copy( this.unprojectOnTbSurface( this.object, _center.x, _center.y, this.domElement, this._tbRadius ) );
-
-							if ( this.enableGrid ) {
-
-								this.disposeGrid();
-
-							}
-
-							this.activateGizmos( true );
-
-						} else {
-
-							//continue with rotate operation
-							this._currentCursorPosition.copy( this.unprojectOnTbSurface( this.object, _center.x, _center.y, this.domElement, this._tbRadius ) );
-
-							const distance = this._startCursorPosition.distanceTo( this._currentCursorPosition );
-							const angle = this._startCursorPosition.angleTo( this._currentCursorPosition );
-							const amount = Math.max( distance / this._tbRadius, angle ) * this.rotateSpeed; //effective rotation angle
-
-							this.applyTransformMatrix( this.rotate( this.calculateRotationAxis( this._startCursorPosition, this._currentCursorPosition ), amount ) );
-
-							if ( this.enableAnimations ) {
-
-								this._timePrev = this._timeCurrent;
-								this._timeCurrent = performance.now();
-								this._anglePrev = this._angleCurrent;
-								this._angleCurrent = amount;
-								this._cursorPosPrev.copy( this._cursorPosCurr );
-								this._cursorPosCurr.copy( this._currentCursorPosition );
-								this._wPrev = this._wCurr;
-								this._wCurr = this.calculateAngularSpeed( this._anglePrev, this._angleCurrent, this._timePrev, this._timeCurrent );
-
-							}
-
-						}
-
-					}
-
-					break;
-
-				case STATE.SCALE:
-
-					if ( this.enableZoom ) {
-
-						if ( restart ) {
-
-							//switch to zoom operation
-
-							this.dispatchEvent( _endEvent );
-							this.dispatchEvent( _startEvent );
-
-							this.updateTbState( opState, true );
-							this._startCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 );
-							this._currentCursorPosition.copy( this._startCursorPosition );
-
-							if ( this.enableGrid ) {
-
-								this.disposeGrid();
-
-							}
-
-							this.activateGizmos( false );
-
-						} else {
-
-							//continue with zoom operation
-							const screenNotches = 8;	//how many wheel notches corresponds to a full screen pan
-							this._currentCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 );
-
-							const movement = this._currentCursorPosition.y - this._startCursorPosition.y;
-
-							let size = 1;
-
-							if ( movement < 0 ) {
-
-								size = 1 / ( Math.pow( this.scaleFactor, - movement * screenNotches ) );
-
-							} else if ( movement > 0 ) {
-
-								size = Math.pow( this.scaleFactor, movement * screenNotches );
-
-							}
-
-							this._v3_1.setFromMatrixPosition( this._gizmoMatrixState );
-
-							this.applyTransformMatrix( this.scale( size, this._v3_1 ) );
-
-						}
-
-					}
-
-					break;
-
-				case STATE.FOV:
-
-					if ( this.enableZoom && this.object.isPerspectiveCamera ) {
-
-						if ( restart ) {
-
-							//switch to fov operation
-
-							this.dispatchEvent( _endEvent );
-							this.dispatchEvent( _startEvent );
-
-							this.updateTbState( opState, true );
-							this._startCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 );
-							this._currentCursorPosition.copy( this._startCursorPosition );
-
-							if ( this.enableGrid ) {
-
-								this.disposeGrid();
-
-							}
-
-							this.activateGizmos( false );
-
-						} else {
-
-							//continue with fov operation
-							const screenNotches = 8;	//how many wheel notches corresponds to a full screen pan
-							this._currentCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 );
-
-							const movement = this._currentCursorPosition.y - this._startCursorPosition.y;
-
-							let size = 1;
-
-							if ( movement < 0 ) {
-
-								size = 1 / ( Math.pow( this.scaleFactor, - movement * screenNotches ) );
-
-							} else if ( movement > 0 ) {
-
-								size = Math.pow( this.scaleFactor, movement * screenNotches );
-
-							}
-
-							this._v3_1.setFromMatrixPosition( this._cameraMatrixState );
-							const x = this._v3_1.distanceTo( this._gizmos.position );
-							let xNew = x / size; //distance between camera and gizmos if scale(size, scalepoint) would be performed
-
-							//check min and max distance
-							xNew = MathUtils.clamp( xNew, this.minDistance, this.maxDistance );
-
-							const y = x * Math.tan( MathUtils.DEG2RAD * this._fovState * 0.5 );
-
-							//calculate new fov
-							let newFov = MathUtils.RAD2DEG * ( Math.atan( y / xNew ) * 2 );
-
-							//check min and max fov
-							newFov = MathUtils.clamp( newFov, this.minFov, this.maxFov );
-
-							const newDistance = y / Math.tan( MathUtils.DEG2RAD * ( newFov / 2 ) );
-							size = x / newDistance;
-							this._v3_2.setFromMatrixPosition( this._gizmoMatrixState );
-
-							this.setFov( newFov );
-							this.applyTransformMatrix( this.scale( size, this._v3_2, false ) );
-
-							//adjusting distance
-							_offset.copy( this._gizmos.position ).sub( this.object.position ).normalize().multiplyScalar( newDistance / x );
-							this._m4_1.makeTranslation( _offset.x, _offset.y, _offset.z );
-
-						}
-
-					}
-
-					break;
-
-			}
-
-			this.dispatchEvent( _changeEvent );
-
-		}
-
-	}
-
-	onSinglePanEnd() {
-
-		if ( this._state == STATE.ROTATE ) {
-
-
-			if ( ! this.enableRotate ) {
-
-				return;
-
-			}
-
-			if ( this.enableAnimations ) {
-
-				//perform rotation animation
-				const deltaTime = ( performance.now() - this._timeCurrent );
-				if ( deltaTime < 120 ) {
-
-					const w = Math.abs( ( this._wPrev + this._wCurr ) / 2 );
-
-					const self = this;
-					this._animationId = window.requestAnimationFrame( function ( t ) {
-
-						self.updateTbState( STATE.ANIMATION_ROTATE, true );
-						const rotationAxis = self.calculateRotationAxis( self._cursorPosPrev, self._cursorPosCurr );
-
-						self.onRotationAnim( t, rotationAxis, Math.min( w, self.wMax ) );
-
-					} );
-
-				} else {
-
-					//cursor has been standing still for over 120 ms since last movement
-					this.updateTbState( STATE.IDLE, false );
-					this.activateGizmos( false );
-					this.dispatchEvent( _changeEvent );
-
-				}
-
-			} else {
-
-				this.updateTbState( STATE.IDLE, false );
-				this.activateGizmos( false );
-				this.dispatchEvent( _changeEvent );
-
-			}
-
-		} else if ( this._state == STATE.PAN || this._state == STATE.IDLE ) {
-
-			this.updateTbState( STATE.IDLE, false );
-
-			if ( this.enableGrid ) {
-
-				this.disposeGrid();
-
-			}
-
-			this.activateGizmos( false );
-			this.dispatchEvent( _changeEvent );
-
-
-		}
-
-		this.dispatchEvent( _endEvent );
-
-	}
-
-	onDoubleTap( event ) {
-
-		if ( this.enabled && this.enablePan && this.enableFocus && this.scene != null ) {
-
-			this.dispatchEvent( _startEvent );
-
-			this.setCenter( event.clientX, event.clientY );
-			const hitP = this.unprojectOnObj( this.getCursorNDC( _center.x, _center.y, this.domElement ), this.object );
-
-			if ( hitP != null && this.enableAnimations ) {
-
-				const self = this;
-				if ( this._animationId != - 1 ) {
-
-					window.cancelAnimationFrame( this._animationId );
-
-				}
-
-				this._timeStart = - 1;
-				this._animationId = window.requestAnimationFrame( function ( t ) {
-
-					self.updateTbState( STATE.ANIMATION_FOCUS, true );
-					self.onFocusAnim( t, hitP, self._cameraMatrixState, self._gizmoMatrixState );
-
-				} );
-
-			} else if ( hitP != null && ! this.enableAnimations ) {
-
-				this.updateTbState( STATE.FOCUS, true );
-				this.focus( hitP, this.scaleFactor );
-				this.updateTbState( STATE.IDLE, false );
-				this.dispatchEvent( _changeEvent );
-
-			}
-
-		}
-
-		this.dispatchEvent( _endEvent );
-
-	}
-
-	onDoublePanStart() {
-
-		if ( this.enabled && this.enablePan ) {
-
-			this.dispatchEvent( _startEvent );
-
-			this.updateTbState( STATE.PAN, true );
-
-			this.setCenter( ( this._touchCurrent[ 0 ].clientX + this._touchCurrent[ 1 ].clientX ) / 2, ( this._touchCurrent[ 0 ].clientY + this._touchCurrent[ 1 ].clientY ) / 2 );
-			this._startCursorPosition.copy( this.unprojectOnTbPlane( this.object, _center.x, _center.y, this.domElement, true ) );
-			this._currentCursorPosition.copy( this._startCursorPosition );
-
-			this.activateGizmos( false );
-
-		}
-
-	}
-
-	onDoublePanMove() {
-
-		if ( this.enabled && this.enablePan ) {
-
-			this.setCenter( ( this._touchCurrent[ 0 ].clientX + this._touchCurrent[ 1 ].clientX ) / 2, ( this._touchCurrent[ 0 ].clientY + this._touchCurrent[ 1 ].clientY ) / 2 );
-
-			if ( this._state != STATE.PAN ) {
-
-				this.updateTbState( STATE.PAN, true );
-				this._startCursorPosition.copy( this._currentCursorPosition );
-
-			}
-
-			this._currentCursorPosition.copy( this.unprojectOnTbPlane( this.object, _center.x, _center.y, this.domElement, true ) );
-			this.applyTransformMatrix( this.pan( this._startCursorPosition, this._currentCursorPosition, true ) );
-			this.dispatchEvent( _changeEvent );
-
-		}
-
-	}
-
-	onDoublePanEnd() {
-
-		this.updateTbState( STATE.IDLE, false );
-		this.dispatchEvent( _endEvent );
-
-	}
-
-	onRotateStart() {
-
-		if ( this.enabled && this.enableRotate ) {
-
-			this.dispatchEvent( _startEvent );
-
-			this.updateTbState( STATE.ZROTATE, true );
-
-			//this._startFingerRotation = event.rotation;
-
-			this._startFingerRotation = this.getAngle( this._touchCurrent[ 1 ], this._touchCurrent[ 0 ] ) + this.getAngle( this._touchStart[ 1 ], this._touchStart[ 0 ] );
-			this._currentFingerRotation = this._startFingerRotation;
-
-			this.object.getWorldDirection( this._rotationAxis ); //rotation axis
-
-			if ( ! this.enablePan && ! this.enableZoom ) {
-
-				this.activateGizmos( true );
-
-			}
-
-		}
-
-	}
-
-	onRotateMove() {
-
-		if ( this.enabled && this.enableRotate ) {
-
-			this.setCenter( ( this._touchCurrent[ 0 ].clientX + this._touchCurrent[ 1 ].clientX ) / 2, ( this._touchCurrent[ 0 ].clientY + this._touchCurrent[ 1 ].clientY ) / 2 );
-			let rotationPoint;
-
-			if ( this._state != STATE.ZROTATE ) {
-
-				this.updateTbState( STATE.ZROTATE, true );
-				this._startFingerRotation = this._currentFingerRotation;
-
-			}
-
-			//this._currentFingerRotation = event.rotation;
-			this._currentFingerRotation = this.getAngle( this._touchCurrent[ 1 ], this._touchCurrent[ 0 ] ) + this.getAngle( this._touchStart[ 1 ], this._touchStart[ 0 ] );
-
-			if ( ! this.enablePan ) {
-
-				rotationPoint = new Vector3().setFromMatrixPosition( this._gizmoMatrixState );
-
-			} else {
-
-				this._v3_2.setFromMatrixPosition( this._gizmoMatrixState );
-				rotationPoint = this.unprojectOnTbPlane( this.object, _center.x, _center.y, this.domElement ).applyQuaternion( this.object.quaternion ).multiplyScalar( 1 / this.object.zoom ).add( this._v3_2 );
-
-			}
-
-			const amount = MathUtils.DEG2RAD * ( this._startFingerRotation - this._currentFingerRotation );
-
-			this.applyTransformMatrix( this.zRotate( rotationPoint, amount ) );
-			this.dispatchEvent( _changeEvent );
-
-		}
-
-	}
-
-	onRotateEnd() {
-
-		this.updateTbState( STATE.IDLE, false );
-		this.activateGizmos( false );
-		this.dispatchEvent( _endEvent );
-
-	}
-
-	onPinchStart() {
-
-		if ( this.enabled && this.enableZoom ) {
-
-			this.dispatchEvent( _startEvent );
-			this.updateTbState( STATE.SCALE, true );
-
-			this._startFingerDistance = this.calculatePointersDistance( this._touchCurrent[ 0 ], this._touchCurrent[ 1 ] );
-			this._currentFingerDistance = this._startFingerDistance;
-
-			this.activateGizmos( false );
-
-		}
-
-	}
-
-	onPinchMove() {
-
-		if ( this.enabled && this.enableZoom ) {
-
-			this.setCenter( ( this._touchCurrent[ 0 ].clientX + this._touchCurrent[ 1 ].clientX ) / 2, ( this._touchCurrent[ 0 ].clientY + this._touchCurrent[ 1 ].clientY ) / 2 );
-			const minDistance = 12; //minimum distance between fingers (in css pixels)
-
-			if ( this._state != STATE.SCALE ) {
-
-				this._startFingerDistance = this._currentFingerDistance;
-				this.updateTbState( STATE.SCALE, true );
-
-			}
-
-			this._currentFingerDistance = Math.max( this.calculatePointersDistance( this._touchCurrent[ 0 ], this._touchCurrent[ 1 ] ), minDistance * this._devPxRatio );
-			const amount = this._currentFingerDistance / this._startFingerDistance;
-
-			let scalePoint;
-
-			if ( ! this.enablePan ) {
-
-				scalePoint = this._gizmos.position;
-
-			} else {
-
-				if ( this.object.isOrthographicCamera ) {
-
-					scalePoint = this.unprojectOnTbPlane( this.object, _center.x, _center.y, this.domElement )
-						.applyQuaternion( this.object.quaternion )
-						.multiplyScalar( 1 / this.object.zoom )
-						.add( this._gizmos.position );
-
-				} else if ( this.object.isPerspectiveCamera ) {
-
-					scalePoint = this.unprojectOnTbPlane( this.object, _center.x, _center.y, this.domElement )
-						.applyQuaternion( this.object.quaternion )
-						.add( this._gizmos.position );
-
-				}
-
-			}
-
-			this.applyTransformMatrix( this.scale( amount, scalePoint ) );
-			this.dispatchEvent( _changeEvent );
-
-		}
-
-	}
-
-	onPinchEnd() {
-
-		this.updateTbState( STATE.IDLE, false );
-		this.dispatchEvent( _endEvent );
-
-	}
-
-	onTriplePanStart() {
-
-		if ( this.enabled && this.enableZoom ) {
-
-			this.dispatchEvent( _startEvent );
-
-			this.updateTbState( STATE.SCALE, true );
-
-			//const center = event.center;
-			let clientX = 0;
-			let clientY = 0;
-			const nFingers = this._touchCurrent.length;
-
-			for ( let i = 0; i < nFingers; i ++ ) {
-
-				clientX += this._touchCurrent[ i ].clientX;
-				clientY += this._touchCurrent[ i ].clientY;
-
-			}
-
-			this.setCenter( clientX / nFingers, clientY / nFingers );
-
-			this._startCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 );
-			this._currentCursorPosition.copy( this._startCursorPosition );
-
-		}
-
-	}
-
-	onTriplePanMove() {
-
-		if ( this.enabled && this.enableZoom ) {
-
-			//	  fov / 2
-			//		|\
-			//		| \
-			//		|  \
-			//	x	|	\
-			//		| 	 \
-			//		| 	  \
-			//		| _ _ _\
-			//			y
-
-			//const center = event.center;
-			let clientX = 0;
-			let clientY = 0;
-			const nFingers = this._touchCurrent.length;
-
-			for ( let i = 0; i < nFingers; i ++ ) {
-
-				clientX += this._touchCurrent[ i ].clientX;
-				clientY += this._touchCurrent[ i ].clientY;
-
-			}
-
-			this.setCenter( clientX / nFingers, clientY / nFingers );
-
-			const screenNotches = 8;	//how many wheel notches corresponds to a full screen pan
-			this._currentCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 );
-
-			const movement = this._currentCursorPosition.y - this._startCursorPosition.y;
-
-			let size = 1;
-
-			if ( movement < 0 ) {
-
-				size = 1 / ( Math.pow( this.scaleFactor, - movement * screenNotches ) );
-
-			} else if ( movement > 0 ) {
-
-				size = Math.pow( this.scaleFactor, movement * screenNotches );
-
-			}
-
-			this._v3_1.setFromMatrixPosition( this._cameraMatrixState );
-			const x = this._v3_1.distanceTo( this._gizmos.position );
-			let xNew = x / size; //distance between camera and gizmos if scale(size, scalepoint) would be performed
-
-			//check min and max distance
-			xNew = MathUtils.clamp( xNew, this.minDistance, this.maxDistance );
-
-			const y = x * Math.tan( MathUtils.DEG2RAD * this._fovState * 0.5 );
-
-			//calculate new fov
-			let newFov = MathUtils.RAD2DEG * ( Math.atan( y / xNew ) * 2 );
-
-			//check min and max fov
-			newFov = MathUtils.clamp( newFov, this.minFov, this.maxFov );
-
-			const newDistance = y / Math.tan( MathUtils.DEG2RAD * ( newFov / 2 ) );
-			size = x / newDistance;
-			this._v3_2.setFromMatrixPosition( this._gizmoMatrixState );
-
-			this.setFov( newFov );
-			this.applyTransformMatrix( this.scale( size, this._v3_2, false ) );
-
-			//adjusting distance
-			_offset.copy( this._gizmos.position ).sub( this.object.position ).normalize().multiplyScalar( newDistance / x );
-			this._m4_1.makeTranslation( _offset.x, _offset.y, _offset.z );
-
-			this.dispatchEvent( _changeEvent );
-
-		}
-
-	}
-
-	onTriplePanEnd() {
-
-		this.updateTbState( STATE.IDLE, false );
-		this.dispatchEvent( _endEvent );
-		//this.dispatchEvent( _changeEvent );
-
-	}
-
-	/**
-	 * Set _center's x/y coordinates.
-	 *
-	 * @private
-	 * @param {number} clientX - The x coordinate.
-	 * @param {number} clientY - The y coordinate.
-	 */
-	setCenter( clientX, clientY ) {
-
-		_center.x = clientX;
-		_center.y = clientY;
-
-	}
-
-	/**
-	 * Set default mouse actions.
-	 *
-	 * @private
-	 */
-	initializeMouseActions() {
-
-		this.setMouseAction( 'PAN', 0, 'CTRL' );
-		this.setMouseAction( 'PAN', 2 );
-
-		this.setMouseAction( 'ROTATE', 0 );
-
-		this.setMouseAction( 'ZOOM', 'WHEEL' );
-		this.setMouseAction( 'ZOOM', 1 );
-
-		this.setMouseAction( 'FOV', 'WHEEL', 'SHIFT' );
-		this.setMouseAction( 'FOV', 1, 'SHIFT' );
-
-
-	}
-
-	/**
-	 * Compare two mouse actions.
-	 *
-	 * @private
-	 * @param {Object} action1 - The first mouse action.
-	 * @param {Object} action2 - The second mouse action.
-	 * @returns {boolean} `true` if action1 and action 2 are the same mouse action, `false` otherwise.
-	 */
-	compareMouseAction( action1, action2 ) {
-
-		if ( action1.operation == action2.operation ) {
-
-			if ( action1.mouse == action2.mouse && action1.key == action2.key ) {
-
-				return true;
-
-			} else {
-
-				return false;
-
-			}
-
-		} else {
-
-			return false;
-
-		}
-
-	}
-
-	/**
-	 * Set a new mouse action by specifying the operation to be performed and a mouse/key combination. In case of conflict, replaces the existing one.
-	 *
-	 * @param {'PAN'|'ROTATE'|'ZOOM'|'FOV'} operation - The operation to be performed ('PAN', 'ROTATE', 'ZOOM', 'FOV').
-	 * @param {0|1|2|'WHEEL'} mouse - A mouse button (0, 1, 2) or 'WHEEL' for wheel notches.
-	 * @param {?('CTRL'|'SHIFT')} [key=null] - The keyboard modifier ('CTRL', 'SHIFT') or null if key is not needed.
-	 * @returns {boolean} `true` if the mouse action has been successfully added, `false` otherwise.
-	 */
-	setMouseAction( operation, mouse, key = null ) {
-
-		const operationInput = [ 'PAN', 'ROTATE', 'ZOOM', 'FOV' ];
-		const mouseInput = [ 0, 1, 2, 'WHEEL' ];
-		const keyInput = [ 'CTRL', 'SHIFT', null ];
-		let state;
-
-		if ( ! operationInput.includes( operation ) || ! mouseInput.includes( mouse ) || ! keyInput.includes( key ) ) {
-
-			//invalid parameters
-			return false;
-
-		}
-
-		if ( mouse == 'WHEEL' ) {
-
-			if ( operation != 'ZOOM' && operation != 'FOV' ) {
-
-				//cannot associate 2D operation to 1D input
-				return false;
-
-			}
-
-		}
-
-		switch ( operation ) {
-
-			case 'PAN':
-
-				state = STATE.PAN;
-				break;
-
-			case 'ROTATE':
-
-				state = STATE.ROTATE;
-				break;
-
-			case 'ZOOM':
-
-				state = STATE.SCALE;
-				break;
-
-			case 'FOV':
-
-				state = STATE.FOV;
-				break;
-
-		}
-
-		const action = {
-
-			operation: operation,
-			mouse: mouse,
-			key: key,
-			state: state
-
-		};
-
-		for ( let i = 0; i < this.mouseActions.length; i ++ ) {
-
-			if ( this.mouseActions[ i ].mouse == action.mouse && this.mouseActions[ i ].key == action.key ) {
-
-				this.mouseActions.splice( i, 1, action );
-				return true;
-
-			}
-
-		}
-
-		this.mouseActions.push( action );
-		return true;
-
-	}
-
-	/**
-	 * Remove a mouse action by specifying its mouse/key combination.
-	 *
-	 * @param {0|1|2|'WHEEL'} mouse - A mouse button (0, 1, 2) or 'WHEEL' for wheel notches.
-	 * @param {?('CTRL'|'SHIFT')} key - The keyboard modifier ('CTRL', 'SHIFT') or null if key is not needed.
-	 * @returns {boolean} `true` if the operation has been successfully removed, `false` otherwise.
-	 */
-	unsetMouseAction( mouse, key = null ) {
-
-		for ( let i = 0; i < this.mouseActions.length; i ++ ) {
-
-			if ( this.mouseActions[ i ].mouse == mouse && this.mouseActions[ i ].key == key ) {
-
-				this.mouseActions.splice( i, 1 );
-				return true;
-
-			}
-
-		}
-
-		return false;
-
-	}
-
-	/**
-	 * Return the operation associated to a mouse/keyboard combination.
-	 *
-	 * @private
-	 * @param {0|1|2|'WHEEL'} mouse - Mouse button index (0, 1, 2) or 'WHEEL' for wheel notches.
-	 * @param {?('CTRL'|'SHIFT')} key - Keyboard modifier.
-	 * @returns {?('PAN'|'ROTATE'|'ZOOM'|'FOV')} The operation if it has been found, `null` otherwise.
-	 */
-	getOpFromAction( mouse, key ) {
-
-		let action;
-
-		for ( let i = 0; i < this.mouseActions.length; i ++ ) {
-
-			action = this.mouseActions[ i ];
-			if ( action.mouse == mouse && action.key == key ) {
-
-				return action.operation;
-
-			}
-
-		}
-
-		if ( key != null ) {
-
-			for ( let i = 0; i < this.mouseActions.length; i ++ ) {
-
-				action = this.mouseActions[ i ];
-				if ( action.mouse == mouse && action.key == null ) {
-
-					return action.operation;
-
-				}
-
-			}
-
-		}
-
-		return null;
-
-	}
-
-	/**
-	 * Get the operation associated to mouse and key combination and returns the corresponding FSA state.
-	 *
-	 * @private
-	 * @param {0|1|2} mouse - Mouse button index (0, 1, 2)
-	 * @param {?('CTRL'|'SHIFT')} key - Keyboard modifier
-	 * @returns {?STATE} The FSA state obtained from the operation associated to mouse/keyboard combination.
-	 */
-	getOpStateFromAction( mouse, key ) {
-
-		let action;
-
-		for ( let i = 0; i < this.mouseActions.length; i ++ ) {
-
-			action = this.mouseActions[ i ];
-			if ( action.mouse == mouse && action.key == key ) {
-
-				return action.state;
-
-			}
-
-		}
-
-		if ( key != null ) {
-
-			for ( let i = 0; i < this.mouseActions.length; i ++ ) {
-
-				action = this.mouseActions[ i ];
-				if ( action.mouse == mouse && action.key == null ) {
-
-					return action.state;
-
-				}
-
-			}
-
-		}
-
-		return null;
-
-	}
-
-	/**
-	 * Calculate the angle between two pointers.
-	 *
-	 * @private
-	 * @param {PointerEvent} p1 - The first pointer event.
-	 * @param {PointerEvent} p2 - The second pointer event.
-	 * @returns {number} The angle between two pointers in degrees.
-	 */
-	getAngle( p1, p2 ) {
-
-		return Math.atan2( p2.clientY - p1.clientY, p2.clientX - p1.clientX ) * 180 / Math.PI;
-
-	}
-
-	/**
-	 * Updates a PointerEvent inside current pointerevents array.
-	 *
-	 * @private
-	 * @param {PointerEvent} event - The pointer event.
-	 */
-	updateTouchEvent( event ) {
-
-		for ( let i = 0; i < this._touchCurrent.length; i ++ ) {
-
-			if ( this._touchCurrent[ i ].pointerId == event.pointerId ) {
-
-				this._touchCurrent.splice( i, 1, event );
-				break;
-
-			}
-
-		}
-
-	}
-
-	/**
-	 * Applies a transformation matrix, to the camera and gizmos.
-	 *
-	 * @private
-	 * @param {Object} transformation - Object containing matrices to apply to camera and gizmos.
-	 */
-	applyTransformMatrix( transformation ) {
-
-		if ( transformation.camera != null ) {
-
-			this._m4_1.copy( this._cameraMatrixState ).premultiply( transformation.camera );
-			this._m4_1.decompose( this.object.position, this.object.quaternion, this.object.scale );
-			this.object.updateMatrix();
-
-			//update camera up vector
-			if ( this._state == STATE.ROTATE || this._state == STATE.ZROTATE || this._state == STATE.ANIMATION_ROTATE ) {
-
-				this.object.up.copy( this._upState ).applyQuaternion( this.object.quaternion );
-
-			}
-
-		}
-
-		if ( transformation.gizmos != null ) {
-
-			this._m4_1.copy( this._gizmoMatrixState ).premultiply( transformation.gizmos );
-			this._m4_1.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale );
-			this._gizmos.updateMatrix();
-
-		}
-
-		if ( this._state == STATE.SCALE || this._state == STATE.FOCUS || this._state == STATE.ANIMATION_FOCUS ) {
-
-			this._tbRadius = this.calculateTbRadius( this.object );
-
-			if ( this.adjustNearFar ) {
-
-				const cameraDistance = this.object.position.distanceTo( this._gizmos.position );
-
-				const bb = new Box3();
-				bb.setFromObject( this._gizmos );
-				const sphere = new Sphere();
-				bb.getBoundingSphere( sphere );
-
-				const adjustedNearPosition = Math.max( this._nearPos0, sphere.radius + sphere.center.length() );
-				const regularNearPosition = cameraDistance - this._initialNear;
-
-				const minNearPos = Math.min( adjustedNearPosition, regularNearPosition );
-				this.object.near = cameraDistance - minNearPos;
-
-
-				const adjustedFarPosition = Math.min( this._farPos0, - sphere.radius + sphere.center.length() );
-				const regularFarPosition = cameraDistance - this._initialFar;
-
-				const minFarPos = Math.min( adjustedFarPosition, regularFarPosition );
-				this.object.far = cameraDistance - minFarPos;
-
-				this.object.updateProjectionMatrix();
-
-			} else {
-
-				let update = false;
-
-				if ( this.object.near != this._initialNear ) {
-
-					this.object.near = this._initialNear;
-					update = true;
-
-				}
-
-				if ( this.object.far != this._initialFar ) {
-
-					this.object.far = this._initialFar;
-					update = true;
-
-				}
-
-				if ( update ) {
-
-					this.object.updateProjectionMatrix();
-
-				}
-
-			}
-
-		}
-
-	}
-
-	/**
-	 * Calculates the angular speed.
-	 *
-	 * @private
-	 * @param {number} p0 - Position at t0.
-	 * @param {number} p1 - Position at t1.
-	 * @param {number} t0 - Initial time in milliseconds.
-	 * @param {number} t1 - Ending time in milliseconds.
-	 * @returns {number} The angular speed.
-	 */
-	calculateAngularSpeed( p0, p1, t0, t1 ) {
-
-		const s = p1 - p0;
-		const t = ( t1 - t0 ) / 1000;
-		if ( t == 0 ) {
-
-			return 0;
-
-		}
-
-		return s / t;
-
-	}
-
-	/**
-	 * Calculates the distance between two pointers.
-	 *
-	 * @private
-	 * @param {PointerEvent} p0 - The first pointer.
-	 * @param {PointerEvent} p1 - The second pointer.
-	 * @returns {number} The distance between the two pointers.
-	 */
-	calculatePointersDistance( p0, p1 ) {
-
-		return Math.sqrt( Math.pow( p1.clientX - p0.clientX, 2 ) + Math.pow( p1.clientY - p0.clientY, 2 ) );
-
-	}
-
-	/**
-	 * Calculates the rotation axis as the vector perpendicular between two vectors.
-	 *
-	 * @private
-	 * @param {Vector3} vec1 - The first vector.
-	 * @param {Vector3} vec2 - The second vector.
-	 * @returns {Vector3} The normalized rotation axis.
-	 */
-	calculateRotationAxis( vec1, vec2 ) {
-
-		this._rotationMatrix.extractRotation( this._cameraMatrixState );
-		this._quat.setFromRotationMatrix( this._rotationMatrix );
-
-		this._rotationAxis.crossVectors( vec1, vec2 ).applyQuaternion( this._quat );
-		return this._rotationAxis.normalize().clone();
-
-	}
-
-	/**
-	 * Calculates the trackball radius so that gizmo's diameter will be 2/3 of the minimum side of the camera frustum.
-	 *
-	 * @private
-	 * @param {Camera} camera - The camera.
-	 * @returns {number} The trackball radius.
-	 */
-	calculateTbRadius( camera ) {
-
-		const distance = camera.position.distanceTo( this._gizmos.position );
-
-		if ( camera.type == 'PerspectiveCamera' ) {
-
-			const halfFovV = MathUtils.DEG2RAD * camera.fov * 0.5; //vertical fov/2 in radians
-			const halfFovH = Math.atan( ( camera.aspect ) * Math.tan( halfFovV ) ); //horizontal fov/2 in radians
-			return Math.tan( Math.min( halfFovV, halfFovH ) ) * distance * this.radiusFactor;
-
-		} else if ( camera.type == 'OrthographicCamera' ) {
-
-			return Math.min( camera.top, camera.right ) * this.radiusFactor;
-
-		}
-
-	}
-
-	/**
-	 * Focus operation consist of positioning the point of interest in front of the camera and a slightly zoom in.
-	 *
-	 * @private
-	 * @param {Vector3} point - The point of interest.
-	 * @param {number} size - Scale factor.
-	 * @param {number} [amount=1] - Amount of operation to be completed (used for focus animations, default is complete full operation).
-	 */
-	focus( point, size, amount = 1 ) {
-
-		//move center of camera (along with gizmos) towards point of interest
-		_offset.copy( point ).sub( this._gizmos.position ).multiplyScalar( amount );
-		this._translationMatrix.makeTranslation( _offset.x, _offset.y, _offset.z );
-
-		_gizmoMatrixStateTemp.copy( this._gizmoMatrixState );
-		this._gizmoMatrixState.premultiply( this._translationMatrix );
-		this._gizmoMatrixState.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale );
-
-		_cameraMatrixStateTemp.copy( this._cameraMatrixState );
-		this._cameraMatrixState.premultiply( this._translationMatrix );
-		this._cameraMatrixState.decompose( this.object.position, this.object.quaternion, this.object.scale );
-
-		//apply zoom
-		if ( this.enableZoom ) {
-
-			this.applyTransformMatrix( this.scale( size, this._gizmos.position ) );
-
-		}
-
-		this._gizmoMatrixState.copy( _gizmoMatrixStateTemp );
-		this._cameraMatrixState.copy( _cameraMatrixStateTemp );
-
-	}
-
-	/**
-	 * Creates a grid if necessary and adds it to the scene.
-	 *
-	 * @private
-	 */
-	drawGrid() {
-
-		if ( this.scene != null ) {
-
-			const color = 0x888888;
-			const multiplier = 3;
-			let size, divisions, maxLength, tick;
-
-			if ( this.object.isOrthographicCamera ) {
-
-				const width = this.object.right - this.object.left;
-				const height = this.object.bottom - this.object.top;
-
-				maxLength = Math.max( width, height );
-				tick = maxLength / 20;
-
-				size = maxLength / this.object.zoom * multiplier;
-				divisions = size / tick * this.object.zoom;
-
-			} else if ( this.object.isPerspectiveCamera ) {
-
-				const distance = this.object.position.distanceTo( this._gizmos.position );
-				const halfFovV = MathUtils.DEG2RAD * this.object.fov * 0.5;
-				const halfFovH = Math.atan( ( this.object.aspect ) * Math.tan( halfFovV ) );
-
-				maxLength = Math.tan( Math.max( halfFovV, halfFovH ) ) * distance * 2;
-				tick = maxLength / 20;
-
-				size = maxLength * multiplier;
-				divisions = size / tick;
-
-			}
-
-			if ( this._grid == null ) {
-
-				this._grid = new GridHelper( size, divisions, color, color );
-				this._grid.position.copy( this._gizmos.position );
-				this._gridPosition.copy( this._grid.position );
-				this._grid.quaternion.copy( this.object.quaternion );
-				this._grid.rotateX( Math.PI * 0.5 );
-
-				this.scene.add( this._grid );
-
-			}
-
-		}
-
-	}
-
-	dispose() {
-
-		if ( this._animationId != - 1 ) {
-
-			window.cancelAnimationFrame( this._animationId );
-
-		}
-
-		this.disconnect();
-
-		if ( this.scene !== null ) this.scene.remove( this._gizmos );
-		this.disposeGrid();
-
-	}
-
-	/**
-	 * Removes the grid from the scene.
-	 */
-	disposeGrid() {
-
-		if ( this._grid != null && this.scene != null ) {
-
-			this.scene.remove( this._grid );
-			this._grid = null;
-
-		}
-
-	}
-
-	/**
-	 * Computes the easing out cubic function for ease out effect in animation.
-	 *
-	 * @private
-	 * @param {number} t - The absolute progress of the animation in the bound of `0` (beginning of the) and `1` (ending of animation).
-	 * @returns {number} Result of easing out cubic at time `t`.
-	 */
-	easeOutCubic( t ) {
-
-		return 1 - Math.pow( 1 - t, 3 );
-
-	}
-
-	/**
-	 * Makes rotation gizmos more or less visible.
-	 *
-	 * @param {boolean} isActive - If set to `true`, gizmos are more visible.
-	 */
-	activateGizmos( isActive ) {
-
-		const gizmoX = this._gizmos.children[ 0 ];
-		const gizmoY = this._gizmos.children[ 1 ];
-		const gizmoZ = this._gizmos.children[ 2 ];
-
-		if ( isActive ) {
-
-			gizmoX.material.setValues( { opacity: 1 } );
-			gizmoY.material.setValues( { opacity: 1 } );
-			gizmoZ.material.setValues( { opacity: 1 } );
-
-		} else {
-
-			gizmoX.material.setValues( { opacity: 0.6 } );
-			gizmoY.material.setValues( { opacity: 0.6 } );
-			gizmoZ.material.setValues( { opacity: 0.6 } );
-
-		}
-
-	}
-
-	/**
-	 * Calculates the cursor position in NDC.
-	 *
-	 * @private
-	 * @param {number} cursorX - Cursor horizontal coordinate within the canvas.
-	 * @param {number} cursorY - Cursor vertical coordinate within the canvas.
-	 * @param {HTMLElement} canvas - The canvas where the renderer draws its output.
-	 * @returns {Vector2} Cursor normalized position inside the canvas.
-	 */
-	getCursorNDC( cursorX, cursorY, canvas ) {
-
-		const canvasRect = canvas.getBoundingClientRect();
-		this._v2_1.setX( ( ( cursorX - canvasRect.left ) / canvasRect.width ) * 2 - 1 );
-		this._v2_1.setY( ( ( canvasRect.bottom - cursorY ) / canvasRect.height ) * 2 - 1 );
-		return this._v2_1.clone();
-
-	}
-
-	/**
-	 * Calculates the cursor position inside the canvas x/y coordinates with the origin being in the center of the canvas.
-	 *
-	 * @private
-	 * @param {number} cursorX - Cursor horizontal coordinate within the canvas.
-	 * @param {number} cursorY - Cursor vertical coordinate within the canvas.
-	 * @param {HTMLElement} canvas - The canvas where the renderer draws its output.
-	 * @returns {Vector2} Cursor position inside the canvas.
-	 */
-	getCursorPosition( cursorX, cursorY, canvas ) {
-
-		this._v2_1.copy( this.getCursorNDC( cursorX, cursorY, canvas ) );
-		this._v2_1.x *= ( this.object.right - this.object.left ) * 0.5;
-		this._v2_1.y *= ( this.object.top - this.object.bottom ) * 0.5;
-		return this._v2_1.clone();
-
-	}
-
-	/**
-	 * Sets the camera to be controlled.  Must be called in order to set a new camera to be controlled.
-	 *
-	 * @param {Camera} camera - The camera to be controlled.
-	 */
-	setCamera( camera ) {
-
-		camera.lookAt( this.target );
-		camera.updateMatrix();
-
-		//setting state
-		if ( camera.type == 'PerspectiveCamera' ) {
-
-			this._fov0 = camera.fov;
-			this._fovState = camera.fov;
-
-		}
-
-		this._cameraMatrixState0.copy( camera.matrix );
-		this._cameraMatrixState.copy( this._cameraMatrixState0 );
-		this._cameraProjectionState.copy( camera.projectionMatrix );
-		this._zoom0 = camera.zoom;
-		this._zoomState = this._zoom0;
-
-		this._initialNear = camera.near;
-		this._nearPos0 = camera.position.distanceTo( this.target ) - camera.near;
-		this._nearPos = this._initialNear;
-
-		this._initialFar = camera.far;
-		this._farPos0 = camera.position.distanceTo( this.target ) - camera.far;
-		this._farPos = this._initialFar;
-
-		this._up0.copy( camera.up );
-		this._upState.copy( camera.up );
-
-		this.object = camera;
-		this.object.updateProjectionMatrix();
-
-		//making gizmos
-		this._tbRadius = this.calculateTbRadius( camera );
-		this.makeGizmos( this.target, this._tbRadius );
-
-	}
-
-	/**
-	 * Sets gizmos visibility.
-	 *
-	 * @param {boolean} value - Value of gizmos visibility.
-	 */
-	setGizmosVisible( value ) {
-
-		this._gizmos.visible = value;
-		this.dispatchEvent( _changeEvent );
-
-	}
-
-	/**
-	 * Sets gizmos radius factor and redraws gizmos.
-	 *
-	 * @param {number} value - Value of radius factor.
-	 */
-	setTbRadius( value ) {
-
-		this.radiusFactor = value;
-		this._tbRadius = this.calculateTbRadius( this.object );
-
-		const curve = new EllipseCurve( 0, 0, this._tbRadius, this._tbRadius );
-		const points = curve.getPoints( this._curvePts );
-		const curveGeometry = new BufferGeometry().setFromPoints( points );
-
-
-		for ( const gizmo in this._gizmos.children ) {
-
-			this._gizmos.children[ gizmo ].geometry = curveGeometry;
-
-		}
-
-		this.dispatchEvent( _changeEvent );
-
-	}
-
-	/**
-	 * Creates the rotation gizmos matching trackball center and radius.
-	 *
-	 * @private
-	 * @param {Vector3} tbCenter - The trackball center.
-	 * @param {number} tbRadius - The trackball radius.
-	 */
-	makeGizmos( tbCenter, tbRadius ) {
-
-		const curve = new EllipseCurve( 0, 0, tbRadius, tbRadius );
-		const points = curve.getPoints( this._curvePts );
-
-		//geometry
-		const curveGeometry = new BufferGeometry().setFromPoints( points );
-
-		//material
-		const curveMaterialX = new LineBasicMaterial( { color: 0xff8080, fog: false, transparent: true, opacity: 0.6 } );
-		const curveMaterialY = new LineBasicMaterial( { color: 0x80ff80, fog: false, transparent: true, opacity: 0.6 } );
-		const curveMaterialZ = new LineBasicMaterial( { color: 0x8080ff, fog: false, transparent: true, opacity: 0.6 } );
-
-		//line
-		const gizmoX = new Line( curveGeometry, curveMaterialX );
-		const gizmoY = new Line( curveGeometry, curveMaterialY );
-		const gizmoZ = new Line( curveGeometry, curveMaterialZ );
-
-		const rotation = Math.PI * 0.5;
-		gizmoX.rotation.x = rotation;
-		gizmoY.rotation.y = rotation;
-
-
-		//setting state
-		this._gizmoMatrixState0.identity().setPosition( tbCenter );
-		this._gizmoMatrixState.copy( this._gizmoMatrixState0 );
-
-		if ( this.object.zoom !== 1 ) {
-
-			//adapt gizmos size to camera zoom
-			const size = 1 / this.object.zoom;
-			this._scaleMatrix.makeScale( size, size, size );
-			this._translationMatrix.makeTranslation( - tbCenter.x, - tbCenter.y, - tbCenter.z );
-
-			this._gizmoMatrixState.premultiply( this._translationMatrix ).premultiply( this._scaleMatrix );
-			this._translationMatrix.makeTranslation( tbCenter.x, tbCenter.y, tbCenter.z );
-			this._gizmoMatrixState.premultiply( this._translationMatrix );
-
-		}
-
-		this._gizmoMatrixState.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale );
-
-		//
-
-		this._gizmos.traverse( function ( object ) {
-
-			if ( object.isLine ) {
-
-				object.geometry.dispose();
-				object.material.dispose();
-
-			}
-
-		} );
-
-		this._gizmos.clear();
-
-		//
-
-		this._gizmos.add( gizmoX );
-		this._gizmos.add( gizmoY );
-		this._gizmos.add( gizmoZ );
-
-	}
-
-	/**
-	 * Performs animation for focus operation.
-	 *
-	 * @private
-	 * @param {number} time - Instant in which this function is called as performance.now().
-	 * @param {Vector3} point - Point of interest for focus operation.
-	 * @param {Matrix4} cameraMatrix - Camera matrix.
-	 * @param {Matrix4} gizmoMatrix - Gizmos matrix.
-	 */
-	onFocusAnim( time, point, cameraMatrix, gizmoMatrix ) {
-
-		if ( this._timeStart == - 1 ) {
-
-			//animation start
-			this._timeStart = time;
-
-		}
-
-		if ( this._state == STATE.ANIMATION_FOCUS ) {
-
-			const deltaTime = time - this._timeStart;
-			const animTime = deltaTime / this.focusAnimationTime;
-
-			this._gizmoMatrixState.copy( gizmoMatrix );
-
-			if ( animTime >= 1 ) {
-
-				//animation end
-
-				this._gizmoMatrixState.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale );
-
-				this.focus( point, this.scaleFactor );
-
-				this._timeStart = - 1;
-				this.updateTbState( STATE.IDLE, false );
-				this.activateGizmos( false );
-
-				this.dispatchEvent( _changeEvent );
-
-			} else {
-
-				const amount = this.easeOutCubic( animTime );
-				const size = ( ( 1 - amount ) + ( this.scaleFactor * amount ) );
-
-				this._gizmoMatrixState.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale );
-				this.focus( point, size, amount );
-
-				this.dispatchEvent( _changeEvent );
-				const self = this;
-				this._animationId = window.requestAnimationFrame( function ( t ) {
-
-					self.onFocusAnim( t, point, cameraMatrix, gizmoMatrix.clone() );
-
-				} );
-
-			}
-
-		} else {
-
-			//interrupt animation
-
-			this._animationId = - 1;
-			this._timeStart = - 1;
-
-		}
-
-	}
-
-	/**
-	 * Performs animation for rotation operation.
-	 *
-	 * @private
-	 * @param {number} time - Instant in which this function is called as performance.now().
-	 * @param {Vector3} rotationAxis - Rotation axis.
-	 * @param {number} w0 - Initial angular velocity.
-	 */
-	onRotationAnim( time, rotationAxis, w0 ) {
-
-		if ( this._timeStart == - 1 ) {
-
-			//animation start
-			this._anglePrev = 0;
-			this._angleCurrent = 0;
-			this._timeStart = time;
-
-		}
-
-		if ( this._state == STATE.ANIMATION_ROTATE ) {
-
-			//w = w0 + alpha * t
-			const deltaTime = ( time - this._timeStart ) / 1000;
-			const w = w0 + ( ( - this.dampingFactor ) * deltaTime );
-
-			if ( w > 0 ) {
-
-				//tetha = 0.5 * alpha * t^2 + w0 * t + tetha0
-				this._angleCurrent = 0.5 * ( - this.dampingFactor ) * Math.pow( deltaTime, 2 ) + w0 * deltaTime + 0;
-				this.applyTransformMatrix( this.rotate( rotationAxis, this._angleCurrent ) );
-				this.dispatchEvent( _changeEvent );
-				const self = this;
-				this._animationId = window.requestAnimationFrame( function ( t ) {
-
-					self.onRotationAnim( t, rotationAxis, w0 );
-
-				} );
-
-			} else {
-
-				this._animationId = - 1;
-				this._timeStart = - 1;
-
-				this.updateTbState( STATE.IDLE, false );
-				this.activateGizmos( false );
-
-				this.dispatchEvent( _changeEvent );
-
-			}
-
-		} else {
-
-			//interrupt animation
-
-			this._animationId = - 1;
-			this._timeStart = - 1;
-
-			if ( this._state != STATE.ROTATE ) {
-
-				this.activateGizmos( false );
-				this.dispatchEvent( _changeEvent );
-
-			}
-
-		}
-
-	}
-
-
-	/**
-	 * Performs pan operation moving camera between two points.
-	 *
-	 * @private
-	 * @param {Vector3} p0 - Initial point.
-	 * @param {Vector3} p1 - Ending point.
-	 * @param {boolean} [adjust=false] - If movement should be adjusted considering camera distance (Perspective only).
-	 * @returns {Object}
-	 */
-	pan( p0, p1, adjust = false ) {
-
-		const movement = p0.clone().sub( p1 );
-
-		if ( this.object.isOrthographicCamera ) {
-
-			//adjust movement amount
-			movement.multiplyScalar( 1 / this.object.zoom );
-
-		} else if ( this.object.isPerspectiveCamera && adjust ) {
-
-			//adjust movement amount
-			this._v3_1.setFromMatrixPosition( this._cameraMatrixState0 );	//camera's initial position
-			this._v3_2.setFromMatrixPosition( this._gizmoMatrixState0 );	//gizmo's initial position
-			const distanceFactor = this._v3_1.distanceTo( this._v3_2 ) / this.object.position.distanceTo( this._gizmos.position );
-			movement.multiplyScalar( 1 / distanceFactor );
-
-		}
-
-		this._v3_1.set( movement.x, movement.y, 0 ).applyQuaternion( this.object.quaternion );
-
-		this._m4_1.makeTranslation( this._v3_1.x, this._v3_1.y, this._v3_1.z );
-
-		this.setTransformationMatrices( this._m4_1, this._m4_1 );
-		return _transformation;
-
-	}
-
-	/**
-	 * Resets the controls.
-	 */
-	reset() {
-
-		this.target.copy( this._target0 );
-		this.object.zoom = this._zoom0;
-
-		if ( this.object.isPerspectiveCamera ) {
-
-			this.object.fov = this._fov0;
-
-		}
-
-		this.object.near = this._nearPos;
-		this.object.far = this._farPos;
-		this._cameraMatrixState.copy( this._cameraMatrixState0 );
-		this._cameraMatrixState.decompose( this.object.position, this.object.quaternion, this.object.scale );
-		this.object.up.copy( this._up0 );
-
-		this.object.updateMatrix();
-		this.object.updateProjectionMatrix();
-
-		this._gizmoMatrixState.copy( this._gizmoMatrixState0 );
-		this._gizmoMatrixState0.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale );
-		this._gizmos.updateMatrix();
-
-		this._tbRadius = this.calculateTbRadius( this.object );
-		this.makeGizmos( this._gizmos.position, this._tbRadius );
-
-		this.object.lookAt( this._gizmos.position );
-
-		this.updateTbState( STATE.IDLE, false );
-
-		this.dispatchEvent( _changeEvent );
-
-	}
-
-	/**
-	 * Rotates the camera around an axis passing by trackball's center.
-	 *
-	 * @private
-	 * @param {Vector3} axis - Rotation axis.
-	 * @param {number} angle - Angle in radians.
-	 * @returns {Object} Object with 'camera' field containing transformation matrix resulting from the operation to be applied to the camera.
-	 */
-	rotate( axis, angle ) {
-
-		const point = this._gizmos.position; //rotation center
-		this._translationMatrix.makeTranslation( - point.x, - point.y, - point.z );
-		this._rotationMatrix.makeRotationAxis( axis, - angle );
-
-		//rotate camera
-		this._m4_1.makeTranslation( point.x, point.y, point.z );
-		this._m4_1.multiply( this._rotationMatrix );
-		this._m4_1.multiply( this._translationMatrix );
-
-		this.setTransformationMatrices( this._m4_1 );
-
-		return _transformation;
-
-	}
-
-	/**
-	 * Copy the current state to clipboard (as a readable JSON text).
-	 */
-	copyState() {
-
-		let state;
-		if ( this.object.isOrthographicCamera ) {
-
-			state = JSON.stringify( {
-				arcballState: {
-					cameraFar: this.object.far,
-					cameraMatrix: this.object.matrix,
-					cameraNear: this.object.near,
-					cameraUp: this.object.up,
-					cameraZoom: this.object.zoom,
-					gizmoMatrix: this._gizmos.matrix,
-					target: this.target
-
-				}
-			} );
-
-		} else if ( this.object.isPerspectiveCamera ) {
-
-			state = JSON.stringify( {
-				arcballState: {
-					cameraFar: this.object.far,
-					cameraFov: this.object.fov,
-					cameraMatrix: this.object.matrix,
-					cameraNear: this.object.near,
-					cameraUp: this.object.up,
-					cameraZoom: this.object.zoom,
-					gizmoMatrix: this._gizmos.matrix,
-					target: this.target
-
-				}
-			} );
-
-		}
-
-		navigator.clipboard.writeText( state );
-
-	}
-
-	/**
-	 * Set the controls state from the clipboard, assumes that the clipboard stores a JSON
-	 * text as saved from `copyState()`.
-	 */
-	pasteState() {
-
-		const self = this;
-		navigator.clipboard.readText().then( function resolved( value ) {
-
-			self.setStateFromJSON( value );
-
-		} );
-
-	}
-
-	/**
-	 * Saves the current state of the control. This can later be recover with `reset()`.
-	 */
-	saveState() {
-
-		this.object.updateMatrix();
-		this._gizmos.updateMatrix();
-
-		this._target0.copy( this.target );
-		this._cameraMatrixState0.copy( this.object.matrix );
-		this._gizmoMatrixState0.copy( this._gizmos.matrix );
-		this._nearPos = this.object.near;
-		this._farPos = this.object.far;
-		this._zoom0 = this.object.zoom;
-		this._up0.copy( this.object.up );
-
-		if ( this.object.isPerspectiveCamera ) {
-
-			this._fov0 = this.object.fov;
-
-		}
-
-	}
-
-	/**
-	 * Performs uniform scale operation around a given point.
-	 *
-	 * @private
-	 * @param {number} size - Scale factor.
-	 * @param {Vector3} point - Point around which scale.
-	 * @param {boolean} scaleGizmos - If gizmos should be scaled (Perspective only).
-	 * @returns {Object} Object with 'camera' and 'gizmo' fields containing transformation matrices resulting from the operation to be applied to the camera and gizmos.
-	 */
-	scale( size, point, scaleGizmos = true ) {
-
-		_scalePointTemp.copy( point );
-		let sizeInverse = 1 / size;
-
-		if ( this.object.isOrthographicCamera ) {
-
-			//camera zoom
-			this.object.zoom = this._zoomState;
-			this.object.zoom *= size;
-
-			//check min and max zoom
-			if ( this.object.zoom > this.maxZoom ) {
-
-				this.object.zoom = this.maxZoom;
-				sizeInverse = this._zoomState / this.maxZoom;
-
-			} else if ( this.object.zoom < this.minZoom ) {
-
-				this.object.zoom = this.minZoom;
-				sizeInverse = this._zoomState / this.minZoom;
-
-			}
-
-			this.object.updateProjectionMatrix();
-
-			this._v3_1.setFromMatrixPosition( this._gizmoMatrixState );	//gizmos position
-
-			//scale gizmos so they appear in the same spot having the same dimension
-			this._scaleMatrix.makeScale( sizeInverse, sizeInverse, sizeInverse );
-			this._translationMatrix.makeTranslation( - this._v3_1.x, - this._v3_1.y, - this._v3_1.z );
-
-			this._m4_2.makeTranslation( this._v3_1.x, this._v3_1.y, this._v3_1.z ).multiply( this._scaleMatrix );
-			this._m4_2.multiply( this._translationMatrix );
-
-
-			//move camera and gizmos to obtain pinch effect
-			_scalePointTemp.sub( this._v3_1 );
-
-			const amount = _scalePointTemp.clone().multiplyScalar( sizeInverse );
-			_scalePointTemp.sub( amount );
-
-			this._m4_1.makeTranslation( _scalePointTemp.x, _scalePointTemp.y, _scalePointTemp.z );
-			this._m4_2.premultiply( this._m4_1 );
-
-			this.setTransformationMatrices( this._m4_1, this._m4_2 );
-			return _transformation;
-
-		} else if ( this.object.isPerspectiveCamera ) {
-
-			this._v3_1.setFromMatrixPosition( this._cameraMatrixState );
-			this._v3_2.setFromMatrixPosition( this._gizmoMatrixState );
-
-			//move camera
-			let distance = this._v3_1.distanceTo( _scalePointTemp );
-			let amount = distance - ( distance * sizeInverse );
-
-			//check min and max distance
-			const newDistance = distance - amount;
-			if ( newDistance < this.minDistance ) {
-
-				sizeInverse = this.minDistance / distance;
-				amount = distance - ( distance * sizeInverse );
-
-			} else if ( newDistance > this.maxDistance ) {
-
-				sizeInverse = this.maxDistance / distance;
-				amount = distance - ( distance * sizeInverse );
-
-			}
-
-			_offset.copy( _scalePointTemp ).sub( this._v3_1 ).normalize().multiplyScalar( amount );
-
-			this._m4_1.makeTranslation( _offset.x, _offset.y, _offset.z );
-
-
-			if ( scaleGizmos ) {
-
-				//scale gizmos so they appear in the same spot having the same dimension
-				const pos = this._v3_2;
-
-				distance = pos.distanceTo( _scalePointTemp );
-				amount = distance - ( distance * sizeInverse );
-				_offset.copy( _scalePointTemp ).sub( this._v3_2 ).normalize().multiplyScalar( amount );
-
-				this._translationMatrix.makeTranslation( pos.x, pos.y, pos.z );
-				this._scaleMatrix.makeScale( sizeInverse, sizeInverse, sizeInverse );
-
-				this._m4_2.makeTranslation( _offset.x, _offset.y, _offset.z ).multiply( this._translationMatrix );
-				this._m4_2.multiply( this._scaleMatrix );
-
-				this._translationMatrix.makeTranslation( - pos.x, - pos.y, - pos.z );
-
-				this._m4_2.multiply( this._translationMatrix );
-				this.setTransformationMatrices( this._m4_1, this._m4_2 );
-
-
-			} else {
-
-				this.setTransformationMatrices( this._m4_1 );
-
-			}
-
-			return _transformation;
-
-		}
-
-	}
-
-	/**
-	 * Sets camera fov.
-	 *
-	 * @private
-	 * @param {number} value - The FOV to be set.
-	 */
-	setFov( value ) {
-
-		if ( this.object.isPerspectiveCamera ) {
-
-			this.object.fov = MathUtils.clamp( value, this.minFov, this.maxFov );
-			this.object.updateProjectionMatrix();
-
-		}
-
-	}
-
-	/**
-	 * Sets values in transformation object.
-	 *
-	 * @private
-	 * @param {?Matrix4} [camera=null] - Transformation to be applied to the camera.
-	 * @param {?Matrix4} [gizmos=null] - Transformation to be applied to gizmos.
-	 */
-	setTransformationMatrices( camera = null, gizmos = null ) {
-
-		if ( camera != null ) {
-
-			if ( _transformation.camera != null ) {
-
-				_transformation.camera.copy( camera );
-
-			} else {
-
-				_transformation.camera = camera.clone();
-
-			}
-
-		} else {
-
-			_transformation.camera = null;
-
-		}
-
-		if ( gizmos != null ) {
-
-			if ( _transformation.gizmos != null ) {
-
-				_transformation.gizmos.copy( gizmos );
-
-			} else {
-
-				_transformation.gizmos = gizmos.clone();
-
-			}
-
-		} else {
-
-			_transformation.gizmos = null;
-
-		}
-
-	}
-
-	/**
-	 * Rotates camera around its direction axis passing by a given point by a given angle.
-	 *
-	 * @private
-	 * @param {Vector3} point - The point where the rotation axis is passing trough.
-	 * @param {number} angle - Angle in radians.
-	 * @returns {Object} The computed transformation matrix.
-	 */
-	zRotate( point, angle ) {
-
-		this._rotationMatrix.makeRotationAxis( this._rotationAxis, angle );
-		this._translationMatrix.makeTranslation( - point.x, - point.y, - point.z );
-
-		this._m4_1.makeTranslation( point.x, point.y, point.z );
-		this._m4_1.multiply( this._rotationMatrix );
-		this._m4_1.multiply( this._translationMatrix );
-
-		this._v3_1.setFromMatrixPosition( this._gizmoMatrixState ).sub( point );	//vector from rotation center to gizmos position
-		this._v3_2.copy( this._v3_1 ).applyAxisAngle( this._rotationAxis, angle );	//apply rotation
-		this._v3_2.sub( this._v3_1 );
-
-		this._m4_2.makeTranslation( this._v3_2.x, this._v3_2.y, this._v3_2.z );
-
-		this.setTransformationMatrices( this._m4_1, this._m4_2 );
-		return _transformation;
-
-	}
-
-	/**
-	 * Returns the raycaster that is used for user interaction. This object is shared between all
-	 * instances of `ArcballControls`.
-	 *
-	 * @returns {Raycaster} The internal raycaster.
-	 */
-	getRaycaster() {
-
-		return _raycaster;
-
-	}
-
-
-	/**
-	 * Unprojects the cursor on the 3D object surface.
-	 *
-	 * @private
-	 * @param {Vector2} cursor - Cursor coordinates in NDC.
-	 * @param {Camera} camera - Virtual camera.
-	 * @returns {?Vector3} The point of intersection with the model, if exist, null otherwise.
-	 */
-	unprojectOnObj( cursor, camera ) {
-
-		const raycaster = this.getRaycaster();
-		raycaster.near = camera.near;
-		raycaster.far = camera.far;
-		raycaster.setFromCamera( cursor, camera );
-
-		const intersect = raycaster.intersectObjects( this.scene.children, true );
-
-		for ( let i = 0; i < intersect.length; i ++ ) {
-
-			if ( intersect[ i ].object.uuid != this._gizmos.uuid && intersect[ i ].face != null ) {
-
-				return intersect[ i ].point.clone();
-
-			}
-
-		}
-
-		return null;
-
-	}
-
-	/**
-	 * Unproject the cursor on the trackball surface.
-	 *
-	 * @private
-	 * @param {Camera} camera - The virtual camera.
-	 * @param {number} cursorX - Cursor horizontal coordinate on screen.
-	 * @param {number} cursorY - Cursor vertical coordinate on screen.
-	 * @param {HTMLElement} canvas - The canvas where the renderer draws its output.
-	 * @param {number} tbRadius - The trackball radius.
-	 * @returns {Vector3} The unprojected point on the trackball surface.
-	 */
-	unprojectOnTbSurface( camera, cursorX, cursorY, canvas, tbRadius ) {
-
-		if ( camera.type == 'OrthographicCamera' ) {
-
-			this._v2_1.copy( this.getCursorPosition( cursorX, cursorY, canvas ) );
-			this._v3_1.set( this._v2_1.x, this._v2_1.y, 0 );
-
-			const x2 = Math.pow( this._v2_1.x, 2 );
-			const y2 = Math.pow( this._v2_1.y, 2 );
-			const r2 = Math.pow( this._tbRadius, 2 );
-
-			if ( x2 + y2 <= r2 * 0.5 ) {
-
-				//intersection with sphere
-				this._v3_1.setZ( Math.sqrt( r2 - ( x2 + y2 ) ) );
-
-			} else {
-
-				//intersection with hyperboloid
-				this._v3_1.setZ( ( r2 * 0.5 ) / ( Math.sqrt( x2 + y2 ) ) );
-
-			}
-
-			return this._v3_1;
-
-		} else if ( camera.type == 'PerspectiveCamera' ) {
-
-			//unproject cursor on the near plane
-			this._v2_1.copy( this.getCursorNDC( cursorX, cursorY, canvas ) );
-
-			this._v3_1.set( this._v2_1.x, this._v2_1.y, - 1 );
-			this._v3_1.applyMatrix4( camera.projectionMatrixInverse );
-
-			const rayDir = this._v3_1.clone().normalize(); //unprojected ray direction
-			const cameraGizmoDistance = camera.position.distanceTo( this._gizmos.position );
-			const radius2 = Math.pow( tbRadius, 2 );
-
-			//	  camera
-			//		|\
-			//		| \
-			//		|  \
-			//	h	|	\
-			//		| 	 \
-			//		| 	  \
-			//	_ _ | _ _ _\ _ _  near plane
-			//			l
-
-			const h = this._v3_1.z;
-			const l = Math.sqrt( Math.pow( this._v3_1.x, 2 ) + Math.pow( this._v3_1.y, 2 ) );
-
-			if ( l == 0 ) {
-
-				//ray aligned with camera
-				rayDir.set( this._v3_1.x, this._v3_1.y, tbRadius );
-				return rayDir;
-
-			}
-
-			const m = h / l;
-			const q = cameraGizmoDistance;
-
-			/*
-			 * calculate intersection point between unprojected ray and trackball surface
-			 *|y = m * x + q
-			 *|x^2 + y^2 = r^2
-			 *
-			 * (m^2 + 1) * x^2 + (2 * m * q) * x + q^2 - r^2 = 0
-			 */
-			let a = Math.pow( m, 2 ) + 1;
-			let b = 2 * m * q;
-			let c = Math.pow( q, 2 ) - radius2;
-			let delta = Math.pow( b, 2 ) - ( 4 * a * c );
-
-			if ( delta >= 0 ) {
-
-				//intersection with sphere
-				this._v2_1.setX( ( - b - Math.sqrt( delta ) ) / ( 2 * a ) );
-				this._v2_1.setY( m * this._v2_1.x + q );
-
-				const angle = MathUtils.RAD2DEG * this._v2_1.angle();
-
-				if ( angle >= 45 ) {
-
-					//if angle between intersection point and X' axis is >= 45°, return that point
-					//otherwise, calculate intersection point with hyperboloid
-
-					const rayLength = Math.sqrt( Math.pow( this._v2_1.x, 2 ) + Math.pow( ( cameraGizmoDistance - this._v2_1.y ), 2 ) );
-					rayDir.multiplyScalar( rayLength );
-					rayDir.z += cameraGizmoDistance;
-					return rayDir;
-
-				}
-
-			}
-
-			//intersection with hyperboloid
-			/*
-			 *|y = m * x + q
-			 *|y = (1 / x) * (r^2 / 2)
-			 *
-			 * m * x^2 + q * x - r^2 / 2 = 0
-			 */
-
-			a = m;
-			b = q;
-			c = - radius2 * 0.5;
-			delta = Math.pow( b, 2 ) - ( 4 * a * c );
-			this._v2_1.setX( ( - b - Math.sqrt( delta ) ) / ( 2 * a ) );
-			this._v2_1.setY( m * this._v2_1.x + q );
-
-			const rayLength = Math.sqrt( Math.pow( this._v2_1.x, 2 ) + Math.pow( ( cameraGizmoDistance - this._v2_1.y ), 2 ) );
-
-			rayDir.multiplyScalar( rayLength );
-			rayDir.z += cameraGizmoDistance;
-			return rayDir;
-
-		}
-
-	}
-
-
-	/**
-	 * Unprojects the cursor on the plane passing through the center of the trackball orthogonal to the camera.
-	 *
-	 * @private
-	 * @param {Camera} camera - The virtual camera.
-	 * @param {number} cursorX - Cursor horizontal coordinate on screen.
-	 * @param {number} cursorY - Cursor vertical coordinate on screen.
-	 * @param {HTMLElement} canvas - The canvas where the renderer draws its output.
-	 * @param {boolean} [initialDistance=false] - If initial distance between camera and gizmos should be used for calculations instead of current (Perspective only).
-	 * @returns {Vector3} The unprojected point on the trackball plane.
-	 */
-	unprojectOnTbPlane( camera, cursorX, cursorY, canvas, initialDistance = false ) {
-
-		if ( camera.type == 'OrthographicCamera' ) {
-
-			this._v2_1.copy( this.getCursorPosition( cursorX, cursorY, canvas ) );
-			this._v3_1.set( this._v2_1.x, this._v2_1.y, 0 );
-
-			return this._v3_1.clone();
-
-		} else if ( camera.type == 'PerspectiveCamera' ) {
-
-			this._v2_1.copy( this.getCursorNDC( cursorX, cursorY, canvas ) );
-
-			//unproject cursor on the near plane
-			this._v3_1.set( this._v2_1.x, this._v2_1.y, - 1 );
-			this._v3_1.applyMatrix4( camera.projectionMatrixInverse );
-
-			const rayDir = this._v3_1.clone().normalize(); //unprojected ray direction
-
-			//	  camera
-			//		|\
-			//		| \
-			//		|  \
-			//	h	|	\
-			//		| 	 \
-			//		| 	  \
-			//	_ _ | _ _ _\ _ _  near plane
-			//			l
-
-			const h = this._v3_1.z;
-			const l = Math.sqrt( Math.pow( this._v3_1.x, 2 ) + Math.pow( this._v3_1.y, 2 ) );
-			let cameraGizmoDistance;
-
-			if ( initialDistance ) {
-
-				cameraGizmoDistance = this._v3_1.setFromMatrixPosition( this._cameraMatrixState0 ).distanceTo( this._v3_2.setFromMatrixPosition( this._gizmoMatrixState0 ) );
-
-			} else {
-
-				cameraGizmoDistance = camera.position.distanceTo( this._gizmos.position );
-
-			}
-
-			/*
-			 * calculate intersection point between unprojected ray and the plane
-			 *|y = mx + q
-			 *|y = 0
-			 *
-			 * x = -q/m
-			*/
-			if ( l == 0 ) {
-
-				//ray aligned with camera
-				rayDir.set( 0, 0, 0 );
-				return rayDir;
-
-			}
-
-			const m = h / l;
-			const q = cameraGizmoDistance;
-			const x = - q / m;
-
-			const rayLength = Math.sqrt( Math.pow( q, 2 ) + Math.pow( x, 2 ) );
-			rayDir.multiplyScalar( rayLength );
-			rayDir.z = 0;
-			return rayDir;
-
-		}
-
-	}
-
-	/**
-	 * Updates camera and gizmos state.
-	 *
-	 * @private
-	 */
-	updateMatrixState() {
-
-		//update camera and gizmos state
-		this._cameraMatrixState.copy( this.object.matrix );
-		this._gizmoMatrixState.copy( this._gizmos.matrix );
-
-		if ( this.object.isOrthographicCamera ) {
-
-			this._cameraProjectionState.copy( this.object.projectionMatrix );
-			this.object.updateProjectionMatrix();
-			this._zoomState = this.object.zoom;
-
-		} else if ( this.object.isPerspectiveCamera ) {
-
-			this._fovState = this.object.fov;
-
-		}
-
-	}
-
-	/**
-	 * Updates the trackball FSA.
-	 *
-	 * @private
-	 * @param {STATE} newState - New state of the FSA.
-	 * @param {boolean} updateMatrices - If matrices state should be updated.
-	 */
-	updateTbState( newState, updateMatrices ) {
-
-		this._state = newState;
-		if ( updateMatrices ) {
-
-			this.updateMatrixState();
-
-		}
-
-	}
-
-	update() {
-
-		if ( this.target.equals( this._currentTarget ) === false ) {
-
-			this._gizmos.position.copy( this.target );	//for correct radius calculation
-			this._tbRadius = this.calculateTbRadius( this.object );
-			this.makeGizmos( this.target, this._tbRadius );
-			this._currentTarget.copy( this.target );
-
-		}
-
-		//check min/max parameters
-		if ( this.object.isOrthographicCamera ) {
-
-			//check zoom
-			if ( this.object.zoom > this.maxZoom || this.object.zoom < this.minZoom ) {
-
-				const newZoom = MathUtils.clamp( this.object.zoom, this.minZoom, this.maxZoom );
-				this.applyTransformMatrix( this.scale( newZoom / this.object.zoom, this._gizmos.position, true ) );
-
-			}
-
-		} else if ( this.object.isPerspectiveCamera ) {
-
-			//check distance
-			const distance = this.object.position.distanceTo( this._gizmos.position );
-
-			if ( distance > this.maxDistance + _EPS || distance < this.minDistance - _EPS ) {
-
-				const newDistance = MathUtils.clamp( distance, this.minDistance, this.maxDistance );
-				this.applyTransformMatrix( this.scale( newDistance / distance, this._gizmos.position ) );
-				this.updateMatrixState();
-
-			}
-
-			//check fov
-			if ( this.object.fov < this.minFov || this.object.fov > this.maxFov ) {
-
-				this.object.fov = MathUtils.clamp( this.object.fov, this.minFov, this.maxFov );
-				this.object.updateProjectionMatrix();
-
-			}
-
-			const oldRadius = this._tbRadius;
-			this._tbRadius = this.calculateTbRadius( this.object );
-
-			if ( oldRadius < this._tbRadius - _EPS || oldRadius > this._tbRadius + _EPS ) {
-
-				const scale = ( this._gizmos.scale.x + this._gizmos.scale.y + this._gizmos.scale.z ) / 3;
-				const newRadius = this._tbRadius / scale;
-				const curve = new EllipseCurve( 0, 0, newRadius, newRadius );
-				const points = curve.getPoints( this._curvePts );
-				const curveGeometry = new BufferGeometry().setFromPoints( points );
-
-				for ( const gizmo in this._gizmos.children ) {
-
-					this._gizmos.children[ gizmo ].geometry = curveGeometry;
-
-				}
-
-			}
-
-		}
-
-		this.object.lookAt( this._gizmos.position );
-
-	}
-
-	setStateFromJSON( json ) {
-
-		const state = JSON.parse( json );
-
-		if ( state.arcballState != undefined ) {
-
-			this.target.fromArray( state.arcballState.target );
-
-			this._cameraMatrixState.fromArray( state.arcballState.cameraMatrix.elements );
-			this._cameraMatrixState.decompose( this.object.position, this.object.quaternion, this.object.scale );
-
-			this.object.up.copy( state.arcballState.cameraUp );
-			this.object.near = state.arcballState.cameraNear;
-			this.object.far = state.arcballState.cameraFar;
-
-			this.object.zoom = state.arcballState.cameraZoom;
-
-			if ( this.object.isPerspectiveCamera ) {
-
-				this.object.fov = state.arcballState.cameraFov;
-
-			}
-
-			this._gizmoMatrixState.fromArray( state.arcballState.gizmoMatrix.elements );
-			this._gizmoMatrixState.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale );
-
-			this.object.updateMatrix();
-			this.object.updateProjectionMatrix();
-
-			this._gizmos.updateMatrix();
-
-			this._tbRadius = this.calculateTbRadius( this.object );
-			const gizmoTmp = new Matrix4().copy( this._gizmoMatrixState0 );
-			this.makeGizmos( this._gizmos.position, this._tbRadius );
-			this._gizmoMatrixState0.copy( gizmoTmp );
-
-			this.object.lookAt( this._gizmos.position );
-			this.updateTbState( STATE.IDLE, false );
-
-			this.dispatchEvent( _changeEvent );
-
-		}
-
-	}
-
-}
-
-//listeners
-
-function onWindowResize() {
-
-	const scale = ( this._gizmos.scale.x + this._gizmos.scale.y + this._gizmos.scale.z ) / 3;
-	this._tbRadius = this.calculateTbRadius( this.object );
-
-	const newRadius = this._tbRadius / scale;
-	const curve = new EllipseCurve( 0, 0, newRadius, newRadius );
-	const points = curve.getPoints( this._curvePts );
-	const curveGeometry = new BufferGeometry().setFromPoints( points );
-
-
-	for ( const gizmo in this._gizmos.children ) {
-
-		this._gizmos.children[ gizmo ].geometry = curveGeometry;
-
-	}
-
-	this.dispatchEvent( _changeEvent );
-
-}
-
-function onContextMenu( event ) {
-
-	if ( ! this.enabled ) {
-
-		return;
-
-	}
-
-	for ( let i = 0; i < this.mouseActions.length; i ++ ) {
-
-		if ( this.mouseActions[ i ].mouse == 2 ) {
-
-			//prevent only if button 2 is actually used
-			event.preventDefault();
-			break;
-
-		}
-
-	}
-
-}
-
-function onPointerCancel() {
-
-	this._touchStart.splice( 0, this._touchStart.length );
-	this._touchCurrent.splice( 0, this._touchCurrent.length );
-	this._input = INPUT.NONE;
-
-}
-
-function onPointerDown( event ) {
-
-	if ( event.button == 0 && event.isPrimary ) {
-
-		this._downValid = true;
-		this._downEvents.push( event );
-		this._downStart = performance.now();
-
-	} else {
-
-		this._downValid = false;
-
-	}
-
-	if ( event.pointerType == 'touch' && this._input != INPUT.CURSOR ) {
-
-		this._touchStart.push( event );
-		this._touchCurrent.push( event );
-
-		switch ( this._input ) {
-
-			case INPUT.NONE:
-
-				//singleStart
-				this._input = INPUT.ONE_FINGER;
-				this.onSinglePanStart( event, 'ROTATE' );
-
-				window.addEventListener( 'pointermove', this._onPointerMove );
-				window.addEventListener( 'pointerup', this._onPointerUp );
-
-				break;
-
-			case INPUT.ONE_FINGER:
-			case INPUT.ONE_FINGER_SWITCHED:
-
-				//doubleStart
-				this._input = INPUT.TWO_FINGER;
-
-				this.onRotateStart();
-				this.onPinchStart();
-				this.onDoublePanStart();
-
-				break;
-
-			case INPUT.TWO_FINGER:
-
-				//multipleStart
-				this._input = INPUT.MULT_FINGER;
-				this.onTriplePanStart( event );
-				break;
-
-		}
-
-	} else if ( event.pointerType != 'touch' && this._input == INPUT.NONE ) {
-
-		let modifier = null;
-
-		if ( event.ctrlKey || event.metaKey ) {
-
-			modifier = 'CTRL';
-
-		} else if ( event.shiftKey ) {
-
-			modifier = 'SHIFT';
-
-		}
-
-		this._mouseOp = this.getOpFromAction( event.button, modifier );
-		if ( this._mouseOp != null ) {
-
-			window.addEventListener( 'pointermove', this._onPointerMove );
-			window.addEventListener( 'pointerup', this._onPointerUp );
-
-			//singleStart
-			this._input = INPUT.CURSOR;
-			this._button = event.button;
-			this.onSinglePanStart( event, this._mouseOp );
-
-		}
-
-	}
-
-}
-
-function onPointerMove( event ) {
-
-	if ( event.pointerType == 'touch' && this._input != INPUT.CURSOR ) {
-
-		switch ( this._input ) {
-
-			case INPUT.ONE_FINGER:
-
-				//singleMove
-				this.updateTouchEvent( event );
-
-				this.onSinglePanMove( event, STATE.ROTATE );
-				break;
-
-			case INPUT.ONE_FINGER_SWITCHED:
-
-				const movement = this.calculatePointersDistance( this._touchCurrent[ 0 ], event ) * this._devPxRatio;
-
-				if ( movement >= this._switchSensibility ) {
-
-					//singleMove
-					this._input = INPUT.ONE_FINGER;
-					this.updateTouchEvent( event );
-
-					this.onSinglePanStart( event, 'ROTATE' );
-					break;
-
-				}
-
-				break;
-
-			case INPUT.TWO_FINGER:
-
-				//rotate/pan/pinchMove
-				this.updateTouchEvent( event );
-
-				this.onRotateMove();
-				this.onPinchMove();
-				this.onDoublePanMove();
-
-				break;
-
-			case INPUT.MULT_FINGER:
-
-				//multMove
-				this.updateTouchEvent( event );
-
-				this.onTriplePanMove( event );
-				break;
-
-		}
-
-	} else if ( event.pointerType != 'touch' && this._input == INPUT.CURSOR ) {
-
-		let modifier = null;
-
-		if ( event.ctrlKey || event.metaKey ) {
-
-			modifier = 'CTRL';
-
-		} else if ( event.shiftKey ) {
-
-			modifier = 'SHIFT';
-
-		}
-
-		const mouseOpState = this.getOpStateFromAction( this._button, modifier );
-
-		if ( mouseOpState != null ) {
-
-			this.onSinglePanMove( event, mouseOpState );
-
-		}
-
-	}
-
-	//checkDistance
-	if ( this._downValid ) {
-
-		const movement = this.calculatePointersDistance( this._downEvents[ this._downEvents.length - 1 ], event ) * this._devPxRatio;
-		if ( movement > this._movementThreshold ) {
-
-			this._downValid = false;
-
-		}
-
-	}
-
-}
-
-function onPointerUp( event ) {
-
-	if ( event.pointerType == 'touch' && this._input != INPUT.CURSOR ) {
-
-		const nTouch = this._touchCurrent.length;
-
-		for ( let i = 0; i < nTouch; i ++ ) {
-
-			if ( this._touchCurrent[ i ].pointerId == event.pointerId ) {
-
-				this._touchCurrent.splice( i, 1 );
-				this._touchStart.splice( i, 1 );
-				break;
-
-			}
-
-		}
-
-		switch ( this._input ) {
-
-			case INPUT.ONE_FINGER:
-			case INPUT.ONE_FINGER_SWITCHED:
-
-				//singleEnd
-				window.removeEventListener( 'pointermove', this._onPointerMove );
-				window.removeEventListener( 'pointerup', this._onPointerUp );
-
-				this._input = INPUT.NONE;
-				this.onSinglePanEnd();
-
-				break;
-
-			case INPUT.TWO_FINGER:
-
-				//doubleEnd
-				this.onDoublePanEnd( event );
-				this.onPinchEnd( event );
-				this.onRotateEnd( event );
-
-				//switching to singleStart
-				this._input = INPUT.ONE_FINGER_SWITCHED;
-
-				break;
-
-			case INPUT.MULT_FINGER:
-
-				if ( this._touchCurrent.length == 0 ) {
-
-					window.removeEventListener( 'pointermove', this._onPointerMove );
-					window.removeEventListener( 'pointerup', this._onPointerUp );
-
-					//multCancel
-					this._input = INPUT.NONE;
-					this.onTriplePanEnd();
-
-				}
-
-				break;
-
-		}
-
-	} else if ( event.pointerType != 'touch' && this._input == INPUT.CURSOR ) {
-
-		window.removeEventListener( 'pointermove', this._onPointerMove );
-		window.removeEventListener( 'pointerup', this._onPointerUp );
-
-		this._input = INPUT.NONE;
-		this.onSinglePanEnd();
-		this._button = - 1;
-
-	}
-
-	if ( event.isPrimary ) {
-
-		if ( this._downValid ) {
-
-			const downTime = event.timeStamp - this._downEvents[ this._downEvents.length - 1 ].timeStamp;
-
-			if ( downTime <= this._maxDownTime ) {
-
-				if ( this._nclicks == 0 ) {
-
-					//first valid click detected
-					this._nclicks = 1;
-					this._clickStart = performance.now();
-
-				} else {
-
-					const clickInterval = event.timeStamp - this._clickStart;
-					const movement = this.calculatePointersDistance( this._downEvents[ 1 ], this._downEvents[ 0 ] ) * this._devPxRatio;
-
-					if ( clickInterval <= this._maxInterval && movement <= this._posThreshold ) {
-
-						//second valid click detected
-						//fire double tap and reset values
-						this._nclicks = 0;
-						this._downEvents.splice( 0, this._downEvents.length );
-						this.onDoubleTap( event );
-
-					} else {
-
-						//new 'first click'
-						this._nclicks = 1;
-						this._downEvents.shift();
-						this._clickStart = performance.now();
-
-					}
-
-				}
-
-			} else {
-
-				this._downValid = false;
-				this._nclicks = 0;
-				this._downEvents.splice( 0, this._downEvents.length );
-
-			}
-
-		} else {
-
-			this._nclicks = 0;
-			this._downEvents.splice( 0, this._downEvents.length );
-
-		}
-
-	}
-
-}
-
-function onWheel( event ) {
-
-	if ( this.enabled && this.enableZoom ) {
-
-		let modifier = null;
-
-		if ( event.ctrlKey || event.metaKey ) {
-
-			modifier = 'CTRL';
-
-		} else if ( event.shiftKey ) {
-
-			modifier = 'SHIFT';
-
-		}
-
-		const mouseOp = this.getOpFromAction( 'WHEEL', modifier );
-
-		if ( mouseOp != null ) {
-
-			event.preventDefault();
-			this.dispatchEvent( _startEvent );
-
-			const notchDeltaY = 125; //distance of one notch of mouse wheel
-			let sgn = event.deltaY / notchDeltaY;
-
-			let size = 1;
-
-			if ( sgn > 0 ) {
-
-				size = 1 / this.scaleFactor;
-
-			} else if ( sgn < 0 ) {
-
-				size = this.scaleFactor;
-
-			}
-
-			switch ( mouseOp ) {
-
-				case 'ZOOM':
-
-					this.updateTbState( STATE.SCALE, true );
-
-					if ( sgn > 0 ) {
-
-						size = 1 / ( Math.pow( this.scaleFactor, sgn ) );
-
-					} else if ( sgn < 0 ) {
-
-						size = Math.pow( this.scaleFactor, - sgn );
-
-					}
-
-					if ( this.cursorZoom && this.enablePan ) {
-
-						let scalePoint;
-
-						if ( this.object.isOrthographicCamera ) {
-
-							scalePoint = this.unprojectOnTbPlane( this.object, event.clientX, event.clientY, this.domElement ).applyQuaternion( this.object.quaternion ).multiplyScalar( 1 / this.object.zoom ).add( this._gizmos.position );
-
-						} else if ( this.object.isPerspectiveCamera ) {
-
-							scalePoint = this.unprojectOnTbPlane( this.object, event.clientX, event.clientY, this.domElement ).applyQuaternion( this.object.quaternion ).add( this._gizmos.position );
-
-						}
-
-						this.applyTransformMatrix( this.scale( size, scalePoint ) );
-
-					} else {
-
-						this.applyTransformMatrix( this.scale( size, this._gizmos.position ) );
-
-					}
-
-					if ( this._grid != null ) {
-
-						this.disposeGrid();
-						this.drawGrid();
-
-					}
-
-					this.updateTbState( STATE.IDLE, false );
-
-					this.dispatchEvent( _changeEvent );
-					this.dispatchEvent( _endEvent );
-
-					break;
-
-				case 'FOV':
-
-					if ( this.object.isPerspectiveCamera ) {
-
-						this.updateTbState( STATE.FOV, true );
-
-
-						//Vertigo effect
-
-						//	  fov / 2
-						//		|\
-						//		| \
-						//		|  \
-						//	x	|	\
-						//		| 	 \
-						//		| 	  \
-						//		| _ _ _\
-						//			y
-
-						//check for iOs shift shortcut
-						if ( event.deltaX != 0 ) {
-
-							sgn = event.deltaX / notchDeltaY;
-
-							size = 1;
-
-							if ( sgn > 0 ) {
-
-								size = 1 / ( Math.pow( this.scaleFactor, sgn ) );
-
-							} else if ( sgn < 0 ) {
-
-								size = Math.pow( this.scaleFactor, - sgn );
-
-							}
-
-						}
-
-						this._v3_1.setFromMatrixPosition( this._cameraMatrixState );
-						const x = this._v3_1.distanceTo( this._gizmos.position );
-						let xNew = x / size;	//distance between camera and gizmos if scale(size, scalepoint) would be performed
-
-						//check min and max distance
-						xNew = MathUtils.clamp( xNew, this.minDistance, this.maxDistance );
-
-						const y = x * Math.tan( MathUtils.DEG2RAD * this.object.fov * 0.5 );
-
-						//calculate new fov
-						let newFov = MathUtils.RAD2DEG * ( Math.atan( y / xNew ) * 2 );
-
-						//check min and max fov
-						if ( newFov > this.maxFov ) {
-
-							newFov = this.maxFov;
-
-						} else if ( newFov < this.minFov ) {
-
-							newFov = this.minFov;
-
-						}
-
-						const newDistance = y / Math.tan( MathUtils.DEG2RAD * ( newFov / 2 ) );
-						size = x / newDistance;
-
-						this.setFov( newFov );
-						this.applyTransformMatrix( this.scale( size, this._gizmos.position, false ) );
-
-					}
-
-					if ( this._grid != null ) {
-
-						this.disposeGrid();
-						this.drawGrid();
-
-					}
-
-					this.updateTbState( STATE.IDLE, false );
-
-					this.dispatchEvent( _changeEvent );
-					this.dispatchEvent( _endEvent );
-
-					break;
-
-			}
-
-		}
-
-	}
-
-}
-
-export { ArcballControls };

+ 0 - 452
node_modules/three/examples/jsm/controls/DragControls.js

@@ -1,452 +0,0 @@
-import {
-	Controls,
-	Matrix4,
-	Plane,
-	Raycaster,
-	Vector2,
-	Vector3,
-	MOUSE,
-	TOUCH
-} from 'three';
-
-const _plane = new Plane();
-
-const _pointer = new Vector2();
-const _offset = new Vector3();
-const _diff = new Vector2();
-const _previousPointer = new Vector2();
-const _intersection = new Vector3();
-const _worldPosition = new Vector3();
-const _inverseMatrix = new Matrix4();
-
-const _up = new Vector3();
-const _right = new Vector3();
-
-let _selected = null, _hovered = null;
-const _intersections = [];
-
-const STATE = {
-	NONE: - 1,
-	PAN: 0,
-	ROTATE: 1
-};
-
-/**
- * This class can be used to provide a drag'n'drop interaction.
- *
- * ```js
- * const controls = new DragControls( objects, camera, renderer.domElement );
- *
- * // add event listener to highlight dragged objects
- * controls.addEventListener( 'dragstart', function ( event ) {
- *
- * 	event.object.material.emissive.set( 0xaaaaaa );
- *
- * } );
- *
- * controls.addEventListener( 'dragend', function ( event ) {
- *
- * 	event.object.material.emissive.set( 0x000000 );
- *
- * } );
- * ```
- *
- * @augments Controls
- * @three_import import { DragControls } from 'three/addons/controls/DragControls.js';
- */
-class DragControls extends Controls {
-
-	/**
-	 * Constructs a new controls instance.
-	 *
-	 * @param {Array<Object3D>} objects - An array of draggable 3D objects.
-	 * @param {Camera} camera - The camera of the rendered scene.
-	 * @param {?HTMLElement} [domElement=null] - The HTML DOM element used for event listeners.
-	 */
-	constructor( objects, camera, domElement = null ) {
-
-		super( camera, domElement );
-
-		/**
-		 * An array of draggable 3D objects.
-		 *
-		 * @type {Array<Object3D>}
-		 */
-		this.objects = objects;
-
-		/**
-		 * Whether children of draggable objects can be dragged independently from their parent.
-		 *
-		 * @type {boolean}
-		 * @default true
-		 */
-		this.recursive = true;
-
-		/**
-		 * This option only works if the `objects` array contains a single draggable  group object.
-		 * If set to `true`, the controls does not transform individual objects but the entire group.
-		 *
-		 * @type {boolean}
-		 * @default false
-		 */
-		this.transformGroup = false;
-
-		/**
-		 * The speed at which the object will rotate when dragged in `rotate` mode.
-		 * The higher the number the faster the rotation.
-		 *
-		 * @type {number}
-		 * @default 1
-		 */
-		this.rotateSpeed = 1;
-
-		/**
-		 * The raycaster used for detecting 3D objects.
-		 *
-		 * @type {Raycaster}
-		 */
-		this.raycaster = new Raycaster();
-
-		// interaction
-
-		this.mouseButtons = { LEFT: MOUSE.PAN, MIDDLE: MOUSE.PAN, RIGHT: MOUSE.ROTATE };
-		this.touches = { ONE: TOUCH.PAN };
-
-		// event listeners
-
-		this._onPointerMove = onPointerMove.bind( this );
-		this._onPointerDown = onPointerDown.bind( this );
-		this._onPointerCancel = onPointerCancel.bind( this );
-		this._onContextMenu = onContextMenu.bind( this );
-
-		//
-
-		if ( domElement !== null ) {
-
-			this.connect( domElement );
-
-		}
-
-	}
-
-	connect( element ) {
-
-		super.connect( element );
-
-		this.domElement.addEventListener( 'pointermove', this._onPointerMove );
-		this.domElement.addEventListener( 'pointerdown', this._onPointerDown );
-		this.domElement.addEventListener( 'pointerup', this._onPointerCancel );
-		this.domElement.addEventListener( 'pointerleave', this._onPointerCancel );
-		this.domElement.addEventListener( 'contextmenu', this._onContextMenu );
-
-		this.domElement.style.touchAction = 'none'; // Disable touch scroll
-
-	}
-
-	disconnect() {
-
-		this.domElement.removeEventListener( 'pointermove', this._onPointerMove );
-		this.domElement.removeEventListener( 'pointerdown', this._onPointerDown );
-		this.domElement.removeEventListener( 'pointerup', this._onPointerCancel );
-		this.domElement.removeEventListener( 'pointerleave', this._onPointerCancel );
-		this.domElement.removeEventListener( 'contextmenu', this._onContextMenu );
-
-		this.domElement.style.touchAction = ''; // Restore touch scroll
-		this.domElement.style.cursor = '';
-
-	}
-
-	dispose() {
-
-		this.disconnect();
-
-	}
-
-	_updatePointer( event ) {
-
-		const rect = this.domElement.getBoundingClientRect();
-
-		_pointer.x = ( event.clientX - rect.left ) / rect.width * 2 - 1;
-		_pointer.y = - ( event.clientY - rect.top ) / rect.height * 2 + 1;
-
-	}
-
-	_updateState( event ) {
-
-		// determine action
-
-		let action;
-
-		if ( event.pointerType === 'touch' ) {
-
-			action = this.touches.ONE;
-
-		} else {
-
-			switch ( event.button ) {
-
-				case 0:
-
-					action = this.mouseButtons.LEFT;
-					break;
-
-				case 1:
-
-					action = this.mouseButtons.MIDDLE;
-					break;
-
-				case 2:
-
-					action = this.mouseButtons.RIGHT;
-					break;
-
-				default:
-
-					action = null;
-
-			}
-
-		}
-
-		// determine state
-
-		switch ( action ) {
-
-			case MOUSE.PAN:
-			case TOUCH.PAN:
-
-				this.state = STATE.PAN;
-
-				break;
-
-			case MOUSE.ROTATE:
-			case TOUCH.ROTATE:
-
-				this.state = STATE.ROTATE;
-
-				break;
-
-			default:
-
-				this.state = STATE.NONE;
-
-		}
-
-	}
-
-}
-
-function onPointerMove( event ) {
-
-	const camera = this.object;
-	const domElement = this.domElement;
-	const raycaster = this.raycaster;
-
-	if ( this.enabled === false ) return;
-
-	this._updatePointer( event );
-
-	raycaster.setFromCamera( _pointer, camera );
-
-	if ( _selected ) {
-
-		if ( this.state === STATE.PAN ) {
-
-			if ( raycaster.ray.intersectPlane( _plane, _intersection ) ) {
-
-				_selected.position.copy( _intersection.sub( _offset ).applyMatrix4( _inverseMatrix ) );
-				this.dispatchEvent( { type: 'drag', object: _selected } );
-
-			}
-
-		} else if ( this.state === STATE.ROTATE ) {
-
-			_diff.subVectors( _pointer, _previousPointer ).multiplyScalar( this.rotateSpeed );
-			_selected.rotateOnWorldAxis( _up, _diff.x );
-			_selected.rotateOnWorldAxis( _right.normalize(), - _diff.y );
-			this.dispatchEvent( { type: 'drag', object: _selected } );
-
-		}
-
-		_previousPointer.copy( _pointer );
-
-	} else {
-
-		// hover support
-
-		if ( event.pointerType === 'mouse' || event.pointerType === 'pen' ) {
-
-			_intersections.length = 0;
-
-			raycaster.setFromCamera( _pointer, camera );
-			raycaster.intersectObjects( this.objects, this.recursive, _intersections );
-
-			if ( _intersections.length > 0 ) {
-
-				const object = _intersections[ 0 ].object;
-
-				_plane.setFromNormalAndCoplanarPoint( camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( object.matrixWorld ) );
-
-				if ( _hovered !== object && _hovered !== null ) {
-
-					this.dispatchEvent( { type: 'hoveroff', object: _hovered } );
-
-					domElement.style.cursor = 'auto';
-					_hovered = null;
-
-				}
-
-				if ( _hovered !== object ) {
-
-					this.dispatchEvent( { type: 'hoveron', object: object } );
-
-					domElement.style.cursor = 'pointer';
-					_hovered = object;
-
-				}
-
-			} else {
-
-				if ( _hovered !== null ) {
-
-					this.dispatchEvent( { type: 'hoveroff', object: _hovered } );
-
-					domElement.style.cursor = 'auto';
-					_hovered = null;
-
-				}
-
-			}
-
-		}
-
-	}
-
-	_previousPointer.copy( _pointer );
-
-}
-
-function onPointerDown( event ) {
-
-	const camera = this.object;
-	const domElement = this.domElement;
-	const raycaster = this.raycaster;
-
-	if ( this.enabled === false ) return;
-
-	this._updatePointer( event );
-	this._updateState( event );
-
-	_intersections.length = 0;
-
-	raycaster.setFromCamera( _pointer, camera );
-	raycaster.intersectObjects( this.objects, this.recursive, _intersections );
-
-	if ( _intersections.length > 0 ) {
-
-		if ( this.transformGroup === true ) {
-
-			// look for the outermost group in the object's upper hierarchy
-
-			_selected = findGroup( _intersections[ 0 ].object );
-
-		} else {
-
-			_selected = _intersections[ 0 ].object;
-
-		}
-
-		_plane.setFromNormalAndCoplanarPoint( camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
-
-		if ( raycaster.ray.intersectPlane( _plane, _intersection ) ) {
-
-			if ( this.state === STATE.PAN ) {
-
-				_inverseMatrix.copy( _selected.parent.matrixWorld ).invert();
-				_offset.copy( _intersection ).sub( _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
-				domElement.style.cursor = 'move';
-				this.dispatchEvent( { type: 'dragstart', object: _selected } );
-
-			} else if ( this.state === STATE.ROTATE ) {
-
-				// the controls only support Y+ up
-				_up.set( 0, 1, 0 ).applyQuaternion( camera.quaternion ).normalize();
-				_right.set( 1, 0, 0 ).applyQuaternion( camera.quaternion ).normalize();
-				domElement.style.cursor = 'move';
-				this.dispatchEvent( { type: 'dragstart', object: _selected } );
-
-			}
-
-		}
-
-	}
-
-	_previousPointer.copy( _pointer );
-
-}
-
-function onPointerCancel() {
-
-	if ( this.enabled === false ) return;
-
-	if ( _selected ) {
-
-		this.dispatchEvent( { type: 'dragend', object: _selected } );
-
-		_selected = null;
-
-	}
-
-	this.domElement.style.cursor = _hovered ? 'pointer' : 'auto';
-
-	this.state = STATE.NONE;
-
-}
-
-function onContextMenu( event ) {
-
-	if ( this.enabled === false ) return;
-
-	event.preventDefault();
-
-}
-
-function findGroup( obj, group = null ) {
-
-	if ( obj.isGroup ) group = obj;
-
-	if ( obj.parent === null ) return group;
-
-	return findGroup( obj.parent, group );
-
-}
-
-/**
- * Fires when the user drags a 3D object.
- *
- * @event DragControls#drag
- * @type {Object}
- */
-
-/**
- * Fires when the user has finished dragging a 3D object.
- *
- * @event DragControls#dragend
- * @type {Object}
- */
-
-/**
- * Fires when the pointer is moved onto a 3D object, or onto one of its children.
- *
- * @event DragControls#hoveron
- * @type {Object}
- */
-
-/**
- * Fires when the pointer is moved out of a 3D object.
- *
- * @event DragControls#hoveroff
- * @type {Object}
- */
-
-export { DragControls };

+ 0 - 451
node_modules/three/examples/jsm/controls/FirstPersonControls.js

@@ -1,451 +0,0 @@
-import {
-	Controls,
-	MathUtils,
-	Spherical,
-	Vector3
-} from 'three';
-
-const _lookDirection = new Vector3();
-const _spherical = new Spherical();
-const _target = new Vector3();
-const _targetPosition = new Vector3();
-
-/**
- * This class is an alternative implementation of {@link FlyControls}.
- *
- * @augments Controls
- * @three_import import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js';
- */
-class FirstPersonControls extends Controls {
-
-	/**
-	 * Constructs a new controls instance.
-	 *
-	 * @param {Object3D} object - The object that is managed by the controls.
-	 * @param {?HTMLElement} domElement - The HTML element used for event listeners.
-	 */
-	constructor( object, domElement = null ) {
-
-		super( object, domElement );
-
-		/**
-		 * The movement speed.
-		 *
-		 * @type {number}
-		 * @default 1
-		 */
-		this.movementSpeed = 1.0;
-
-		/**
-		 * The look around speed.
-		 *
-		 * @type {number}
-		 * @default 0.005
-		 */
-		this.lookSpeed = 0.005;
-
-		/**
-		 * Whether it's possible to vertically look around or not.
-		 *
-		 * @type {boolean}
-		 * @default true
-		 */
-		this.lookVertical = true;
-
-		/**
-		 * Whether the camera is automatically moved forward or not.
-		 *
-		 * @type {boolean}
-		 * @default false
-		 */
-		this.autoForward = false;
-
-		/**
-		 * Whether or not the camera's height influences the forward movement speed.
-		 * Use the properties `heightCoef`, `heightMin` and `heightMax` for configuration.
-		 *
-		 * @type {boolean}
-		 * @default false
-		 */
-		this.heightSpeed = false;
-
-		/**
-		 * Determines how much faster the camera moves when it's y-component is near `heightMax`.
-		 *
-		 * @type {number}
-		 * @default 1
-		 */
-		this.heightCoef = 1.0;
-
-		/**
-		 * Lower camera height limit used for movement speed adjustment.
-		 *
-		 * @type {number}
-		 * @default 0
-		 */
-		this.heightMin = 0.0;
-
-		/**
-		 * Upper camera height limit used for movement speed adjustment.
-		 *
-		 * @type {number}
-		 * @default 1
-		 */
-		this.heightMax = 1.0;
-
-		/**
-		 * Whether or not looking around is vertically constrained by `verticalMin` and `verticalMax`.
-		 *
-		 * @type {boolean}
-		 * @default false
-		 */
-		this.constrainVertical = false;
-
-		/**
-		 * How far you can vertically look around, lower limit. Range is `0` to `Math.PI` in radians.
-		 *
-		 * @type {number}
-		 * @default 0
-		 */
-		this.verticalMin = 0;
-
-		/**
-		 * How far you can vertically look around, upper limit. Range is `0` to `Math.PI` in radians.
-		 *
-		 * @type {number}
-		 * @default 0
-		 */
-		this.verticalMax = Math.PI;
-
-		/**
-		 * Whether the mouse is pressed down or not.
-		 *
-		 * @type {boolean}
-		 * @readonly
-		 * @default false
-		 */
-		this.mouseDragOn = false;
-
-		// internals
-
-		this._autoSpeedFactor = 0.0;
-
-		this._pointerX = 0;
-		this._pointerY = 0;
-
-		this._pointerDownX = 0;
-		this._pointerDownY = 0;
-
-		this._pointerCount = 0;
-
-		this._moveForward = false;
-		this._moveBackward = false;
-		this._moveLeft = false;
-		this._moveRight = false;
-
-		this._lat = 0;
-		this._lon = 0;
-
-		// event listeners
-
-		this._onPointerMove = onPointerMove.bind( this );
-		this._onPointerDown = onPointerDown.bind( this );
-		this._onPointerUp = onPointerUp.bind( this );
-		this._onContextMenu = onContextMenu.bind( this );
-		this._onKeyDown = onKeyDown.bind( this );
-		this._onKeyUp = onKeyUp.bind( this );
-
-		//
-
-		if ( domElement !== null ) {
-
-			this.connect( domElement );
-
-		}
-
-		this._setOrientation();
-
-	}
-
-	connect( element ) {
-
-		super.connect( element );
-
-		window.addEventListener( 'keydown', this._onKeyDown );
-		window.addEventListener( 'keyup', this._onKeyUp );
-
-		this.domElement.addEventListener( 'pointermove', this._onPointerMove );
-		this.domElement.addEventListener( 'pointerdown', this._onPointerDown );
-		this.domElement.addEventListener( 'pointerup', this._onPointerUp );
-		this.domElement.addEventListener( 'contextmenu', this._onContextMenu );
-
-		this.domElement.style.touchAction = 'none'; // Disable touch scroll
-
-	}
-
-	disconnect() {
-
-		window.removeEventListener( 'keydown', this._onKeyDown );
-		window.removeEventListener( 'keyup', this._onKeyUp );
-
-		this.domElement.removeEventListener( 'pointermove', this._onPointerMove );
-		this.domElement.removeEventListener( 'pointerdown', this._onPointerDown );
-		this.domElement.removeEventListener( 'pointerup', this._onPointerUp );
-		this.domElement.removeEventListener( 'contextmenu', this._onContextMenu );
-
-		this.domElement.style.touchAction = ''; // Restore touch scroll
-
-	}
-
-	dispose() {
-
-		this.disconnect();
-
-	}
-
-	/**
-	 * Rotates the camera towards the defined target position.
-	 *
-	 * @param {number|Vector3} x - The x coordinate of the target position or alternatively a vector representing the target position.
-	 * @param {number} y - The y coordinate of the target position.
-	 * @param {number} z - The z coordinate of the target position.
-	 * @return {FirstPersonControls} A reference to this controls.
-	 */
-	lookAt( x, y, z ) {
-
-		if ( x.isVector3 ) {
-
-			_target.copy( x );
-
-		} else {
-
-			_target.set( x, y, z );
-
-		}
-
-		this.object.lookAt( _target );
-
-		this._setOrientation();
-
-		return this;
-
-	}
-
-	update( delta ) {
-
-		if ( this.enabled === false ) return;
-
-		if ( this.heightSpeed ) {
-
-			const y = MathUtils.clamp( this.object.position.y, this.heightMin, this.heightMax );
-			const heightDelta = y - this.heightMin;
-
-			this._autoSpeedFactor = delta * ( heightDelta * this.heightCoef );
-
-		} else {
-
-			this._autoSpeedFactor = 0.0;
-
-		}
-
-		const actualMoveSpeed = delta * this.movementSpeed;
-
-		if ( this._moveForward || ( this.autoForward && ! this._moveBackward ) ) this.object.translateZ( - ( actualMoveSpeed + this._autoSpeedFactor ) );
-		if ( this._moveBackward ) this.object.translateZ( actualMoveSpeed );
-
-		if ( this._moveLeft ) this.object.translateX( - actualMoveSpeed );
-		if ( this._moveRight ) this.object.translateX( actualMoveSpeed );
-
-		if ( this._moveUp ) this.object.translateY( actualMoveSpeed );
-		if ( this._moveDown ) this.object.translateY( - actualMoveSpeed );
-
-		const actualLookSpeed = delta * this.lookSpeed;
-
-		let verticalLookRatio = 1;
-
-		if ( this.constrainVertical ) {
-
-			verticalLookRatio = Math.PI / ( this.verticalMax - this.verticalMin );
-
-		}
-
-		if ( this.mouseDragOn ) {
-
-			this._lon -= this._pointerX * actualLookSpeed;
-			if ( this.lookVertical ) this._lat -= this._pointerY * actualLookSpeed * verticalLookRatio;
-
-		}
-
-		this._lat = Math.max( - 85, Math.min( 85, this._lat ) );
-
-		let phi = MathUtils.degToRad( 90 - this._lat );
-		const theta = MathUtils.degToRad( this._lon );
-
-		if ( this.constrainVertical ) {
-
-			phi = MathUtils.mapLinear( phi, 0, Math.PI, this.verticalMin, this.verticalMax );
-
-		}
-
-		const position = this.object.position;
-
-		_targetPosition.setFromSphericalCoords( 1, phi, theta ).add( position );
-
-		this.object.lookAt( _targetPosition );
-
-	}
-
-	_setOrientation() {
-
-		const quaternion = this.object.quaternion;
-
-		_lookDirection.set( 0, 0, - 1 ).applyQuaternion( quaternion );
-		_spherical.setFromVector3( _lookDirection );
-
-		this._lat = 90 - MathUtils.radToDeg( _spherical.phi );
-		this._lon = MathUtils.radToDeg( _spherical.theta );
-
-	}
-
-	/**
-	 * @deprecated, r184. This method is no longer needed.
-	 */
-	handleResize() {
-
-		console.warn( 'THREE.FirstPersonControls: handleResize() has been removed.' );
-
-	}
-
-}
-
-function onPointerDown( event ) {
-
-	if ( this.domElement !== document ) {
-
-		this.domElement.focus();
-
-	}
-
-	this.domElement.setPointerCapture( event.pointerId );
-
-	this._pointerCount ++;
-
-	if ( event.pointerType === 'touch' ) {
-
-		this._moveForward = this._pointerCount === 1;
-		this._moveBackward = this._pointerCount >= 2;
-
-	} else {
-
-		switch ( event.button ) {
-
-			case 0: this._moveForward = true; break;
-			case 2: this._moveBackward = true; break;
-
-		}
-
-	}
-
-	this._pointerDownX = event.pageX;
-	this._pointerDownY = event.pageY;
-
-	this._pointerX = 0;
-	this._pointerY = 0;
-
-	this.mouseDragOn = true;
-
-}
-
-function onPointerUp( event ) {
-
-	this.domElement.releasePointerCapture( event.pointerId );
-
-	this._pointerCount --;
-
-	if ( event.pointerType === 'touch' ) {
-
-		this._moveForward = this._pointerCount === 1;
-		this._moveBackward = false;
-
-	} else {
-
-		switch ( event.button ) {
-
-			case 0: this._moveForward = false; break;
-			case 2: this._moveBackward = false; break;
-
-		}
-
-	}
-
-	this._pointerX = 0;
-	this._pointerY = 0;
-
-	if ( this._pointerCount === 0 ) this.mouseDragOn = false;
-
-}
-
-function onPointerMove( event ) {
-
-	if ( this.mouseDragOn === false ) return;
-
-	this._pointerX = event.pageX - this._pointerDownX;
-	this._pointerY = event.pageY - this._pointerDownY;
-
-}
-
-function onKeyDown( event ) {
-
-	switch ( event.code ) {
-
-		case 'ArrowUp':
-		case 'KeyW': this._moveForward = true; break;
-
-		case 'ArrowLeft':
-		case 'KeyA': this._moveLeft = true; break;
-
-		case 'ArrowDown':
-		case 'KeyS': this._moveBackward = true; break;
-
-		case 'ArrowRight':
-		case 'KeyD': this._moveRight = true; break;
-
-		case 'KeyR': this._moveUp = true; break;
-		case 'KeyF': this._moveDown = true; break;
-
-	}
-
-}
-
-function onKeyUp( event ) {
-
-	switch ( event.code ) {
-
-		case 'ArrowUp':
-		case 'KeyW': this._moveForward = false; break;
-
-		case 'ArrowLeft':
-		case 'KeyA': this._moveLeft = false; break;
-
-		case 'ArrowDown':
-		case 'KeyS': this._moveBackward = false; break;
-
-		case 'ArrowRight':
-		case 'KeyD': this._moveRight = false; break;
-
-		case 'KeyR': this._moveUp = false; break;
-		case 'KeyF': this._moveDown = false; break;
-
-	}
-
-}
-
-function onContextMenu( event ) {
-
-	if ( this.enabled === false ) return;
-
-	event.preventDefault();
-
-}
-
-export { FirstPersonControls };

+ 0 - 384
node_modules/three/examples/jsm/controls/FlyControls.js

@@ -1,384 +0,0 @@
-import {
-	Controls,
-	Quaternion,
-	Vector3
-} from 'three';
-
-/**
- * Fires when the camera has been transformed by the controls.
- *
- * @event FlyControls#change
- * @type {Object}
- */
-const _changeEvent = { type: 'change' };
-
-const _EPS = 0.000001;
-const _tmpQuaternion = new Quaternion();
-
-/**
- * This class enables a navigation similar to fly modes in DCC tools like Blender.
- * You can arbitrarily transform the camera in 3D space without any limitations
- * (e.g. focus on a specific target).
- *
- * @augments Controls
- * @three_import import { FlyControls } from 'three/addons/controls/FlyControls.js';
- */
-class FlyControls extends Controls {
-
-	/**
-	 * Constructs a new controls instance.
-	 *
-	 * @param {Object3D} object - The object that is managed by the controls.
-	 * @param {?HTMLElement} domElement - The HTML element used for event listeners.
-	 */
-	constructor( object, domElement = null ) {
-
-		super( object, domElement );
-
-		/**
-		 * The movement speed.
-		 *
-		 * @type {number}
-		 * @default 1
-		 */
-		this.movementSpeed = 1.0;
-
-		/**
-		 * The rotation speed.
-		 *
-		 * @type {number}
-		 * @default 0.005
-		 */
-		this.rollSpeed = 0.005;
-
-		/**
-		 * If set to `true`, you can only look around by performing a drag interaction.
-		 *
-		 * @type {boolean}
-		 * @default false
-		 */
-		this.dragToLook = false;
-
-		/**
-		 * If set to `true`, the camera automatically moves forward (and does not stop) when initially translated.
-		 *
-		 * @type {boolean}
-		 * @default false
-		 */
-		this.autoForward = false;
-
-		// internals
-
-		this._moveState = { up: 0, down: 0, left: 0, right: 0, forward: 0, back: 0, pitchUp: 0, pitchDown: 0, yawLeft: 0, yawRight: 0, rollLeft: 0, rollRight: 0 };
-		this._moveVector = new Vector3( 0, 0, 0 );
-		this._rotationVector = new Vector3( 0, 0, 0 );
-		this._lastQuaternion = new Quaternion();
-		this._lastPosition = new Vector3();
-		this._status = 0;
-
-		// event listeners
-
-		this._onKeyDown = onKeyDown.bind( this );
-		this._onKeyUp = onKeyUp.bind( this );
-		this._onPointerMove = onPointerMove.bind( this );
-		this._onPointerDown = onPointerDown.bind( this );
-		this._onPointerUp = onPointerUp.bind( this );
-		this._onPointerCancel = onPointerCancel.bind( this );
-		this._onContextMenu = onContextMenu.bind( this );
-
-		//
-
-		if ( domElement !== null ) {
-
-			this.connect( domElement );
-
-		}
-
-	}
-
-	connect( element ) {
-
-		super.connect( element );
-
-		window.addEventListener( 'keydown', this._onKeyDown );
-		window.addEventListener( 'keyup', this._onKeyUp );
-
-		this.domElement.addEventListener( 'pointermove', this._onPointerMove );
-		this.domElement.addEventListener( 'pointerdown', this._onPointerDown );
-		this.domElement.addEventListener( 'pointerup', this._onPointerUp );
-		this.domElement.addEventListener( 'pointercancel', this._onPointerCancel );
-		this.domElement.addEventListener( 'contextmenu', this._onContextMenu );
-
-		this.domElement.style.touchAction = 'none'; // Disable touch scroll
-
-	}
-
-	disconnect() {
-
-		window.removeEventListener( 'keydown', this._onKeyDown );
-		window.removeEventListener( 'keyup', this._onKeyUp );
-
-		this.domElement.removeEventListener( 'pointermove', this._onPointerMove );
-		this.domElement.removeEventListener( 'pointerdown', this._onPointerDown );
-		this.domElement.removeEventListener( 'pointerup', this._onPointerUp );
-		this.domElement.removeEventListener( 'pointercancel', this._onPointerCancel );
-		this.domElement.removeEventListener( 'contextmenu', this._onContextMenu );
-
-		this.domElement.style.touchAction = ''; // Restore touch scroll
-
-	}
-
-	dispose() {
-
-		this.disconnect();
-
-	}
-
-	update( delta ) {
-
-		if ( this.enabled === false ) return;
-
-		const object = this.object;
-
-		const moveMult = delta * this.movementSpeed;
-		const rotMult = delta * this.rollSpeed;
-
-		object.translateX( this._moveVector.x * moveMult );
-		object.translateY( this._moveVector.y * moveMult );
-		object.translateZ( this._moveVector.z * moveMult );
-
-		_tmpQuaternion.set( this._rotationVector.x * rotMult, this._rotationVector.y * rotMult, this._rotationVector.z * rotMult, 1 ).normalize();
-		object.quaternion.multiply( _tmpQuaternion );
-
-		if (
-			this._lastPosition.distanceToSquared( object.position ) > _EPS ||
-			8 * ( 1 - this._lastQuaternion.dot( object.quaternion ) ) > _EPS
-		) {
-
-			this.dispatchEvent( _changeEvent );
-			this._lastQuaternion.copy( object.quaternion );
-			this._lastPosition.copy( object.position );
-
-		}
-
-	}
-
-	// private
-
-	_updateMovementVector() {
-
-		const forward = ( this._moveState.forward || ( this.autoForward && ! this._moveState.back ) ) ? 1 : 0;
-
-		this._moveVector.x = ( - this._moveState.left + this._moveState.right );
-		this._moveVector.y = ( - this._moveState.down + this._moveState.up );
-		this._moveVector.z = ( - forward + this._moveState.back );
-
-		//console.log( 'move:', [ this._moveVector.x, this._moveVector.y, this._moveVector.z ] );
-
-	}
-
-	_updateRotationVector() {
-
-		this._rotationVector.x = ( - this._moveState.pitchDown + this._moveState.pitchUp );
-		this._rotationVector.y = ( - this._moveState.yawRight + this._moveState.yawLeft );
-		this._rotationVector.z = ( - this._moveState.rollRight + this._moveState.rollLeft );
-
-		//console.log( 'rotate:', [ this._rotationVector.x, this._rotationVector.y, this._rotationVector.z ] );
-
-	}
-
-	_getContainerDimensions() {
-
-		if ( this.domElement != document ) {
-
-			return {
-				size: [ this.domElement.offsetWidth, this.domElement.offsetHeight ],
-				offset: [ this.domElement.offsetLeft, this.domElement.offsetTop ]
-			};
-
-		} else {
-
-			return {
-				size: [ window.innerWidth, window.innerHeight ],
-				offset: [ 0, 0 ]
-			};
-
-		}
-
-	}
-
-}
-
-function onKeyDown( event ) {
-
-	if ( event.altKey || this.enabled === false ) {
-
-		return;
-
-	}
-
-	switch ( event.code ) {
-
-		case 'ShiftLeft':
-		case 'ShiftRight': this.movementSpeedMultiplier = .1; break;
-
-		case 'KeyW': this._moveState.forward = 1; break;
-		case 'KeyS': this._moveState.back = 1; break;
-
-		case 'KeyA': this._moveState.left = 1; break;
-		case 'KeyD': this._moveState.right = 1; break;
-
-		case 'KeyR': this._moveState.up = 1; break;
-		case 'KeyF': this._moveState.down = 1; break;
-
-		case 'ArrowUp': this._moveState.pitchUp = 1; break;
-		case 'ArrowDown': this._moveState.pitchDown = 1; break;
-
-		case 'ArrowLeft': this._moveState.yawLeft = 1; break;
-		case 'ArrowRight': this._moveState.yawRight = 1; break;
-
-		case 'KeyQ': this._moveState.rollLeft = 1; break;
-		case 'KeyE': this._moveState.rollRight = 1; break;
-
-	}
-
-	this._updateMovementVector();
-	this._updateRotationVector();
-
-}
-
-function onKeyUp( event ) {
-
-	if ( this.enabled === false ) return;
-
-	switch ( event.code ) {
-
-		case 'ShiftLeft':
-		case 'ShiftRight': this.movementSpeedMultiplier = 1; break;
-
-		case 'KeyW': this._moveState.forward = 0; break;
-		case 'KeyS': this._moveState.back = 0; break;
-
-		case 'KeyA': this._moveState.left = 0; break;
-		case 'KeyD': this._moveState.right = 0; break;
-
-		case 'KeyR': this._moveState.up = 0; break;
-		case 'KeyF': this._moveState.down = 0; break;
-
-		case 'ArrowUp': this._moveState.pitchUp = 0; break;
-		case 'ArrowDown': this._moveState.pitchDown = 0; break;
-
-		case 'ArrowLeft': this._moveState.yawLeft = 0; break;
-		case 'ArrowRight': this._moveState.yawRight = 0; break;
-
-		case 'KeyQ': this._moveState.rollLeft = 0; break;
-		case 'KeyE': this._moveState.rollRight = 0; break;
-
-	}
-
-	this._updateMovementVector();
-	this._updateRotationVector();
-
-}
-
-function onPointerDown( event ) {
-
-	if ( this.enabled === false ) return;
-
-	if ( this.dragToLook ) {
-
-		this._status ++;
-
-	} else {
-
-		switch ( event.button ) {
-
-			case 0: this._moveState.forward = 1; break;
-			case 2: this._moveState.back = 1; break;
-
-		}
-
-		this._updateMovementVector();
-
-	}
-
-}
-
-function onPointerMove( event ) {
-
-	if ( this.enabled === false ) return;
-
-	if ( ! this.dragToLook || this._status > 0 ) {
-
-		const container = this._getContainerDimensions();
-		const halfWidth = container.size[ 0 ] / 2;
-		const halfHeight = container.size[ 1 ] / 2;
-
-		this._moveState.yawLeft = - ( ( event.pageX - container.offset[ 0 ] ) - halfWidth ) / halfWidth;
-		this._moveState.pitchDown = ( ( event.pageY - container.offset[ 1 ] ) - halfHeight ) / halfHeight;
-
-		this._updateRotationVector();
-
-	}
-
-}
-
-function onPointerUp( event ) {
-
-	if ( this.enabled === false ) return;
-
-	if ( this.dragToLook ) {
-
-		this._status --;
-
-		this._moveState.yawLeft = this._moveState.pitchDown = 0;
-
-	} else {
-
-		switch ( event.button ) {
-
-			case 0: this._moveState.forward = 0; break;
-			case 2: this._moveState.back = 0; break;
-
-		}
-
-		this._updateMovementVector();
-
-	}
-
-	this._updateRotationVector();
-
-}
-
-function onPointerCancel() {
-
-	if ( this.enabled === false ) return;
-
-	if ( this.dragToLook ) {
-
-		this._status = 0;
-
-		this._moveState.yawLeft = this._moveState.pitchDown = 0;
-
-	} else {
-
-		this._moveState.forward = 0;
-		this._moveState.back = 0;
-
-		this._updateMovementVector();
-
-	}
-
-	this._updateRotationVector();
-
-}
-
-function onContextMenu( event ) {
-
-	if ( this.enabled === false ) return;
-
-	event.preventDefault();
-
-}
-
-export { FlyControls };

+ 0 - 116
node_modules/three/examples/jsm/controls/MapControls.js

@@ -1,116 +0,0 @@
-import { MOUSE, TOUCH, Plane, Raycaster, Vector2, Vector3 } from 'three';
-
-import { OrbitControls } from './OrbitControls.js';
-
-const _plane = new Plane();
-const _raycaster = new Raycaster();
-const _mouse = new Vector2();
-const _panCurrent = new Vector3();
-
-/**
- * This class is intended for transforming a camera over a map from bird's eye perspective.
- * The class shares its implementation with {@link OrbitControls} but uses a specific preset
- * for mouse/touch interaction and disables screen space panning by default.
- *
- * - Orbit: Right mouse, or left mouse + ctrl/meta/shiftKey / touch: two-finger rotate.
- * - Zoom: Middle mouse, or mousewheel / touch: two-finger spread or squish.
- * - Pan: Left mouse, or arrow keys / touch: one-finger move.
- *
- * @augments OrbitControls
- * @three_import import { MapControls } from 'three/addons/controls/MapControls.js';
- */
-class MapControls extends OrbitControls {
-
-	constructor( object, domElement ) {
-
-		super( object, domElement );
-
-		/**
-		 * Overwritten and set to `false` to pan orthogonal to world-space direction `camera.up`.
-		 *
-		 * @type {boolean}
-		 * @default false
-		 */
-		this.screenSpacePanning = false;
-
-		/**
-		 * This object contains references to the mouse actions used by the controls.
-		 *
-		 * ```js
-		 * controls.mouseButtons = {
-		 * 	LEFT: THREE.MOUSE.PAN,
-		 * 	MIDDLE: THREE.MOUSE.DOLLY,
-		 * 	RIGHT: THREE.MOUSE.ROTATE
-		 * }
-		 * ```
-		 * @type {Object}
-		 */
-		this.mouseButtons = { LEFT: MOUSE.PAN, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.ROTATE };
-
-		/**
-		 * This object contains references to the touch actions used by the controls.
-		 *
-		 * ```js
-		 * controls.mouseButtons = {
-		 * 	ONE: THREE.TOUCH.PAN,
-		 * 	TWO: THREE.TOUCH.DOLLY_ROTATE
-		 * }
-		 * ```
-		 * @type {Object}
-		 */
-		this.touches = { ONE: TOUCH.PAN, TWO: TOUCH.DOLLY_ROTATE };
-
-		this._panWorldStart = new Vector3();
-
-	}
-
-	_handleMouseDownPan( event ) {
-
-		super._handleMouseDownPan( event );
-
-		this._panOffset.set( 0, 0, 0 );
-
-		if ( this.screenSpacePanning === true ) return;
-
-		_plane.setFromNormalAndCoplanarPoint( this.object.up, this.target );
-
-		const element = this.domElement;
-		const rect = element.getBoundingClientRect();
-		_mouse.x = ( ( event.clientX - rect.left ) / rect.width ) * 2 - 1;
-		_mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1;
-
-		_raycaster.setFromCamera( _mouse, this.object );
-		_raycaster.ray.intersectPlane( _plane, this._panWorldStart );
-
-	}
-
-	_handleMouseMovePan( event ) {
-
-		if ( this.screenSpacePanning === true ) {
-
-			super._handleMouseMovePan( event );
-			return;
-
-		}
-
-		const element = this.domElement;
-		const rect = element.getBoundingClientRect();
-		_mouse.x = ( ( event.clientX - rect.left ) / rect.width ) * 2 - 1;
-		_mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1;
-
-		_raycaster.setFromCamera( _mouse, this.object );
-
-		if ( _raycaster.ray.intersectPlane( _plane, _panCurrent ) ) {
-
-			_panCurrent.sub( this._panWorldStart );
-			this._panOffset.copy( _panCurrent ).negate();
-
-			this.update();
-
-		}
-
-	}
-
-}
-
-export { MapControls };

+ 0 - 1963
node_modules/three/examples/jsm/controls/OrbitControls.js

@@ -1,1963 +0,0 @@
-import {
-	Controls,
-	MOUSE,
-	Quaternion,
-	Spherical,
-	TOUCH,
-	Vector2,
-	Vector3,
-	Plane,
-	Ray,
-	MathUtils
-} from 'three';
-
-/**
- * Fires when the camera has been transformed by the controls.
- *
- * @event OrbitControls#change
- * @type {Object}
- */
-const _changeEvent = { type: 'change' };
-
-/**
- * Fires when an interaction was initiated.
- *
- * @event OrbitControls#start
- * @type {Object}
- */
-const _startEvent = { type: 'start' };
-
-/**
- * Fires when an interaction has finished.
- *
- * @event OrbitControls#end
- * @type {Object}
- */
-const _endEvent = { type: 'end' };
-
-const _ray = new Ray();
-const _plane = new Plane();
-const _TILT_LIMIT = Math.cos( 70 * MathUtils.DEG2RAD );
-
-const _v = new Vector3();
-const _twoPI = 2 * Math.PI;
-
-const _STATE = {
-	NONE: - 1,
-	ROTATE: 0,
-	DOLLY: 1,
-	PAN: 2,
-	TOUCH_ROTATE: 3,
-	TOUCH_PAN: 4,
-	TOUCH_DOLLY_PAN: 5,
-	TOUCH_DOLLY_ROTATE: 6
-};
-const _EPS = 0.000001;
-
-
-/**
- * Orbit controls allow the camera to orbit around a target.
- *
- * OrbitControls performs orbiting, dollying (zooming), and panning. Unlike {@link TrackballControls},
- * it maintains the "up" direction `object.up` (+Y by default).
- *
- * - Orbit: Left mouse / touch: one-finger move.
- * - Zoom: Middle mouse, or mousewheel / touch: two-finger spread or squish.
- * - Pan: Right mouse, or left mouse + ctrl/meta/shiftKey, or arrow keys / touch: two-finger move.
- *
- * ```js
- * const controls = new OrbitControls( camera, renderer.domElement );
- *
- * // controls.update() must be called after any manual changes to the camera's transform
- * camera.position.set( 0, 20, 100 );
- * controls.update();
- *
- * function animate() {
- *
- * 	// required if controls.enableDamping or controls.autoRotate are set to true
- * 	controls.update();
- *
- * 	renderer.render( scene, camera );
- *
- * }
- * ```
- *
- * @augments Controls
- * @three_import import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
- */
-class OrbitControls extends Controls {
-
-	/**
-	 * Constructs a new controls instance.
-	 *
-	 * @param {Object3D} object - The object that is managed by the controls.
-	 * @param {?HTMLElement} domElement - The HTML element used for event listeners.
-	 */
-	constructor( object, domElement = null ) {
-
-		super( object, domElement );
-
-		this.state = _STATE.NONE;
-
-		/**
-		 * The focus point of the controls, the `object` orbits around this.
-		 * It can be updated manually at any point to change the focus of the controls.
-		 *
-		 * @type {Vector3}
-		 */
-		this.target = new Vector3();
-
-		/**
-		 * The focus point of the `minTargetRadius` and `maxTargetRadius` limits.
-		 * It can be updated manually at any point to change the center of interest
-		 * for the `target`.
-		 *
-		 * @type {Vector3}
-		 */
-		this.cursor = new Vector3();
-
-		/**
-		 * How far you can dolly in (perspective camera only).
-		 *
-		 * @type {number}
-		 * @default 0
-		 */
-		this.minDistance = 0;
-
-		/**
-		 * How far you can dolly out (perspective camera only).
-		 *
-		 * @type {number}
-		 * @default Infinity
-		 */
-		this.maxDistance = Infinity;
-
-		/**
-		 * How far you can zoom in (orthographic camera only).
-		 *
-		 * @type {number}
-		 * @default 0
-		 */
-		this.minZoom = 0;
-
-		/**
-		 * How far you can zoom out (orthographic camera only).
-		 *
-		 * @type {number}
-		 * @default Infinity
-		 */
-		this.maxZoom = Infinity;
-
-		/**
-		 * How close you can get the target to the 3D `cursor`.
-		 *
-		 * @type {number}
-		 * @default 0
-		 */
-		this.minTargetRadius = 0;
-
-		/**
-		 * How far you can move the target from the 3D `cursor`.
-		 *
-		 * @type {number}
-		 * @default Infinity
-		 */
-		this.maxTargetRadius = Infinity;
-
-		/**
-		 * How far you can orbit vertically, lower limit. Range is `[0, Math.PI]` radians.
-		 *
-		 * @type {number}
-		 * @default 0
-		 */
-		this.minPolarAngle = 0;
-
-		/**
-		 * How far you can orbit vertically, upper limit. Range is `[0, Math.PI]` radians.
-		 *
-		 * @type {number}
-		 * @default Math.PI
-		 */
-		this.maxPolarAngle = Math.PI;
-
-		/**
-		 * How far you can orbit horizontally, lower limit. If set, the interval `[ min, max ]`
-		 * must be a sub-interval of `[ - 2 PI, 2 PI ]`, with `( max - min < 2 PI )`.
-		 *
-		 * @type {number}
-		 * @default -Infinity
-		 */
-		this.minAzimuthAngle = - Infinity;
-
-		/**
-		 * How far you can orbit horizontally, upper limit. If set, the interval `[ min, max ]`
-		 * must be a sub-interval of `[ - 2 PI, 2 PI ]`, with `( max - min < 2 PI )`.
-		 *
-		 * @type {number}
-		 * @default -Infinity
-		 */
-		this.maxAzimuthAngle = Infinity;
-
-		/**
-		 * Set to `true` to enable damping (inertia), which can be used to give a sense of weight
-		 * to the controls. Note that if this is enabled, you must call `update()` in your animation
-		 * loop.
-		 *
-		 * @type {boolean}
-		 * @default false
-		 */
-		this.enableDamping = false;
-
-		/**
-		 * The damping inertia used if `enableDamping` is set to `true`.
-		 *
-		 * Note that for this to work, you must call `update()` in your animation loop.
-		 *
-		 * @type {number}
-		 * @default 0.05
-		 */
-		this.dampingFactor = 0.05;
-
-		/**
-		 * Enable or disable zooming (dollying) of the camera.
-		 *
-		 * @type {boolean}
-		 * @default true
-		 */
-		this.enableZoom = true;
-
-		/**
-		 * Speed of zooming / dollying.
-		 *
-		 * @type {number}
-		 * @default 1
-		 */
-		this.zoomSpeed = 1.0;
-
-		/**
-		 * Enable or disable horizontal and vertical rotation of the camera.
-		 *
-		 * Note that it is possible to disable a single axis by setting the min and max of the
-		 * `minPolarAngle` or `minAzimuthAngle` to the same value, which will cause the vertical
-		 * or horizontal rotation to be fixed at that value.
-		 *
-		 * @type {boolean}
-		 * @default true
-		 */
-		this.enableRotate = true;
-
-		/**
-		 * Speed of rotation.
-		 *
-		 * @type {number}
-		 * @default 1
-		 */
-		this.rotateSpeed = 1.0;
-
-		/**
-		 * How fast to rotate the camera when the keyboard is used.
-		 *
-		 * @type {number}
-		 * @default 1
-		 */
-		this.keyRotateSpeed = 1.0;
-
-		/**
-		 * Enable or disable camera panning.
-		 *
-		 * @type {boolean}
-		 * @default true
-		 */
-		this.enablePan = true;
-
-		/**
-		 * Speed of panning.
-		 *
-		 * @type {number}
-		 * @default 1
-		 */
-		this.panSpeed = 1.0;
-
-		/**
-		 * Defines how the camera's position is translated when panning. If `true`, the camera pans
-		 * in screen space. Otherwise, the camera pans in the plane orthogonal to the camera's up
-		 * direction.
-		 *
-		 * @type {boolean}
-		 * @default true
-		 */
-		this.screenSpacePanning = true;
-
-		/**
-		 * How fast to pan the camera when the keyboard is used in
-		 * pixels per keypress.
-		 *
-		 * @type {number}
-		 * @default 7
-		 */
-		this.keyPanSpeed = 7.0;
-
-		/**
-		 * Setting this property to `true` allows to zoom to the cursor's position.
-		 *
-		 * @type {boolean}
-		 * @default false
-		 */
-		this.zoomToCursor = false;
-
-		/**
-		 * Set to true to automatically rotate around the target
-		 *
-		 * Note that if this is enabled, you must call `update()` in your animation loop.
-		 * If you want the auto-rotate speed to be independent of the frame rate (the refresh
-		 * rate of the display), you must pass the time `deltaTime`, in seconds, to `update()`.
-		 *
-		 * @type {boolean}
-		 * @default false
-		 */
-		this.autoRotate = false;
-
-		/**
-		 * How fast to rotate around the target if `autoRotate` is `true`. The default  equates to 30 seconds
-		 * per orbit at 60fps.
-		 *
-		 * Note that if `autoRotate` is enabled, you must call `update()` in your animation loop.
-		 *
-		 * @type {number}
-		 * @default 2
-		 */
-		this.autoRotateSpeed = 2.0;
-
-		/**
-		 * This object contains references to the keycodes for controlling camera panning.
-		 *
-		 * ```js
-		 * controls.keys = {
-		 * 	LEFT: 'ArrowLeft', //left arrow
-		 * 	UP: 'ArrowUp', // up arrow
-		 * 	RIGHT: 'ArrowRight', // right arrow
-		 * 	BOTTOM: 'ArrowDown' // down arrow
-		 * }
-		 * ```
-		 * @type {Object}
-		 */
-		this.keys = { LEFT: 'ArrowLeft', UP: 'ArrowUp', RIGHT: 'ArrowRight', BOTTOM: 'ArrowDown' };
-
-		/**
-		 * This object contains references to the mouse actions used by the controls.
-		 *
-		 * ```js
-		 * controls.mouseButtons = {
-		 * 	LEFT: THREE.MOUSE.ROTATE,
-		 * 	MIDDLE: THREE.MOUSE.DOLLY,
-		 * 	RIGHT: THREE.MOUSE.PAN
-		 * }
-		 * ```
-		 * @type {Object}
-		 */
-		this.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.PAN };
-
-		/**
-		 * This object contains references to the touch actions used by the controls.
-		 *
-		 * ```js
-		 * controls.mouseButtons = {
-		 * 	ONE: THREE.TOUCH.ROTATE,
-		 * 	TWO: THREE.TOUCH.DOLLY_PAN
-		 * }
-		 * ```
-		 * @type {Object}
-		 */
-		this.touches = { ONE: TOUCH.ROTATE, TWO: TOUCH.DOLLY_PAN };
-
-		/**
-		 * Used internally by `saveState()` and `reset()`.
-		 *
-		 * @type {Vector3}
-		 */
-		this.target0 = this.target.clone();
-
-		/**
-		 * Used internally by `saveState()` and `reset()`.
-		 *
-		 * @type {Vector3}
-		 */
-		this.position0 = this.object.position.clone();
-
-		/**
-		 * Used internally by `saveState()` and `reset()`.
-		 *
-		 * @type {number}
-		 */
-		this.zoom0 = this.object.zoom;
-
-		this._cursorStyle = 'auto';
-
-		// the target DOM element for key events
-		this._domElementKeyEvents = null;
-
-		// internals
-
-		this._lastPosition = new Vector3();
-		this._lastQuaternion = new Quaternion();
-		this._lastTargetPosition = new Vector3();
-
-		// so camera.up is the orbit axis
-		this._quat = new Quaternion().setFromUnitVectors( object.up, new Vector3( 0, 1, 0 ) );
-		this._quatInverse = this._quat.clone().invert();
-
-		// current position in spherical coordinates
-		this._spherical = new Spherical();
-		this._sphericalDelta = new Spherical();
-
-		this._scale = 1;
-		this._panOffset = new Vector3();
-
-		this._rotateStart = new Vector2();
-		this._rotateEnd = new Vector2();
-		this._rotateDelta = new Vector2();
-
-		this._panStart = new Vector2();
-		this._panEnd = new Vector2();
-		this._panDelta = new Vector2();
-
-		this._dollyStart = new Vector2();
-		this._dollyEnd = new Vector2();
-		this._dollyDelta = new Vector2();
-
-		this._dollyDirection = new Vector3();
-		this._mouse = new Vector2();
-		this._performCursorZoom = false;
-
-		this._pointers = [];
-		this._pointerPositions = {};
-
-		this._controlActive = false;
-
-		// event listeners
-
-		this._onPointerMove = onPointerMove.bind( this );
-		this._onPointerDown = onPointerDown.bind( this );
-		this._onPointerUp = onPointerUp.bind( this );
-		this._onContextMenu = onContextMenu.bind( this );
-		this._onMouseWheel = onMouseWheel.bind( this );
-		this._onKeyDown = onKeyDown.bind( this );
-
-		this._onTouchStart = onTouchStart.bind( this );
-		this._onTouchMove = onTouchMove.bind( this );
-
-		this._onMouseDown = onMouseDown.bind( this );
-		this._onMouseMove = onMouseMove.bind( this );
-
-		this._interceptControlDown = interceptControlDown.bind( this );
-		this._interceptControlUp = interceptControlUp.bind( this );
-
-		//
-
-		if ( this.domElement !== null ) {
-
-			this.connect( this.domElement );
-
-		}
-
-		this.update();
-
-	}
-
-	/**
-	 * Defines the visual representation of the cursor.
-	 *
-	 * @type {('auto'|'grab')}
-	 * @default 'auto'
-	 */
-	set cursorStyle( type ) {
-
-		this._cursorStyle = type;
-
-		if ( type === 'grab' ) {
-
-			this.domElement.style.cursor = 'grab';
-
-		} else {
-
-			this.domElement.style.cursor = 'auto';
-
-		}
-
-	}
-
-	get cursorStyle() {
-
-		return this._cursorStyle;
-
-	}
-
-	connect( element ) {
-
-		super.connect( element );
-
-		this.domElement.addEventListener( 'pointerdown', this._onPointerDown );
-		this.domElement.addEventListener( 'pointercancel', this._onPointerUp );
-
-		this.domElement.addEventListener( 'contextmenu', this._onContextMenu );
-		this.domElement.addEventListener( 'wheel', this._onMouseWheel, { passive: false } );
-
-		const document = this.domElement.getRootNode(); // offscreen canvas compatibility
-		document.addEventListener( 'keydown', this._interceptControlDown, { passive: true, capture: true } );
-
-		this.domElement.style.touchAction = 'none'; // Disable touch scroll
-
-	}
-
-	disconnect() {
-
-		this.domElement.removeEventListener( 'pointerdown', this._onPointerDown );
-		this.domElement.ownerDocument.removeEventListener( 'pointermove', this._onPointerMove );
-		this.domElement.ownerDocument.removeEventListener( 'pointerup', this._onPointerUp );
-		this.domElement.removeEventListener( 'pointercancel', this._onPointerUp );
-
-		this.domElement.removeEventListener( 'wheel', this._onMouseWheel );
-		this.domElement.removeEventListener( 'contextmenu', this._onContextMenu );
-
-		this.stopListenToKeyEvents();
-
-		const document = this.domElement.getRootNode(); // offscreen canvas compatibility
-		document.removeEventListener( 'keydown', this._interceptControlDown, { capture: true } );
-
-		this.domElement.style.touchAction = ''; // Restore touch scroll
-
-	}
-
-	dispose() {
-
-		this.disconnect();
-
-	}
-
-	/**
-	 * Get the current vertical rotation, in radians.
-	 *
-	 * @return {number} The current vertical rotation, in radians.
-	 */
-	getPolarAngle() {
-
-		return this._spherical.phi;
-
-	}
-
-	/**
-	 * Get the current horizontal rotation, in radians.
-	 *
-	 * @return {number} The current horizontal rotation, in radians.
-	 */
-	getAzimuthalAngle() {
-
-		return this._spherical.theta;
-
-	}
-
-	/**
-	 * Returns the distance from the camera to the target.
-	 *
-	 * @return {number} The distance from the camera to the target.
-	 */
-	getDistance() {
-
-		return this.object.position.distanceTo( this.target );
-
-	}
-
-	/**
-	 * Adds key event listeners to the given DOM element.
-	 * `window` is a recommended argument for using this method.
-	 *
-	 * @param {HTMLElement} domElement - The DOM element
-	 */
-	listenToKeyEvents( domElement ) {
-
-		domElement.addEventListener( 'keydown', this._onKeyDown );
-		this._domElementKeyEvents = domElement;
-
-	}
-
-	/**
-	 * Removes the key event listener previously defined with `listenToKeyEvents()`.
-	 */
-	stopListenToKeyEvents() {
-
-		if ( this._domElementKeyEvents !== null ) {
-
-			this._domElementKeyEvents.removeEventListener( 'keydown', this._onKeyDown );
-			this._domElementKeyEvents = null;
-
-		}
-
-	}
-
-	/**
-	 * Save the current state of the controls. This can later be recovered with `reset()`.
-	 */
-	saveState() {
-
-		this.target0.copy( this.target );
-		this.position0.copy( this.object.position );
-		this.zoom0 = this.object.zoom;
-
-	}
-
-	/**
-	 * Reset the controls to their state from either the last time the `saveState()`
-	 * was called, or the initial state.
-	 */
-	reset() {
-
-		this.target.copy( this.target0 );
-		this.object.position.copy( this.position0 );
-		this.object.zoom = this.zoom0;
-
-		this.object.updateProjectionMatrix();
-		this.dispatchEvent( _changeEvent );
-
-		this.update();
-
-		this.state = _STATE.NONE;
-
-	}
-
-	/**
-	 * Programmatically pan the camera.
-	 *
-	 * @param {number} deltaX - The horizontal pan amount in pixels.
-	 * @param {number} deltaY - The vertical pan amount in pixels.
-	 */
-	pan( deltaX, deltaY ) {
-
-		this._pan( deltaX, deltaY );
-		this.update();
-
-	}
-
-	/**
-	 * Programmatically dolly in (zoom in for perspective camera).
-	 *
-	 * @param {number} dollyScale - The dolly scale factor.
-	 */
-	dollyIn( dollyScale ) {
-
-		this._dollyIn( dollyScale );
-		this.update();
-
-	}
-
-	/**
-	 * Programmatically dolly out (zoom out for perspective camera).
-	 *
-	 * @param {number} dollyScale - The dolly scale factor.
-	 */
-	dollyOut( dollyScale ) {
-
-		this._dollyOut( dollyScale );
-		this.update();
-
-	}
-
-	/**
-	 * Programmatically rotate the camera left (around the vertical axis).
-	 *
-	 * @param {number} angle - The rotation angle in radians.
-	 */
-	rotateLeft( angle ) {
-
-		this._rotateLeft( angle );
-		this.update();
-
-	}
-
-	/**
-	 * Programmatically rotate the camera up (around the horizontal axis).
-	 *
-	 * @param {number} angle - The rotation angle in radians.
-	 */
-	rotateUp( angle ) {
-
-		this._rotateUp( angle );
-		this.update();
-
-	}
-
-	update( deltaTime = null ) {
-
-		const position = this.object.position;
-
-		_v.copy( position ).sub( this.target );
-
-		// rotate offset to "y-axis-is-up" space
-		_v.applyQuaternion( this._quat );
-
-		// angle from z-axis around y-axis
-		this._spherical.setFromVector3( _v );
-
-		if ( this.autoRotate && this.state === _STATE.NONE ) {
-
-			this._rotateLeft( this._getAutoRotationAngle( deltaTime ) );
-
-		}
-
-		if ( this.enableDamping ) {
-
-			this._spherical.theta += this._sphericalDelta.theta * this.dampingFactor;
-			this._spherical.phi += this._sphericalDelta.phi * this.dampingFactor;
-
-		} else {
-
-			this._spherical.theta += this._sphericalDelta.theta;
-			this._spherical.phi += this._sphericalDelta.phi;
-
-		}
-
-		// restrict theta to be between desired limits
-
-		let min = this.minAzimuthAngle;
-		let max = this.maxAzimuthAngle;
-
-		if ( isFinite( min ) && isFinite( max ) ) {
-
-			if ( min < - Math.PI ) min += _twoPI; else if ( min > Math.PI ) min -= _twoPI;
-
-			if ( max < - Math.PI ) max += _twoPI; else if ( max > Math.PI ) max -= _twoPI;
-
-			if ( min <= max ) {
-
-				this._spherical.theta = Math.max( min, Math.min( max, this._spherical.theta ) );
-
-			} else {
-
-				this._spherical.theta = ( this._spherical.theta > ( min + max ) / 2 ) ?
-					Math.max( min, this._spherical.theta ) :
-					Math.min( max, this._spherical.theta );
-
-			}
-
-		}
-
-		// restrict phi to be between desired limits
-		this._spherical.phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, this._spherical.phi ) );
-
-		this._spherical.makeSafe();
-
-
-		// move target to panned location
-
-		if ( this.enableDamping === true ) {
-
-			this.target.addScaledVector( this._panOffset, this.dampingFactor );
-
-		} else {
-
-			this.target.add( this._panOffset );
-
-		}
-
-		// Limit the target distance from the cursor to create a sphere around the center of interest
-		this.target.sub( this.cursor );
-		this.target.clampLength( this.minTargetRadius, this.maxTargetRadius );
-		this.target.add( this.cursor );
-
-		let zoomChanged = false;
-		// adjust the camera position based on zoom only if we're not zooming to the cursor or if it's an ortho camera
-		// we adjust zoom later in these cases
-		if ( this.zoomToCursor && this._performCursorZoom || this.object.isOrthographicCamera ) {
-
-			this._spherical.radius = this._clampDistance( this._spherical.radius );
-
-		} else {
-
-			const prevRadius = this._spherical.radius;
-			this._spherical.radius = this._clampDistance( this._spherical.radius * this._scale );
-			zoomChanged = prevRadius != this._spherical.radius;
-
-		}
-
-		_v.setFromSpherical( this._spherical );
-
-		// rotate offset back to "camera-up-vector-is-up" space
-		_v.applyQuaternion( this._quatInverse );
-
-		position.copy( this.target ).add( _v );
-
-		this.object.lookAt( this.target );
-
-		if ( this.enableDamping === true ) {
-
-			this._sphericalDelta.theta *= ( 1 - this.dampingFactor );
-			this._sphericalDelta.phi *= ( 1 - this.dampingFactor );
-
-			this._panOffset.multiplyScalar( 1 - this.dampingFactor );
-
-		} else {
-
-			this._sphericalDelta.set( 0, 0, 0 );
-
-			this._panOffset.set( 0, 0, 0 );
-
-		}
-
-		// adjust camera position
-		if ( this.zoomToCursor && this._performCursorZoom ) {
-
-			let newRadius = null;
-			if ( this.object.isPerspectiveCamera ) {
-
-				// move the camera down the pointer ray
-				// this method avoids floating point error
-				const prevRadius = _v.length();
-				newRadius = this._clampDistance( prevRadius * this._scale );
-
-				const radiusDelta = prevRadius - newRadius;
-				this.object.position.addScaledVector( this._dollyDirection, radiusDelta );
-				this.object.updateMatrixWorld();
-
-				zoomChanged = !! radiusDelta;
-
-			} else if ( this.object.isOrthographicCamera ) {
-
-				// adjust the ortho camera position based on zoom changes
-				const mouseBefore = new Vector3( this._mouse.x, this._mouse.y, 0 );
-				mouseBefore.unproject( this.object );
-
-				const prevZoom = this.object.zoom;
-				this.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom / this._scale ) );
-				this.object.updateProjectionMatrix();
-
-				zoomChanged = prevZoom !== this.object.zoom;
-
-				const mouseAfter = new Vector3( this._mouse.x, this._mouse.y, 0 );
-				mouseAfter.unproject( this.object );
-
-				this.object.position.sub( mouseAfter ).add( mouseBefore );
-				this.object.updateMatrixWorld();
-
-				newRadius = _v.length();
-
-			} else {
-
-				console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled.' );
-				this.zoomToCursor = false;
-
-			}
-
-			// handle the placement of the target
-			if ( newRadius !== null ) {
-
-				if ( this.screenSpacePanning ) {
-
-					// position the orbit target in front of the new camera position
-					this.target.set( 0, 0, - 1 )
-						.transformDirection( this.object.matrix )
-						.multiplyScalar( newRadius )
-						.add( this.object.position );
-
-				} else {
-
-					// get the ray and translation plane to compute target
-					_ray.origin.copy( this.object.position );
-					_ray.direction.set( 0, 0, - 1 ).transformDirection( this.object.matrix );
-
-					// if the camera is 20 degrees above the horizon then don't adjust the focus target to avoid
-					// extremely large values
-					if ( Math.abs( this.object.up.dot( _ray.direction ) ) < _TILT_LIMIT ) {
-
-						this.object.lookAt( this.target );
-
-					} else {
-
-						_plane.setFromNormalAndCoplanarPoint( this.object.up, this.target );
-						_ray.intersectPlane( _plane, this.target );
-
-					}
-
-				}
-
-			}
-
-		} else if ( this.object.isOrthographicCamera ) {
-
-			const prevZoom = this.object.zoom;
-			this.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom / this._scale ) );
-
-			if ( prevZoom !== this.object.zoom ) {
-
-				this.object.updateProjectionMatrix();
-				zoomChanged = true;
-
-			}
-
-		}
-
-		this._scale = 1;
-		this._performCursorZoom = false;
-
-		// update condition is:
-		// min(camera displacement, camera rotation in radians)^2 > EPS
-		// using small-angle approximation cos(x/2) = 1 - x^2 / 8
-
-		if ( zoomChanged ||
-			this._lastPosition.distanceToSquared( this.object.position ) > _EPS ||
-			8 * ( 1 - this._lastQuaternion.dot( this.object.quaternion ) ) > _EPS ||
-			this._lastTargetPosition.distanceToSquared( this.target ) > _EPS ) {
-
-			this.dispatchEvent( _changeEvent );
-
-			this._lastPosition.copy( this.object.position );
-			this._lastQuaternion.copy( this.object.quaternion );
-			this._lastTargetPosition.copy( this.target );
-
-			return true;
-
-		}
-
-		return false;
-
-	}
-
-	_getAutoRotationAngle( deltaTime ) {
-
-		if ( deltaTime !== null ) {
-
-			return ( _twoPI / 60 * this.autoRotateSpeed ) * deltaTime;
-
-		} else {
-
-			return _twoPI / 60 / 60 * this.autoRotateSpeed;
-
-		}
-
-	}
-
-	_getZoomScale( delta ) {
-
-		const normalizedDelta = Math.abs( delta * 0.01 );
-		return Math.pow( 0.95, this.zoomSpeed * normalizedDelta );
-
-	}
-
-	_rotateLeft( angle ) {
-
-		this._sphericalDelta.theta -= angle;
-
-	}
-
-	_rotateUp( angle ) {
-
-		this._sphericalDelta.phi -= angle;
-
-	}
-
-	_panLeft( distance, objectMatrix ) {
-
-		_v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix
-		_v.multiplyScalar( - distance );
-
-		this._panOffset.add( _v );
-
-	}
-
-	_panUp( distance, objectMatrix ) {
-
-		if ( this.screenSpacePanning === true ) {
-
-			_v.setFromMatrixColumn( objectMatrix, 1 );
-
-		} else {
-
-			_v.setFromMatrixColumn( objectMatrix, 0 );
-			_v.crossVectors( this.object.up, _v );
-
-		}
-
-		_v.multiplyScalar( distance );
-
-		this._panOffset.add( _v );
-
-	}
-
-	// deltaX and deltaY are in pixels; right and down are positive
-	_pan( deltaX, deltaY ) {
-
-		const element = this.domElement;
-
-		if ( this.object.isPerspectiveCamera ) {
-
-			// perspective
-			const position = this.object.position;
-			_v.copy( position ).sub( this.target );
-			let targetDistance = _v.length();
-
-			// half of the fov is center to top of screen
-			targetDistance *= Math.tan( ( this.object.fov / 2 ) * Math.PI / 180.0 );
-
-			// we use only clientHeight here so aspect ratio does not distort speed
-			this._panLeft( 2 * deltaX * targetDistance / element.clientHeight, this.object.matrix );
-			this._panUp( 2 * deltaY * targetDistance / element.clientHeight, this.object.matrix );
-
-		} else if ( this.object.isOrthographicCamera ) {
-
-			// orthographic
-			this._panLeft( deltaX * ( this.object.right - this.object.left ) / this.object.zoom / element.clientWidth, this.object.matrix );
-			this._panUp( deltaY * ( this.object.top - this.object.bottom ) / this.object.zoom / element.clientHeight, this.object.matrix );
-
-		} else {
-
-			// camera neither orthographic nor perspective
-			console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );
-			this.enablePan = false;
-
-		}
-
-	}
-
-	_dollyOut( dollyScale ) {
-
-		if ( this.object.isPerspectiveCamera || this.object.isOrthographicCamera ) {
-
-			this._scale /= dollyScale;
-
-		} else {
-
-			console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
-			this.enableZoom = false;
-
-		}
-
-	}
-
-	_dollyIn( dollyScale ) {
-
-		if ( this.object.isPerspectiveCamera || this.object.isOrthographicCamera ) {
-
-			this._scale *= dollyScale;
-
-		} else {
-
-			console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
-			this.enableZoom = false;
-
-		}
-
-	}
-
-	_updateZoomParameters( x, y ) {
-
-		if ( ! this.zoomToCursor ) {
-
-			return;
-
-		}
-
-		this._performCursorZoom = true;
-
-		const rect = this.domElement.getBoundingClientRect();
-		const dx = x - rect.left;
-		const dy = y - rect.top;
-		const w = rect.width;
-		const h = rect.height;
-
-		this._mouse.x = ( dx / w ) * 2 - 1;
-		this._mouse.y = - ( dy / h ) * 2 + 1;
-
-		this._dollyDirection.set( this._mouse.x, this._mouse.y, 1 ).unproject( this.object ).sub( this.object.position ).normalize();
-
-	}
-
-	_clampDistance( dist ) {
-
-		return Math.max( this.minDistance, Math.min( this.maxDistance, dist ) );
-
-	}
-
-	//
-	// event callbacks - update the object state
-	//
-
-	_handleMouseDownRotate( event ) {
-
-		this._rotateStart.set( event.clientX, event.clientY );
-
-	}
-
-	_handleMouseDownDolly( event ) {
-
-		this._updateZoomParameters( event.clientX, event.clientX );
-		this._dollyStart.set( event.clientX, event.clientY );
-
-	}
-
-	_handleMouseDownPan( event ) {
-
-		this._panStart.set( event.clientX, event.clientY );
-
-	}
-
-	_handleMouseMoveRotate( event ) {
-
-		this._rotateEnd.set( event.clientX, event.clientY );
-
-		this._rotateDelta.subVectors( this._rotateEnd, this._rotateStart ).multiplyScalar( this.rotateSpeed );
-
-		const element = this.domElement;
-
-		this._rotateLeft( _twoPI * this._rotateDelta.x / element.clientHeight ); // yes, height
-
-		this._rotateUp( _twoPI * this._rotateDelta.y / element.clientHeight );
-
-		this._rotateStart.copy( this._rotateEnd );
-
-		this.update();
-
-	}
-
-	_handleMouseMoveDolly( event ) {
-
-		this._dollyEnd.set( event.clientX, event.clientY );
-
-		this._dollyDelta.subVectors( this._dollyEnd, this._dollyStart );
-
-		if ( this._dollyDelta.y > 0 ) {
-
-			this._dollyOut( this._getZoomScale( this._dollyDelta.y ) );
-
-		} else if ( this._dollyDelta.y < 0 ) {
-
-			this._dollyIn( this._getZoomScale( this._dollyDelta.y ) );
-
-		}
-
-		this._dollyStart.copy( this._dollyEnd );
-
-		this.update();
-
-	}
-
-	_handleMouseMovePan( event ) {
-
-		this._panEnd.set( event.clientX, event.clientY );
-
-		this._panDelta.subVectors( this._panEnd, this._panStart ).multiplyScalar( this.panSpeed );
-
-		this._pan( this._panDelta.x, this._panDelta.y );
-
-		this._panStart.copy( this._panEnd );
-
-		this.update();
-
-	}
-
-	_handleMouseWheel( event ) {
-
-		this._updateZoomParameters( event.clientX, event.clientY );
-
-		if ( event.deltaY < 0 ) {
-
-			this._dollyIn( this._getZoomScale( event.deltaY ) );
-
-		} else if ( event.deltaY > 0 ) {
-
-			this._dollyOut( this._getZoomScale( event.deltaY ) );
-
-		}
-
-		this.update();
-
-	}
-
-	_handleKeyDown( event ) {
-
-		let needsUpdate = false;
-
-		switch ( event.code ) {
-
-			case this.keys.UP:
-
-				if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
-
-					if ( this.enableRotate ) {
-
-						this._rotateUp( _twoPI * this.keyRotateSpeed / this.domElement.clientHeight );
-
-					}
-
-				} else {
-
-					if ( this.enablePan ) {
-
-						this._pan( 0, this.keyPanSpeed );
-
-					}
-
-				}
-
-				needsUpdate = true;
-				break;
-
-			case this.keys.BOTTOM:
-
-				if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
-
-					if ( this.enableRotate ) {
-
-						this._rotateUp( - _twoPI * this.keyRotateSpeed / this.domElement.clientHeight );
-
-					}
-
-				} else {
-
-					if ( this.enablePan ) {
-
-						this._pan( 0, - this.keyPanSpeed );
-
-					}
-
-				}
-
-				needsUpdate = true;
-				break;
-
-			case this.keys.LEFT:
-
-				if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
-
-					if ( this.enableRotate ) {
-
-						this._rotateLeft( _twoPI * this.keyRotateSpeed / this.domElement.clientHeight );
-
-					}
-
-				} else {
-
-					if ( this.enablePan ) {
-
-						this._pan( this.keyPanSpeed, 0 );
-
-					}
-
-				}
-
-				needsUpdate = true;
-				break;
-
-			case this.keys.RIGHT:
-
-				if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
-
-					if ( this.enableRotate ) {
-
-						this._rotateLeft( - _twoPI * this.keyRotateSpeed / this.domElement.clientHeight );
-
-					}
-
-				} else {
-
-					if ( this.enablePan ) {
-
-						this._pan( - this.keyPanSpeed, 0 );
-
-					}
-
-				}
-
-				needsUpdate = true;
-				break;
-
-		}
-
-		if ( needsUpdate ) {
-
-			// prevent the browser from scrolling on cursor keys
-			event.preventDefault();
-
-			this.update();
-
-		}
-
-
-	}
-
-	_handleTouchStartRotate( event ) {
-
-		if ( this._pointers.length === 1 ) {
-
-			this._rotateStart.set( event.pageX, event.pageY );
-
-		} else {
-
-			const position = this._getSecondPointerPosition( event );
-
-			const x = 0.5 * ( event.pageX + position.x );
-			const y = 0.5 * ( event.pageY + position.y );
-
-			this._rotateStart.set( x, y );
-
-		}
-
-	}
-
-	_handleTouchStartPan( event ) {
-
-		if ( this._pointers.length === 1 ) {
-
-			this._panStart.set( event.pageX, event.pageY );
-
-		} else {
-
-			const position = this._getSecondPointerPosition( event );
-
-			const x = 0.5 * ( event.pageX + position.x );
-			const y = 0.5 * ( event.pageY + position.y );
-
-			this._panStart.set( x, y );
-
-		}
-
-	}
-
-	_handleTouchStartDolly( event ) {
-
-		const position = this._getSecondPointerPosition( event );
-
-		const dx = event.pageX - position.x;
-		const dy = event.pageY - position.y;
-
-		const distance = Math.sqrt( dx * dx + dy * dy );
-
-		this._dollyStart.set( 0, distance );
-
-	}
-
-	_handleTouchStartDollyPan( event ) {
-
-		if ( this.enableZoom ) this._handleTouchStartDolly( event );
-
-		if ( this.enablePan ) this._handleTouchStartPan( event );
-
-	}
-
-	_handleTouchStartDollyRotate( event ) {
-
-		if ( this.enableZoom ) this._handleTouchStartDolly( event );
-
-		if ( this.enableRotate ) this._handleTouchStartRotate( event );
-
-	}
-
-	_handleTouchMoveRotate( event ) {
-
-		if ( this._pointers.length == 1 ) {
-
-			this._rotateEnd.set( event.pageX, event.pageY );
-
-		} else {
-
-			const position = this._getSecondPointerPosition( event );
-
-			const x = 0.5 * ( event.pageX + position.x );
-			const y = 0.5 * ( event.pageY + position.y );
-
-			this._rotateEnd.set( x, y );
-
-		}
-
-		this._rotateDelta.subVectors( this._rotateEnd, this._rotateStart ).multiplyScalar( this.rotateSpeed );
-
-		const element = this.domElement;
-
-		this._rotateLeft( _twoPI * this._rotateDelta.x / element.clientHeight ); // yes, height
-
-		this._rotateUp( _twoPI * this._rotateDelta.y / element.clientHeight );
-
-		this._rotateStart.copy( this._rotateEnd );
-
-	}
-
-	_handleTouchMovePan( event ) {
-
-		if ( this._pointers.length === 1 ) {
-
-			this._panEnd.set( event.pageX, event.pageY );
-
-		} else {
-
-			const position = this._getSecondPointerPosition( event );
-
-			const x = 0.5 * ( event.pageX + position.x );
-			const y = 0.5 * ( event.pageY + position.y );
-
-			this._panEnd.set( x, y );
-
-		}
-
-		this._panDelta.subVectors( this._panEnd, this._panStart ).multiplyScalar( this.panSpeed );
-
-		this._pan( this._panDelta.x, this._panDelta.y );
-
-		this._panStart.copy( this._panEnd );
-
-	}
-
-	_handleTouchMoveDolly( event ) {
-
-		const position = this._getSecondPointerPosition( event );
-
-		const dx = event.pageX - position.x;
-		const dy = event.pageY - position.y;
-
-		const distance = Math.sqrt( dx * dx + dy * dy );
-
-		this._dollyEnd.set( 0, distance );
-
-		this._dollyDelta.set( 0, Math.pow( this._dollyEnd.y / this._dollyStart.y, this.zoomSpeed ) );
-
-		this._dollyOut( this._dollyDelta.y );
-
-		this._dollyStart.copy( this._dollyEnd );
-
-		const centerX = ( event.pageX + position.x ) * 0.5;
-		const centerY = ( event.pageY + position.y ) * 0.5;
-
-		this._updateZoomParameters( centerX, centerY );
-
-	}
-
-	_handleTouchMoveDollyPan( event ) {
-
-		if ( this.enableZoom ) this._handleTouchMoveDolly( event );
-
-		if ( this.enablePan ) this._handleTouchMovePan( event );
-
-	}
-
-	_handleTouchMoveDollyRotate( event ) {
-
-		if ( this.enableZoom ) this._handleTouchMoveDolly( event );
-
-		if ( this.enableRotate ) this._handleTouchMoveRotate( event );
-
-	}
-
-	// pointers
-
-	_addPointer( event ) {
-
-		this._pointers.push( event.pointerId );
-
-	}
-
-	_removePointer( event ) {
-
-		delete this._pointerPositions[ event.pointerId ];
-
-		for ( let i = 0; i < this._pointers.length; i ++ ) {
-
-			if ( this._pointers[ i ] == event.pointerId ) {
-
-				this._pointers.splice( i, 1 );
-				return;
-
-			}
-
-		}
-
-	}
-
-	_isTrackingPointer( event ) {
-
-		for ( let i = 0; i < this._pointers.length; i ++ ) {
-
-			if ( this._pointers[ i ] == event.pointerId ) return true;
-
-		}
-
-		return false;
-
-	}
-
-	_trackPointer( event ) {
-
-		let position = this._pointerPositions[ event.pointerId ];
-
-		if ( position === undefined ) {
-
-			position = new Vector2();
-			this._pointerPositions[ event.pointerId ] = position;
-
-		}
-
-		position.set( event.pageX, event.pageY );
-
-	}
-
-	_getSecondPointerPosition( event ) {
-
-		const pointerId = ( event.pointerId === this._pointers[ 0 ] ) ? this._pointers[ 1 ] : this._pointers[ 0 ];
-
-		return this._pointerPositions[ pointerId ];
-
-	}
-
-	//
-
-	_customWheelEvent( event ) {
-
-		const mode = event.deltaMode;
-
-		// minimal wheel event altered to meet delta-zoom demand
-		const newEvent = {
-			clientX: event.clientX,
-			clientY: event.clientY,
-			deltaY: event.deltaY,
-		};
-
-		switch ( mode ) {
-
-			case 1: // LINE_MODE
-				newEvent.deltaY *= 16;
-				break;
-
-			case 2: // PAGE_MODE
-				newEvent.deltaY *= 100;
-				break;
-
-		}
-
-		// detect if event was triggered by pinching
-		if ( event.ctrlKey && ! this._controlActive ) {
-
-			newEvent.deltaY *= 10;
-
-		}
-
-		return newEvent;
-
-	}
-
-}
-
-function onPointerDown( event ) {
-
-	if ( this.enabled === false ) return;
-
-	if ( this._pointers.length === 0 ) {
-
-		this.domElement.setPointerCapture( event.pointerId );
-
-		this.domElement.ownerDocument.addEventListener( 'pointermove', this._onPointerMove );
-		this.domElement.ownerDocument.addEventListener( 'pointerup', this._onPointerUp );
-
-	}
-
-	//
-
-	if ( this._isTrackingPointer( event ) ) return;
-
-	//
-
-	this._addPointer( event );
-
-	if ( event.pointerType === 'touch' ) {
-
-		this._onTouchStart( event );
-
-	} else {
-
-		this._onMouseDown( event );
-
-	}
-
-	if ( this._cursorStyle === 'grab' ) {
-
-		this.domElement.style.cursor = 'grabbing';
-
-	}
-
-}
-
-function onPointerMove( event ) {
-
-	if ( this.enabled === false ) return;
-
-	if ( event.pointerType === 'touch' ) {
-
-		this._onTouchMove( event );
-
-	} else {
-
-		this._onMouseMove( event );
-
-	}
-
-}
-
-function onPointerUp( event ) {
-
-	this._removePointer( event );
-
-	switch ( this._pointers.length ) {
-
-		case 0:
-
-			this.domElement.releasePointerCapture( event.pointerId );
-
-			this.domElement.ownerDocument.removeEventListener( 'pointermove', this._onPointerMove );
-			this.domElement.ownerDocument.removeEventListener( 'pointerup', this._onPointerUp );
-
-			this.dispatchEvent( _endEvent );
-
-			this.state = _STATE.NONE;
-
-			if ( this._cursorStyle === 'grab' ) {
-
-				this.domElement.style.cursor = 'grab';
-
-			}
-
-			break;
-
-		case 1:
-
-			const pointerId = this._pointers[ 0 ];
-			const position = this._pointerPositions[ pointerId ];
-
-			// minimal placeholder event - allows state correction on pointer-up
-			this._onTouchStart( { pointerId: pointerId, pageX: position.x, pageY: position.y } );
-
-			break;
-
-	}
-
-}
-
-function onMouseDown( event ) {
-
-	let mouseAction;
-
-	switch ( event.button ) {
-
-		case 0:
-
-			mouseAction = this.mouseButtons.LEFT;
-			break;
-
-		case 1:
-
-			mouseAction = this.mouseButtons.MIDDLE;
-			break;
-
-		case 2:
-
-			mouseAction = this.mouseButtons.RIGHT;
-			break;
-
-		default:
-
-			mouseAction = - 1;
-
-	}
-
-	switch ( mouseAction ) {
-
-		case MOUSE.DOLLY:
-
-			if ( this.enableZoom === false ) return;
-
-			this._handleMouseDownDolly( event );
-
-			this.state = _STATE.DOLLY;
-
-			break;
-
-		case MOUSE.ROTATE:
-
-			if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
-
-				if ( this.enablePan === false ) return;
-
-				this._handleMouseDownPan( event );
-
-				this.state = _STATE.PAN;
-
-			} else {
-
-				if ( this.enableRotate === false ) return;
-
-				this._handleMouseDownRotate( event );
-
-				this.state = _STATE.ROTATE;
-
-			}
-
-			break;
-
-		case MOUSE.PAN:
-
-			if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
-
-				if ( this.enableRotate === false ) return;
-
-				this._handleMouseDownRotate( event );
-
-				this.state = _STATE.ROTATE;
-
-			} else {
-
-				if ( this.enablePan === false ) return;
-
-				this._handleMouseDownPan( event );
-
-				this.state = _STATE.PAN;
-
-			}
-
-			break;
-
-		default:
-
-			this.state = _STATE.NONE;
-
-	}
-
-	if ( this.state !== _STATE.NONE ) {
-
-		this.dispatchEvent( _startEvent );
-
-	}
-
-}
-
-function onMouseMove( event ) {
-
-	switch ( this.state ) {
-
-		case _STATE.ROTATE:
-
-			if ( this.enableRotate === false ) return;
-
-			this._handleMouseMoveRotate( event );
-
-			break;
-
-		case _STATE.DOLLY:
-
-			if ( this.enableZoom === false ) return;
-
-			this._handleMouseMoveDolly( event );
-
-			break;
-
-		case _STATE.PAN:
-
-			if ( this.enablePan === false ) return;
-
-			this._handleMouseMovePan( event );
-
-			break;
-
-	}
-
-}
-
-function onMouseWheel( event ) {
-
-	if ( this.enabled === false || this.enableZoom === false || this.state !== _STATE.NONE ) return;
-
-	event.preventDefault();
-
-	this.dispatchEvent( _startEvent );
-
-	this._handleMouseWheel( this._customWheelEvent( event ) );
-
-	this.dispatchEvent( _endEvent );
-
-}
-
-function onKeyDown( event ) {
-
-	if ( this.enabled === false ) return;
-
-	this._handleKeyDown( event );
-
-}
-
-function onTouchStart( event ) {
-
-	this._trackPointer( event );
-
-	switch ( this._pointers.length ) {
-
-		case 1:
-
-			switch ( this.touches.ONE ) {
-
-				case TOUCH.ROTATE:
-
-					if ( this.enableRotate === false ) return;
-
-					this._handleTouchStartRotate( event );
-
-					this.state = _STATE.TOUCH_ROTATE;
-
-					break;
-
-				case TOUCH.PAN:
-
-					if ( this.enablePan === false ) return;
-
-					this._handleTouchStartPan( event );
-
-					this.state = _STATE.TOUCH_PAN;
-
-					break;
-
-				default:
-
-					this.state = _STATE.NONE;
-
-			}
-
-			break;
-
-		case 2:
-
-			switch ( this.touches.TWO ) {
-
-				case TOUCH.DOLLY_PAN:
-
-					if ( this.enableZoom === false && this.enablePan === false ) return;
-
-					this._handleTouchStartDollyPan( event );
-
-					this.state = _STATE.TOUCH_DOLLY_PAN;
-
-					break;
-
-				case TOUCH.DOLLY_ROTATE:
-
-					if ( this.enableZoom === false && this.enableRotate === false ) return;
-
-					this._handleTouchStartDollyRotate( event );
-
-					this.state = _STATE.TOUCH_DOLLY_ROTATE;
-
-					break;
-
-				default:
-
-					this.state = _STATE.NONE;
-
-			}
-
-			break;
-
-		default:
-
-			this.state = _STATE.NONE;
-
-	}
-
-	if ( this.state !== _STATE.NONE ) {
-
-		this.dispatchEvent( _startEvent );
-
-	}
-
-}
-
-function onTouchMove( event ) {
-
-	this._trackPointer( event );
-
-	switch ( this.state ) {
-
-		case _STATE.TOUCH_ROTATE:
-
-			if ( this.enableRotate === false ) return;
-
-			this._handleTouchMoveRotate( event );
-
-			this.update();
-
-			break;
-
-		case _STATE.TOUCH_PAN:
-
-			if ( this.enablePan === false ) return;
-
-			this._handleTouchMovePan( event );
-
-			this.update();
-
-			break;
-
-		case _STATE.TOUCH_DOLLY_PAN:
-
-			if ( this.enableZoom === false && this.enablePan === false ) return;
-
-			this._handleTouchMoveDollyPan( event );
-
-			this.update();
-
-			break;
-
-		case _STATE.TOUCH_DOLLY_ROTATE:
-
-			if ( this.enableZoom === false && this.enableRotate === false ) return;
-
-			this._handleTouchMoveDollyRotate( event );
-
-			this.update();
-
-			break;
-
-		default:
-
-			this.state = _STATE.NONE;
-
-	}
-
-}
-
-function onContextMenu( event ) {
-
-	if ( this.enabled === false ) return;
-
-	event.preventDefault();
-
-}
-
-function interceptControlDown( event ) {
-
-	if ( event.key === 'Control' ) {
-
-		this._controlActive = true;
-
-		const document = this.domElement.getRootNode(); // offscreen canvas compatibility
-
-		document.addEventListener( 'keyup', this._interceptControlUp, { passive: true, capture: true } );
-
-	}
-
-}
-
-function interceptControlUp( event ) {
-
-	if ( event.key === 'Control' ) {
-
-		this._controlActive = false;
-
-		const document = this.domElement.getRootNode(); // offscreen canvas compatibility
-
-		document.removeEventListener( 'keyup', this._interceptControlUp, { passive: true, capture: true } );
-
-	}
-
-}
-
-export { OrbitControls };

+ 0 - 264
node_modules/three/examples/jsm/controls/PointerLockControls.js

@@ -1,264 +0,0 @@
-import {
-	Controls,
-	Euler,
-	Vector3
-} from 'three';
-
-const _euler = new Euler( 0, 0, 0, 'YXZ' );
-const _vector = new Vector3();
-
-/**
- * Fires when the user moves the mouse.
- *
- * @event PointerLockControls#change
- * @type {Object}
- */
-const _changeEvent = { type: 'change' };
-
-/**
- * Fires when the pointer lock status is "locked" (in other words: the mouse is captured).
- *
- * @event PointerLockControls#lock
- * @type {Object}
- */
-const _lockEvent = { type: 'lock' };
-
-/**
- * Fires when the pointer lock status is "unlocked" (in other words: the mouse is not captured anymore).
- *
- * @event PointerLockControls#unlock
- * @type {Object}
- */
-const _unlockEvent = { type: 'unlock' };
-
-const _MOUSE_SENSITIVITY = 0.002;
-const _PI_2 = Math.PI / 2;
-
-/**
- * The implementation of this class is based on the [Pointer Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API).
- * `PointerLockControls` is a perfect choice for first person 3D games.
- *
- * ```js
- * const controls = new PointerLockControls( camera, document.body );
- *
- * // add event listener to show/hide a UI (e.g. the game's menu)
- * controls.addEventListener( 'lock', function () {
- *
- * 	menu.style.display = 'none';
- *
- * } );
- *
- * controls.addEventListener( 'unlock', function () {
- *
- * 	menu.style.display = 'block';
- *
- * } );
- * ```
- *
- * @augments Controls
- * @three_import import { PointerLockControls } from 'three/addons/controls/PointerLockControls.js';
- */
-class PointerLockControls extends Controls {
-
-	/**
-	 * Constructs a new controls instance.
-	 *
-	 * @param {Camera} camera - The camera that is managed by the controls.
-	 * @param {?HTMLElement} domElement - The HTML element used for event listeners.
-	 */
-	constructor( camera, domElement = null ) {
-
-		super( camera, domElement );
-
-		/**
-		 * Whether the controls are locked or not.
-		 *
-		 * @type {boolean}
-		 * @readonly
-		 * @default false
-		 */
-		this.isLocked = false;
-
-		/**
-		 * Camera pitch, lower limit. Range is '[0, Math.PI]' in radians.
-		 *
-		 * @type {number}
-		 * @default 0
-		 */
-		this.minPolarAngle = 0;
-
-		/**
-		 * Camera pitch, upper limit. Range is '[0, Math.PI]' in radians.
-		 *
-		 * @type {number}
-		 * @default Math.PI
-		 */
-		this.maxPolarAngle = Math.PI;
-
-		/**
-		 * Multiplier for how much the pointer movement influences the camera rotation.
-		 *
-		 * @type {number}
-		 * @default 1
-		 */
-		this.pointerSpeed = 1.0;
-
-		// event listeners
-
-		this._onMouseMove = onMouseMove.bind( this );
-		this._onPointerlockChange = onPointerlockChange.bind( this );
-		this._onPointerlockError = onPointerlockError.bind( this );
-
-		if ( this.domElement !== null ) {
-
-			this.connect( this.domElement );
-
-		}
-
-	}
-
-	connect( element ) {
-
-		super.connect( element );
-
-		this.domElement.ownerDocument.addEventListener( 'mousemove', this._onMouseMove );
-		this.domElement.ownerDocument.addEventListener( 'pointerlockchange', this._onPointerlockChange );
-		this.domElement.ownerDocument.addEventListener( 'pointerlockerror', this._onPointerlockError );
-
-	}
-
-	disconnect() {
-
-		this.domElement.ownerDocument.removeEventListener( 'mousemove', this._onMouseMove );
-		this.domElement.ownerDocument.removeEventListener( 'pointerlockchange', this._onPointerlockChange );
-		this.domElement.ownerDocument.removeEventListener( 'pointerlockerror', this._onPointerlockError );
-
-	}
-
-	dispose() {
-
-		this.disconnect();
-
-	}
-
-	/**
-	 * Returns the look direction of the camera.
-	 *
-	 * @param {Vector3} v - The target vector that is used to store the method's result.
-	 * @return {Vector3} The normalized direction vector.
-	 */
-	getDirection( v ) {
-
-		return v.set( 0, 0, - 1 ).applyQuaternion( this.object.quaternion );
-
-	}
-
-	/**
-	 * Moves the camera forward parallel to the xz-plane. Assumes camera.up is y-up.
-	 *
-	 * @param {number} distance - The signed distance.
-	 */
-	moveForward( distance ) {
-
-		if ( this.enabled === false ) return;
-
-		// move forward parallel to the xz-plane
-		// assumes camera.up is y-up
-
-		const camera = this.object;
-
-		_vector.setFromMatrixColumn( camera.matrix, 0 );
-
-		_vector.crossVectors( camera.up, _vector );
-
-		camera.position.addScaledVector( _vector, distance );
-
-	}
-
-	/**
-	 * Moves the camera sidewards parallel to the xz-plane.
-	 *
-	 * @param {number} distance - The signed distance.
-	 */
-	moveRight( distance ) {
-
-		if ( this.enabled === false ) return;
-
-		const camera = this.object;
-
-		_vector.setFromMatrixColumn( camera.matrix, 0 );
-
-		camera.position.addScaledVector( _vector, distance );
-
-	}
-
-	/**
-	 * Activates the pointer lock.
-	 *
-	 * @param {boolean} [unadjustedMovement=false] - Disables OS-level adjustment for mouse acceleration, and accesses raw mouse input instead.
-	 * Setting it to true will disable mouse acceleration.
-	 */
-	lock( unadjustedMovement = false ) {
-
-		this.domElement.requestPointerLock( {
-			unadjustedMovement
-		} );
-
-	}
-
-	/**
-	 * Exits the pointer lock.
-	 */
-	unlock() {
-
-		this.domElement.ownerDocument.exitPointerLock();
-
-	}
-
-}
-
-// event listeners
-
-function onMouseMove( event ) {
-
-	if ( this.enabled === false || this.isLocked === false ) return;
-
-	const camera = this.object;
-	_euler.setFromQuaternion( camera.quaternion );
-
-	_euler.y -= event.movementX * _MOUSE_SENSITIVITY * this.pointerSpeed;
-	_euler.x -= event.movementY * _MOUSE_SENSITIVITY * this.pointerSpeed;
-
-	_euler.x = Math.max( _PI_2 - this.maxPolarAngle, Math.min( _PI_2 - this.minPolarAngle, _euler.x ) );
-
-	camera.quaternion.setFromEuler( _euler );
-
-	this.dispatchEvent( _changeEvent );
-
-}
-
-function onPointerlockChange() {
-
-	if ( this.domElement.ownerDocument.pointerLockElement === this.domElement ) {
-
-		this.dispatchEvent( _lockEvent );
-
-		this.isLocked = true;
-
-	} else {
-
-		this.dispatchEvent( _unlockEvent );
-
-		this.isLocked = false;
-
-	}
-
-}
-
-function onPointerlockError() {
-
-	console.error( 'THREE.PointerLockControls: Unable to use Pointer Lock API' );
-
-}
-
-export { PointerLockControls };

+ 0 - 1001
node_modules/three/examples/jsm/controls/TrackballControls.js

@@ -1,1001 +0,0 @@
-import {
-	Controls,
-	MathUtils,
-	MOUSE,
-	Quaternion,
-	Vector2,
-	Vector3
-} from 'three';
-
-/**
- * Fires when the camera has been transformed by the controls.
- *
- * @event TrackballControls#change
- * @type {Object}
- */
-const _changeEvent = { type: 'change' };
-
-/**
- * Fires when an interaction was initiated.
- *
- * @event TrackballControls#start
- * @type {Object}
- */
-const _startEvent = { type: 'start' };
-
-/**
- * Fires when an interaction has finished.
- *
- * @event TrackballControls#end
- * @type {Object}
- */
-const _endEvent = { type: 'end' };
-
-const _EPS = 0.000001;
-const _STATE = { NONE: - 1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 };
-
-const _v2 = new Vector2();
-const _mouseChange = new Vector2();
-const _objectUp = new Vector3();
-const _pan = new Vector3();
-const _axis = new Vector3();
-const _quaternion = new Quaternion();
-const _eyeDirection = new Vector3();
-const _objectUpDirection = new Vector3();
-const _objectSidewaysDirection = new Vector3();
-const _moveDirection = new Vector3();
-
-/**
- * This class is similar to {@link OrbitControls}. However, it does not maintain a constant camera
- * `up` vector. That means if the camera orbits over the “north” and “south” poles, it does not flip
- * to stay "right side up".
- *
- * @augments Controls
- * @three_import import { TrackballControls } from 'three/addons/controls/TrackballControls.js';
- */
-class TrackballControls extends Controls {
-
-	/**
-	 * Constructs a new controls instance.
-	 *
-	 * @param {Object3D} object - The object that is managed by the controls.
-	 * @param {?HTMLElement} domElement - The HTML element used for event listeners.
-	 */
-	constructor( object, domElement = null ) {
-
-		super( object, domElement );
-
-		/**
-		 * Represents the properties of the screen. Automatically set when `handleResize()` is called.
-		 *
-		 * @type {Object}
-		 * @readonly
-		 */
-		this.screen = { left: 0, top: 0, width: 0, height: 0 };
-
-		/**
-		 * The rotation speed.
-		 *
-		 * @type {number}
-		 * @default 1
-		 */
-		this.rotateSpeed = 1.0;
-
-		/**
-		 * The zoom speed.
-		 *
-		 * @type {number}
-		 * @default 1.2
-		 */
-		this.zoomSpeed = 1.2;
-
-		/**
-		 * The pan speed.
-		 *
-		 * @type {number}
-		 * @default 0.3
-		 */
-		this.panSpeed = 0.3;
-
-		/**
-		 * Whether rotation is disabled or not.
-		 *
-		 * @type {boolean}
-		 * @default false
-		 */
-		this.noRotate = false;
-
-		/**
-		 * Whether zooming is disabled or not.
-		 *
-		 * @type {boolean}
-		 * @default false
-		 */
-		this.noZoom = false;
-
-		/**
-		 * Whether panning is disabled or not.
-		 *
-		 * @type {boolean}
-		 * @default false
-		 */
-		this.noPan = false;
-
-		/**
-		 * Whether damping is disabled or not.
-		 *
-		 * @type {boolean}
-		 * @default false
-		 */
-		this.staticMoving = false;
-
-		/**
-		 * Defines the intensity of damping. Only considered if `staticMoving` is set to `false`.
-		 *
-		 * @type {number}
-		 * @default 0.2
-		 */
-		this.dynamicDampingFactor = 0.2;
-
-		/**
-		 * How far you can dolly in (perspective camera only).
-		 *
-		 * @type {number}
-		 * @default 0
-		 */
-		this.minDistance = 0;
-
-		/**
-		 * How far you can dolly out (perspective camera only).
-		 *
-		 * @type {number}
-		 * @default Infinity
-		 */
-		this.maxDistance = Infinity;
-
-		/**
-		 * How far you can zoom in (orthographic camera only).
-		 *
-		 * @type {number}
-		 * @default 0
-		 */
-		this.minZoom = 0;
-
-		/**
-		 * How far you can zoom out (orthographic camera only).
-		 *
-		 * @type {number}
-		 * @default Infinity
-		 */
-		this.maxZoom = Infinity;
-
-		/**
-		 * This array holds keycodes for controlling interactions.
-		 *
-		 * - When the first defined key is pressed, all mouse interactions (left, middle, right) performs orbiting.
-		 * - When the second defined key is pressed, all mouse interactions (left, middle, right) performs zooming.
-		 * - When the third defined key is pressed, all mouse interactions (left, middle, right) performs panning.
-		 *
-		 * Default is *KeyA, KeyS, KeyD* which represents A, S, D.
-		 *
-		 * @type {Array<string>}
-		 */
-		this.keys = [ 'KeyA' /*A*/, 'KeyS' /*S*/, 'KeyD' /*D*/ ];
-
-		/**
-		 * This object contains references to the mouse actions used by the controls.
-		 *
-		 * ```js
-		 * controls.mouseButtons = {
-		 * 	LEFT: THREE.MOUSE.ROTATE,
-		 * 	MIDDLE: THREE.MOUSE.DOLLY,
-		 * 	RIGHT: THREE.MOUSE.PAN
-		 * }
-		 * ```
-		 * @type {Object}
-		 */
-		this.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.PAN };
-
-		/**
-		 * The focus point of the controls.
-		 *
-		 * @type {Vector3}
-		 */
-		this.target = new Vector3();
-
-		// internals
-
-		this.state = _STATE.NONE;
-		this.keyState = _STATE.NONE;
-
-		this._lastPosition = new Vector3();
-		this._lastZoom = 1;
-		this._touchZoomDistanceStart = 0;
-		this._touchZoomDistanceEnd = 0;
-		this._lastAngle = 0;
-
-		this._eye = new Vector3();
-
-		this._movePrev = new Vector2();
-		this._moveCurr = new Vector2();
-
-		this._lastAxis = new Vector3();
-
-		this._zoomStart = new Vector2();
-		this._zoomEnd = new Vector2();
-
-		this._panStart = new Vector2();
-		this._panEnd = new Vector2();
-
-		this._pointers = [];
-		this._pointerPositions = {};
-
-		// event listeners
-
-		this._onPointerMove = onPointerMove.bind( this );
-		this._onPointerDown = onPointerDown.bind( this );
-		this._onPointerUp = onPointerUp.bind( this );
-		this._onPointerCancel = onPointerCancel.bind( this );
-		this._onContextMenu = onContextMenu.bind( this );
-		this._onMouseWheel = onMouseWheel.bind( this );
-		this._onKeyDown = onKeyDown.bind( this );
-		this._onKeyUp = onKeyUp.bind( this );
-
-		this._onTouchStart = onTouchStart.bind( this );
-		this._onTouchMove = onTouchMove.bind( this );
-		this._onTouchEnd = onTouchEnd.bind( this );
-
-		this._onMouseDown = onMouseDown.bind( this );
-		this._onMouseMove = onMouseMove.bind( this );
-		this._onMouseUp = onMouseUp.bind( this );
-
-		// for reset
-
-		this._target0 = this.target.clone();
-		this._position0 = this.object.position.clone();
-		this._up0 = this.object.up.clone();
-		this._zoom0 = this.object.zoom;
-
-		if ( domElement !== null ) {
-
-			this.connect( domElement );
-
-			this.handleResize();
-
-		}
-
-		// force an update at start
-		this.update();
-
-	}
-
-	connect( element ) {
-
-		super.connect( element );
-
-		window.addEventListener( 'keydown', this._onKeyDown );
-		window.addEventListener( 'keyup', this._onKeyUp );
-
-		this.domElement.addEventListener( 'pointerdown', this._onPointerDown );
-		this.domElement.addEventListener( 'pointercancel', this._onPointerCancel );
-		this.domElement.addEventListener( 'wheel', this._onMouseWheel, { passive: false } );
-		this.domElement.addEventListener( 'contextmenu', this._onContextMenu );
-
-		this.domElement.style.touchAction = 'none'; // Disable touch scroll
-
-	}
-
-	disconnect() {
-
-		window.removeEventListener( 'keydown', this._onKeyDown );
-		window.removeEventListener( 'keyup', this._onKeyUp );
-
-		this.domElement.removeEventListener( 'pointerdown', this._onPointerDown );
-		this.domElement.ownerDocument.removeEventListener( 'pointermove', this._onPointerMove );
-		this.domElement.ownerDocument.removeEventListener( 'pointerup', this._onPointerUp );
-		this.domElement.removeEventListener( 'pointercancel', this._onPointerCancel );
-		this.domElement.removeEventListener( 'wheel', this._onMouseWheel );
-		this.domElement.removeEventListener( 'contextmenu', this._onContextMenu );
-
-		this.domElement.style.touchAction = ''; // Restore touch scroll
-
-	}
-
-	dispose() {
-
-		this.disconnect();
-
-	}
-
-	/**
-	 * Must be called if the application window is resized.
-	 */
-	handleResize() {
-
-		const box = this.domElement.getBoundingClientRect();
-		// adjustments come from similar code in the jquery offset() function
-		const d = this.domElement.ownerDocument.documentElement;
-
-		this.screen.left = box.left + window.pageXOffset - d.clientLeft;
-		this.screen.top = box.top + window.pageYOffset - d.clientTop;
-		this.screen.width = box.width;
-		this.screen.height = box.height;
-
-	}
-
-	update() {
-
-		this._eye.subVectors( this.object.position, this.target );
-
-		if ( ! this.noRotate ) {
-
-			this._rotateCamera();
-
-		}
-
-		if ( ! this.noZoom ) {
-
-			this._zoomCamera();
-
-		}
-
-		if ( ! this.noPan ) {
-
-			this._panCamera();
-
-		}
-
-		this.object.position.addVectors( this.target, this._eye );
-
-		if ( this.object.isPerspectiveCamera ) {
-
-			this._checkDistances();
-
-			this.object.lookAt( this.target );
-
-			if ( this._lastPosition.distanceToSquared( this.object.position ) > _EPS ) {
-
-				this.dispatchEvent( _changeEvent );
-
-				this._lastPosition.copy( this.object.position );
-
-			}
-
-		} else if ( this.object.isOrthographicCamera ) {
-
-			this.object.lookAt( this.target );
-
-			if ( this._lastPosition.distanceToSquared( this.object.position ) > _EPS || this._lastZoom !== this.object.zoom ) {
-
-				this.dispatchEvent( _changeEvent );
-
-				this._lastPosition.copy( this.object.position );
-				this._lastZoom = this.object.zoom;
-
-			}
-
-		} else {
-
-			console.warn( 'THREE.TrackballControls: Unsupported camera type.' );
-
-		}
-
-	}
-
-	/**
-	 * Resets the controls to its initial state.
-	 */
-	reset() {
-
-		this.state = _STATE.NONE;
-		this.keyState = _STATE.NONE;
-
-		this.target.copy( this._target0 );
-		this.object.position.copy( this._position0 );
-		this.object.up.copy( this._up0 );
-		this.object.zoom = this._zoom0;
-
-		this.object.updateProjectionMatrix();
-
-		this._eye.subVectors( this.object.position, this.target );
-
-		this.object.lookAt( this.target );
-
-		this.dispatchEvent( _changeEvent );
-
-		this._lastPosition.copy( this.object.position );
-		this._lastZoom = this.object.zoom;
-
-	}
-
-	_panCamera() {
-
-		_mouseChange.copy( this._panEnd ).sub( this._panStart );
-
-		if ( _mouseChange.lengthSq() ) {
-
-			if ( this.object.isOrthographicCamera ) {
-
-				const scale_x = ( this.object.right - this.object.left ) / this.object.zoom / this.domElement.clientWidth;
-				const scale_y = ( this.object.top - this.object.bottom ) / this.object.zoom / this.domElement.clientWidth;
-
-				_mouseChange.x *= scale_x;
-				_mouseChange.y *= scale_y;
-
-			}
-
-			_mouseChange.multiplyScalar( this._eye.length() * this.panSpeed );
-
-			_pan.copy( this._eye ).cross( this.object.up ).setLength( _mouseChange.x );
-			_pan.add( _objectUp.copy( this.object.up ).setLength( _mouseChange.y ) );
-
-			this.object.position.add( _pan );
-			this.target.add( _pan );
-
-			if ( this.staticMoving ) {
-
-				this._panStart.copy( this._panEnd );
-
-			} else {
-
-				this._panStart.add( _mouseChange.subVectors( this._panEnd, this._panStart ).multiplyScalar( this.dynamicDampingFactor ) );
-
-			}
-
-		}
-
-	}
-
-	_rotateCamera() {
-
-		_moveDirection.set( this._moveCurr.x - this._movePrev.x, this._moveCurr.y - this._movePrev.y, 0 );
-		let angle = _moveDirection.length();
-
-		if ( angle ) {
-
-			this._eye.copy( this.object.position ).sub( this.target );
-
-			_eyeDirection.copy( this._eye ).normalize();
-			_objectUpDirection.copy( this.object.up ).normalize();
-			_objectSidewaysDirection.crossVectors( _objectUpDirection, _eyeDirection ).normalize();
-
-			_objectUpDirection.setLength( this._moveCurr.y - this._movePrev.y );
-			_objectSidewaysDirection.setLength( this._moveCurr.x - this._movePrev.x );
-
-			_moveDirection.copy( _objectUpDirection.add( _objectSidewaysDirection ) );
-
-			_axis.crossVectors( _moveDirection, this._eye ).normalize();
-
-			angle *= this.rotateSpeed;
-			_quaternion.setFromAxisAngle( _axis, angle );
-
-			this._eye.applyQuaternion( _quaternion );
-			this.object.up.applyQuaternion( _quaternion );
-
-			this._lastAxis.copy( _axis );
-			this._lastAngle = angle;
-
-		} else if ( ! this.staticMoving && this._lastAngle ) {
-
-			this._lastAngle *= Math.sqrt( 1.0 - this.dynamicDampingFactor );
-			this._eye.copy( this.object.position ).sub( this.target );
-			_quaternion.setFromAxisAngle( this._lastAxis, this._lastAngle );
-			this._eye.applyQuaternion( _quaternion );
-			this.object.up.applyQuaternion( _quaternion );
-
-		}
-
-		this._movePrev.copy( this._moveCurr );
-
-	}
-
-	_zoomCamera() {
-
-		let factor;
-
-		if ( this.state === _STATE.TOUCH_ZOOM_PAN ) {
-
-			factor = this._touchZoomDistanceStart / this._touchZoomDistanceEnd;
-			this._touchZoomDistanceStart = this._touchZoomDistanceEnd;
-
-			if ( this.object.isPerspectiveCamera ) {
-
-				this._eye.multiplyScalar( factor );
-
-			} else if ( this.object.isOrthographicCamera ) {
-
-				this.object.zoom = MathUtils.clamp( this.object.zoom / factor, this.minZoom, this.maxZoom );
-
-				if ( this._lastZoom !== this.object.zoom ) {
-
-					this.object.updateProjectionMatrix();
-
-				}
-
-			} else {
-
-				console.warn( 'THREE.TrackballControls: Unsupported camera type' );
-
-			}
-
-		} else {
-
-			factor = 1.0 + ( this._zoomEnd.y - this._zoomStart.y ) * this.zoomSpeed;
-
-			if ( factor !== 1.0 && factor > 0.0 ) {
-
-				if ( this.object.isPerspectiveCamera ) {
-
-					this._eye.multiplyScalar( factor );
-
-				} else if ( this.object.isOrthographicCamera ) {
-
-					this.object.zoom = MathUtils.clamp( this.object.zoom / factor, this.minZoom, this.maxZoom );
-
-					if ( this._lastZoom !== this.object.zoom ) {
-
-						this.object.updateProjectionMatrix();
-
-					}
-
-				} else {
-
-					console.warn( 'THREE.TrackballControls: Unsupported camera type' );
-
-				}
-
-			}
-
-			if ( this.staticMoving ) {
-
-				this._zoomStart.copy( this._zoomEnd );
-
-			} else {
-
-				this._zoomStart.y += ( this._zoomEnd.y - this._zoomStart.y ) * this.dynamicDampingFactor;
-
-			}
-
-		}
-
-	}
-
-	_getMouseOnScreen( pageX, pageY ) {
-
-		_v2.set(
-			( pageX - this.screen.left ) / this.screen.width,
-			( pageY - this.screen.top ) / this.screen.height
-		);
-
-		return _v2;
-
-	}
-
-	_getMouseOnCircle( pageX, pageY ) {
-
-		_v2.set(
-			( ( pageX - this.screen.width * 0.5 - this.screen.left ) / ( this.screen.width * 0.5 ) ),
-			( ( this.screen.height + 2 * ( this.screen.top - pageY ) ) / this.screen.width ) // screen.width intentional
-		);
-
-		return _v2;
-
-	}
-
-	_addPointer( event ) {
-
-		this._pointers.push( event );
-
-	}
-
-	_removePointer( event ) {
-
-		delete this._pointerPositions[ event.pointerId ];
-
-		for ( let i = 0; i < this._pointers.length; i ++ ) {
-
-			if ( this._pointers[ i ].pointerId == event.pointerId ) {
-
-				this._pointers.splice( i, 1 );
-				return;
-
-			}
-
-		}
-
-	}
-
-	_trackPointer( event ) {
-
-		let position = this._pointerPositions[ event.pointerId ];
-
-		if ( position === undefined ) {
-
-			position = new Vector2();
-			this._pointerPositions[ event.pointerId ] = position;
-
-		}
-
-		position.set( event.pageX, event.pageY );
-
-	}
-
-	_getSecondPointerPosition( event ) {
-
-		const pointer = ( event.pointerId === this._pointers[ 0 ].pointerId ) ? this._pointers[ 1 ] : this._pointers[ 0 ];
-
-		return this._pointerPositions[ pointer.pointerId ];
-
-	}
-
-	_checkDistances() {
-
-		if ( ! this.noZoom || ! this.noPan ) {
-
-			if ( this._eye.lengthSq() > this.maxDistance * this.maxDistance ) {
-
-				this.object.position.addVectors( this.target, this._eye.setLength( this.maxDistance ) );
-				this._zoomStart.copy( this._zoomEnd );
-
-			}
-
-			if ( this._eye.lengthSq() < this.minDistance * this.minDistance ) {
-
-				this.object.position.addVectors( this.target, this._eye.setLength( this.minDistance ) );
-				this._zoomStart.copy( this._zoomEnd );
-
-			}
-
-		}
-
-	}
-
-}
-
-function onPointerDown( event ) {
-
-	if ( this.enabled === false ) return;
-
-	if ( this._pointers.length === 0 ) {
-
-		this.domElement.setPointerCapture( event.pointerId );
-
-		this.domElement.ownerDocument.addEventListener( 'pointermove', this._onPointerMove );
-		this.domElement.ownerDocument.addEventListener( 'pointerup', this._onPointerUp );
-
-	}
-
-	//
-
-	this._addPointer( event );
-
-	if ( event.pointerType === 'touch' ) {
-
-		this._onTouchStart( event );
-
-	} else {
-
-		this._onMouseDown( event );
-
-	}
-
-}
-
-function onPointerMove( event ) {
-
-	if ( this.enabled === false ) return;
-
-	if ( event.pointerType === 'touch' ) {
-
-		this._onTouchMove( event );
-
-	} else {
-
-		this._onMouseMove( event );
-
-	}
-
-}
-
-function onPointerUp( event ) {
-
-	if ( this.enabled === false ) return;
-
-	if ( event.pointerType === 'touch' ) {
-
-		this._onTouchEnd( event );
-
-	} else {
-
-		this._onMouseUp();
-
-	}
-
-	//
-
-	this._removePointer( event );
-
-	if ( this._pointers.length === 0 ) {
-
-		this.domElement.releasePointerCapture( event.pointerId );
-
-		this.domElement.ownerDocument.removeEventListener( 'pointermove', this._onPointerMove );
-		this.domElement.ownerDocument.removeEventListener( 'pointerup', this._onPointerUp );
-
-	}
-
-}
-
-function onPointerCancel( event ) {
-
-	this._removePointer( event );
-
-}
-
-function onKeyUp() {
-
-	if ( this.enabled === false ) return;
-
-	this.keyState = _STATE.NONE;
-
-	window.addEventListener( 'keydown', this._onKeyDown );
-
-}
-
-function onKeyDown( event ) {
-
-	if ( this.enabled === false ) return;
-
-	window.removeEventListener( 'keydown', this._onKeyDown );
-
-	if ( this.keyState !== _STATE.NONE ) {
-
-		return;
-
-	} else if ( event.code === this.keys[ _STATE.ROTATE ] && ! this.noRotate ) {
-
-		this.keyState = _STATE.ROTATE;
-
-	} else if ( event.code === this.keys[ _STATE.ZOOM ] && ! this.noZoom ) {
-
-		this.keyState = _STATE.ZOOM;
-
-	} else if ( event.code === this.keys[ _STATE.PAN ] && ! this.noPan ) {
-
-		this.keyState = _STATE.PAN;
-
-	}
-
-}
-
-function onMouseDown( event ) {
-
-	let mouseAction;
-
-	switch ( event.button ) {
-
-		case 0:
-			mouseAction = this.mouseButtons.LEFT;
-			break;
-
-		case 1:
-			mouseAction = this.mouseButtons.MIDDLE;
-			break;
-
-		case 2:
-			mouseAction = this.mouseButtons.RIGHT;
-			break;
-
-		default:
-			mouseAction = - 1;
-
-	}
-
-	switch ( mouseAction ) {
-
-		case MOUSE.DOLLY:
-			this.state = _STATE.ZOOM;
-			break;
-
-		case MOUSE.ROTATE:
-			this.state = _STATE.ROTATE;
-			break;
-
-		case MOUSE.PAN:
-			this.state = _STATE.PAN;
-			break;
-
-		default:
-			this.state = _STATE.NONE;
-
-	}
-
-	const state = ( this.keyState !== _STATE.NONE ) ? this.keyState : this.state;
-
-	if ( state === _STATE.ROTATE && ! this.noRotate ) {
-
-		this._moveCurr.copy( this._getMouseOnCircle( event.pageX, event.pageY ) );
-		this._movePrev.copy( this._moveCurr );
-
-	} else if ( state === _STATE.ZOOM && ! this.noZoom ) {
-
-		this._zoomStart.copy( this._getMouseOnScreen( event.pageX, event.pageY ) );
-		this._zoomEnd.copy( this._zoomStart );
-
-	} else if ( state === _STATE.PAN && ! this.noPan ) {
-
-		this._panStart.copy( this._getMouseOnScreen( event.pageX, event.pageY ) );
-		this._panEnd.copy( this._panStart );
-
-	}
-
-	this.dispatchEvent( _startEvent );
-
-}
-
-function onMouseMove( event ) {
-
-	const state = ( this.keyState !== _STATE.NONE ) ? this.keyState : this.state;
-
-	if ( state === _STATE.ROTATE && ! this.noRotate ) {
-
-		this._movePrev.copy( this._moveCurr );
-		this._moveCurr.copy( this._getMouseOnCircle( event.pageX, event.pageY ) );
-
-	} else if ( state === _STATE.ZOOM && ! this.noZoom ) {
-
-		this._zoomEnd.copy( this._getMouseOnScreen( event.pageX, event.pageY ) );
-
-	} else if ( state === _STATE.PAN && ! this.noPan ) {
-
-		this._panEnd.copy( this._getMouseOnScreen( event.pageX, event.pageY ) );
-
-	}
-
-}
-
-function onMouseUp() {
-
-	this.state = _STATE.NONE;
-
-	this.dispatchEvent( _endEvent );
-
-}
-
-function onMouseWheel( event ) {
-
-	if ( this.enabled === false ) return;
-
-	if ( this.noZoom === true ) return;
-
-	event.preventDefault();
-
-	switch ( event.deltaMode ) {
-
-		case 2:
-			// Zoom in pages
-			this._zoomStart.y -= event.deltaY * 0.025;
-			break;
-
-		case 1:
-			// Zoom in lines
-			this._zoomStart.y -= event.deltaY * 0.01;
-			break;
-
-		default:
-			// undefined, 0, assume pixels
-			this._zoomStart.y -= event.deltaY * 0.00025;
-			break;
-
-	}
-
-	this.dispatchEvent( _startEvent );
-	this.dispatchEvent( _endEvent );
-
-}
-
-function onContextMenu( event ) {
-
-	if ( this.enabled === false ) return;
-
-	event.preventDefault();
-
-}
-
-function onTouchStart( event ) {
-
-	this._trackPointer( event );
-
-	switch ( this._pointers.length ) {
-
-		case 1:
-			this.state = _STATE.TOUCH_ROTATE;
-			this._moveCurr.copy( this._getMouseOnCircle( this._pointers[ 0 ].pageX, this._pointers[ 0 ].pageY ) );
-			this._movePrev.copy( this._moveCurr );
-			break;
-
-		default: // 2 or more
-			this.state = _STATE.TOUCH_ZOOM_PAN;
-			const dx = this._pointers[ 0 ].pageX - this._pointers[ 1 ].pageX;
-			const dy = this._pointers[ 0 ].pageY - this._pointers[ 1 ].pageY;
-			this._touchZoomDistanceEnd = this._touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy );
-
-			const x = ( this._pointers[ 0 ].pageX + this._pointers[ 1 ].pageX ) / 2;
-			const y = ( this._pointers[ 0 ].pageY + this._pointers[ 1 ].pageY ) / 2;
-			this._panStart.copy( this._getMouseOnScreen( x, y ) );
-			this._panEnd.copy( this._panStart );
-			break;
-
-	}
-
-	this.dispatchEvent( _startEvent );
-
-}
-
-function onTouchMove( event ) {
-
-	this._trackPointer( event );
-
-	switch ( this._pointers.length ) {
-
-		case 1:
-			this._movePrev.copy( this._moveCurr );
-			this._moveCurr.copy( this._getMouseOnCircle( event.pageX, event.pageY ) );
-			break;
-
-		default: // 2 or more
-
-			const position = this._getSecondPointerPosition( event );
-
-			const dx = event.pageX - position.x;
-			const dy = event.pageY - position.y;
-			this._touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy );
-
-			const x = ( event.pageX + position.x ) / 2;
-			const y = ( event.pageY + position.y ) / 2;
-			this._panEnd.copy( this._getMouseOnScreen( x, y ) );
-			break;
-
-	}
-
-}
-
-function onTouchEnd( event ) {
-
-	switch ( this._pointers.length ) {
-
-		case 0:
-			this.state = _STATE.NONE;
-			break;
-
-		case 1:
-			this.state = _STATE.TOUCH_ROTATE;
-			this._moveCurr.copy( this._getMouseOnCircle( event.pageX, event.pageY ) );
-			this._movePrev.copy( this._moveCurr );
-			break;
-
-		case 2:
-			this.state = _STATE.TOUCH_ZOOM_PAN;
-
-			for ( let i = 0; i < this._pointers.length; i ++ ) {
-
-				if ( this._pointers[ i ].pointerId !== event.pointerId ) {
-
-					const position = this._pointerPositions[ this._pointers[ i ].pointerId ];
-					this._moveCurr.copy( this._getMouseOnCircle( position.x, position.y ) );
-					this._movePrev.copy( this._moveCurr );
-					break;
-
-				}
-
-			}
-
-			break;
-
-	}
-
-	this.dispatchEvent( _endEvent );
-
-}
-
-export { TrackballControls };

+ 0 - 1950
node_modules/three/examples/jsm/controls/TransformControls.js

@@ -1,1950 +0,0 @@
-import {
-	BoxGeometry,
-	BufferGeometry,
-	Controls,
-	CylinderGeometry,
-	DoubleSide,
-	Euler,
-	Float32BufferAttribute,
-	Line,
-	LineBasicMaterial,
-	Matrix4,
-	Mesh,
-	MeshBasicMaterial,
-	Object3D,
-	OctahedronGeometry,
-	PlaneGeometry,
-	Quaternion,
-	Raycaster,
-	SphereGeometry,
-	TorusGeometry,
-	Vector3
-} from 'three';
-
-const _raycaster = new Raycaster();
-
-const _tempVector = new Vector3();
-const _tempVector2 = new Vector3();
-const _tempQuaternion = new Quaternion();
-const _unit = {
-	X: new Vector3( 1, 0, 0 ),
-	Y: new Vector3( 0, 1, 0 ),
-	Z: new Vector3( 0, 0, 1 )
-};
-
-/**
- * Fires if any type of change (object or property change) is performed. Property changes
- * are separate events you can add event listeners to. The event type is "propertyname-changed".
- *
- * @event TransformControls#change
- * @type {Object}
- */
-const _changeEvent = { type: 'change' };
-
-/**
- * Fires if a pointer (mouse/touch) becomes active.
- *
- * @event TransformControls#mouseDown
- * @type {Object}
- */
-const _mouseDownEvent = { type: 'mouseDown', mode: null };
-
-/**
- * Fires if a pointer (mouse/touch) is no longer active.
- *
- * @event TransformControls#mouseUp
- * @type {Object}
- */
-const _mouseUpEvent = { type: 'mouseUp', mode: null };
-
-/**
- * Fires if the controlled 3D object is changed.
- *
- * @event TransformControls#objectChange
- * @type {Object}
- */
-const _objectChangeEvent = { type: 'objectChange' };
-
-/**
- * This class can be used to transform objects in 3D space by adapting a similar interaction model
- * of DCC tools like Blender. Unlike other controls, it is not intended to transform the scene's camera.
- *
- * `TransformControls` expects that its attached 3D object is part of the scene graph.
- *
- * @augments Controls
- * @three_import import { TransformControls } from 'three/addons/controls/TransformControls.js';
- */
-class TransformControls extends Controls {
-
-	/**
-	 * Constructs a new controls instance.
-	 *
-	 * @param {Camera} camera - The camera of the rendered scene.
-	 * @param {?HTMLElement} domElement - The HTML element used for event listeners.
-	 */
-	constructor( camera, domElement = null ) {
-
-		super( undefined, domElement );
-
-		const root = new TransformControlsRoot( this );
-		this._root = root;
-
-		const gizmo = new TransformControlsGizmo();
-		this._gizmo = gizmo;
-		root.add( gizmo );
-
-		const plane = new TransformControlsPlane();
-		this._plane = plane;
-		root.add( plane );
-
-		const scope = this;
-
-		// Defined getter, setter and store for a property
-		function defineProperty( propName, defaultValue ) {
-
-			let propValue = defaultValue;
-
-			Object.defineProperty( scope, propName, {
-
-				get: function () {
-
-					return propValue !== undefined ? propValue : defaultValue;
-
-				},
-
-				set: function ( value ) {
-
-					if ( propValue !== value ) {
-
-						propValue = value;
-						plane[ propName ] = value;
-						gizmo[ propName ] = value;
-
-						scope.dispatchEvent( { type: propName + '-changed', value: value } );
-						scope.dispatchEvent( _changeEvent );
-
-					}
-
-				}
-
-			} );
-
-			scope[ propName ] = defaultValue;
-			plane[ propName ] = defaultValue;
-			gizmo[ propName ] = defaultValue;
-
-		}
-
-		// Define properties with getters/setter
-		// Setting the defined property will automatically trigger change event
-		// Defined properties are passed down to gizmo and plane
-
-		/**
-		 * The camera of the rendered scene.
-		 *
-		 * @name TransformControls#camera
-		 * @type {Camera}
-		 */
-		defineProperty( 'camera', camera );
-		defineProperty( 'object', undefined );
-		defineProperty( 'enabled', true );
-
-		/**
-		 * The current transformation axis.
-		 *
-		 * @name TransformControls#axis
-		 * @type {string}
-		 */
-		defineProperty( 'axis', null );
-
-		/**
-		 * The current transformation axis.
-		 *
-		 * @name TransformControls#mode
-		 * @type {('translate'|'rotate'|'scale')}
-		 * @default 'translate'
-		 */
-		defineProperty( 'mode', 'translate' );
-
-		/**
-		 * By default, 3D objects are continuously translated. If you set this property to a numeric
-		 * value (world units), you can define in which steps the 3D object should be translated.
-		 *
-		 * @name TransformControls#translationSnap
-		 * @type {?number}
-		 * @default null
-		 */
-		defineProperty( 'translationSnap', null );
-
-		/**
-		 * By default, 3D objects are continuously rotated. If you set this property to a numeric
-		 * value (radians), you can define in which steps the 3D object should be rotated.
-		 *
-		 * @name TransformControls#rotationSnap
-		 * @type {?number}
-		 * @default null
-		 */
-		defineProperty( 'rotationSnap', null );
-
-		/**
-		 * By default, 3D objects are continuously scaled. If you set this property to a numeric
-		 * value, you can define in which steps the 3D object should be scaled.
-		 *
-		 * @name TransformControls#scaleSnap
-		 * @type {?number}
-		 * @default null
-		 */
-		defineProperty( 'scaleSnap', null );
-
-		/**
-		 * Defines in which coordinate space transformations should be performed.
-		 *
-		 * @name TransformControls#space
-		 * @type {('world'|'local')}
-		 * @default 'world'
-		 */
-		defineProperty( 'space', 'world' );
-
-		/**
-		 * The size of the helper UI (axes/planes).
-		 *
-		 * @name TransformControls#size
-		 * @type {number}
-		 * @default 1
-		 */
-		defineProperty( 'size', 1 );
-
-		/**
-		 * Whether dragging is currently performed or not.
-		 *
-		 * @name TransformControls#dragging
-		 * @type {boolean}
-		 * @readonly
-		 * @default false
-		 */
-		defineProperty( 'dragging', false );
-
-		/**
-		 * Whether the x-axis helper should be visible or not.
-		 *
-		 * @name TransformControls#showX
-		 * @type {boolean}
-		 * @default true
-		 */
-		defineProperty( 'showX', true );
-
-		/**
-		 * Whether the y-axis helper should be visible or not.
-		 *
-		 * @name TransformControls#showY
-		 * @type {boolean}
-		 * @default true
-		 */
-		defineProperty( 'showY', true );
-
-		/**
-		 * Whether the z-axis helper should be visible or not.
-		 *
-		 * @name TransformControls#showZ
-		 * @type {boolean}
-		 * @default true
-		 */
-		defineProperty( 'showZ', true );
-
-		/**
-		 * Whether the xy-plane helper should be visible or not.
-		 *
-		 * @name TransformControls#showXY
-		 * @type {boolean}
-		 * @default true
-		 */
-		defineProperty( 'showXY', true );
-
-		/**
-		 * Whether the yz-plane helper should be visible or not.
-		 *
-		 * @name TransformControls#showYZ
-		 * @type {boolean}
-		 * @default true
-		 */
-		defineProperty( 'showYZ', true );
-
-		/**
-		 * Whether the xz-axis helper should be visible or not.
-		 *
-		 * @name TransformControls#showXZ
-		 * @type {boolean}
-		 * @default true
-		 */
-		defineProperty( 'showXZ', true );
-
-		/**
-		 * The minimum allowed X position during translation.
-		 *
-		 * @name TransformControls#minX
-		 * @type {number}
-		 * @default -Infinity
-		 */
-		defineProperty( 'minX', - Infinity );
-
-		/**
-		 * The maximum allowed X position during translation.
-		 *
-		 * @name TransformControls#maxX
-		 * @type {number}
-		 * @default Infinity
-		 */
-		defineProperty( 'maxX', Infinity );
-
-		/**
-		 * The minimum allowed y position during translation.
-		 *
-		 * @name TransformControls#minY
-		 * @type {number}
-		 * @default -Infinity
-		 */
-		defineProperty( 'minY', - Infinity );
-
-		/**
-		 * The maximum allowed Y position during translation.
-		 *
-		 * @name TransformControls#maxY
-		 * @type {number}
-		 * @default Infinity
-		 */
-		defineProperty( 'maxY', Infinity );
-
-		/**
-		 * The minimum allowed z position during translation.
-		 *
-		 * @name TransformControls#minZ
-		 * @type {number}
-		 * @default -Infinity
-		 */
-		defineProperty( 'minZ', - Infinity );
-
-		/**
-		 * The maximum allowed Z position during translation.
-		 *
-		 * @name TransformControls#maxZ
-		 * @type {number}
-		 * @default Infinity
-		 */
-		defineProperty( 'maxZ', Infinity );
-
-		// Reusable utility variables
-
-		const worldPosition = new Vector3();
-		const worldPositionStart = new Vector3();
-		const worldQuaternion = new Quaternion();
-		const worldQuaternionStart = new Quaternion();
-		const cameraPosition = new Vector3();
-		const cameraQuaternion = new Quaternion();
-		const pointStart = new Vector3();
-		const pointEnd = new Vector3();
-		const rotationAxis = new Vector3();
-		const rotationAngle = 0;
-		const eye = new Vector3();
-
-		// TODO: remove properties unused in plane and gizmo
-
-		defineProperty( 'worldPosition', worldPosition );
-		defineProperty( 'worldPositionStart', worldPositionStart );
-		defineProperty( 'worldQuaternion', worldQuaternion );
-		defineProperty( 'worldQuaternionStart', worldQuaternionStart );
-		defineProperty( 'cameraPosition', cameraPosition );
-		defineProperty( 'cameraQuaternion', cameraQuaternion );
-		defineProperty( 'pointStart', pointStart );
-		defineProperty( 'pointEnd', pointEnd );
-		defineProperty( 'rotationAxis', rotationAxis );
-		defineProperty( 'rotationAngle', rotationAngle );
-		defineProperty( 'eye', eye );
-
-		this._offset = new Vector3();
-		this._startNorm = new Vector3();
-		this._endNorm = new Vector3();
-		this._cameraScale = new Vector3();
-
-		this._parentPosition = new Vector3();
-		this._parentQuaternion = new Quaternion();
-		this._parentQuaternionInv = new Quaternion();
-		this._parentScale = new Vector3();
-
-		this._worldScaleStart = new Vector3();
-		this._worldQuaternionInv = new Quaternion();
-		this._worldScale = new Vector3();
-
-		this._positionStart = new Vector3();
-		this._quaternionStart = new Quaternion();
-		this._scaleStart = new Vector3();
-
-		this._getPointer = getPointer.bind( this );
-		this._onPointerDown = onPointerDown.bind( this );
-		this._onPointerHover = onPointerHover.bind( this );
-		this._onPointerMove = onPointerMove.bind( this );
-		this._onPointerUp = onPointerUp.bind( this );
-
-		if ( domElement !== null ) {
-
-			this.connect( domElement );
-
-		}
-
-	}
-
-	connect( element ) {
-
-		super.connect( element );
-
-		this.domElement.addEventListener( 'pointerdown', this._onPointerDown );
-		this.domElement.addEventListener( 'pointermove', this._onPointerHover );
-		this.domElement.addEventListener( 'pointerup', this._onPointerUp );
-
-		this.domElement.style.touchAction = 'none'; // Disable touch scroll
-
-	}
-
-	disconnect() {
-
-		this.domElement.removeEventListener( 'pointerdown', this._onPointerDown );
-		this.domElement.removeEventListener( 'pointermove', this._onPointerHover );
-		this.domElement.removeEventListener( 'pointermove', this._onPointerMove );
-		this.domElement.removeEventListener( 'pointerup', this._onPointerUp );
-
-		this.domElement.style.touchAction = ''; // Restore touch scroll
-
-	}
-
-	/**
-	 * Returns the visual representation of the controls. Add the helper to your scene to
-	 * visually transform the attached  3D object.
-	 *
-	 * @return {TransformControlsRoot} The helper.
-	 */
-	getHelper() {
-
-		return this._root;
-
-	}
-
-	pointerHover( pointer ) {
-
-		if ( this.object === undefined || this.dragging === true ) return;
-
-		if ( pointer !== null ) _raycaster.setFromCamera( pointer, this.camera );
-
-		const intersect = intersectObjectWithRay( this._gizmo.picker[ this.mode ], _raycaster );
-
-		if ( intersect ) {
-
-			this.axis = intersect.object.name;
-
-		} else {
-
-			this.axis = null;
-
-		}
-
-	}
-
-	pointerDown( pointer ) {
-
-		if ( this.object === undefined || this.dragging === true || ( pointer != null && pointer.button !== 0 ) ) return;
-
-		if ( this.axis !== null ) {
-
-			if ( pointer !== null ) _raycaster.setFromCamera( pointer, this.camera );
-
-			const planeIntersect = intersectObjectWithRay( this._plane, _raycaster, true );
-
-			if ( planeIntersect ) {
-
-				this.object.updateMatrixWorld();
-				this.object.parent.updateMatrixWorld();
-
-				this._positionStart.copy( this.object.position );
-				this._quaternionStart.copy( this.object.quaternion );
-				this._scaleStart.copy( this.object.scale );
-
-				this.object.matrixWorld.decompose( this.worldPositionStart, this.worldQuaternionStart, this._worldScaleStart );
-
-				this.pointStart.copy( planeIntersect.point ).sub( this.worldPositionStart );
-
-			}
-
-			this.dragging = true;
-			_mouseDownEvent.mode = this.mode;
-			this.dispatchEvent( _mouseDownEvent );
-
-		}
-
-	}
-
-	pointerMove( pointer ) {
-
-		const axis = this.axis;
-		const mode = this.mode;
-		const object = this.object;
-		let space = this.space;
-
-		if ( mode === 'scale' ) {
-
-			space = 'local';
-
-		} else if ( axis === 'E' || axis === 'XYZE' || axis === 'XYZ' ) {
-
-			space = 'world';
-
-		}
-
-		if ( object === undefined || axis === null || this.dragging === false || ( pointer !== null && pointer.button !== - 1 ) ) return;
-
-		if ( pointer !== null ) _raycaster.setFromCamera( pointer, this.camera );
-
-		const planeIntersect = intersectObjectWithRay( this._plane, _raycaster, true );
-
-		if ( ! planeIntersect ) return;
-
-		this.pointEnd.copy( planeIntersect.point ).sub( this.worldPositionStart );
-
-		if ( mode === 'translate' ) {
-
-			// Apply translate
-
-			this._offset.copy( this.pointEnd ).sub( this.pointStart );
-
-			if ( space === 'local' && axis !== 'XYZ' ) {
-
-				this._offset.applyQuaternion( this._worldQuaternionInv );
-
-			}
-
-			if ( axis.indexOf( 'X' ) === - 1 ) this._offset.x = 0;
-			if ( axis.indexOf( 'Y' ) === - 1 ) this._offset.y = 0;
-			if ( axis.indexOf( 'Z' ) === - 1 ) this._offset.z = 0;
-
-			if ( space === 'local' && axis !== 'XYZ' ) {
-
-				this._offset.applyQuaternion( this._quaternionStart ).divide( this._parentScale );
-
-			} else {
-
-				this._offset.applyQuaternion( this._parentQuaternionInv ).divide( this._parentScale );
-
-			}
-
-			object.position.copy( this._offset ).add( this._positionStart );
-
-			// Apply translation snap
-
-			if ( this.translationSnap ) {
-
-				if ( space === 'local' ) {
-
-					object.position.applyQuaternion( _tempQuaternion.copy( this._quaternionStart ).invert() );
-
-					if ( axis.search( 'X' ) !== - 1 ) {
-
-						object.position.x = Math.round( object.position.x / this.translationSnap ) * this.translationSnap;
-
-					}
-
-					if ( axis.search( 'Y' ) !== - 1 ) {
-
-						object.position.y = Math.round( object.position.y / this.translationSnap ) * this.translationSnap;
-
-					}
-
-					if ( axis.search( 'Z' ) !== - 1 ) {
-
-						object.position.z = Math.round( object.position.z / this.translationSnap ) * this.translationSnap;
-
-					}
-
-					object.position.applyQuaternion( this._quaternionStart );
-
-				}
-
-				if ( space === 'world' ) {
-
-					if ( object.parent ) {
-
-						object.position.add( _tempVector.setFromMatrixPosition( object.parent.matrixWorld ) );
-
-					}
-
-					if ( axis.search( 'X' ) !== - 1 ) {
-
-						object.position.x = Math.round( object.position.x / this.translationSnap ) * this.translationSnap;
-
-					}
-
-					if ( axis.search( 'Y' ) !== - 1 ) {
-
-						object.position.y = Math.round( object.position.y / this.translationSnap ) * this.translationSnap;
-
-					}
-
-					if ( axis.search( 'Z' ) !== - 1 ) {
-
-						object.position.z = Math.round( object.position.z / this.translationSnap ) * this.translationSnap;
-
-					}
-
-					if ( object.parent ) {
-
-						object.position.sub( _tempVector.setFromMatrixPosition( object.parent.matrixWorld ) );
-
-					}
-
-				}
-
-			}
-
-			object.position.x = Math.max( this.minX, Math.min( this.maxX, object.position.x ) );
-			object.position.y = Math.max( this.minY, Math.min( this.maxY, object.position.y ) );
-			object.position.z = Math.max( this.minZ, Math.min( this.maxZ, object.position.z ) );
-
-		} else if ( mode === 'scale' ) {
-
-			if ( axis.search( 'XYZ' ) !== - 1 ) {
-
-				let d = this.pointEnd.length() / this.pointStart.length();
-
-				if ( this.pointEnd.dot( this.pointStart ) < 0 ) d *= - 1;
-
-				_tempVector2.set( d, d, d );
-
-			} else {
-
-				_tempVector.copy( this.pointStart );
-				_tempVector2.copy( this.pointEnd );
-
-				_tempVector.applyQuaternion( this._worldQuaternionInv );
-				_tempVector2.applyQuaternion( this._worldQuaternionInv );
-
-				_tempVector2.divide( _tempVector );
-
-				if ( axis.search( 'X' ) === - 1 ) {
-
-					_tempVector2.x = 1;
-
-				}
-
-				if ( axis.search( 'Y' ) === - 1 ) {
-
-					_tempVector2.y = 1;
-
-				}
-
-				if ( axis.search( 'Z' ) === - 1 ) {
-
-					_tempVector2.z = 1;
-
-				}
-
-			}
-
-			// Apply scale
-
-			object.scale.copy( this._scaleStart ).multiply( _tempVector2 );
-
-			if ( this.scaleSnap ) {
-
-				if ( axis.search( 'X' ) !== - 1 ) {
-
-					object.scale.x = Math.round( object.scale.x / this.scaleSnap ) * this.scaleSnap || this.scaleSnap;
-
-				}
-
-				if ( axis.search( 'Y' ) !== - 1 ) {
-
-					object.scale.y = Math.round( object.scale.y / this.scaleSnap ) * this.scaleSnap || this.scaleSnap;
-
-				}
-
-				if ( axis.search( 'Z' ) !== - 1 ) {
-
-					object.scale.z = Math.round( object.scale.z / this.scaleSnap ) * this.scaleSnap || this.scaleSnap;
-
-				}
-
-			}
-
-		} else if ( mode === 'rotate' ) {
-
-			this._offset.copy( this.pointEnd ).sub( this.pointStart );
-
-			const ROTATION_SPEED = 20 / this.worldPosition.distanceTo( _tempVector.setFromMatrixPosition( this.camera.matrixWorld ) );
-
-			let _inPlaneRotation = false;
-
-			if ( axis === 'XYZE' ) {
-
-				this.rotationAxis.copy( this._offset ).cross( this.eye ).normalize();
-				this.rotationAngle = this._offset.dot( _tempVector.copy( this.rotationAxis ).cross( this.eye ) ) * ROTATION_SPEED;
-
-			} else if ( axis === 'X' || axis === 'Y' || axis === 'Z' ) {
-
-				this.rotationAxis.copy( _unit[ axis ] );
-
-				_tempVector.copy( _unit[ axis ] );
-
-				if ( space === 'local' ) {
-
-					_tempVector.applyQuaternion( this.worldQuaternion );
-
-				}
-
-				_tempVector.cross( this.eye );
-
-				// When _tempVector is 0 after cross with this.eye the vectors are parallel and should use in-plane rotation logic.
-				if ( _tempVector.length() === 0 ) {
-
-					_inPlaneRotation = true;
-
-				} else {
-
-					this.rotationAngle = this._offset.dot( _tempVector.normalize() ) * ROTATION_SPEED;
-
-				}
-
-
-			}
-
-			if ( axis === 'E' || _inPlaneRotation ) {
-
-				this.rotationAxis.copy( this.eye );
-				this.rotationAngle = this.pointEnd.angleTo( this.pointStart );
-
-				this._startNorm.copy( this.pointStart ).normalize();
-				this._endNorm.copy( this.pointEnd ).normalize();
-
-				this.rotationAngle *= ( this._endNorm.cross( this._startNorm ).dot( this.eye ) < 0 ? 1 : - 1 );
-
-			}
-
-			// Apply rotation snap
-
-			if ( this.rotationSnap ) this.rotationAngle = Math.round( this.rotationAngle / this.rotationSnap ) * this.rotationSnap;
-
-			// Apply rotate
-			if ( space === 'local' && axis !== 'E' && axis !== 'XYZE' ) {
-
-				object.quaternion.copy( this._quaternionStart );
-				object.quaternion.multiply( _tempQuaternion.setFromAxisAngle( this.rotationAxis, this.rotationAngle ) ).normalize();
-
-			} else {
-
-				this.rotationAxis.applyQuaternion( this._parentQuaternionInv );
-				object.quaternion.copy( _tempQuaternion.setFromAxisAngle( this.rotationAxis, this.rotationAngle ) );
-				object.quaternion.multiply( this._quaternionStart ).normalize();
-
-			}
-
-		}
-
-		this.dispatchEvent( _changeEvent );
-		this.dispatchEvent( _objectChangeEvent );
-
-	}
-
-	pointerUp( pointer ) {
-
-		if ( pointer !== null && pointer.button !== 0 ) return;
-
-		if ( this.dragging && ( this.axis !== null ) ) {
-
-			_mouseUpEvent.mode = this.mode;
-			this.dispatchEvent( _mouseUpEvent );
-
-		}
-
-		this.dragging = false;
-		this.axis = null;
-
-	}
-
-	dispose() {
-
-		this.disconnect();
-
-		this._root.dispose();
-
-	}
-
-	/**
-	 * Sets the 3D object that should be transformed and ensures the controls UI is visible.
-	 *
-	 * @param {Object3D} object -  The 3D object that should be transformed.
-	 * @return {TransformControls} A reference to this controls.
-	 */
-	attach( object ) {
-
-		this.object = object;
-		this._root.visible = true;
-
-		return this;
-
-	}
-
-	/**
-	 * Removes the current 3D object from the controls and makes the helper UI invisible.
-	 *
-	 * @return {TransformControls} A reference to this controls.
-	 */
-	detach() {
-
-		this.object = undefined;
-		this.axis = null;
-
-		this._root.visible = false;
-
-		return this;
-
-	}
-
-	/**
-	 * Resets the object's position, rotation and scale to when the current transform began.
-	 */
-	reset() {
-
-		if ( ! this.enabled ) return;
-
-		if ( this.dragging ) {
-
-			this.object.position.copy( this._positionStart );
-			this.object.quaternion.copy( this._quaternionStart );
-			this.object.scale.copy( this._scaleStart );
-
-			this.dispatchEvent( _changeEvent );
-			this.dispatchEvent( _objectChangeEvent );
-
-			this.pointStart.copy( this.pointEnd );
-
-		}
-
-	}
-
-	/**
-	 * Returns the raycaster that is used for user interaction. This object is shared between all
-	 * instances of `TransformControls`.
-	 *
-	 * @returns {Raycaster} The internal raycaster.
-	 */
-	getRaycaster() {
-
-		return _raycaster;
-
-	}
-
-	/**
-	 * Returns the transformation mode.
-	 *
-	 * @returns {'translate'|'rotate'|'scale'} The transformation mode.
-	 */
-	getMode() {
-
-		return this.mode;
-
-	}
-
-	/**
-	 * Sets the given transformation mode.
-	 *
-	 * @param {'translate'|'rotate'|'scale'} mode - The transformation mode to set.
-	 */
-	setMode( mode ) {
-
-		this.mode = mode;
-
-	}
-
-	/**
-	 * Sets the translation snap.
-	 *
-	 * @param {?number} translationSnap - The translation snap to set.
-	 */
-	setTranslationSnap( translationSnap ) {
-
-		this.translationSnap = translationSnap;
-
-	}
-
-	/**
-	 * Sets the rotation snap.
-	 *
-	 * @param {?number} rotationSnap - The rotation snap to set.
-	 */
-	setRotationSnap( rotationSnap ) {
-
-		this.rotationSnap = rotationSnap;
-
-	}
-
-	/**
-	 * Sets the scale snap.
-	 *
-	 * @param {?number} scaleSnap - The scale snap to set.
-	 */
-	setScaleSnap( scaleSnap ) {
-
-		this.scaleSnap = scaleSnap;
-
-	}
-
-	/**
-	 * Sets the size of the helper UI.
-	 *
-	 * @param {number} size - The size to set.
-	 */
-	setSize( size ) {
-
-		this.size = size;
-
-	}
-
-	/**
-	 * Sets the coordinate space in which transformations are applied.
-	 *
-	 * @param {'world'|'local'} space - The space to set.
-	 */
-	setSpace( space ) {
-
-		this.space = space;
-
-	}
-
-	/**
-	 * Sets the colors of the control's gizmo.
-	 *
-	 * @param {number|Color|string} xAxis - The x-axis color.
-	 * @param {number|Color|string} yAxis - The y-axis color.
-	 * @param {number|Color|string} zAxis - The z-axis color.
-	 * @param {number|Color|string} active - The color for active elements.
-	 */
-	setColors( xAxis, yAxis, zAxis, active ) {
-
-		const materialLib = this._gizmo.materialLib;
-
-		materialLib.xAxis.color.set( xAxis );
-		materialLib.yAxis.color.set( yAxis );
-		materialLib.zAxis.color.set( zAxis );
-		materialLib.active.color.set( active );
-		materialLib.xAxisTransparent.color.set( xAxis );
-		materialLib.yAxisTransparent.color.set( yAxis );
-		materialLib.zAxisTransparent.color.set( zAxis );
-		materialLib.activeTransparent.color.set( active );
-
-		// update color caches
-
-		if ( materialLib.xAxis._color ) materialLib.xAxis._color.set( xAxis );
-		if ( materialLib.yAxis._color ) materialLib.yAxis._color.set( yAxis );
-		if ( materialLib.zAxis._color ) materialLib.zAxis._color.set( zAxis );
-		if ( materialLib.active._color ) materialLib.active._color.set( active );
-		if ( materialLib.xAxisTransparent._color ) materialLib.xAxisTransparent._color.set( xAxis );
-		if ( materialLib.yAxisTransparent._color ) materialLib.yAxisTransparent._color.set( yAxis );
-		if ( materialLib.zAxisTransparent._color ) materialLib.zAxisTransparent._color.set( zAxis );
-		if ( materialLib.activeTransparent._color ) materialLib.activeTransparent._color.set( active );
-
-	}
-
-}
-
-// mouse / touch event handlers
-
-function getPointer( event ) {
-
-	if ( this.domElement.ownerDocument.pointerLockElement ) {
-
-		return {
-			x: 0,
-			y: 0,
-			button: event.button
-		};
-
-	} else {
-
-		const rect = this.domElement.getBoundingClientRect();
-
-		return {
-			x: ( event.clientX - rect.left ) / rect.width * 2 - 1,
-			y: - ( event.clientY - rect.top ) / rect.height * 2 + 1,
-			button: event.button
-		};
-
-	}
-
-}
-
-function onPointerHover( event ) {
-
-	if ( ! this.enabled ) return;
-
-	switch ( event.pointerType ) {
-
-		case 'mouse':
-		case 'pen':
-			this.pointerHover( this._getPointer( event ) );
-			break;
-
-	}
-
-}
-
-function onPointerDown( event ) {
-
-	if ( ! this.enabled ) return;
-
-	if ( ! document.pointerLockElement ) {
-
-		this.domElement.setPointerCapture( event.pointerId );
-
-	}
-
-	this.domElement.addEventListener( 'pointermove', this._onPointerMove );
-
-	this.pointerHover( this._getPointer( event ) );
-	this.pointerDown( this._getPointer( event ) );
-
-}
-
-function onPointerMove( event ) {
-
-	if ( ! this.enabled ) return;
-
-	this.pointerMove( this._getPointer( event ) );
-
-}
-
-function onPointerUp( event ) {
-
-	if ( ! this.enabled ) return;
-
-	this.domElement.releasePointerCapture( event.pointerId );
-
-	this.domElement.removeEventListener( 'pointermove', this._onPointerMove );
-
-	this.pointerUp( this._getPointer( event ) );
-
-}
-
-function intersectObjectWithRay( object, raycaster, includeInvisible ) {
-
-	const allIntersections = raycaster.intersectObject( object, true );
-
-	for ( let i = 0; i < allIntersections.length; i ++ ) {
-
-		if ( allIntersections[ i ].object.visible || includeInvisible ) {
-
-			return allIntersections[ i ];
-
-		}
-
-	}
-
-	return false;
-
-}
-
-//
-
-// Reusable utility variables
-
-const _tempEuler = new Euler();
-const _alignVector = new Vector3( 0, 1, 0 );
-const _zeroVector = new Vector3( 0, 0, 0 );
-const _lookAtMatrix = new Matrix4();
-const _tempQuaternion2 = new Quaternion();
-const _identityQuaternion = new Quaternion();
-const _dirVector = new Vector3();
-const _tempMatrix = new Matrix4();
-
-const _unitX = new Vector3( 1, 0, 0 );
-const _unitY = new Vector3( 0, 1, 0 );
-const _unitZ = new Vector3( 0, 0, 1 );
-
-const _v1 = new Vector3();
-const _v2 = new Vector3();
-const _v3 = new Vector3();
-
-class TransformControlsRoot extends Object3D {
-
-	constructor( controls ) {
-
-		super();
-
-		this.isTransformControlsRoot = true;
-
-		this.controls = controls;
-		this.visible = false;
-
-	}
-
-	// updateMatrixWorld updates key transformation variables
-	updateMatrixWorld( force ) {
-
-		const controls = this.controls;
-
-		if ( controls.object !== undefined ) {
-
-			controls.object.updateMatrixWorld();
-
-			if ( controls.object.parent === null ) {
-
-				console.error( 'TransformControls: The attached 3D object must be a part of the scene graph.' );
-
-			} else {
-
-				controls.object.parent.matrixWorld.decompose( controls._parentPosition, controls._parentQuaternion, controls._parentScale );
-
-			}
-
-			controls.object.matrixWorld.decompose( controls.worldPosition, controls.worldQuaternion, controls._worldScale );
-
-			controls._parentQuaternionInv.copy( controls._parentQuaternion ).invert();
-			controls._worldQuaternionInv.copy( controls.worldQuaternion ).invert();
-
-		}
-
-		controls.camera.updateMatrixWorld();
-		controls.camera.matrixWorld.decompose( controls.cameraPosition, controls.cameraQuaternion, controls._cameraScale );
-
-		if ( controls.camera.isOrthographicCamera ) {
-
-			controls.camera.getWorldDirection( controls.eye ).negate();
-
-		} else {
-
-			controls.eye.copy( controls.cameraPosition ).sub( controls.worldPosition ).normalize();
-
-		}
-
-		super.updateMatrixWorld( force );
-
-	}
-
-	dispose() {
-
-		this.traverse( function ( child ) {
-
-			if ( child.geometry ) child.geometry.dispose();
-			if ( child.material ) child.material.dispose();
-
-		} );
-
-	}
-
-}
-
-class TransformControlsGizmo extends Object3D {
-
-	constructor() {
-
-		super();
-
-		this.isTransformControlsGizmo = true;
-
-		this.type = 'TransformControlsGizmo';
-
-		// shared materials
-
-		const gizmoMaterial = new MeshBasicMaterial( {
-			depthTest: false,
-			depthWrite: false,
-			fog: false,
-			toneMapped: false,
-			transparent: true
-		} );
-
-		const gizmoLineMaterial = new LineBasicMaterial( {
-			depthTest: false,
-			depthWrite: false,
-			fog: false,
-			toneMapped: false,
-			transparent: true
-		} );
-
-		// Make unique material for each axis/color
-
-		const matInvisible = gizmoMaterial.clone();
-		matInvisible.opacity = 0.15;
-
-		const matHelper = gizmoLineMaterial.clone();
-		matHelper.opacity = 0.5;
-
-		const matRed = gizmoMaterial.clone();
-		matRed.color.setHex( 0xff0000 );
-
-		const matGreen = gizmoMaterial.clone();
-		matGreen.color.setHex( 0x00ff00 );
-
-		const matBlue = gizmoMaterial.clone();
-		matBlue.color.setHex( 0x0000ff );
-
-		const matRedTransparent = gizmoMaterial.clone();
-		matRedTransparent.color.setHex( 0xff0000 );
-		matRedTransparent.opacity = 0.5;
-
-		const matGreenTransparent = gizmoMaterial.clone();
-		matGreenTransparent.color.setHex( 0x00ff00 );
-		matGreenTransparent.opacity = 0.5;
-
-		const matBlueTransparent = gizmoMaterial.clone();
-		matBlueTransparent.color.setHex( 0x0000ff );
-		matBlueTransparent.opacity = 0.5;
-
-		const matWhiteTransparent = gizmoMaterial.clone();
-		matWhiteTransparent.opacity = 0.25;
-
-		const matYellowTransparent = gizmoMaterial.clone();
-		matYellowTransparent.color.setHex( 0xffff00 );
-		matYellowTransparent.opacity = 0.25;
-
-		const matYellow = gizmoMaterial.clone();
-		matYellow.color.setHex( 0xffff00 );
-
-		const matGray = gizmoMaterial.clone();
-		matGray.color.setHex( 0x787878 );
-
-		// materials in the below property are configurable via setColors()
-
-		this.materialLib = {
-			xAxis: matRed,
-			yAxis: matGreen,
-			zAxis: matBlue,
-			active: matYellow,
-			xAxisTransparent: matRedTransparent,
-			yAxisTransparent: matGreenTransparent,
-			zAxisTransparent: matBlueTransparent,
-			activeTransparent: matYellowTransparent
-		};
-
-		// reusable geometry
-
-		const arrowGeometry = new CylinderGeometry( 0, 0.04, 0.1, 12 );
-		arrowGeometry.translate( 0, 0.05, 0 );
-
-		const scaleHandleGeometry = new BoxGeometry( 0.08, 0.08, 0.08 );
-		scaleHandleGeometry.translate( 0, 0.04, 0 );
-
-		const lineGeometry = new BufferGeometry();
-		lineGeometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0,	1, 0, 0 ], 3 ) );
-
-		const lineGeometry2 = new CylinderGeometry( 0.0075, 0.0075, 0.5, 3 );
-		lineGeometry2.translate( 0, 0.25, 0 );
-
-		function CircleGeometry( radius, arc ) {
-
-			const geometry = new TorusGeometry( radius, 0.0075, 3, 64, arc * Math.PI * 2 );
-			geometry.rotateY( Math.PI / 2 );
-			geometry.rotateX( Math.PI / 2 );
-			return geometry;
-
-		}
-
-		// Special geometry for transform helper. If scaled with position vector it spans from [0,0,0] to position
-
-		function TranslateHelperGeometry() {
-
-			const geometry = new BufferGeometry();
-
-			geometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 1, 1, 1 ], 3 ) );
-
-			return geometry;
-
-		}
-
-		// Gizmo definitions - custom hierarchy definitions for setupGizmo() function
-
-		const gizmoTranslate = {
-			X: [
-				[ new Mesh( arrowGeometry, matRed ), [ 0.5, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],
-				[ new Mesh( arrowGeometry, matRed ), [ - 0.5, 0, 0 ], [ 0, 0, Math.PI / 2 ]],
-				[ new Mesh( lineGeometry2, matRed ), [ 0, 0, 0 ], [ 0, 0, - Math.PI / 2 ]]
-			],
-			Y: [
-				[ new Mesh( arrowGeometry, matGreen ), [ 0, 0.5, 0 ]],
-				[ new Mesh( arrowGeometry, matGreen ), [ 0, - 0.5, 0 ], [ Math.PI, 0, 0 ]],
-				[ new Mesh( lineGeometry2, matGreen ) ]
-			],
-			Z: [
-				[ new Mesh( arrowGeometry, matBlue ), [ 0, 0, 0.5 ], [ Math.PI / 2, 0, 0 ]],
-				[ new Mesh( arrowGeometry, matBlue ), [ 0, 0, - 0.5 ], [ - Math.PI / 2, 0, 0 ]],
-				[ new Mesh( lineGeometry2, matBlue ), null, [ Math.PI / 2, 0, 0 ]]
-			],
-			XYZ: [
-				[ new Mesh( new OctahedronGeometry( 0.1, 0 ), matWhiteTransparent ), [ 0, 0, 0 ]]
-			],
-			XY: [
-				[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matBlueTransparent ), [ 0.15, 0.15, 0 ]]
-			],
-			YZ: [
-				[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matRedTransparent ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]]
-			],
-			XZ: [
-				[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matGreenTransparent ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]]
-			]
-		};
-
-		const pickerTranslate = {
-			X: [
-				[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0.3, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],
-				[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ - 0.3, 0, 0 ], [ 0, 0, Math.PI / 2 ]]
-			],
-			Y: [
-				[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0.3, 0 ]],
-				[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, - 0.3, 0 ], [ 0, 0, Math.PI ]]
-			],
-			Z: [
-				[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0, 0.3 ], [ Math.PI / 2, 0, 0 ]],
-				[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0, - 0.3 ], [ - Math.PI / 2, 0, 0 ]]
-			],
-			XYZ: [
-				[ new Mesh( new OctahedronGeometry( 0.2, 0 ), matInvisible ) ]
-			],
-			XY: [
-				[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0.15, 0.15, 0 ]]
-			],
-			YZ: [
-				[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]]
-			],
-			XZ: [
-				[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]]
-			]
-		};
-
-		const helperTranslate = {
-			START: [
-				[ new Mesh( new OctahedronGeometry( 0.01, 2 ), matHelper ), null, null, null, 'helper' ]
-			],
-			END: [
-				[ new Mesh( new OctahedronGeometry( 0.01, 2 ), matHelper ), null, null, null, 'helper' ]
-			],
-			DELTA: [
-				[ new Line( TranslateHelperGeometry(), matHelper ), null, null, null, 'helper' ]
-			],
-			X: [
-				[ new Line( lineGeometry, matHelper ), [ - 1e3, 0, 0 ], null, [ 1e6, 1, 1 ], 'helper' ]
-			],
-			Y: [
-				[ new Line( lineGeometry, matHelper ), [ 0, - 1e3, 0 ], [ 0, 0, Math.PI / 2 ], [ 1e6, 1, 1 ], 'helper' ]
-			],
-			Z: [
-				[ new Line( lineGeometry, matHelper ), [ 0, 0, - 1e3 ], [ 0, - Math.PI / 2, 0 ], [ 1e6, 1, 1 ], 'helper' ]
-			]
-		};
-
-		const gizmoRotate = {
-			XYZE: [
-				[ new Mesh( CircleGeometry( 0.5, 1 ), matGray ), null, [ 0, Math.PI / 2, 0 ]]
-			],
-			X: [
-				[ new Mesh( CircleGeometry( 0.5, 0.5 ), matRed ) ]
-			],
-			Y: [
-				[ new Mesh( CircleGeometry( 0.5, 0.5 ), matGreen ), null, [ 0, 0, - Math.PI / 2 ]]
-			],
-			Z: [
-				[ new Mesh( CircleGeometry( 0.5, 0.5 ), matBlue ), null, [ 0, Math.PI / 2, 0 ]]
-			],
-			E: [
-				[ new Mesh( CircleGeometry( 0.75, 1 ), matYellowTransparent ), null, [ 0, Math.PI / 2, 0 ]]
-			]
-		};
-
-		const helperRotate = {
-			AXIS: [
-				[ new Line( lineGeometry, matHelper ), [ - 1e3, 0, 0 ], null, [ 1e6, 1, 1 ], 'helper' ]
-			]
-		};
-
-		const pickerRotate = {
-			XYZE: [
-				[ new Mesh( new SphereGeometry( 0.25, 10, 8 ), matInvisible ) ]
-			],
-			X: [
-				[ new Mesh( new TorusGeometry( 0.5, 0.1, 4, 24 ), matInvisible ), [ 0, 0, 0 ], [ 0, - Math.PI / 2, - Math.PI / 2 ]],
-			],
-			Y: [
-				[ new Mesh( new TorusGeometry( 0.5, 0.1, 4, 24 ), matInvisible ), [ 0, 0, 0 ], [ Math.PI / 2, 0, 0 ]],
-			],
-			Z: [
-				[ new Mesh( new TorusGeometry( 0.5, 0.1, 4, 24 ), matInvisible ), [ 0, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],
-			],
-			E: [
-				[ new Mesh( new TorusGeometry( 0.75, 0.1, 2, 24 ), matInvisible ) ]
-			]
-		};
-
-		const gizmoScale = {
-			X: [
-				[ new Mesh( scaleHandleGeometry, matRed ), [ 0.5, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],
-				[ new Mesh( lineGeometry2, matRed ), [ 0, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],
-				[ new Mesh( scaleHandleGeometry, matRed ), [ - 0.5, 0, 0 ], [ 0, 0, Math.PI / 2 ]],
-			],
-			Y: [
-				[ new Mesh( scaleHandleGeometry, matGreen ), [ 0, 0.5, 0 ]],
-				[ new Mesh( lineGeometry2, matGreen ) ],
-				[ new Mesh( scaleHandleGeometry, matGreen ), [ 0, - 0.5, 0 ], [ 0, 0, Math.PI ]],
-			],
-			Z: [
-				[ new Mesh( scaleHandleGeometry, matBlue ), [ 0, 0, 0.5 ], [ Math.PI / 2, 0, 0 ]],
-				[ new Mesh( lineGeometry2, matBlue ), [ 0, 0, 0 ], [ Math.PI / 2, 0, 0 ]],
-				[ new Mesh( scaleHandleGeometry, matBlue ), [ 0, 0, - 0.5 ], [ - Math.PI / 2, 0, 0 ]]
-			],
-			XY: [
-				[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matBlueTransparent ), [ 0.15, 0.15, 0 ]]
-			],
-			YZ: [
-				[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matRedTransparent ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]]
-			],
-			XZ: [
-				[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matGreenTransparent ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]]
-			],
-			XYZ: [
-				[ new Mesh( new BoxGeometry( 0.1, 0.1, 0.1 ), matWhiteTransparent ) ],
-			]
-		};
-
-		const pickerScale = {
-			X: [
-				[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0.3, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],
-				[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ - 0.3, 0, 0 ], [ 0, 0, Math.PI / 2 ]]
-			],
-			Y: [
-				[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0.3, 0 ]],
-				[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, - 0.3, 0 ], [ 0, 0, Math.PI ]]
-			],
-			Z: [
-				[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0, 0.3 ], [ Math.PI / 2, 0, 0 ]],
-				[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0, - 0.3 ], [ - Math.PI / 2, 0, 0 ]]
-			],
-			XY: [
-				[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0.15, 0.15, 0 ]],
-			],
-			YZ: [
-				[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]],
-			],
-			XZ: [
-				[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]],
-			],
-			XYZ: [
-				[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.2 ), matInvisible ), [ 0, 0, 0 ]],
-			]
-		};
-
-		const helperScale = {
-			X: [
-				[ new Line( lineGeometry, matHelper ), [ - 1e3, 0, 0 ], null, [ 1e6, 1, 1 ], 'helper' ]
-			],
-			Y: [
-				[ new Line( lineGeometry, matHelper ), [ 0, - 1e3, 0 ], [ 0, 0, Math.PI / 2 ], [ 1e6, 1, 1 ], 'helper' ]
-			],
-			Z: [
-				[ new Line( lineGeometry, matHelper ), [ 0, 0, - 1e3 ], [ 0, - Math.PI / 2, 0 ], [ 1e6, 1, 1 ], 'helper' ]
-			]
-		};
-
-		// Creates an Object3D with gizmos described in custom hierarchy definition.
-
-		function setupGizmo( gizmoMap ) {
-
-			const gizmo = new Object3D();
-
-			for ( const name in gizmoMap ) {
-
-				for ( let i = gizmoMap[ name ].length; i --; ) {
-
-					const object = gizmoMap[ name ][ i ][ 0 ].clone();
-					const position = gizmoMap[ name ][ i ][ 1 ];
-					const rotation = gizmoMap[ name ][ i ][ 2 ];
-					const scale = gizmoMap[ name ][ i ][ 3 ];
-					const tag = gizmoMap[ name ][ i ][ 4 ];
-
-					// name and tag properties are essential for picking and updating logic.
-					object.name = name;
-					object.tag = tag;
-
-					if ( position ) {
-
-						object.position.set( position[ 0 ], position[ 1 ], position[ 2 ] );
-
-					}
-
-					if ( rotation ) {
-
-						object.rotation.set( rotation[ 0 ], rotation[ 1 ], rotation[ 2 ] );
-
-					}
-
-					if ( scale ) {
-
-						object.scale.set( scale[ 0 ], scale[ 1 ], scale[ 2 ] );
-
-					}
-
-					object.updateMatrix();
-
-					const tempGeometry = object.geometry.clone();
-					tempGeometry.applyMatrix4( object.matrix );
-					object.geometry = tempGeometry;
-					object.renderOrder = Infinity;
-
-					object.position.set( 0, 0, 0 );
-					object.rotation.set( 0, 0, 0 );
-					object.scale.set( 1, 1, 1 );
-
-					gizmo.add( object );
-
-				}
-
-			}
-
-			return gizmo;
-
-		}
-
-		// Gizmo creation
-
-		this.gizmo = {};
-		this.picker = {};
-		this.helper = {};
-
-		this.add( this.gizmo[ 'translate' ] = setupGizmo( gizmoTranslate ) );
-		this.add( this.gizmo[ 'rotate' ] = setupGizmo( gizmoRotate ) );
-		this.add( this.gizmo[ 'scale' ] = setupGizmo( gizmoScale ) );
-		this.add( this.picker[ 'translate' ] = setupGizmo( pickerTranslate ) );
-		this.add( this.picker[ 'rotate' ] = setupGizmo( pickerRotate ) );
-		this.add( this.picker[ 'scale' ] = setupGizmo( pickerScale ) );
-		this.add( this.helper[ 'translate' ] = setupGizmo( helperTranslate ) );
-		this.add( this.helper[ 'rotate' ] = setupGizmo( helperRotate ) );
-		this.add( this.helper[ 'scale' ] = setupGizmo( helperScale ) );
-
-		// Pickers should be hidden always
-
-		this.picker[ 'translate' ].visible = false;
-		this.picker[ 'rotate' ].visible = false;
-		this.picker[ 'scale' ].visible = false;
-
-	}
-
-	// updateMatrixWorld will update transformations and appearance of individual handles
-
-	updateMatrixWorld( force ) {
-
-		const space = ( this.mode === 'scale' ) ? 'local' : this.space; // scale always oriented to local rotation
-
-		const quaternion = ( space === 'local' ) ? this.worldQuaternion : _identityQuaternion;
-
-		// Show only gizmos for current transform mode
-
-		this.gizmo[ 'translate' ].visible = this.mode === 'translate';
-		this.gizmo[ 'rotate' ].visible = this.mode === 'rotate';
-		this.gizmo[ 'scale' ].visible = this.mode === 'scale';
-
-		this.helper[ 'translate' ].visible = this.mode === 'translate';
-		this.helper[ 'rotate' ].visible = this.mode === 'rotate';
-		this.helper[ 'scale' ].visible = this.mode === 'scale';
-
-
-		let handles = [];
-		handles = handles.concat( this.picker[ this.mode ].children );
-		handles = handles.concat( this.gizmo[ this.mode ].children );
-		handles = handles.concat( this.helper[ this.mode ].children );
-
-		for ( let i = 0; i < handles.length; i ++ ) {
-
-			const handle = handles[ i ];
-
-			// hide aligned to camera
-
-			handle.visible = true;
-			handle.rotation.set( 0, 0, 0 );
-			handle.position.copy( this.worldPosition );
-
-			let factor;
-
-			if ( this.camera.isOrthographicCamera ) {
-
-				factor = ( this.camera.top - this.camera.bottom ) / this.camera.zoom;
-
-			} else {
-
-				factor = this.worldPosition.distanceTo( this.cameraPosition ) * Math.min( 1.9 * Math.tan( Math.PI * this.camera.fov / 360 ) / this.camera.zoom, 7 );
-
-			}
-
-			handle.scale.set( 1, 1, 1 ).multiplyScalar( factor * this.size / 4 );
-
-			// TODO: simplify helpers and consider decoupling from gizmo
-
-			if ( handle.tag === 'helper' ) {
-
-				handle.visible = false;
-
-				if ( handle.name === 'AXIS' ) {
-
-					handle.visible = !! this.axis;
-
-					if ( this.axis === 'X' ) {
-
-						_tempQuaternion.setFromEuler( _tempEuler.set( 0, 0, 0 ) );
-						handle.quaternion.copy( quaternion ).multiply( _tempQuaternion );
-
-						if ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) {
-
-							handle.visible = false;
-
-						}
-
-					}
-
-					if ( this.axis === 'Y' ) {
-
-						_tempQuaternion.setFromEuler( _tempEuler.set( 0, 0, Math.PI / 2 ) );
-						handle.quaternion.copy( quaternion ).multiply( _tempQuaternion );
-
-						if ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) {
-
-							handle.visible = false;
-
-						}
-
-					}
-
-					if ( this.axis === 'Z' ) {
-
-						_tempQuaternion.setFromEuler( _tempEuler.set( 0, Math.PI / 2, 0 ) );
-						handle.quaternion.copy( quaternion ).multiply( _tempQuaternion );
-
-						if ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) {
-
-							handle.visible = false;
-
-						}
-
-					}
-
-					if ( this.axis === 'XYZE' ) {
-
-						_tempQuaternion.setFromEuler( _tempEuler.set( 0, Math.PI / 2, 0 ) );
-						_alignVector.copy( this.rotationAxis );
-						handle.quaternion.setFromRotationMatrix( _lookAtMatrix.lookAt( _zeroVector, _alignVector, _unitY ) );
-						handle.quaternion.multiply( _tempQuaternion );
-						handle.visible = this.dragging;
-
-					}
-
-					if ( this.axis === 'E' ) {
-
-						handle.visible = false;
-
-					}
-
-
-				} else if ( handle.name === 'START' ) {
-
-					handle.position.copy( this.worldPositionStart );
-					handle.visible = this.dragging;
-
-				} else if ( handle.name === 'END' ) {
-
-					handle.position.copy( this.worldPosition );
-					handle.visible = this.dragging;
-
-				} else if ( handle.name === 'DELTA' ) {
-
-					handle.position.copy( this.worldPositionStart );
-					handle.quaternion.copy( this.worldQuaternionStart );
-					_tempVector.set( 1e-10, 1e-10, 1e-10 ).add( this.worldPositionStart ).sub( this.worldPosition ).multiplyScalar( - 1 );
-					_tempVector.applyQuaternion( this.worldQuaternionStart.clone().invert() );
-					handle.scale.copy( _tempVector );
-					handle.visible = this.dragging;
-
-				} else {
-
-					handle.quaternion.copy( quaternion );
-
-					if ( this.dragging ) {
-
-						handle.position.copy( this.worldPositionStart );
-
-					} else {
-
-						handle.position.copy( this.worldPosition );
-
-					}
-
-					if ( this.axis ) {
-
-						handle.visible = this.axis.search( handle.name ) !== - 1;
-
-					}
-
-				}
-
-				// If updating helper, skip rest of the loop
-				continue;
-
-			}
-
-			// Align handles to current local or world rotation
-
-			handle.quaternion.copy( quaternion );
-
-			if ( this.mode === 'translate' || this.mode === 'scale' ) {
-
-				// Hide translate and scale axis facing the camera
-
-				const AXIS_HIDE_THRESHOLD = 0.99;
-				const PLANE_HIDE_THRESHOLD = 0.2;
-
-				if ( handle.name === 'X' ) {
-
-					if ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_THRESHOLD ) {
-
-						handle.scale.set( 1e-10, 1e-10, 1e-10 );
-						handle.visible = false;
-
-					}
-
-				}
-
-				if ( handle.name === 'Y' ) {
-
-					if ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_THRESHOLD ) {
-
-						handle.scale.set( 1e-10, 1e-10, 1e-10 );
-						handle.visible = false;
-
-					}
-
-				}
-
-				if ( handle.name === 'Z' ) {
-
-					if ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_THRESHOLD ) {
-
-						handle.scale.set( 1e-10, 1e-10, 1e-10 );
-						handle.visible = false;
-
-					}
-
-				}
-
-				if ( handle.name === 'XY' ) {
-
-					if ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_THRESHOLD ) {
-
-						handle.scale.set( 1e-10, 1e-10, 1e-10 );
-						handle.visible = false;
-
-					}
-
-				}
-
-				if ( handle.name === 'YZ' ) {
-
-					if ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_THRESHOLD ) {
-
-						handle.scale.set( 1e-10, 1e-10, 1e-10 );
-						handle.visible = false;
-
-					}
-
-				}
-
-				if ( handle.name === 'XZ' ) {
-
-					if ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_THRESHOLD ) {
-
-						handle.scale.set( 1e-10, 1e-10, 1e-10 );
-						handle.visible = false;
-
-					}
-
-				}
-
-			} else if ( this.mode === 'rotate' ) {
-
-				// Align handles to current local or world rotation
-
-				_tempQuaternion2.copy( quaternion );
-				_alignVector.copy( this.eye ).applyQuaternion( _tempQuaternion.copy( quaternion ).invert() );
-
-				if ( handle.name.search( 'E' ) !== - 1 ) {
-
-					handle.quaternion.setFromRotationMatrix( _lookAtMatrix.lookAt( this.eye, _zeroVector, _unitY ) );
-
-				}
-
-				if ( handle.name === 'X' ) {
-
-					_tempQuaternion.setFromAxisAngle( _unitX, Math.atan2( - _alignVector.y, _alignVector.z ) );
-					_tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion );
-					handle.quaternion.copy( _tempQuaternion );
-
-				}
-
-				if ( handle.name === 'Y' ) {
-
-					_tempQuaternion.setFromAxisAngle( _unitY, Math.atan2( _alignVector.x, _alignVector.z ) );
-					_tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion );
-					handle.quaternion.copy( _tempQuaternion );
-
-				}
-
-				if ( handle.name === 'Z' ) {
-
-					_tempQuaternion.setFromAxisAngle( _unitZ, Math.atan2( _alignVector.y, _alignVector.x ) );
-					_tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion );
-					handle.quaternion.copy( _tempQuaternion );
-
-				}
-
-			}
-
-			// Hide disabled axes
-			handle.visible = handle.visible && ( handle.name.indexOf( 'X' ) === - 1 || this.showX );
-			handle.visible = handle.visible && ( handle.name.indexOf( 'Y' ) === - 1 || this.showY );
-			handle.visible = handle.visible && ( handle.name.indexOf( 'Z' ) === - 1 || this.showZ );
-			handle.visible = handle.visible && ( handle.name.indexOf( 'E' ) === - 1 || ( this.showX && this.showY && this.showZ ) );
-
-			// Hide disabled plane helpers
-			handle.visible = handle.visible && ( handle.name.indexOf( 'XY' ) === - 1 || this.showXY );
-			handle.visible = handle.visible && ( handle.name.indexOf( 'YZ' ) === - 1 || this.showYZ );
-			handle.visible = handle.visible && ( handle.name.indexOf( 'XZ' ) === - 1 || this.showXZ );
-
-			// highlight selected axis
-
-			handle.material._color = handle.material._color || handle.material.color.clone();
-			handle.material._opacity = handle.material._opacity || handle.material.opacity;
-
-			handle.material.color.copy( handle.material._color );
-			handle.material.opacity = handle.material._opacity;
-
-			if ( this.enabled && this.axis ) {
-
-				if ( handle.name === this.axis ) {
-
-					handle.material.color.copy( this.materialLib.active.color );
-					handle.material.opacity = 1.0;
-
-				} else if ( this.axis.split( '' ).some( function ( a ) {
-
-					return handle.name === a;
-
-				} ) ) {
-
-					handle.material.color.copy( this.materialLib.active.color );
-					handle.material.opacity = 1.0;
-
-				}
-
-			}
-
-		}
-
-		super.updateMatrixWorld( force );
-
-	}
-
-}
-
-//
-
-class TransformControlsPlane extends Mesh {
-
-	constructor() {
-
-		super(
-			new PlaneGeometry( 100000, 100000, 2, 2 ),
-			new MeshBasicMaterial( { visible: false, wireframe: true, side: DoubleSide, transparent: true, opacity: 0.1, toneMapped: false } )
-		);
-
-		this.isTransformControlsPlane = true;
-
-		this.type = 'TransformControlsPlane';
-
-	}
-
-	updateMatrixWorld( force ) {
-
-		let space = this.space;
-
-		this.position.copy( this.worldPosition );
-
-		if ( this.mode === 'scale' ) space = 'local'; // scale always oriented to local rotation
-
-		_v1.copy( _unitX ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion );
-		_v2.copy( _unitY ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion );
-		_v3.copy( _unitZ ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion );
-
-		// Align the plane for current transform mode, axis and space.
-
-		_alignVector.copy( _v2 );
-
-		switch ( this.mode ) {
-
-			case 'translate':
-			case 'scale':
-				switch ( this.axis ) {
-
-					case 'X':
-						_alignVector.copy( this.eye ).cross( _v1 );
-						_dirVector.copy( _v1 ).cross( _alignVector );
-						break;
-					case 'Y':
-						_alignVector.copy( this.eye ).cross( _v2 );
-						_dirVector.copy( _v2 ).cross( _alignVector );
-						break;
-					case 'Z':
-						_alignVector.copy( this.eye ).cross( _v3 );
-						_dirVector.copy( _v3 ).cross( _alignVector );
-						break;
-					case 'XY':
-						_dirVector.copy( _v3 );
-						break;
-					case 'YZ':
-						_dirVector.copy( _v1 );
-						break;
-					case 'XZ':
-						_alignVector.copy( _v3 );
-						_dirVector.copy( _v2 );
-						break;
-					case 'XYZ':
-					case 'E':
-						_dirVector.set( 0, 0, 0 );
-						break;
-
-				}
-
-				break;
-			case 'rotate':
-			default:
-				// special case for rotate
-				_dirVector.set( 0, 0, 0 );
-
-		}
-
-		if ( _dirVector.length() === 0 ) {
-
-			// If in rotate mode, make the plane parallel to camera
-			this.quaternion.copy( this.cameraQuaternion );
-
-		} else {
-
-			_tempMatrix.lookAt( _tempVector.set( 0, 0, 0 ), _dirVector, _alignVector );
-
-			this.quaternion.setFromRotationMatrix( _tempMatrix );
-
-		}
-
-		super.updateMatrixWorld( force );
-
-	}
-
-}
-
-export { TransformControls, TransformControlsGizmo, TransformControlsPlane };

+ 0 - 598
node_modules/three/examples/jsm/csm/CSM.js

@@ -1,598 +0,0 @@
-import {
-	Vector2,
-	Vector3,
-	DirectionalLight,
-	MathUtils,
-	ShaderChunk,
-	Matrix4,
-	Box3
-} from 'three';
-import { CSMFrustum } from './CSMFrustum.js';
-import { CSMShader } from './CSMShader.js';
-
-const _cameraToLightMatrix = new Matrix4();
-const _lightSpaceFrustum = new CSMFrustum( { webGL: true } );
-const _center = new Vector3();
-const _origin = new Vector3();
-const _bbox = new Box3();
-const _uniformArray = [];
-const _logArray = [];
-const _lightOrientationMatrix = new Matrix4();
-const _lightOrientationMatrixInverse = new Matrix4();
-const _up = new Vector3( 0, 1, 0 );
-
-/**
- * An implementation of Cascade Shadow Maps (CSM).
- *
- * This module can only be used with {@link WebGLRenderer}. When using {@link WebGPURenderer},
- * use {@link CSMShadowNode} instead.
- *
- * @three_import import { CSM } from 'three/addons/csm/CSM.js';
- */
-export class CSM {
-
-	/**
-	 * Constructs a new CSM instance.
-	 *
-	 * @param {CSM~Data} data - The CSM data.
-	 */
-	constructor( data ) {
-
-		/**
-		 * The scene's camera.
-		 *
-		 * @type {Camera}
-		 */
-		this.camera = data.camera;
-
-		/**
-		 * The parent object, usually the scene.
-		 *
-		 * @type {Object3D}
-		 */
-		this.parent = data.parent;
-
-		/**
-		 * The number of cascades.
-		 *
-		 * @type {number}
-		 * @default 3
-		 */
-		this.cascades = data.cascades || 3;
-
-		/**
-		 * The maximum far value.
-		 *
-		 * @type {number}
-		 * @default 100000
-		 */
-		this.maxFar = data.maxFar || 100000;
-
-		/**
-		 * The frustum split mode.
-		 *
-		 * @type {('practical'|'uniform'|'logarithmic'|'custom')}
-		 * @default 'practical'
-		 */
-		this.mode = data.mode || 'practical';
-
-		/**
-		 * The shadow map size.
-		 *
-		 * @type {number}
-		 * @default 2048
-		 */
-		this.shadowMapSize = data.shadowMapSize || 2048;
-
-		/**
-		 * The shadow bias.
-		 *
-		 * @type {number}
-		 * @default 0.000001
-		 */
-		this.shadowBias = data.shadowBias || 0.000001;
-
-		/**
-		 * The light direction.
-		 *
-		 * @type {Vector3}
-		 */
-		this.lightDirection = data.lightDirection || new Vector3( 1, - 1, 1 ).normalize();
-
-		/**
-		 * The light intensity.
-		 *
-		 * @type {number}
-		 * @default 3
-		 */
-		this.lightIntensity = data.lightIntensity || 3;
-
-		/**
-		 * The light near value.
-		 *
-		 * @type {number}
-		 * @default 1
-		 */
-		this.lightNear = data.lightNear || 1;
-
-		/**
-		 * The light far value.
-		 *
-		 * @type {number}
-		 * @default 2000
-		 */
-		this.lightFar = data.lightFar || 2000;
-
-		/**
-		 * The light margin.
-		 *
-		 * @type {number}
-		 * @default 200
-		 */
-		this.lightMargin = data.lightMargin || 200;
-
-		/**
-		 * Custom split callback when using `mode='custom'`.
-		 *
-		 * @type {Function}
-		 */
-		this.customSplitsCallback = data.customSplitsCallback;
-
-		/**
-		 * Whether to fade between cascades or not.
-		 *
-		 * @type {boolean}
-		 * @default false
-		 */
-		this.fade = false;
-
-		/**
-		 * The main frustum.
-		 *
-		 * @type {CSMFrustum}
-		 */
-		this.mainFrustum = new CSMFrustum( { webGL: true } );
-
-		/**
-		 * An array of frustums representing the cascades.
-		 *
-		 * @type {Array<CSMFrustum>}
-		 */
-		this.frustums = [];
-
-		/**
-		 * An array of numbers in the range `[0,1]` the defines how the
-		 * mainCSM frustum should be split up.
-		 *
-		 * @type {Array<number>}
-		 */
-		this.breaks = [];
-
-		/**
-		 * An array of directional lights which cast the shadows for
-		 * the different cascades. There is one directional light for each
-		 * cascade.
-		 *
-		 * @type {Array<DirectionalLight>}
-		 */
-		this.lights = [];
-
-		/**
-		 * A Map holding enhanced material shaders.
-		 *
-		 * @type {Map<Material,Object>}
-		 */
-		this.shaders = new Map();
-
-		this._createLights();
-		this.updateFrustums();
-		this._injectInclude();
-
-	}
-
-	/**
-	 * Creates the directional lights of this CSM instance.
-	 *
-	 * @private
-	 */
-	_createLights() {
-
-		for ( let i = 0; i < this.cascades; i ++ ) {
-
-			const light = new DirectionalLight( 0xffffff, this.lightIntensity );
-			light.castShadow = true;
-			light.shadow.mapSize.width = this.shadowMapSize;
-			light.shadow.mapSize.height = this.shadowMapSize;
-
-			light.shadow.camera.near = this.lightNear;
-			light.shadow.camera.far = this.lightFar;
-			light.shadow.bias = this.shadowBias;
-
-			this.parent.add( light );
-			this.parent.add( light.target );
-			this.lights.push( light );
-
-		}
-
-	}
-
-	/**
-	 * Inits the cascades according to the scene's camera and breaks configuration.
-	 *
-	 * @private
-	 */
-	_initCascades() {
-
-		const camera = this.camera;
-		camera.updateProjectionMatrix();
-		this.mainFrustum.setFromProjectionMatrix( camera.projectionMatrix, this.maxFar );
-		this.mainFrustum.split( this.breaks, this.frustums );
-
-	}
-
-	/**
-	 * Updates the shadow bounds of this CSM instance.
-	 *
-	 * @private
-	 */
-	_updateShadowBounds() {
-
-		const frustums = this.frustums;
-		for ( let i = 0; i < frustums.length; i ++ ) {
-
-			const light = this.lights[ i ];
-			const shadowCam = light.shadow.camera;
-			const frustum = this.frustums[ i ];
-
-			// Get the two points that represent that furthest points on the frustum assuming
-			// that's either the diagonal across the far plane or the diagonal across the whole
-			// frustum itself.
-			const nearVerts = frustum.vertices.near;
-			const farVerts = frustum.vertices.far;
-			const point1 = farVerts[ 0 ];
-			let point2;
-			if ( point1.distanceTo( farVerts[ 2 ] ) > point1.distanceTo( nearVerts[ 2 ] ) ) {
-
-				point2 = farVerts[ 2 ];
-
-			} else {
-
-				point2 = nearVerts[ 2 ];
-
-			}
-
-			let squaredBBWidth = point1.distanceTo( point2 );
-			if ( this.fade ) {
-
-				// expand the shadow extents by the fade margin if fade is enabled.
-				const camera = this.camera;
-				const far = Math.max( camera.far, this.maxFar );
-				const linearDepth = frustum.vertices.far[ 0 ].z / ( far - camera.near );
-				const margin = 0.25 * Math.pow( linearDepth, 2.0 ) * ( far - camera.near );
-
-				squaredBBWidth += margin;
-
-			}
-
-			shadowCam.left = - squaredBBWidth / 2;
-			shadowCam.right = squaredBBWidth / 2;
-			shadowCam.top = squaredBBWidth / 2;
-			shadowCam.bottom = - squaredBBWidth / 2;
-			shadowCam.updateProjectionMatrix();
-
-		}
-
-	}
-
-	/**
-	 * Computes the breaks of this CSM instance based on the scene's camera, number of cascades
-	 * and the selected split mode.
-	 *
-	 * @private
-	 */
-	_getBreaks() {
-
-		const camera = this.camera;
-		const far = Math.min( camera.far, this.maxFar );
-		this.breaks.length = 0;
-
-		switch ( this.mode ) {
-
-			case 'uniform':
-				uniformSplit( this.cascades, camera.near, far, this.breaks );
-				break;
-			case 'logarithmic':
-				logarithmicSplit( this.cascades, camera.near, far, this.breaks );
-				break;
-			case 'practical':
-				practicalSplit( this.cascades, camera.near, far, 0.5, this.breaks );
-				break;
-			case 'custom':
-				if ( this.customSplitsCallback === undefined ) console.error( 'CSM: Custom split scheme callback not defined.' );
-				this.customSplitsCallback( this.cascades, camera.near, far, this.breaks );
-				break;
-
-		}
-
-		function uniformSplit( amount, near, far, target ) {
-
-			for ( let i = 1; i < amount; i ++ ) {
-
-				target.push( ( near + ( far - near ) * i / amount ) / far );
-
-			}
-
-			target.push( 1 );
-
-		}
-
-		function logarithmicSplit( amount, near, far, target ) {
-
-			for ( let i = 1; i < amount; i ++ ) {
-
-				target.push( ( near * ( far / near ) ** ( i / amount ) ) / far );
-
-			}
-
-			target.push( 1 );
-
-		}
-
-		function practicalSplit( amount, near, far, lambda, target ) {
-
-			_uniformArray.length = 0;
-			_logArray.length = 0;
-			logarithmicSplit( amount, near, far, _logArray );
-			uniformSplit( amount, near, far, _uniformArray );
-
-			for ( let i = 1; i < amount; i ++ ) {
-
-				target.push( MathUtils.lerp( _uniformArray[ i - 1 ], _logArray[ i - 1 ], lambda ) );
-
-			}
-
-			target.push( 1 );
-
-		}
-
-	}
-
-	/**
-	 * Updates the CSM. This method must be called in your animation loop before
-	 * calling `renderer.render()`.
-	 */
-	update() {
-
-		const camera = this.camera;
-		const frustums = this.frustums;
-
-		// for each frustum we need to find its min-max box aligned with the light orientation
-		// the position in _lightOrientationMatrix does not matter, as we transform there and back
-		_lightOrientationMatrix.lookAt( _origin, this.lightDirection, _up );
-		_lightOrientationMatrixInverse.copy( _lightOrientationMatrix ).invert();
-
-		for ( let i = 0; i < frustums.length; i ++ ) {
-
-			const light = this.lights[ i ];
-			const shadowCam = light.shadow.camera;
-			const texelWidth = ( shadowCam.right - shadowCam.left ) / this.shadowMapSize;
-			const texelHeight = ( shadowCam.top - shadowCam.bottom ) / this.shadowMapSize;
-			_cameraToLightMatrix.multiplyMatrices( _lightOrientationMatrixInverse, camera.matrixWorld );
-			frustums[ i ].toSpace( _cameraToLightMatrix, _lightSpaceFrustum );
-
-			const nearVerts = _lightSpaceFrustum.vertices.near;
-			const farVerts = _lightSpaceFrustum.vertices.far;
-			_bbox.makeEmpty();
-			for ( let j = 0; j < 4; j ++ ) {
-
-				_bbox.expandByPoint( nearVerts[ j ] );
-				_bbox.expandByPoint( farVerts[ j ] );
-
-			}
-
-			_bbox.getCenter( _center );
-			_center.z = _bbox.max.z + this.lightMargin;
-			_center.x = Math.floor( _center.x / texelWidth ) * texelWidth;
-			_center.y = Math.floor( _center.y / texelHeight ) * texelHeight;
-			_center.applyMatrix4( _lightOrientationMatrix );
-
-			light.position.copy( _center );
-			light.target.position.copy( _center );
-
-			light.target.position.x += this.lightDirection.x;
-			light.target.position.y += this.lightDirection.y;
-			light.target.position.z += this.lightDirection.z;
-
-		}
-
-	}
-
-	/**
-	 * Injects the CSM shader enhancements into the built-in materials.
-	 *
-	 * @private
-	 */
-	_injectInclude() {
-
-		ShaderChunk.lights_fragment_begin = CSMShader.lights_fragment_begin;
-		ShaderChunk.lights_pars_begin = CSMShader.lights_pars_begin;
-
-	}
-
-	/**
-	 * Applications must call this method for all materials that should be affected by CSM.
-	 *
-	 * @param {Material} material - The material to setup for CSM support.
-	 */
-	setupMaterial( material ) {
-
-		material.defines = material.defines || {};
-		material.defines.USE_CSM = 1;
-		material.defines.CSM_CASCADES = this.cascades;
-
-		if ( this.fade ) {
-
-			material.defines.CSM_FADE = '';
-
-		}
-
-		const breaksVec2 = [];
-		const scope = this;
-		const shaders = this.shaders;
-
-		material.onBeforeCompile = function ( shader ) {
-
-			const far = Math.min( scope.camera.far, scope.maxFar );
-			scope._getExtendedBreaks( breaksVec2 );
-
-			shader.uniforms.CSM_cascades = { value: breaksVec2 };
-			shader.uniforms.cameraNear = { value: scope.camera.near };
-			shader.uniforms.shadowFar = { value: far };
-
-			shaders.set( material, shader );
-
-		};
-
-		shaders.set( material, null );
-
-	}
-
-	/**
-	 * Updates the CSM uniforms.
-	 *
-	 * @private
-	 */
-	_updateUniforms() {
-
-		const far = Math.min( this.camera.far, this.maxFar );
-		const shaders = this.shaders;
-
-		shaders.forEach( function ( shader, material ) {
-
-			if ( shader !== null ) {
-
-				const uniforms = shader.uniforms;
-				this._getExtendedBreaks( uniforms.CSM_cascades.value );
-				uniforms.cameraNear.value = this.camera.near;
-				uniforms.shadowFar.value = far;
-
-			}
-
-			if ( ! this.fade && 'CSM_FADE' in material.defines ) {
-
-				delete material.defines.CSM_FADE;
-				material.needsUpdate = true;
-
-			} else if ( this.fade && ! ( 'CSM_FADE' in material.defines ) ) {
-
-				material.defines.CSM_FADE = '';
-				material.needsUpdate = true;
-
-			}
-
-		}, this );
-
-	}
-
-	/**
-	 * Computes the extended breaks for the CSM uniforms.
-	 *
-	 * @private
-	 * @param {Array<Vector2>} target - The target array that holds the extended breaks.
-	 */
-	_getExtendedBreaks( target ) {
-
-		while ( target.length < this.breaks.length ) {
-
-			target.push( new Vector2() );
-
-		}
-
-		target.length = this.breaks.length;
-
-		for ( let i = 0; i < this.cascades; i ++ ) {
-
-			const amount = this.breaks[ i ];
-			const prev = this.breaks[ i - 1 ] || 0;
-			target[ i ].x = prev;
-			target[ i ].y = amount;
-
-		}
-
-	}
-
-	/**
-	 * Applications must call this method every time they change camera or CSM settings.
-	 */
-	updateFrustums() {
-
-		this._getBreaks();
-		this._initCascades();
-		this._updateShadowBounds();
-		this._updateUniforms();
-
-	}
-
-	/**
-	 * Applications must call this method when they remove the CSM usage from their scene.
-	 */
-	remove() {
-
-		for ( let i = 0; i < this.lights.length; i ++ ) {
-
-			this.parent.remove( this.lights[ i ].target );
-			this.parent.remove( this.lights[ i ] );
-
-		}
-
-	}
-
-	/**
-	 * Frees the GPU-related resources allocated by this instance. Call this
-	 * method whenever this instance is no longer used in your app.
-	 */
-	dispose() {
-
-		const shaders = this.shaders;
-		shaders.forEach( function ( shader, material ) {
-
-			delete material.onBeforeCompile;
-			delete material.defines.USE_CSM;
-			delete material.defines.CSM_CASCADES;
-			delete material.defines.CSM_FADE;
-
-			if ( shader !== null ) {
-
-				delete shader.uniforms.CSM_cascades;
-				delete shader.uniforms.cameraNear;
-				delete shader.uniforms.shadowFar;
-
-			}
-
-			material.needsUpdate = true;
-
-		} );
-		shaders.clear();
-
-	}
-
-}
-
-/**
- * Constructor data of `CSM`.
- *
- * @typedef {Object} CSM~Data
- * @property {Camera} camera - The scene's camera.
- * @property {Object3D} parent - The parent object, usually the scene.
- * @property {number} [cascades=3] - The number of cascades.
- * @property {number} [maxFar=100000] - The maximum far value.
- * @property {('practical'|'uniform'|'logarithmic'|'custom')} [mode='practical'] - The frustum split mode.
- * @property {Function} [customSplitsCallback] - Custom split callback when using `mode='custom'`.
- * @property {number} [shadowMapSize=2048] - The shadow map size.
- * @property {number} [shadowBias=0.000001] - The shadow bias.
- * @property {Vector3} [lightDirection] - The light direction.
- * @property {number} [lightIntensity=3] - The light intensity.
- * @property {number} [lightNear=1] - The light near value.
- * @property {number} [lightNear=2000] - The light far value.
- * @property {number} [lightMargin=200] - The light margin.
- **/

+ 0 - 209
node_modules/three/examples/jsm/csm/CSMFrustum.js

@@ -1,209 +0,0 @@
-import { Vector3, Matrix4 } from 'three';
-
-const inverseProjectionMatrix = new Matrix4();
-
-/**
- * Represents the frustum of a CSM instance.
- *
- * @three_import import { CSMFrustum } from 'three/addons/csm/CSMFrustum.js';
- */
-class CSMFrustum {
-
-	/**
-	 * Constructs a new CSM frustum.
-	 *
-	 * @param {CSMFrustum~Data} [data] - The CSM data.
-	 */
-	constructor( data ) {
-
-		data = data || {};
-
-		/**
-		 * The zNear value. This value depends on whether the CSM
-		 * is used with WebGL or WebGPU. Both API use different
-		 * conventions for their projection matrices.
-		 *
-		 * @type {number}
-		 */
-		this.zNear = data.webGL === true ? - 1 : 0;
-
-		/**
-		 * An object representing the vertices of the near and
-		 * far plane in view space.
-		 *
-		 * @type {Object}
-		 */
-		this.vertices = {
-			near: [
-				new Vector3(),
-				new Vector3(),
-				new Vector3(),
-				new Vector3()
-			],
-			far: [
-				new Vector3(),
-				new Vector3(),
-				new Vector3(),
-				new Vector3()
-			]
-		};
-
-		if ( data.projectionMatrix !== undefined ) {
-
-			this.setFromProjectionMatrix( data.projectionMatrix, data.maxFar || 10000 );
-
-		}
-
-	}
-
-	/**
-	 * Setups this CSM frustum from the given projection matrix and max far value.
-	 *
-	 * @param {Matrix4} projectionMatrix - The projection matrix, usually of the scene's camera.
-	 * @param {number} maxFar - The maximum far value.
-	 * @returns {Object} An object representing the vertices of the near and far plane in view space.
-	 */
-	setFromProjectionMatrix( projectionMatrix, maxFar ) {
-
-		const zNear = this.zNear;
-		const isOrthographic = projectionMatrix.elements[ 2 * 4 + 3 ] === 0;
-
-		inverseProjectionMatrix.copy( projectionMatrix ).invert();
-
-		// 3 --- 0  vertices.near/far order
-		// |     |
-		// 2 --- 1
-		// clip space spans from [-1, 1]
-
-		this.vertices.near[ 0 ].set( 1, 1, zNear );
-		this.vertices.near[ 1 ].set( 1, - 1, zNear );
-		this.vertices.near[ 2 ].set( - 1, - 1, zNear );
-		this.vertices.near[ 3 ].set( - 1, 1, zNear );
-		this.vertices.near.forEach( function ( v ) {
-
-			v.applyMatrix4( inverseProjectionMatrix );
-
-		} );
-
-		this.vertices.far[ 0 ].set( 1, 1, 1 );
-		this.vertices.far[ 1 ].set( 1, - 1, 1 );
-		this.vertices.far[ 2 ].set( - 1, - 1, 1 );
-		this.vertices.far[ 3 ].set( - 1, 1, 1 );
-		this.vertices.far.forEach( function ( v ) {
-
-			v.applyMatrix4( inverseProjectionMatrix );
-
-			const absZ = Math.abs( v.z );
-			if ( isOrthographic ) {
-
-				v.z *= Math.min( maxFar / absZ, 1.0 );
-
-			} else {
-
-				v.multiplyScalar( Math.min( maxFar / absZ, 1.0 ) );
-
-			}
-
-		} );
-
-		return this.vertices;
-
-	}
-
-	/**
-	 * Splits the CSM frustum by the given array. The new CSM frustum are pushed into the given
-	 * target array.
-	 *
-	 * @param {Array<number>} breaks - An array of numbers in the range `[0,1]` the defines how the
-	 * CSM frustum should be split up.
-	 * @param {Array<CSMFrustum>} target - The target array that holds the new CSM frustums.
-	 */
-	split( breaks, target ) {
-
-		while ( breaks.length > target.length ) {
-
-			target.push( new CSMFrustum() );
-
-		}
-
-		target.length = breaks.length;
-
-		for ( let i = 0; i < breaks.length; i ++ ) {
-
-			const cascade = target[ i ];
-
-			if ( i === 0 ) {
-
-				for ( let j = 0; j < 4; j ++ ) {
-
-					cascade.vertices.near[ j ].copy( this.vertices.near[ j ] );
-
-				}
-
-			} else {
-
-				for ( let j = 0; j < 4; j ++ ) {
-
-					cascade.vertices.near[ j ].lerpVectors( this.vertices.near[ j ], this.vertices.far[ j ], breaks[ i - 1 ] );
-
-				}
-
-			}
-
-			if ( i === breaks.length - 1 ) {
-
-				for ( let j = 0; j < 4; j ++ ) {
-
-					cascade.vertices.far[ j ].copy( this.vertices.far[ j ] );
-
-				}
-
-			} else {
-
-				for ( let j = 0; j < 4; j ++ ) {
-
-					cascade.vertices.far[ j ].lerpVectors( this.vertices.near[ j ], this.vertices.far[ j ], breaks[ i ] );
-
-				}
-
-			}
-
-		}
-
-	}
-
-	/**
-	 * Transforms the given target CSM frustum into the different coordinate system defined by the
-	 * given camera matrix.
-	 *
-	 * @param {Matrix4} cameraMatrix - The matrix that defines the new coordinate system.
-	 * @param {CSMFrustum} target - The CSM to convert.
-	 */
-	toSpace( cameraMatrix, target ) {
-
-		for ( let i = 0; i < 4; i ++ ) {
-
-			target.vertices.near[ i ]
-				.copy( this.vertices.near[ i ] )
-				.applyMatrix4( cameraMatrix );
-
-			target.vertices.far[ i ]
-				.copy( this.vertices.far[ i ] )
-				.applyMatrix4( cameraMatrix );
-
-		}
-
-	}
-
-}
-
-/**
- * Constructor data of `CSMFrustum`.
- *
- * @typedef {Object} CSMFrustum~Data
- * @property {boolean} [webGL] - Whether this CSM frustum is used with WebGL or WebGPU.
- * @property {Matrix4} [projectionMatrix] - A projection matrix usually of the scene's camera.
- * @property {number} [maxFar] - The maximum far value.
- **/
-
-export { CSMFrustum };

+ 0 - 243
node_modules/three/examples/jsm/csm/CSMHelper.js

@@ -1,243 +0,0 @@
-import {
-	Group,
-	Mesh,
-	LineSegments,
-	BufferGeometry,
-	LineBasicMaterial,
-	Box3Helper,
-	Box3,
-	PlaneGeometry,
-	MeshBasicMaterial,
-	BufferAttribute,
-	DoubleSide
-} from 'three';
-
-/**
- * A helper for visualizing the cascades of a CSM instance.
- *
- * @augments Group
- * @three_import import { CSMHelper } from 'three/addons/csm/CSMHelper.js';
- */
-class CSMHelper extends Group {
-
-	/**
-	 * Constructs a new CSM helper.
-	 *
-	 * @param {CSM|CSMShadowNode} csm - The CSM instance to visualize.
-	 */
-	constructor( csm ) {
-
-		super();
-
-		/**
-		 * The CSM instance to visualize.
-		 *
-		 * @type {CSM|CSMShadowNode}
-		 */
-		this.csm = csm;
-
-		/**
-		 * Whether to display the CSM frustum or not.
-		 *
-		 * @type {boolean}
-		 * @default true
-		 */
-		this.displayFrustum = true;
-
-		/**
-		 * Whether to display the cascade planes or not.
-		 *
-		 * @type {boolean}
-		 * @default true
-		 */
-		this.displayPlanes = true;
-
-		/**
-		 * Whether to display the shadow bounds or not.
-		 *
-		 * @type {boolean}
-		 * @default true
-		 */
-		this.displayShadowBounds = true;
-
-		const indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );
-		const positions = new Float32Array( 24 );
-		const frustumGeometry = new BufferGeometry();
-		frustumGeometry.setIndex( new BufferAttribute( indices, 1 ) );
-		frustumGeometry.setAttribute( 'position', new BufferAttribute( positions, 3, false ) );
-		const frustumLines = new LineSegments( frustumGeometry, new LineBasicMaterial() );
-		this.add( frustumLines );
-
-		this.frustumLines = frustumLines;
-		this.cascadeLines = [];
-		this.cascadePlanes = [];
-		this.shadowLines = [];
-
-	}
-
-	/**
-	 * This method must be called if one of the `display*` properties is changed at runtime.
-	 */
-	updateVisibility() {
-
-		const displayFrustum = this.displayFrustum;
-		const displayPlanes = this.displayPlanes;
-		const displayShadowBounds = this.displayShadowBounds;
-
-		const frustumLines = this.frustumLines;
-		const cascadeLines = this.cascadeLines;
-		const cascadePlanes = this.cascadePlanes;
-		const shadowLines = this.shadowLines;
-		for ( let i = 0, l = cascadeLines.length; i < l; i ++ ) {
-
-			const cascadeLine = cascadeLines[ i ];
-			const cascadePlane = cascadePlanes[ i ];
-			const shadowLineGroup = shadowLines[ i ];
-
-			cascadeLine.visible = displayFrustum;
-			cascadePlane.visible = displayFrustum && displayPlanes;
-			shadowLineGroup.visible = displayShadowBounds;
-
-		}
-
-		frustumLines.visible = displayFrustum;
-
-	}
-
-	/**
-	 * Updates the helper. This method should be called in the app's animation loop.
-	 */
-	update() {
-
-		const csm = this.csm;
-		const camera = csm.camera;
-		const cascades = csm.cascades;
-		const mainFrustum = csm.mainFrustum;
-		const frustums = csm.frustums;
-		const lights = csm.lights;
-
-		const frustumLines = this.frustumLines;
-		const frustumLinePositions = frustumLines.geometry.getAttribute( 'position' );
-		const cascadeLines = this.cascadeLines;
-		const cascadePlanes = this.cascadePlanes;
-		const shadowLines = this.shadowLines;
-
-		if ( camera === null ) return;
-
-		this.position.copy( camera.position );
-		this.quaternion.copy( camera.quaternion );
-		this.scale.copy( camera.scale );
-		this.updateMatrixWorld( true );
-
-		while ( cascadeLines.length > cascades ) {
-
-			this.remove( cascadeLines.pop() );
-			this.remove( cascadePlanes.pop() );
-			this.remove( shadowLines.pop() );
-
-		}
-
-		while ( cascadeLines.length < cascades ) {
-
-			const cascadeLine = new Box3Helper( new Box3(), 0xffffff );
-			const planeMat = new MeshBasicMaterial( { transparent: true, opacity: 0.1, depthWrite: false, side: DoubleSide } );
-			const cascadePlane = new Mesh( new PlaneGeometry(), planeMat );
-			const shadowLineGroup = new Group();
-			const shadowLine = new Box3Helper( new Box3(), 0xffff00 );
-			shadowLineGroup.add( shadowLine );
-
-			this.add( cascadeLine );
-			this.add( cascadePlane );
-			this.add( shadowLineGroup );
-
-			cascadeLines.push( cascadeLine );
-			cascadePlanes.push( cascadePlane );
-			shadowLines.push( shadowLineGroup );
-
-		}
-
-		for ( let i = 0; i < cascades; i ++ ) {
-
-			const frustum = frustums[ i ];
-			const light = lights[ i ];
-			const shadowCam = light.shadow.camera;
-			const farVerts = frustum.vertices.far;
-
-			const cascadeLine = cascadeLines[ i ];
-			const cascadePlane = cascadePlanes[ i ];
-			const shadowLineGroup = shadowLines[ i ];
-			const shadowLine = shadowLineGroup.children[ 0 ];
-
-			cascadeLine.box.min.copy( farVerts[ 2 ] );
-			cascadeLine.box.max.copy( farVerts[ 0 ] );
-			cascadeLine.box.max.z += 1e-4;
-
-			cascadePlane.position.addVectors( farVerts[ 0 ], farVerts[ 2 ] );
-			cascadePlane.position.multiplyScalar( 0.5 );
-			cascadePlane.scale.subVectors( farVerts[ 0 ], farVerts[ 2 ] );
-			cascadePlane.scale.z = 1e-4;
-
-			this.remove( shadowLineGroup );
-			shadowLineGroup.position.copy( shadowCam.position );
-			shadowLineGroup.quaternion.copy( shadowCam.quaternion );
-			shadowLineGroup.scale.copy( shadowCam.scale );
-			shadowLineGroup.updateMatrixWorld( true );
-			this.attach( shadowLineGroup );
-
-			shadowLine.box.min.set( shadowCam.bottom, shadowCam.left, - shadowCam.far );
-			shadowLine.box.max.set( shadowCam.top, shadowCam.right, - shadowCam.near );
-
-		}
-
-		const nearVerts = mainFrustum.vertices.near;
-		const farVerts = mainFrustum.vertices.far;
-		frustumLinePositions.setXYZ( 0, farVerts[ 0 ].x, farVerts[ 0 ].y, farVerts[ 0 ].z );
-		frustumLinePositions.setXYZ( 1, farVerts[ 3 ].x, farVerts[ 3 ].y, farVerts[ 3 ].z );
-		frustumLinePositions.setXYZ( 2, farVerts[ 2 ].x, farVerts[ 2 ].y, farVerts[ 2 ].z );
-		frustumLinePositions.setXYZ( 3, farVerts[ 1 ].x, farVerts[ 1 ].y, farVerts[ 1 ].z );
-
-		frustumLinePositions.setXYZ( 4, nearVerts[ 0 ].x, nearVerts[ 0 ].y, nearVerts[ 0 ].z );
-		frustumLinePositions.setXYZ( 5, nearVerts[ 3 ].x, nearVerts[ 3 ].y, nearVerts[ 3 ].z );
-		frustumLinePositions.setXYZ( 6, nearVerts[ 2 ].x, nearVerts[ 2 ].y, nearVerts[ 2 ].z );
-		frustumLinePositions.setXYZ( 7, nearVerts[ 1 ].x, nearVerts[ 1 ].y, nearVerts[ 1 ].z );
-		frustumLinePositions.needsUpdate = true;
-
-	}
-
-	/**
-	 * Frees the GPU-related resources allocated by this instance. Call this
-	 * method whenever this instance is no longer used in your app.
-	 */
-	dispose() {
-
-		const frustumLines = this.frustumLines;
-		const cascadeLines = this.cascadeLines;
-		const cascadePlanes = this.cascadePlanes;
-		const shadowLines = this.shadowLines;
-
-		frustumLines.geometry.dispose();
-		frustumLines.material.dispose();
-
-		const cascades = this.csm.cascades;
-
-		for ( let i = 0; i < cascades; i ++ ) {
-
-			const cascadeLine = cascadeLines[ i ];
-			const cascadePlane = cascadePlanes[ i ];
-			const shadowLineGroup = shadowLines[ i ];
-			const shadowLine = shadowLineGroup.children[ 0 ];
-
-			cascadeLine.dispose(); // Box3Helper
-
-			cascadePlane.geometry.dispose();
-			cascadePlane.material.dispose();
-
-			shadowLine.dispose(); // Box3Helper
-
-		}
-
-	}
-
-}
-
-export { CSMHelper };

+ 0 - 307
node_modules/three/examples/jsm/csm/CSMShader.js

@@ -1,307 +0,0 @@
-import { ShaderChunk } from 'three';
-
-/**
- * @module CSMShader
- * @three_import import { CSMShader } from 'three/addons/csm/CSMShader.js';
- */
-
-/**
- * The object that holds the GLSL enhancements to enable CSM. This
- * code is injected into the built-in material shaders by {@link CSM}.
- *
- * @type {Object}
- */
-const CSMShader = {
-	lights_fragment_begin: /* glsl */`
-vec3 geometryPosition = - vViewPosition;
-vec3 geometryNormal = normal;
-vec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );
-
-vec3 geometryClearcoatNormal = vec3( 0.0 );
-
-#ifdef USE_CLEARCOAT
-
-	geometryClearcoatNormal = clearcoatNormal;
-
-#endif
-
-#ifdef USE_IRIDESCENCE
-	float dotNVi = saturate( dot( normal, geometryViewDir ) );
-	if ( material.iridescenceThickness == 0.0 ) {
-		material.iridescence = 0.0;
-	} else {
-		material.iridescence = saturate( material.iridescence );
-	}
-	if ( material.iridescence > 0.0 ) {
-		material.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );
-		// Iridescence F0 approximation
-		material.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );
-	}
-#endif
-
-IncidentLight directLight;
-
-#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )
-
-	PointLight pointLight;
-	#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0
-	PointLightShadow pointLightShadow;
-	#endif
-
-	#pragma unroll_loop_start
-	for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {
-
-		pointLight = pointLights[ i ];
-
-		getPointLightInfo( pointLight, geometryPosition, directLight );
-
-		#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )
-		pointLightShadow = pointLightShadows[ i ];
-		directLight.color *= ( directLight.visible && receiveShadow ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowIntensity, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;
-
-		#endif
-
-		RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );
-
-	}
-	#pragma unroll_loop_end
-
-#endif
-
-#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )
-
-	SpotLight spotLight;
- 	vec4 spotColor;
-	vec3 spotLightCoord;
-	bool inSpotLightMap;
-
-	#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0
-	SpotLightShadow spotLightShadow;
-	#endif
-
-	#pragma unroll_loop_start
-	for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {
-
-		spotLight = spotLights[ i ];
-
-		getSpotLightInfo( spotLight, geometryPosition, directLight );
-
-  		// spot lights are ordered [shadows with maps, shadows without maps, maps without shadows, none]
-		#if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )
-		#define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX
-		#elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )
-		#define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS
-		#else
-		#define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )
-		#endif
-		#if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS )
-			spotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w;
-			inSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) );
-			spotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy );
-			directLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color;
-		#endif
-		#undef SPOT_LIGHT_MAP_INDEX
-
-		#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )
-		spotLightShadow = spotLightShadows[ i ];
-		directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowIntensity, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;
-
-		#endif
-
-		RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );
-
-	}
-	#pragma unroll_loop_end
-
-#endif
-
-#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct ) && defined( USE_CSM ) && defined( CSM_CASCADES )
-
-	DirectionalLight directionalLight;
-	float linearDepth = (vViewPosition.z) / (shadowFar - cameraNear);
-	#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0
-	DirectionalLightShadow directionalLightShadow;
-	#endif
-
-	#if defined( USE_SHADOWMAP ) && defined( CSM_FADE )
-		vec2 cascade;
-		float cascadeCenter;
-		float closestEdge;
-		float margin;
-		float csmx;
-		float csmy;
-
-		#pragma unroll_loop_start
-		for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {
-
-			directionalLight = directionalLights[ i ];
-			getDirectionalLightInfo( directionalLight, directLight );
-
-			#if ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )
-				// NOTE: Depth gets larger away from the camera.
-				// cascade.x is closer, cascade.y is further
-				cascade = CSM_cascades[ i ];
-				cascadeCenter = ( cascade.x + cascade.y ) / 2.0;
-				closestEdge = linearDepth < cascadeCenter ? cascade.x : cascade.y;
-				margin = 0.25 * pow( closestEdge, 2.0 );
-				csmx = cascade.x - margin / 2.0;
-				csmy = cascade.y + margin / 2.0;
-				if( linearDepth >= csmx && ( linearDepth < csmy || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 ) ) {
-
-					float dist = min( linearDepth - csmx, csmy - linearDepth );
-					float ratio = clamp( dist / margin, 0.0, 1.0 );
-
-					vec3 prevColor = directLight.color;
-					directionalLightShadow = directionalLightShadows[ i ];
-					directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
-
-					bool shouldFadeLastCascade = UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 && linearDepth > cascadeCenter;
-					directLight.color = mix( prevColor, directLight.color, shouldFadeLastCascade ? ratio : 1.0 );
-
-					ReflectedLight prevLight = reflectedLight;
-					RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );
-
-					bool shouldBlend = UNROLLED_LOOP_INDEX != CSM_CASCADES - 1 || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 && linearDepth < cascadeCenter;
-					float blendRatio = shouldBlend ? ratio : 1.0;
-
-					reflectedLight.directDiffuse = mix( prevLight.directDiffuse, reflectedLight.directDiffuse, blendRatio );
-					reflectedLight.directSpecular = mix( prevLight.directSpecular, reflectedLight.directSpecular, blendRatio );
-					reflectedLight.indirectDiffuse = mix( prevLight.indirectDiffuse, reflectedLight.indirectDiffuse, blendRatio );
-					reflectedLight.indirectSpecular = mix( prevLight.indirectSpecular, reflectedLight.indirectSpecular, blendRatio );
-
-				}
-			#endif
-
-		}
-		#pragma unroll_loop_end
-	#elif defined (USE_SHADOWMAP)
-
-		#pragma unroll_loop_start
-		for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {
-
-			directionalLight = directionalLights[ i ];
-			getDirectionalLightInfo( directionalLight, directLight );
-
-			#if ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )
-
-				directionalLightShadow = directionalLightShadows[ i ];
-				if(linearDepth >= CSM_cascades[UNROLLED_LOOP_INDEX].x && linearDepth < CSM_cascades[UNROLLED_LOOP_INDEX].y) directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
-
-				if(linearDepth >= CSM_cascades[UNROLLED_LOOP_INDEX].x && (linearDepth < CSM_cascades[UNROLLED_LOOP_INDEX].y || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1)) RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );
-
-			#endif
-
-		}
-		#pragma unroll_loop_end
-
-	#elif ( NUM_DIR_LIGHT_SHADOWS > 0 )
-		// note: no loop here - all CSM lights are in fact one light only
-		getDirectionalLightInfo( directionalLights[0], directLight );
-		RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );
-
-	#endif
-
-	#if ( NUM_DIR_LIGHTS > NUM_DIR_LIGHT_SHADOWS)
-		// compute the lights not casting shadows (if any)
-
-		#pragma unroll_loop_start
-		for ( int i = NUM_DIR_LIGHT_SHADOWS; i < NUM_DIR_LIGHTS; i ++ ) {
-
-			directionalLight = directionalLights[ i ];
-
-			getDirectionalLightInfo( directionalLight, directLight );
-
-			RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );
-
-		}
-		#pragma unroll_loop_end
-
-	#endif
-
-#endif
-
-
-#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct ) && !defined( USE_CSM ) && !defined( CSM_CASCADES )
-
-	DirectionalLight directionalLight;
-	#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0
-	DirectionalLightShadow directionalLightShadow;
-	#endif
-
-	#pragma unroll_loop_start
-	for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {
-
-		directionalLight = directionalLights[ i ];
-
-		getDirectionalLightInfo( directionalLight, directLight );
-
-		#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )
-		directionalLightShadow = directionalLightShadows[ i ];
-		directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
-		#endif
-
-		RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );
-
-	}
-	#pragma unroll_loop_end
-
-#endif
-
-#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )
-
-	RectAreaLight rectAreaLight;
-
-	#pragma unroll_loop_start
-	for ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {
-
-		rectAreaLight = rectAreaLights[ i ];
-		RE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );
-
-	}
-	#pragma unroll_loop_end
-
-#endif
-
-#if defined( RE_IndirectDiffuse )
-
-	vec3 iblIrradiance = vec3( 0.0 );
-
-	vec3 irradiance = getAmbientLightIrradiance( ambientLightColor );
-
-	#if defined( USE_LIGHT_PROBES )
-
-		irradiance += getLightProbeIrradiance( lightProbe, geometryNormal );
-
-	#endif
-
-	#if ( NUM_HEMI_LIGHTS > 0 )
-
-		#pragma unroll_loop_start
-		for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {
-
-			irradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal );
-
-		}
-		#pragma unroll_loop_end
-
-	#endif
-
-#endif
-
-#if defined( RE_IndirectSpecular )
-
-	vec3 radiance = vec3( 0.0 );
-	vec3 clearcoatRadiance = vec3( 0.0 );
-
-#endif
-`,
-	lights_pars_begin: /* glsl */`
-#if defined( USE_CSM ) && defined( CSM_CASCADES )
-uniform vec2 CSM_cascades[CSM_CASCADES];
-uniform float cameraNear;
-uniform float shadowFar;
-#endif
-	` + ShaderChunk.lights_pars_begin
-};
-
-export { CSMShader };

+ 0 - 603
node_modules/three/examples/jsm/csm/CSMShadowNode.js

@@ -1,603 +0,0 @@
-import {
-	Vector2,
-	Vector3,
-	MathUtils,
-	Matrix4,
-	Box3,
-	Object3D,
-	WebGLCoordinateSystem,
-	ShadowBaseNode
-} from 'three/webgpu';
-
-import { CSMFrustum } from './CSMFrustum.js';
-import { viewZToOrthographicDepth, reference, uniform, float, vec4, vec2, If, Fn, min, renderGroup, positionView, shadow } from 'three/tsl';
-
-const _cameraToLightMatrix = new Matrix4();
-const _lightSpaceFrustum = new CSMFrustum();
-const _center = new Vector3();
-const _bbox = new Box3();
-const _uniformArray = [];
-const _logArray = [];
-const _lightDirection = new Vector3();
-const _lightOrientationMatrix = new Matrix4();
-const _lightOrientationMatrixInverse = new Matrix4();
-const _up = new Vector3( 0, 1, 0 );
-
-class LwLight extends Object3D {
-
-	constructor() {
-
-		super();
-
-		this.target = new Object3D();
-
-	}
-
-}
-
-/**
- * An implementation of Cascade Shadow Maps (CSM).
- *
- * This module can only be used with {@link WebGPURenderer}. When using {@link WebGLRenderer},
- * use {@link CSM} instead.
- *
- * @augments ShadowBaseNode
- * @three_import import { CSMShadowNode } from 'three/addons/csm/CSMShadowNode.js';
- */
-class CSMShadowNode extends ShadowBaseNode {
-
-	/**
-	 * Constructs a new CSM shadow node.
-	 *
-	 * @param {DirectionalLight} light - The CSM light.
-	 * @param {CSMShadowNode~Data} [data={}] - The CSM data.
-	 */
-	constructor( light, data = {} ) {
-
-		super( light );
-
-		/**
-		 * The scene's camera.
-		 *
-		 * @type {?Camera}
-		 * @default null
-		 */
-		this.camera = null;
-
-		/**
-		 * The number of cascades.
-		 *
-		 * @type {number}
-		 * @default 3
-		 */
-		this.cascades = data.cascades || 3;
-
-		/**
-		 * The maximum far value.
-		 *
-		 * @type {number}
-		 * @default 100000
-		 */
-		this.maxFar = data.maxFar || 100000;
-
-		/**
-		 * The frustum split mode.
-		 *
-		 * @type {('practical'|'uniform'|'logarithmic'|'custom')}
-		 * @default 'practical'
-		 */
-		this.mode = data.mode || 'practical';
-
-		/**
-		 * The light margin.
-		 *
-		 * @type {number}
-		 * @default 200
-		 */
-		this.lightMargin = data.lightMargin || 200;
-
-		/**
-		 * Custom split callback when using `mode='custom'`.
-		 *
-		 * @type {Function}
-		 */
-		this.customSplitsCallback = data.customSplitsCallback;
-
-		/**
-		 * Whether to fade between cascades or not.
-		 *
-		 * @type {boolean}
-		 * @default false
-		 */
-		this.fade = false;
-
-		/**
-		 * An array of numbers in the range `[0,1]` the defines how the
-		 * mainCSM frustum should be split up.
-		 *
-		 * @type {Array<number>}
-		 */
-		this.breaks = [];
-
-		this._cascades = [];
-
-		/**
-		 * The main frustum.
-		 *
-		 * @type {?CSMFrustum}
-		 * @default null
-		 */
-		this.mainFrustum = null;
-
-		/**
-		 * An array of frustums representing the cascades.
-		 *
-		 * @type {Array<CSMFrustum>}
-		 */
-		this.frustums = [];
-
-		/**
-		 * An array of directional lights which cast the shadows for
-		 * the different cascades. There is one directional light for each
-		 * cascade.
-		 *
-		 * @type {Array<DirectionalLight>}
-		 */
-		this.lights = [];
-
-		this._shadowNodes = [];
-
-	}
-
-	/**
-	 * Inits the CSM shadow node.
-	 *
-	 * @private
-	 * @param {NodeBuilder} builder - The node builder.
-	 */
-	_init( { camera, renderer } ) {
-
-		this.camera = camera;
-
-		const data = { webGL: renderer.coordinateSystem === WebGLCoordinateSystem };
-		this.mainFrustum = new CSMFrustum( data );
-
-		const light = this.light;
-
-		for ( let i = 0; i < this.cascades; i ++ ) {
-
-			const lwLight = new LwLight();
-			lwLight.castShadow = true;
-
-			const lShadow = light.shadow.clone();
-			lShadow.bias = lShadow.bias * ( i + 1 );
-
-			this.lights.push( lwLight );
-
-			lwLight.shadow = lShadow;
-
-			this._shadowNodes.push( shadow( lwLight, lShadow ) );
-
-			this._cascades.push( new Vector2() );
-
-		}
-
-		this.updateFrustums();
-
-	}
-
-	/**
-	 * Inits the cascades according to the scene's camera and breaks configuration.
-	 *
-	 * @private
-	 */
-	_initCascades() {
-
-		const camera = this.camera;
-		camera.updateProjectionMatrix();
-
-		this.mainFrustum.setFromProjectionMatrix( camera.projectionMatrix, this.maxFar );
-		this.mainFrustum.split( this.breaks, this.frustums );
-
-	}
-
-	/**
-	 * Computes the breaks of this CSM instance based on the scene's camera, number of cascades
-	 * and the selected split mode.
-	 *
-	 * @private
-	 */
-	_getBreaks() {
-
-		const camera = this.camera;
-		const far = Math.min( camera.far, this.maxFar );
-
-		this.breaks.length = 0;
-
-		switch ( this.mode ) {
-
-			case 'uniform':
-				uniformSplit( this.cascades, camera.near, far, this.breaks );
-				break;
-
-			case 'logarithmic':
-				logarithmicSplit( this.cascades, camera.near, far, this.breaks );
-				break;
-
-			case 'practical':
-				practicalSplit( this.cascades, camera.near, far, 0.5, this.breaks );
-				break;
-
-			case 'custom':
-				if ( this.customSplitsCallback === undefined ) console.error( 'CSM: Custom split scheme callback not defined.' );
-				this.customSplitsCallback( this.cascades, camera.near, far, this.breaks );
-				break;
-
-		}
-
-		function uniformSplit( amount, near, far, target ) {
-
-			for ( let i = 1; i < amount; i ++ ) {
-
-				target.push( ( near + ( far - near ) * i / amount ) / far );
-
-			}
-
-			target.push( 1 );
-
-		}
-
-		function logarithmicSplit( amount, near, far, target ) {
-
-			for ( let i = 1; i < amount; i ++ ) {
-
-				target.push( ( near * ( far / near ) ** ( i / amount ) ) / far );
-
-			}
-
-			target.push( 1 );
-
-		}
-
-		function practicalSplit( amount, near, far, lambda, target ) {
-
-			_uniformArray.length = 0;
-			_logArray.length = 0;
-			logarithmicSplit( amount, near, far, _logArray );
-			uniformSplit( amount, near, far, _uniformArray );
-
-			for ( let i = 1; i < amount; i ++ ) {
-
-				target.push( MathUtils.lerp( _uniformArray[ i - 1 ], _logArray[ i - 1 ], lambda ) );
-
-			}
-
-			target.push( 1 );
-
-		}
-
-	}
-
-	/**
-	 * Sets the light breaks.
-	 *
-	 * @private
-	 */
-	_setLightBreaks() {
-
-		for ( let i = 0, l = this.cascades; i < l; i ++ ) {
-
-			const amount = this.breaks[ i ];
-			const prev = this.breaks[ i - 1 ] || 0;
-
-			this._cascades[ i ].set( prev, amount );
-
-		}
-
-	}
-
-	/**
-	 * Updates the shadow bounds of this CSM instance.
-	 *
-	 * @private
-	 */
-	_updateShadowBounds() {
-
-		const frustums = this.frustums;
-
-		for ( let i = 0; i < frustums.length; i ++ ) {
-
-			const shadowCam = this.lights[ i ].shadow.camera;
-			const frustum = this.frustums[ i ];
-
-			// Get the two points that represent that furthest points on the frustum assuming
-			// that's either the diagonal across the far plane or the diagonal across the whole
-			// frustum itself.
-			const nearVerts = frustum.vertices.near;
-			const farVerts = frustum.vertices.far;
-			const point1 = farVerts[ 0 ];
-
-			let point2;
-
-			if ( point1.distanceTo( farVerts[ 2 ] ) > point1.distanceTo( nearVerts[ 2 ] ) ) {
-
-				point2 = farVerts[ 2 ];
-
-			} else {
-
-				point2 = nearVerts[ 2 ];
-
-			}
-
-			let squaredBBWidth = point1.distanceTo( point2 );
-
-			if ( this.fade ) {
-
-				// expand the shadow extents by the fade margin if fade is enabled.
-				const camera = this.camera;
-				const far = Math.max( camera.far, this.maxFar );
-				const linearDepth = frustum.vertices.far[ 0 ].z / ( far - camera.near );
-				const margin = 0.25 * Math.pow( linearDepth, 2.0 ) * ( far - camera.near );
-
-				squaredBBWidth += margin;
-
-			}
-
-			shadowCam.left = - squaredBBWidth / 2;
-			shadowCam.right = squaredBBWidth / 2;
-			shadowCam.top = squaredBBWidth / 2;
-			shadowCam.bottom = - squaredBBWidth / 2;
-			shadowCam.updateProjectionMatrix();
-
-		}
-
-	}
-
-	/**
-	 * Applications must call this method every time they change camera or CSM settings.
-	 */
-	updateFrustums() {
-
-		this._getBreaks();
-		this._initCascades();
-		this._updateShadowBounds();
-		this._setLightBreaks();
-
-	}
-
-	/**
-	 * Setups the TSL when using fading.
-	 *
-	 * @private
-	 * @return {ShaderCallNodeInternal}
-	 */
-	_setupFade() {
-
-		const cameraNear = reference( 'camera.near', 'float', this ).setGroup( renderGroup );
-		const cascades = reference( '_cascades', 'vec2', this ).setGroup( renderGroup ).setName( 'cascades' );
-
-		const shadowFar = uniform( 'float' ).setGroup( renderGroup ).setName( 'shadowFar' )
-			.onRenderUpdate( () => Math.min( this.maxFar, this.camera.far ) );
-
-		const linearDepth = viewZToOrthographicDepth( positionView.z, cameraNear, shadowFar ).toVar( 'linearDepth' );
-		const lastCascade = this.cascades - 1;
-
-		return Fn( ( builder ) => {
-
-			this.setupShadowPosition( builder );
-
-			const ret = vec4( 1, 1, 1, 1 ).toVar( 'shadowValue' );
-
-			const cascade = vec2().toVar( 'cascade' );
-			const cascadeCenter = float().toVar( 'cascadeCenter' );
-
-			const margin = float().toVar( 'margin' );
-
-			const csmX = float().toVar( 'csmX' );
-			const csmY = float().toVar( 'csmY' );
-
-			for ( let i = 0; i < this.cascades; i ++ ) {
-
-				const isLastCascade = i === lastCascade;
-
-				cascade.assign( cascades.element( i ) );
-
-				cascadeCenter.assign( cascade.x.add( cascade.y ).div( 2.0 ) );
-
-				const closestEdge = linearDepth.lessThan( cascadeCenter ).select( cascade.x, cascade.y );
-
-				margin.assign( float( 0.25 ).mul( closestEdge.pow( 2.0 ) ) );
-
-				csmX.assign( cascade.x.sub( margin.div( 2.0 ) ) );
-
-				if ( isLastCascade ) {
-
-					csmY.assign( cascade.y );
-
-				} else {
-
-					csmY.assign( cascade.y.add( margin.div( 2.0 ) ) );
-
-				}
-
-				const inRange = linearDepth.greaterThanEqual( csmX ).and( linearDepth.lessThanEqual( csmY ) );
-
-				If( inRange, () => {
-
-					const dist = min( linearDepth.sub( csmX ), csmY.sub( linearDepth ) ).toVar();
-
-					let ratio = dist.div( margin ).clamp( 0.0, 1.0 );
-
-					if ( i === 0 ) {
-
-						// don't fade at nearest edge
-						ratio = linearDepth.greaterThan( cascadeCenter ).select( ratio, 1 );
-
-					}
-
-					ret.subAssign( this._shadowNodes[ i ].oneMinus().mul( ratio ) );
-
-				} );
-
-			}
-
-			return ret;
-
-		} )();
-
-	}
-
-	/**
-	 * Setups the TSL when no fading (default).
-	 *
-	 * @private
-	 * @return {ShaderCallNodeInternal}
-	 */
-	_setupStandard() {
-
-		const cameraNear = reference( 'camera.near', 'float', this ).setGroup( renderGroup );
-		const cascades = reference( '_cascades', 'vec2', this ).setGroup( renderGroup ).setName( 'cascades' );
-
-		const shadowFar = uniform( 'float' ).setGroup( renderGroup ).setName( 'shadowFar' )
-			.onRenderUpdate( () => Math.min( this.maxFar, this.camera.far ) );
-
-		const linearDepth = viewZToOrthographicDepth( positionView.z, cameraNear, shadowFar ).toVar( 'linearDepth' );
-
-		return Fn( ( builder ) => {
-
-			this.setupShadowPosition( builder );
-
-			const ret = vec4( 1, 1, 1, 1 ).toVar( 'shadowValue' );
-			const cascade = vec2().toVar( 'cascade' );
-
-			for ( let i = 0; i < this.cascades; i ++ ) {
-
-				cascade.assign( cascades.element( i ) );
-
-				If( linearDepth.greaterThanEqual( cascade.x ).and( linearDepth.lessThanEqual( cascade.y ) ), () => {
-
-					ret.assign( this._shadowNodes[ i ] );
-
-				} );
-
-			}
-
-			return ret;
-
-		} )();
-
-	}
-
-	setup( builder ) {
-
-		if ( this.camera === null ) this._init( builder );
-
-		return this.fade === true ? this._setupFade() : this._setupStandard();
-
-	}
-
-	updateBefore( /*builder*/ ) {
-
-		const light = this.light;
-		const parent = light.parent;
-		const camera = this.camera;
-		const frustums = this.frustums;
-
-		// make sure the placeholder light objects which represent the
-		// multiple cascade shadow casters are part of the scene graph
-
-		for ( let i = 0; i < this.lights.length; i ++ ) {
-
-			const lwLight = this.lights[ i ];
-
-			if ( lwLight.parent === null ) {
-
-				parent.add( lwLight.target );
-				parent.add( lwLight );
-
-			}
-
-		}
-
-		_lightDirection.subVectors( light.target.position, light.position ).normalize();
-
-		// for each frustum we need to find its min-max box aligned with the light orientation
-		// the position in _lightOrientationMatrix does not matter, as we transform there and back
-		_lightOrientationMatrix.lookAt( light.position, light.target.position, _up );
-		_lightOrientationMatrixInverse.copy( _lightOrientationMatrix ).invert();
-
-		for ( let i = 0; i < frustums.length; i ++ ) {
-
-			const lwLight = this.lights[ i ];
-			const shadow = lwLight.shadow;
-			const shadowCam = shadow.camera;
-			const texelWidth = ( shadowCam.right - shadowCam.left ) / shadow.mapSize.width;
-			const texelHeight = ( shadowCam.top - shadowCam.bottom ) / shadow.mapSize.height;
-
-			_cameraToLightMatrix.multiplyMatrices( _lightOrientationMatrixInverse, camera.matrixWorld );
-			frustums[ i ].toSpace( _cameraToLightMatrix, _lightSpaceFrustum );
-
-			const nearVerts = _lightSpaceFrustum.vertices.near;
-			const farVerts = _lightSpaceFrustum.vertices.far;
-
-			_bbox.makeEmpty();
-
-			for ( let j = 0; j < 4; j ++ ) {
-
-				_bbox.expandByPoint( nearVerts[ j ] );
-				_bbox.expandByPoint( farVerts[ j ] );
-
-			}
-
-			_bbox.getCenter( _center );
-			_center.z = _bbox.max.z + this.lightMargin;
-			_center.x = Math.floor( _center.x / texelWidth ) * texelWidth;
-			_center.y = Math.floor( _center.y / texelHeight ) * texelHeight;
-			_center.applyMatrix4( _lightOrientationMatrix );
-
-			lwLight.position.copy( _center );
-			lwLight.target.position.copy( _center );
-			lwLight.target.position.add( _lightDirection );
-
-		}
-
-	}
-
-	/**
-	 * Frees the GPU-related resources allocated by this instance. Call this
-	 * method whenever this instance is no longer used in your app.
-	 */
-	dispose() {
-
-		for ( let i = 0; i < this.lights.length; i ++ ) {
-
-			const light = this.lights[ i ];
-			const parent = light.parent;
-
-			if ( parent !== null ) {
-
-				parent.remove( light.target );
-				parent.remove( light );
-
-			}
-
-		}
-
-		super.dispose();
-
-	}
-
-}
-
-/**
- * Constructor data of `CSMShadowNode`.
- *
- * @typedef {Object} CSMShadowNode~Data
- * @property {number} [cascades=3] - The number of cascades.
- * @property {number} [maxFar=100000] - The maximum far value.
- * @property {('practical'|'uniform'|'logarithmic'|'custom')} [mode='practical'] - The frustum split mode.
- * @property {Function} [customSplitsCallback] - Custom split callback when using `mode='custom'`.
- * @property {number} [lightMargin=200] - The light margin.
- **/
-
-export { CSMShadowNode };

+ 0 - 694
node_modules/three/examples/jsm/curves/CurveExtras.js

@@ -1,694 +0,0 @@
-import {
-	Curve,
-	Vector3
-} from 'three';
-
-/**
- * A bunch of parametric curves
- *
- * Formulas collected from various sources
- * http://mathworld.wolfram.com/HeartCurve.html
- * http://en.wikipedia.org/wiki/Viviani%27s_curve
- * http://www.mi.sanu.ac.rs/vismath/taylorapril2011/Taylor.pdf
- * https://prideout.net/blog/old/blog/index.html@p=44.html
- */
-
-/**
- * A Granny Knot curve.
- *
- * @augments Curve
- * @three_import import { GrannyKnot } from 'three/addons/curves/CurveExtras.js';
- */
-class GrannyKnot extends Curve {
-
-	/**
-	 * This method returns a vector in 3D space for the given interpolation factor.
-	 *
-	 * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
-	 * @param {Vector3} [optionalTarget] - The optional target vector the result is written to.
-	 * @return {Vector3} The position on the curve.
-	 */
-	getPoint( t, optionalTarget = new Vector3() ) {
-
-		const point = optionalTarget;
-
-		t = 2 * Math.PI * t;
-
-		const x = - 0.22 * Math.cos( t ) - 1.28 * Math.sin( t ) - 0.44 * Math.cos( 3 * t ) - 0.78 * Math.sin( 3 * t );
-		const y = - 0.1 * Math.cos( 2 * t ) - 0.27 * Math.sin( 2 * t ) + 0.38 * Math.cos( 4 * t ) + 0.46 * Math.sin( 4 * t );
-		const z = 0.7 * Math.cos( 3 * t ) - 0.4 * Math.sin( 3 * t );
-
-		return point.set( x, y, z ).multiplyScalar( 20 );
-
-	}
-
-}
-
-/**
- * A heart curve.
- *
- * @augments Curve
- * @three_import import { HeartCurve } from 'three/addons/curves/CurveExtras.js';
- */
-class HeartCurve extends Curve {
-
-	/**
-	 * Constructs a new heart curve.
-	 *
-	 * @param {number} [scale=5] - The curve's scale.
-	 */
-	constructor( scale = 5 ) {
-
-		super();
-
-		/**
-		 * The curve's scale.
-		 *
-		 * @type {number}
-		 * @default 5
-		 */
-		this.scale = scale;
-
-	}
-
-	/**
-	 * This method returns a vector in 3D space for the given interpolation factor.
-	 *
-	 * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
-	 * @param {Vector3} [optionalTarget] - The optional target vector the result is written to.
-	 * @return {Vector3} The position on the curve.
-	 */
-	getPoint( t, optionalTarget = new Vector3() ) {
-
-		const point = optionalTarget;
-
-		t *= 2 * Math.PI;
-
-		const x = 16 * Math.pow( Math.sin( t ), 3 );
-		const y = 13 * Math.cos( t ) - 5 * Math.cos( 2 * t ) - 2 * Math.cos( 3 * t ) - Math.cos( 4 * t );
-		const z = 0;
-
-		return point.set( x, y, z ).multiplyScalar( this.scale );
-
-	}
-
-}
-
-/**
- * A Viviani curve.
- *
- * @augments Curve
- * @three_import import { VivianiCurve } from 'three/addons/curves/CurveExtras.js';
- */
-class VivianiCurve extends Curve {
-
-	/**
-	 * Constructs a new Viviani curve.
-	 *
-	 * @param {number} [scale=70] - The curve's scale.
-	 */
-	constructor( scale = 70 ) {
-
-		super();
-
-		/**
-		 * The curve's scale.
-		 *
-		 * @type {number}
-		 * @default 70
-		 */
-		this.scale = scale;
-
-	}
-
-	/**
-	 * This method returns a vector in 3D space for the given interpolation factor.
-	 *
-	 * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
-	 * @param {Vector3} [optionalTarget] - The optional target vector the result is written to.
-	 * @return {Vector3} The position on the curve.
-	 */
-	getPoint( t, optionalTarget = new Vector3() ) {
-
-		const point = optionalTarget;
-
-		t = t * 4 * Math.PI; // normalized to 0..1
-		const a = this.scale / 2;
-
-		const x = a * ( 1 + Math.cos( t ) );
-		const y = a * Math.sin( t );
-		const z = 2 * a * Math.sin( t / 2 );
-
-		return point.set( x, y, z );
-
-	}
-
-}
-
-/**
- * A knot curve.
- *
- * @augments Curve
- * @three_import import { KnotCurve } from 'three/addons/curves/CurveExtras.js';
- */
-class KnotCurve extends Curve {
-
-	/**
-	 * This method returns a vector in 3D space for the given interpolation factor.
-	 *
-	 * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
-	 * @param {Vector3} [optionalTarget] - The optional target vector the result is written to.
-	 * @return {Vector3} The position on the curve.
-	 */
-	getPoint( t, optionalTarget = new Vector3() ) {
-
-		const point = optionalTarget;
-
-		t *= 2 * Math.PI;
-
-		const R = 10;
-		const s = 50;
-
-		const x = s * Math.sin( t );
-		const y = Math.cos( t ) * ( R + s * Math.cos( t ) );
-		const z = Math.sin( t ) * ( R + s * Math.cos( t ) );
-
-		return point.set( x, y, z );
-
-	}
-
-}
-
-/**
- * A helix curve.
- *
- * @augments Curve
- * @three_import import { HelixCurve } from 'three/addons/curves/CurveExtras.js';
- */
-class HelixCurve extends Curve {
-
-	/**
-	 * This method returns a vector in 3D space for the given interpolation factor.
-	 *
-	 * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
-	 * @param {Vector3} [optionalTarget] - The optional target vector the result is written to.
-	 * @return {Vector3} The position on the curve.
-	 */
-	getPoint( t, optionalTarget = new Vector3() ) {
-
-		const point = optionalTarget;
-
-		const a = 30; // radius
-		const b = 150; // height
-
-		const t2 = 2 * Math.PI * t * b / 30;
-
-		const x = Math.cos( t2 ) * a;
-		const y = Math.sin( t2 ) * a;
-		const z = b * t;
-
-		return point.set( x, y, z );
-
-	}
-
-}
-
-/**
- * A Trefoil Knot.
- *
- * @augments Curve
- * @three_import import { TrefoilKnot } from 'three/addons/curves/CurveExtras.js';
- */
-class TrefoilKnot extends Curve {
-
-	/**
-	 * Constructs a new Trefoil Knot.
-	 *
-	 * @param {number} [scale=10] - The curve's scale.
-	 */
-	constructor( scale = 10 ) {
-
-		super();
-
-		/**
-		 * The curve's scale.
-		 *
-		 * @type {number}
-		 * @default 10
-		 */
-		this.scale = scale;
-
-	}
-
-	/**
-	 * This method returns a vector in 3D space for the given interpolation factor.
-	 *
-	 * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
-	 * @param {Vector3} [optionalTarget] - The optional target vector the result is written to.
-	 * @return {Vector3} The position on the curve.
-	 */
-	getPoint( t, optionalTarget = new Vector3() ) {
-
-		const point = optionalTarget;
-
-		t *= Math.PI * 2;
-
-		const x = ( 2 + Math.cos( 3 * t ) ) * Math.cos( 2 * t );
-		const y = ( 2 + Math.cos( 3 * t ) ) * Math.sin( 2 * t );
-		const z = Math.sin( 3 * t );
-
-		return point.set( x, y, z ).multiplyScalar( this.scale );
-
-	}
-
-}
-
-/**
- * A torus knot.
- *
- * @augments Curve
- * @three_import import { TorusKnot } from 'three/addons/curves/CurveExtras.js';
- */
-class TorusKnot extends Curve {
-
-	/**
-	 * Constructs a new torus knot.
-	 *
-	 * @param {number} [scale=10] - The curve's scale.
-	 */
-	constructor( scale = 10 ) {
-
-		super();
-
-		/**
-		 * The curve's scale.
-		 *
-		 * @type {number}
-		 * @default 10
-		 */
-		this.scale = scale;
-
-	}
-
-	/**
-	 * This method returns a vector in 3D space for the given interpolation factor.
-	 *
-	 * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
-	 * @param {Vector3} [optionalTarget] - The optional target vector the result is written to.
-	 * @return {Vector3} The position on the curve.
-	 */
-	getPoint( t, optionalTarget = new Vector3() ) {
-
-		const point = optionalTarget;
-
-		const p = 3;
-		const q = 4;
-
-		t *= Math.PI * 2;
-
-		const x = ( 2 + Math.cos( q * t ) ) * Math.cos( p * t );
-		const y = ( 2 + Math.cos( q * t ) ) * Math.sin( p * t );
-		const z = Math.sin( q * t );
-
-		return point.set( x, y, z ).multiplyScalar( this.scale );
-
-	}
-
-}
-
-/**
- * A Cinquefoil Knot.
- *
- * @augments Curve
- * @three_import import { CinquefoilKnot } from 'three/addons/curves/CurveExtras.js';
- */
-class CinquefoilKnot extends Curve {
-
-	/**
-	 * Constructs a new Cinquefoil Knot.
-	 *
-	 * @param {number} [scale=10] - The curve's scale.
-	 */
-	constructor( scale = 10 ) {
-
-		super();
-
-		/**
-		 * The curve's scale.
-		 *
-		 * @type {number}
-		 * @default 10
-		 */
-		this.scale = scale;
-
-	}
-
-	/**
-	 * This method returns a vector in 3D space for the given interpolation factor.
-	 *
-	 * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
-	 * @param {Vector3} [optionalTarget] - The optional target vector the result is written to.
-	 * @return {Vector3} The position on the curve.
-	 */
-	getPoint( t, optionalTarget = new Vector3() ) {
-
-		const point = optionalTarget;
-
-		const p = 2;
-		const q = 5;
-
-		t *= Math.PI * 2;
-
-		const x = ( 2 + Math.cos( q * t ) ) * Math.cos( p * t );
-		const y = ( 2 + Math.cos( q * t ) ) * Math.sin( p * t );
-		const z = Math.sin( q * t );
-
-		return point.set( x, y, z ).multiplyScalar( this.scale );
-
-	}
-
-}
-
-/**
- * A Trefoil Polynomial Knot.
- *
- * @augments Curve
- * @three_import import { TrefoilPolynomialKnot } from 'three/addons/curves/CurveExtras.js';
- */
-class TrefoilPolynomialKnot extends Curve {
-
-	/**
-	 * Constructs a new Trefoil Polynomial Knot.
-	 *
-	 * @param {number} [scale=10] - The curve's scale.
-	 */
-	constructor( scale = 10 ) {
-
-		super();
-
-		/**
-		 * The curve's scale.
-		 *
-		 * @type {number}
-		 * @default 10
-		 */
-		this.scale = scale;
-
-	}
-
-	/**
-	 * This method returns a vector in 3D space for the given interpolation factor.
-	 *
-	 * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
-	 * @param {Vector3} [optionalTarget] - The optional target vector the result is written to.
-	 * @return {Vector3} The position on the curve.
-	 */
-	getPoint( t, optionalTarget = new Vector3() ) {
-
-		const point = optionalTarget;
-
-		t = t * 4 - 2;
-
-		const x = Math.pow( t, 3 ) - 3 * t;
-		const y = Math.pow( t, 4 ) - 4 * t * t;
-		const z = 1 / 5 * Math.pow( t, 5 ) - 2 * t;
-
-		return point.set( x, y, z ).multiplyScalar( this.scale );
-
-	}
-
-}
-
-function scaleTo( x, y, t ) {
-
-	const r = y - x;
-	return t * r + x;
-
-}
-
-/**
- * A Figure Eight Polynomial Knot.
- *
- * @augments Curve
- * @three_import import { FigureEightPolynomialKnot } from 'three/addons/curves/CurveExtras.js';
- */
-class FigureEightPolynomialKnot extends Curve {
-
-	/**
-	 * Constructs a new Figure Eight Polynomial Knot.
-	 *
-	 * @param {number} [scale=1] - The curve's scale.
-	 */
-	constructor( scale = 1 ) {
-
-		super();
-
-		/**
-		 * The curve's scale.
-		 *
-		 * @type {number}
-		 * @default 1
-		 */
-		this.scale = scale;
-
-	}
-
-	/**
-	 * This method returns a vector in 3D space for the given interpolation factor.
-	 *
-	 * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
-	 * @param {Vector3} [optionalTarget] - The optional target vector the result is written to.
-	 * @return {Vector3} The position on the curve.
-	 */
-	getPoint( t, optionalTarget = new Vector3() ) {
-
-		const point = optionalTarget;
-
-		t = scaleTo( - 4, 4, t );
-
-		const x = 2 / 5 * t * ( t * t - 7 ) * ( t * t - 10 );
-		const y = Math.pow( t, 4 ) - 13 * t * t;
-		const z = 1 / 10 * t * ( t * t - 4 ) * ( t * t - 9 ) * ( t * t - 12 );
-
-		return point.set( x, y, z ).multiplyScalar( this.scale );
-
-	}
-
-}
-
-/**
- * A Decorated Torus Knot 4a.
- *
- * @augments Curve
- * @three_import import { DecoratedTorusKnot4a } from 'three/addons/curves/CurveExtras.js';
- */
-class DecoratedTorusKnot4a extends Curve {
-
-	/**
-	 * Constructs a new Decorated Torus Knot 4a.
-	 *
-	 * @param {number} [scale=1] - The curve's scale.
-	 */
-	constructor( scale = 40 ) {
-
-		super();
-
-		/**
-		 * The curve's scale.
-		 *
-		 * @type {number}
-		 * @default 40
-		 */
-		this.scale = scale;
-
-	}
-
-	/**
-	 * This method returns a vector in 3D space for the given interpolation factor.
-	 *
-	 * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
-	 * @param {Vector3} [optionalTarget] - The optional target vector the result is written to.
-	 * @return {Vector3} The position on the curve.
-	 */
-	getPoint( t, optionalTarget = new Vector3() ) {
-
-		const point = optionalTarget;
-
-		t *= Math.PI * 2;
-
-		const x = Math.cos( 2 * t ) * ( 1 + 0.6 * ( Math.cos( 5 * t ) + 0.75 * Math.cos( 10 * t ) ) );
-		const y = Math.sin( 2 * t ) * ( 1 + 0.6 * ( Math.cos( 5 * t ) + 0.75 * Math.cos( 10 * t ) ) );
-		const z = 0.35 * Math.sin( 5 * t );
-
-		return point.set( x, y, z ).multiplyScalar( this.scale );
-
-	}
-
-}
-
-/**
- * A Decorated Torus Knot 4b.
- *
- * @augments Curve
- * @three_import import { DecoratedTorusKnot4b } from 'three/addons/curves/CurveExtras.js';
- */
-class DecoratedTorusKnot4b extends Curve {
-
-	/**
-	 * Constructs a new Decorated Torus Knot 4b.
-	 *
-	 * @param {number} [scale=1] - The curve's scale.
-	 */
-	constructor( scale = 40 ) {
-
-		super();
-
-		/**
-		 * The curve's scale.
-		 *
-		 * @type {number}
-		 * @default 40
-		 */
-		this.scale = scale;
-
-	}
-
-	/**
-	 * This method returns a vector in 3D space for the given interpolation factor.
-	 *
-	 * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
-	 * @param {Vector3} [optionalTarget] - The optional target vector the result is written to.
-	 * @return {Vector3} The position on the curve.
-	 */
-	getPoint( t, optionalTarget = new Vector3() ) {
-
-		const point = optionalTarget;
-
-		const fi = t * Math.PI * 2;
-
-		const x = Math.cos( 2 * fi ) * ( 1 + 0.45 * Math.cos( 3 * fi ) + 0.4 * Math.cos( 9 * fi ) );
-		const y = Math.sin( 2 * fi ) * ( 1 + 0.45 * Math.cos( 3 * fi ) + 0.4 * Math.cos( 9 * fi ) );
-		const z = 0.2 * Math.sin( 9 * fi );
-
-		return point.set( x, y, z ).multiplyScalar( this.scale );
-
-	}
-
-}
-
-/**
- * A Decorated Torus Knot 5a.
- *
- * @augments Curve
- * @three_import import { DecoratedTorusKnot5a } from 'three/addons/curves/CurveExtras.js';
- */
-class DecoratedTorusKnot5a extends Curve {
-
-	/**
-	 * Constructs a new Decorated Torus Knot 5a.
-	 *
-	 * @param {number} [scale=1] - The curve's scale.
-	 */
-	constructor( scale = 40 ) {
-
-		super();
-
-		/**
-		 * The curve's scale.
-		 *
-		 * @type {number}
-		 * @default 40
-		 */
-		this.scale = scale;
-
-	}
-
-	/**
-	 * This method returns a vector in 3D space for the given interpolation factor.
-	 *
-	 * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
-	 * @param {Vector3} [optionalTarget] - The optional target vector the result is written to.
-	 * @return {Vector3} The position on the curve.
-	 */
-	getPoint( t, optionalTarget = new Vector3() ) {
-
-		const point = optionalTarget;
-
-		const fi = t * Math.PI * 2;
-
-		const x = Math.cos( 3 * fi ) * ( 1 + 0.3 * Math.cos( 5 * fi ) + 0.5 * Math.cos( 10 * fi ) );
-		const y = Math.sin( 3 * fi ) * ( 1 + 0.3 * Math.cos( 5 * fi ) + 0.5 * Math.cos( 10 * fi ) );
-		const z = 0.2 * Math.sin( 20 * fi );
-
-		return point.set( x, y, z ).multiplyScalar( this.scale );
-
-	}
-
-}
-
-/**
- * A Decorated Torus Knot 5c.
- *
- * @augments Curve
- * @three_import import { DecoratedTorusKnot5c } from 'three/addons/curves/CurveExtras.js';
- */
-class DecoratedTorusKnot5c extends Curve {
-
-	/**
-	 * Constructs a new Decorated Torus Knot 5c.
-	 *
-	 * @param {number} [scale=1] - The curve's scale.
-	 */
-	constructor( scale = 40 ) {
-
-		super();
-
-		/**
-		 * The curve's scale.
-		 *
-		 * @type {number}
-		 * @default 40
-		 */
-		this.scale = scale;
-
-	}
-
-	/**
-	 * This method returns a vector in 3D space for the given interpolation factor.
-	 *
-	 * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
-	 * @param {Vector3} [optionalTarget] - The optional target vector the result is written to.
-	 * @return {Vector3} The position on the curve.
-	 */
-	getPoint( t, optionalTarget = new Vector3() ) {
-
-		const point = optionalTarget;
-
-		const fi = t * Math.PI * 2;
-
-		const x = Math.cos( 4 * fi ) * ( 1 + 0.5 * ( Math.cos( 5 * fi ) + 0.4 * Math.cos( 20 * fi ) ) );
-		const y = Math.sin( 4 * fi ) * ( 1 + 0.5 * ( Math.cos( 5 * fi ) + 0.4 * Math.cos( 20 * fi ) ) );
-		const z = 0.35 * Math.sin( 15 * fi );
-
-		return point.set( x, y, z ).multiplyScalar( this.scale );
-
-	}
-
-}
-
-export {
-	GrannyKnot,
-	HeartCurve,
-	VivianiCurve,
-	KnotCurve,
-	HelixCurve,
-	TrefoilKnot,
-	TorusKnot,
-	CinquefoilKnot,
-	TrefoilPolynomialKnot,
-	FigureEightPolynomialKnot,
-	DecoratedTorusKnot4a,
-	DecoratedTorusKnot4b,
-	DecoratedTorusKnot5a,
-	DecoratedTorusKnot5c
-};

+ 0 - 155
node_modules/three/examples/jsm/curves/NURBSCurve.js

@@ -1,155 +0,0 @@
-import {
-	Curve,
-	Vector3,
-	Vector4
-} from 'three';
-import * as NURBSUtils from '../curves/NURBSUtils.js';
-
-/**
- * This class represents a NURBS curve.
- *
- * Implementation is based on `(x, y [, z=0 [, w=1]])` control points with `w=weight`.
- *
- * @augments Curve
- * @three_import import { NURBSCurve } from 'three/addons/curves/NURBSCurve.js';
- */
-class NURBSCurve extends Curve {
-
-	/**
-	 * Constructs a new NURBS curve.
-	 *
-	 * @param {number} degree - The NURBS degree.
-	 * @param {Array<number>} knots - The knots as a flat array of numbers.
-	 * @param {Array<Vector2|Vector3|Vector4>} controlPoints - An array holding control points.
-	 * @param {number} [startKnot] - Index of the start knot into the `knots` array.
-	 * @param {number} [endKnot] - Index of the end knot into the `knots` array.
-	 */
-	constructor( degree, knots, controlPoints, startKnot, endKnot ) {
-
-		super();
-
-		const knotsLength = knots ? knots.length - 1 : 0;
-		const pointsLength = controlPoints ? controlPoints.length : 0;
-
-		/**
-		 * The NURBS degree.
-		 *
-		 * @type {number}
-		 */
-		this.degree = degree;
-
-		/**
-		 * The knots as a flat array of numbers.
-		 *
-		 * @type {Array<number>}
-		 */
-		this.knots = knots;
-
-		/**
-		 * An array of control points.
-		 *
-		 * @type {Array<Vector4>}
-		 */
-		this.controlPoints = [];
-
-		/**
-		 * Index of the start knot into the `knots` array.
-		 *
-		 * @type {number}
-		 */
-		this.startKnot = startKnot || 0;
-
-		/**
-		 * Index of the end knot into the `knots` array.
-		 *
-		 * @type {number}
-		 */
-		this.endKnot = endKnot || knotsLength;
-
-		for ( let i = 0; i < pointsLength; ++ i ) {
-
-			// ensure Vector4 for control points
-			const point = controlPoints[ i ];
-			this.controlPoints[ i ] = new Vector4( point.x, point.y, point.z, point.w );
-
-		}
-
-	}
-
-	/**
-	 * This method returns a vector in 3D space for the given interpolation factor.
-	 *
-	 * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
-	 * @param {Vector3} [optionalTarget] - The optional target vector the result is written to.
-	 * @return {Vector3} The position on the curve.
-	 */
-	getPoint( t, optionalTarget = new Vector3() ) {
-
-		const point = optionalTarget;
-
-		const u = this.knots[ this.startKnot ] + t * ( this.knots[ this.endKnot ] - this.knots[ this.startKnot ] ); // linear mapping t->u
-
-		// following results in (wx, wy, wz, w) homogeneous point
-		const hpoint = NURBSUtils.calcBSplinePoint( this.degree, this.knots, this.controlPoints, u );
-
-		if ( hpoint.w !== 1.0 ) {
-
-			// project to 3D space: (wx, wy, wz, w) -> (x, y, z, 1)
-			hpoint.divideScalar( hpoint.w );
-
-		}
-
-		return point.set( hpoint.x, hpoint.y, hpoint.z );
-
-	}
-
-	/**
-	 * Returns a unit vector tangent for the given interpolation factor.
-	 *
-	 * @param {number} t - The interpolation factor.
-	 * @param {Vector3} [optionalTarget] - The optional target vector the result is written to.
-	 * @return {Vector3} The tangent vector.
-	 */
-	getTangent( t, optionalTarget = new Vector3() ) {
-
-		const tangent = optionalTarget;
-
-		const u = this.knots[ 0 ] + t * ( this.knots[ this.knots.length - 1 ] - this.knots[ 0 ] );
-		const ders = NURBSUtils.calcNURBSDerivatives( this.degree, this.knots, this.controlPoints, u, 1 );
-		tangent.copy( ders[ 1 ] ).normalize();
-
-		return tangent;
-
-	}
-
-	toJSON() {
-
-		const data = super.toJSON();
-
-		data.degree = this.degree;
-		data.knots = [ ...this.knots ];
-		data.controlPoints = this.controlPoints.map( p => p.toArray() );
-		data.startKnot = this.startKnot;
-		data.endKnot = this.endKnot;
-
-		return data;
-
-	}
-
-	fromJSON( json ) {
-
-		super.fromJSON( json );
-
-		this.degree = json.degree;
-		this.knots = [ ...json.knots ];
-		this.controlPoints = json.controlPoints.map( p => new Vector4( p[ 0 ], p[ 1 ], p[ 2 ], p[ 3 ] ) );
-		this.startKnot = json.startKnot;
-		this.endKnot = json.endKnot;
-
-		return this;
-
-	}
-
-}
-
-export { NURBSCurve };

+ 0 - 98
node_modules/three/examples/jsm/curves/NURBSSurface.js

@@ -1,98 +0,0 @@
-import {
-	Vector4
-} from 'three';
-import * as NURBSUtils from '../curves/NURBSUtils.js';
-
-/**
- * This class represents a NURBS surface.
- *
- * Implementation is based on `(x, y [, z=0 [, w=1]])` control points with `w=weight`.
- *
- * @three_import import { NURBSSurface } from 'three/addons/curves/NURBSSurface.js';
- */
-class NURBSSurface {
-
-	/**
-	 * Constructs a new NURBS surface.
-	 *
-	 * @param {number} degree1 - The first NURBS degree.
-	 * @param {number} degree2 - The second NURBS degree.
-	 * @param {Array<number>} knots1 - The first knots as a flat array of numbers.
-	 * @param {Array<number>} knots2 - The second knots as a flat array of numbers.
-	 * @param {Array<Array<Vector2|Vector3|Vector4>>} controlPoints - An array^2 holding control points.
-	 */
-	constructor( degree1, degree2, knots1, knots2, controlPoints ) {
-
-		/**
-		 * The first NURBS degree.
-		 *
-		 * @type {number}
-		 */
-		this.degree1 = degree1;
-
-		/**
-		 * The second NURBS degree.
-		 *
-		 * @type {number}
-		 */
-		this.degree2 = degree2;
-
-		/**
-		 * The first knots as a flat array of numbers.
-		 *
-		 * @type {Array<number>}
-		 */
-		this.knots1 = knots1;
-
-		/**
-		 * The second knots as a flat array of numbers.
-		 *
-		 * @type {Array<number>}
-		 */
-		this.knots2 = knots2;
-
-		/**
-		 *  An array holding arrays of control points.
-		 *
-		 * @type {Array<Array<Vector2|Vector3|Vector4>>}
-		 */
-		this.controlPoints = [];
-
-		const len1 = knots1.length - degree1 - 1;
-		const len2 = knots2.length - degree2 - 1;
-
-		// ensure Vector4 for control points
-		for ( let i = 0; i < len1; ++ i ) {
-
-			this.controlPoints[ i ] = [];
-
-			for ( let j = 0; j < len2; ++ j ) {
-
-				const point = controlPoints[ i ][ j ];
-				this.controlPoints[ i ][ j ] = new Vector4( point.x, point.y, point.z, point.w );
-
-			}
-
-		}
-
-	}
-
-	/**
-	 * This method returns a vector in 3D space for the given interpolation factor. This vector lies on the NURBS surface.
-	 *
-	 * @param {number} t1 - The first interpolation factor representing the `u` position on the surface. Must be in the range `[0,1]`.
-	 * @param {number} t2 - The second interpolation factor representing the `v` position on the surface. Must be in the range `[0,1]`.
-	 * @param {Vector3} target - The target vector the result is written to.
-	 */
-	getPoint( t1, t2, target ) {
-
-		const u = this.knots1[ 0 ] + t1 * ( this.knots1[ this.knots1.length - 1 ] - this.knots1[ 0 ] ); // linear mapping t1->u
-		const v = this.knots2[ 0 ] + t2 * ( this.knots2[ this.knots2.length - 1 ] - this.knots2[ 0 ] ); // linear mapping t2->u
-
-		NURBSUtils.calcSurfacePoint( this.degree1, this.degree2, this.knots1, this.knots2, this.controlPoints, u, v, target );
-
-	}
-
-}
-
-export { NURBSSurface };

+ 0 - 532
node_modules/three/examples/jsm/curves/NURBSUtils.js

@@ -1,532 +0,0 @@
-import {
-	Vector3,
-	Vector4
-} from 'three';
-
-/**
- * @module NURBSUtils
- * @three_import import * as NURBSUtils from 'three/addons/curves/NURBSUtils.js';
- */
-
-/**
- * Finds knot vector span.
- *
- * @param {number} p - The degree.
- * @param {number} u - The parametric value.
- * @param {Array<number>} U - The knot vector.
- * @return {number} The span.
- */
-function findSpan( p, u, U ) {
-
-	const n = U.length - p - 1;
-
-	if ( u >= U[ n ] ) {
-
-		return n - 1;
-
-	}
-
-	if ( u <= U[ p ] ) {
-
-		return p;
-
-	}
-
-	let low = p;
-	let high = n;
-	let mid = Math.floor( ( low + high ) / 2 );
-
-	while ( u < U[ mid ] || u >= U[ mid + 1 ] ) {
-
-		if ( u < U[ mid ] ) {
-
-			high = mid;
-
-		} else {
-
-			low = mid;
-
-		}
-
-		mid = Math.floor( ( low + high ) / 2 );
-
-	}
-
-	return mid;
-
-}
-
-/**
- * Calculates basis functions. See The NURBS Book, page 70, algorithm A2.2.
- *
- * @param {number} span - The span in which `u` lies.
- * @param {number} u - The parametric value.
- * @param {number} p - The degree.
- * @param {Array<number>} U - The knot vector.
- * @return {Array<number>} Array[p+1] with basis functions values.
- */
-function calcBasisFunctions( span, u, p, U ) {
-
-	const N = [];
-	const left = [];
-	const right = [];
-	N[ 0 ] = 1.0;
-
-	for ( let j = 1; j <= p; ++ j ) {
-
-		left[ j ] = u - U[ span + 1 - j ];
-		right[ j ] = U[ span + j ] - u;
-
-		let saved = 0.0;
-
-		for ( let r = 0; r < j; ++ r ) {
-
-			const rv = right[ r + 1 ];
-			const lv = left[ j - r ];
-			const temp = N[ r ] / ( rv + lv );
-			N[ r ] = saved + rv * temp;
-			saved = lv * temp;
-
-		}
-
-		N[ j ] = saved;
-
-	}
-
-	return N;
-
-}
-
-/**
- * Calculates B-Spline curve points. See The NURBS Book, page 82, algorithm A3.1.
- *
- * @param {number} p - The degree of the B-Spline.
- * @param {Array<number>} U - The knot vector.
- * @param {Array<Vector4>} P - The control points
- * @param {number} u - The parametric point.
- * @return {Vector4} The point for given `u`.
- */
-function calcBSplinePoint( p, U, P, u ) {
-
-	const span = findSpan( p, u, U );
-	const N = calcBasisFunctions( span, u, p, U );
-	const C = new Vector4( 0, 0, 0, 0 );
-
-	for ( let j = 0; j <= p; ++ j ) {
-
-		const point = P[ span - p + j ];
-		const Nj = N[ j ];
-		const wNj = point.w * Nj;
-		C.x += point.x * wNj;
-		C.y += point.y * wNj;
-		C.z += point.z * wNj;
-		C.w += point.w * Nj;
-
-	}
-
-	return C;
-
-}
-
-/**
- * Calculates basis functions derivatives. See The NURBS Book, page 72, algorithm A2.3.
- *
- * @param {number} span - The span in which `u` lies.
- * @param {number} u - The parametric point.
- * @param {number} p - The degree.
- * @param {number} n - number of derivatives to calculate
- * @param {Array<number>} U - The knot vector.
- * @return {Array<Array<number>>} An array[n+1][p+1] with basis functions derivatives.
- */
-function calcBasisFunctionDerivatives( span, u, p, n, U ) {
-
-	const zeroArr = [];
-	for ( let i = 0; i <= p; ++ i )
-		zeroArr[ i ] = 0.0;
-
-	const ders = [];
-
-	for ( let i = 0; i <= n; ++ i )
-		ders[ i ] = zeroArr.slice( 0 );
-
-	const ndu = [];
-
-	for ( let i = 0; i <= p; ++ i )
-		ndu[ i ] = zeroArr.slice( 0 );
-
-	ndu[ 0 ][ 0 ] = 1.0;
-
-	const left = zeroArr.slice( 0 );
-	const right = zeroArr.slice( 0 );
-
-	for ( let j = 1; j <= p; ++ j ) {
-
-		left[ j ] = u - U[ span + 1 - j ];
-		right[ j ] = U[ span + j ] - u;
-
-		let saved = 0.0;
-
-		for ( let r = 0; r < j; ++ r ) {
-
-			const rv = right[ r + 1 ];
-			const lv = left[ j - r ];
-			ndu[ j ][ r ] = rv + lv;
-
-			const temp = ndu[ r ][ j - 1 ] / ndu[ j ][ r ];
-			ndu[ r ][ j ] = saved + rv * temp;
-			saved = lv * temp;
-
-		}
-
-		ndu[ j ][ j ] = saved;
-
-	}
-
-	for ( let j = 0; j <= p; ++ j ) {
-
-		ders[ 0 ][ j ] = ndu[ j ][ p ];
-
-	}
-
-	for ( let r = 0; r <= p; ++ r ) {
-
-		let s1 = 0;
-		let s2 = 1;
-
-		const a = [];
-		for ( let i = 0; i <= p; ++ i ) {
-
-			a[ i ] = zeroArr.slice( 0 );
-
-		}
-
-		a[ 0 ][ 0 ] = 1.0;
-
-		for ( let k = 1; k <= n; ++ k ) {
-
-			let d = 0.0;
-			const rk = r - k;
-			const pk = p - k;
-
-			if ( r >= k ) {
-
-				a[ s2 ][ 0 ] = a[ s1 ][ 0 ] / ndu[ pk + 1 ][ rk ];
-				d = a[ s2 ][ 0 ] * ndu[ rk ][ pk ];
-
-			}
-
-			const j1 = ( rk >= - 1 ) ? 1 : - rk;
-			const j2 = ( r - 1 <= pk ) ? k - 1 : p - r;
-
-			for ( let j = j1; j <= j2; ++ j ) {
-
-				a[ s2 ][ j ] = ( a[ s1 ][ j ] - a[ s1 ][ j - 1 ] ) / ndu[ pk + 1 ][ rk + j ];
-				d += a[ s2 ][ j ] * ndu[ rk + j ][ pk ];
-
-			}
-
-			if ( r <= pk ) {
-
-				a[ s2 ][ k ] = - a[ s1 ][ k - 1 ] / ndu[ pk + 1 ][ r ];
-				d += a[ s2 ][ k ] * ndu[ r ][ pk ];
-
-			}
-
-			ders[ k ][ r ] = d;
-
-			const j = s1;
-			s1 = s2;
-			s2 = j;
-
-		}
-
-	}
-
-	let r = p;
-
-	for ( let k = 1; k <= n; ++ k ) {
-
-		for ( let j = 0; j <= p; ++ j ) {
-
-			ders[ k ][ j ] *= r;
-
-		}
-
-		r *= p - k;
-
-	}
-
-	return ders;
-
-}
-
-/**
- * Calculates derivatives of a B-Spline. See The NURBS Book, page 93, algorithm A3.2.
- *
- * @param {number} p - The degree.
- * @param {Array<number>} U - The knot vector.
- * @param {Array<Vector4>} P - The control points
- * @param {number} u - The parametric point.
- * @param {number} nd - The number of derivatives.
- * @return {Array<Vector4>} An array[d+1] with derivatives.
- */
-function calcBSplineDerivatives( p, U, P, u, nd ) {
-
-	const du = nd < p ? nd : p;
-	const CK = [];
-	const span = findSpan( p, u, U );
-	const nders = calcBasisFunctionDerivatives( span, u, p, du, U );
-	const Pw = [];
-
-	for ( let i = 0; i < P.length; ++ i ) {
-
-		const point = P[ i ].clone();
-		const w = point.w;
-
-		point.x *= w;
-		point.y *= w;
-		point.z *= w;
-
-		Pw[ i ] = point;
-
-	}
-
-	for ( let k = 0; k <= du; ++ k ) {
-
-		const point = Pw[ span - p ].clone().multiplyScalar( nders[ k ][ 0 ] );
-
-		for ( let j = 1; j <= p; ++ j ) {
-
-			point.add( Pw[ span - p + j ].clone().multiplyScalar( nders[ k ][ j ] ) );
-
-		}
-
-		CK[ k ] = point;
-
-	}
-
-	for ( let k = du + 1; k <= nd + 1; ++ k ) {
-
-		CK[ k ] = new Vector4( 0, 0, 0 );
-
-	}
-
-	return CK;
-
-}
-
-/**
- * Calculates "K over I".
- *
- * @param {number} k - The K value.
- * @param {number} i - The I value.
- * @return {number} k!/(i!(k-i)!)
- */
-function calcKoverI( k, i ) {
-
-	let nom = 1;
-
-	for ( let j = 2; j <= k; ++ j ) {
-
-		nom *= j;
-
-	}
-
-	let denom = 1;
-
-	for ( let j = 2; j <= i; ++ j ) {
-
-		denom *= j;
-
-	}
-
-	for ( let j = 2; j <= k - i; ++ j ) {
-
-		denom *= j;
-
-	}
-
-	return nom / denom;
-
-}
-
-/**
- * Calculates derivatives (0-nd) of rational curve. See The NURBS Book, page 127, algorithm A4.2.
- *
- * @param {Array<Vector4>} Pders - Array with derivatives.
- * @return {Array<Vector3>} An array with derivatives for rational curve.
- */
-function calcRationalCurveDerivatives( Pders ) {
-
-	const nd = Pders.length;
-	const Aders = [];
-	const wders = [];
-
-	for ( let i = 0; i < nd; ++ i ) {
-
-		const point = Pders[ i ];
-		Aders[ i ] = new Vector3( point.x, point.y, point.z );
-		wders[ i ] = point.w;
-
-	}
-
-	const CK = [];
-
-	for ( let k = 0; k < nd; ++ k ) {
-
-		const v = Aders[ k ].clone();
-
-		for ( let i = 1; i <= k; ++ i ) {
-
-			v.sub( CK[ k - i ].clone().multiplyScalar( calcKoverI( k, i ) * wders[ i ] ) );
-
-		}
-
-		CK[ k ] = v.divideScalar( wders[ 0 ] );
-
-	}
-
-	return CK;
-
-}
-
-/**
- * Calculates NURBS curve derivatives. See The NURBS Book, page 127, algorithm A4.2.
- *
- * @param {number} p - The degree.
- * @param {Array<number>} U - The knot vector.
- * @param {Array<Vector4>} P - The control points in homogeneous space.
- * @param {number} u - The parametric point.
- * @param {number} nd - The number of derivatives.
- * @return {Array<Vector3>} array with derivatives for rational curve.
- */
-function calcNURBSDerivatives( p, U, P, u, nd ) {
-
-	const Pders = calcBSplineDerivatives( p, U, P, u, nd );
-	return calcRationalCurveDerivatives( Pders );
-
-}
-
-/**
- * Calculates a rational B-Spline surface point. See The NURBS Book, page 134, algorithm A4.3.
- *
- * @param {number} p - The first degree of B-Spline surface.
- * @param {number} q - The second degree of B-Spline surface.
- * @param {Array<number>} U - The first knot vector.
- * @param {Array<number>} V - The second knot vector.
- * @param {Array<Array<Vector4>>} P - The control points in homogeneous space.
- * @param {number} u - The first parametric point.
- * @param {number} v - The second parametric point.
- * @param {Vector3} target - The target vector.
- */
-function calcSurfacePoint( p, q, U, V, P, u, v, target ) {
-
-	const uspan = findSpan( p, u, U );
-	const vspan = findSpan( q, v, V );
-	const Nu = calcBasisFunctions( uspan, u, p, U );
-	const Nv = calcBasisFunctions( vspan, v, q, V );
-	const temp = [];
-
-	for ( let l = 0; l <= q; ++ l ) {
-
-		temp[ l ] = new Vector4( 0, 0, 0, 0 );
-		for ( let k = 0; k <= p; ++ k ) {
-
-			const point = P[ uspan - p + k ][ vspan - q + l ].clone();
-			const w = point.w;
-			point.x *= w;
-			point.y *= w;
-			point.z *= w;
-			temp[ l ].add( point.multiplyScalar( Nu[ k ] ) );
-
-		}
-
-	}
-
-	const Sw = new Vector4( 0, 0, 0, 0 );
-	for ( let l = 0; l <= q; ++ l ) {
-
-		Sw.add( temp[ l ].multiplyScalar( Nv[ l ] ) );
-
-	}
-
-	Sw.divideScalar( Sw.w );
-	target.set( Sw.x, Sw.y, Sw.z );
-
-}
-
-/**
- * Calculates a rational B-Spline volume point. See The NURBS Book, page 134, algorithm A4.3.
- *
- * @param {number} p - The first degree of B-Spline surface.
- * @param {number} q - The second degree of B-Spline surface.
- * @param {number} r - The third degree of B-Spline surface.
- * @param {Array<number>} U - The first knot vector.
- * @param {Array<number>} V - The second knot vector.
- * @param {Array<number>} W - The third knot vector.
- * @param {Array<Array<Array<Vector4>>>} P - The control points in homogeneous space.
- * @param {number} u - The first parametric point.
- * @param {number} v - The second parametric point.
- * @param {number} w - The third parametric point.
- * @param {Vector3} target - The target vector.
- */
-function calcVolumePoint( p, q, r, U, V, W, P, u, v, w, target ) {
-
-	const uspan = findSpan( p, u, U );
-	const vspan = findSpan( q, v, V );
-	const wspan = findSpan( r, w, W );
-	const Nu = calcBasisFunctions( uspan, u, p, U );
-	const Nv = calcBasisFunctions( vspan, v, q, V );
-	const Nw = calcBasisFunctions( wspan, w, r, W );
-	const temp = [];
-
-	for ( let m = 0; m <= r; ++ m ) {
-
-		temp[ m ] = [];
-
-		for ( let l = 0; l <= q; ++ l ) {
-
-			temp[ m ][ l ] = new Vector4( 0, 0, 0, 0 );
-			for ( let k = 0; k <= p; ++ k ) {
-
-				const point = P[ uspan - p + k ][ vspan - q + l ][ wspan - r + m ].clone();
-				const w = point.w;
-				point.x *= w;
-				point.y *= w;
-				point.z *= w;
-				temp[ m ][ l ].add( point.multiplyScalar( Nu[ k ] ) );
-
-			}
-
-		}
-
-	}
-
-	const Sw = new Vector4( 0, 0, 0, 0 );
-	for ( let m = 0; m <= r; ++ m ) {
-
-		for ( let l = 0; l <= q; ++ l ) {
-
-			Sw.add( temp[ m ][ l ].multiplyScalar( Nw[ m ] ).multiplyScalar( Nv[ l ] ) );
-
-		}
-
-	}
-
-	Sw.divideScalar( Sw.w );
-	target.set( Sw.x, Sw.y, Sw.z );
-
-}
-
-export {
-	findSpan,
-	calcBasisFunctions,
-	calcBSplinePoint,
-	calcBasisFunctionDerivatives,
-	calcBSplineDerivatives,
-	calcKoverI,
-	calcRationalCurveDerivatives,
-	calcNURBSDerivatives,
-	calcSurfacePoint,
-	calcVolumePoint,
-};

+ 0 - 82
node_modules/three/examples/jsm/curves/NURBSVolume.js

@@ -1,82 +0,0 @@
-import {
-	Vector4
-} from 'three';
-import * as NURBSUtils from '../curves/NURBSUtils.js';
-
-/**
- * This class represents a NURBS volume.
- *
- * Implementation is based on `(x, y [, z=0 [, w=1]])` control points with `w=weight`.
- *
- * @three_import import { NURBSVolume } from 'three/addons/curves/NURBSVolume.js';
- */
-class NURBSVolume {
-
-	/**
-	 * Constructs a new NURBS surface.
-	 *
-	 * @param {number} degree1 - The first NURBS degree.
-	 * @param {number} degree2 - The second NURBS degree.
-	 * @param {number} degree3 - The third NURBS degree.
-	 * @param {Array<number>} knots1 - The first knots as a flat array of numbers.
-	 * @param {Array<number>} knots2 - The second knots as a flat array of numbers.
-	 * @param {Array<number>} knots3 - The third knots as a flat array of numbers.
-	 * @param {Array<Array<Array<Vector2|Vector3|Vector4>>>} controlPoints - An array^3 holding control points.
-	 */
-	constructor( degree1, degree2, degree3, knots1, knots2, knots3 /* arrays of reals */, controlPoints /* array^3 of Vector(2|3|4) */ ) {
-
-		this.degree1 = degree1;
-		this.degree2 = degree2;
-		this.degree3 = degree3;
-		this.knots1 = knots1;
-		this.knots2 = knots2;
-		this.knots3 = knots3;
-		this.controlPoints = [];
-
-		const len1 = knots1.length - degree1 - 1;
-		const len2 = knots2.length - degree2 - 1;
-		const len3 = knots3.length - degree3 - 1;
-
-		// ensure Vector4 for control points
-		for ( let i = 0; i < len1; ++ i ) {
-
-			this.controlPoints[ i ] = [];
-
-			for ( let j = 0; j < len2; ++ j ) {
-
-				this.controlPoints[ i ][ j ] = [];
-
-				for ( let k = 0; k < len3; ++ k ) {
-
-					const point = controlPoints[ i ][ j ][ k ];
-					this.controlPoints[ i ][ j ][ k ] = new Vector4( point.x, point.y, point.z, point.w );
-
-				}
-
-			}
-
-		}
-
-	}
-
-	/**
-	 * This method returns a vector in 3D space for the given interpolation factor. This vector lies within the NURBS volume.
-	 *
-	 * @param {number} t1 - The first interpolation factor representing the `u` position within the volume. Must be in the range `[0,1]`.
-	 * @param {number} t2 - The second interpolation factor representing the `v` position within the volume. Must be in the range `[0,1]`.
-	 * @param {number} t3 - The third interpolation factor representing the `w` position within the volume. Must be in the range `[0,1]`.
-	 * @param {Vector3} target - The target vector the result is written to.
-	 */
-	getPoint( t1, t2, t3, target ) {
-
-		const u = this.knots1[ 0 ] + t1 * ( this.knots1[ this.knots1.length - 1 ] - this.knots1[ 0 ] ); // linear mapping t1->u
-		const v = this.knots2[ 0 ] + t2 * ( this.knots2[ this.knots2.length - 1 ] - this.knots2[ 0 ] ); // linear mapping t2->v
-		const w = this.knots3[ 0 ] + t3 * ( this.knots3[ this.knots3.length - 1 ] - this.knots3[ 0 ] ); // linear mapping t3->w
-
-		NURBSUtils.calcVolumePoint( this.degree1, this.degree2, this.degree3, this.knots1, this.knots2, this.knots3, this.controlPoints, u, v, w, target );
-
-	}
-
-}
-
-export { NURBSVolume };

+ 0 - 274
node_modules/three/examples/jsm/effects/AnaglyphEffect.js

@@ -1,274 +0,0 @@
-import {
-	LinearFilter,
-	MathUtils,
-	Matrix3,
-	NearestFilter,
-	PerspectiveCamera,
-	RGBAFormat,
-	ShaderMaterial,
-	Vector3,
-	WebGLRenderTarget
-} from 'three';
-import { FullScreenQuad } from '../postprocessing/Pass.js';
-import { frameCorners } from '../utils/CameraUtils.js';
-
-const _cameraL = /*@__PURE__*/ new PerspectiveCamera();
-const _cameraR = /*@__PURE__*/ new PerspectiveCamera();
-
-// Reusable vectors for screen corner calculations
-const _eyeL = /*@__PURE__*/ new Vector3();
-const _eyeR = /*@__PURE__*/ new Vector3();
-const _screenCenter = /*@__PURE__*/ new Vector3();
-const _screenBottomLeft = /*@__PURE__*/ new Vector3();
-const _screenBottomRight = /*@__PURE__*/ new Vector3();
-const _screenTopLeft = /*@__PURE__*/ new Vector3();
-const _right = /*@__PURE__*/ new Vector3();
-const _up = /*@__PURE__*/ new Vector3();
-const _forward = /*@__PURE__*/ new Vector3();
-
-/**
- * A class that creates an anaglyph effect using physically-correct
- * off-axis stereo projection.
- *
- * This implementation uses CameraUtils.frameCorners() to align stereo
- * camera frustums to a virtual screen plane, providing accurate depth
- * perception with zero parallax at the plane distance.
- *
- * Note that this class can only be used with {@link WebGLRenderer}.
- * When using {@link WebGPURenderer}, use {@link AnaglyphPassNode}.
- *
- * @three_import import { AnaglyphEffect } from 'three/addons/effects/AnaglyphEffect.js';
- */
-class AnaglyphEffect {
-
-	/**
-	 * Constructs a new anaglyph effect.
-	 *
-	 * @param {WebGLRenderer} renderer - The renderer.
-	 * @param {number} width - The width of the effect in physical pixels.
-	 * @param {number} height - The height of the effect in physical pixels.
-	 */
-	constructor( renderer, width = 512, height = 512 ) {
-
-		// Dubois matrices from https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.7.6968&rep=rep1&type=pdf#page=4
-
-		this.colorMatrixLeft = new Matrix3().fromArray( [
-			0.456100, - 0.0400822, - 0.0152161,
-			0.500484, - 0.0378246, - 0.0205971,
-			0.176381, - 0.0157589, - 0.00546856
-		] );
-
-		this.colorMatrixRight = new Matrix3().fromArray( [
-			- 0.0434706, 0.378476, - 0.0721527,
-			- 0.0879388, 0.73364, - 0.112961,
-			- 0.00155529, - 0.0184503, 1.2264
-		] );
-
-		/**
-		 * The interpupillary distance (eye separation) in world units.
-		 * Typical human IPD is 0.064 meters (64mm).
-		 *
-		 * @type {number}
-		 * @default 0.064
-		 */
-		this.eyeSep = 0.064;
-
-		/**
-		 * The distance in world units from the viewer to the virtual
-		 * screen plane where zero parallax (screen depth) occurs.
-		 * Objects at this distance appear at the screen surface.
-		 * Objects closer appear in front of the screen (negative parallax).
-		 * Objects further appear behind the screen (positive parallax).
-		 *
-		 * The screen dimensions are derived from the camera's FOV and aspect ratio
-		 * at this distance, ensuring the stereo view matches the camera's field of view.
-		 *
-		 * @type {number}
-		 * @default 0.5
-		 */
-		this.planeDistance = 0.5;
-
-		const _params = { minFilter: LinearFilter, magFilter: NearestFilter, format: RGBAFormat };
-
-		const _renderTargetL = new WebGLRenderTarget( width, height, _params );
-		const _renderTargetR = new WebGLRenderTarget( width, height, _params );
-
-		_cameraL.layers.enable( 1 );
-		_cameraR.layers.enable( 2 );
-
-		const _material = new ShaderMaterial( {
-
-			uniforms: {
-
-				'mapLeft': { value: _renderTargetL.texture },
-				'mapRight': { value: _renderTargetR.texture },
-
-				'colorMatrixLeft': { value: this.colorMatrixLeft },
-				'colorMatrixRight': { value: this.colorMatrixRight }
-
-			},
-
-			vertexShader: [
-
-				'varying vec2 vUv;',
-
-				'void main() {',
-
-				'	vUv = vec2( uv.x, uv.y );',
-				'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
-
-				'}'
-
-			].join( '\n' ),
-
-			fragmentShader: [
-
-				'uniform sampler2D mapLeft;',
-				'uniform sampler2D mapRight;',
-				'varying vec2 vUv;',
-
-				'uniform mat3 colorMatrixLeft;',
-				'uniform mat3 colorMatrixRight;',
-
-				'void main() {',
-
-				'	vec2 uv = vUv;',
-
-				'	vec4 colorL = texture2D( mapLeft, uv );',
-				'	vec4 colorR = texture2D( mapRight, uv );',
-
-				'	vec3 color = clamp(',
-				'			colorMatrixLeft * colorL.rgb +',
-				'			colorMatrixRight * colorR.rgb, 0., 1. );',
-
-				'	gl_FragColor = vec4(',
-				'			color.r, color.g, color.b,',
-				'			max( colorL.a, colorR.a ) );',
-
-				'	#include <tonemapping_fragment>',
-				'	#include <colorspace_fragment>',
-
-				'}'
-
-			].join( '\n' )
-
-		} );
-
-		const _quad = new FullScreenQuad( _material );
-
-		/**
-		 * Resizes the effect.
-		 *
-		 * @param {number} width - The width of the effect in logical pixels.
-		 * @param {number} height - The height of the effect in logical pixels.
-		 */
-		this.setSize = function ( width, height ) {
-
-			renderer.setSize( width, height );
-
-			const pixelRatio = renderer.getPixelRatio();
-
-			_renderTargetL.setSize( width * pixelRatio, height * pixelRatio );
-			_renderTargetR.setSize( width * pixelRatio, height * pixelRatio );
-
-		};
-
-		/**
-		 * When using this effect, this method should be called instead of the
-		 * default {@link WebGLRenderer#render}.
-		 *
-		 * @param {Object3D} scene - The scene to render.
-		 * @param {Camera} camera - The camera.
-		 */
-		this.render = function ( scene, camera ) {
-
-			const currentRenderTarget = renderer.getRenderTarget();
-
-			if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
-
-			if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
-
-			// Get the camera's local coordinate axes from its world matrix
-			camera.matrixWorld.extractBasis( _right, _up, _forward );
-			_right.normalize();
-			_up.normalize();
-			_forward.normalize();
-
-			// Calculate eye positions
-			const halfSep = this.eyeSep / 2;
-			_eyeL.copy( camera.position ).addScaledVector( _right, - halfSep );
-			_eyeR.copy( camera.position ).addScaledVector( _right, halfSep );
-
-			// Calculate screen center (at planeDistance in front of the camera center)
-			_screenCenter.copy( camera.position ).addScaledVector( _forward, - this.planeDistance );
-
-			// Calculate screen dimensions from camera FOV and aspect ratio
-			const halfHeight = this.planeDistance * Math.tan( MathUtils.DEG2RAD * camera.fov / 2 );
-			const halfWidth = halfHeight * camera.aspect;
-
-			// Calculate screen corners
-			_screenBottomLeft.copy( _screenCenter )
-				.addScaledVector( _right, - halfWidth )
-				.addScaledVector( _up, - halfHeight );
-
-			_screenBottomRight.copy( _screenCenter )
-				.addScaledVector( _right, halfWidth )
-				.addScaledVector( _up, - halfHeight );
-
-			_screenTopLeft.copy( _screenCenter )
-				.addScaledVector( _right, - halfWidth )
-				.addScaledVector( _up, halfHeight );
-
-			// Set up left eye camera
-			_cameraL.position.copy( _eyeL );
-			_cameraL.near = camera.near;
-			_cameraL.far = camera.far;
-			frameCorners( _cameraL, _screenBottomLeft, _screenBottomRight, _screenTopLeft, true );
-			_cameraL.matrixWorld.compose( _cameraL.position, _cameraL.quaternion, _cameraL.scale );
-			_cameraL.matrixWorldInverse.copy( _cameraL.matrixWorld ).invert();
-
-			// Set up right eye camera
-			_cameraR.position.copy( _eyeR );
-			_cameraR.near = camera.near;
-			_cameraR.far = camera.far;
-			frameCorners( _cameraR, _screenBottomLeft, _screenBottomRight, _screenTopLeft, true );
-			_cameraR.matrixWorld.compose( _cameraR.position, _cameraR.quaternion, _cameraR.scale );
-			_cameraR.matrixWorldInverse.copy( _cameraR.matrixWorld ).invert();
-
-			// Render left eye
-			renderer.setRenderTarget( _renderTargetL );
-			renderer.clear();
-			renderer.render( scene, _cameraL );
-
-			// Render right eye
-			renderer.setRenderTarget( _renderTargetR );
-			renderer.clear();
-			renderer.render( scene, _cameraR );
-
-			// Composite anaglyph
-			renderer.setRenderTarget( null );
-			_quad.render( renderer );
-
-			renderer.setRenderTarget( currentRenderTarget );
-
-		};
-
-		/**
-		 * Frees internal resources. This method should be called
-		 * when the effect is no longer required.
-		 */
-		this.dispose = function () {
-
-			_renderTargetL.dispose();
-			_renderTargetR.dispose();
-
-			_material.dispose();
-			_quad.dispose();
-
-		};
-
-	}
-
-}
-
-export { AnaglyphEffect };

+ 0 - 310
node_modules/three/examples/jsm/effects/AsciiEffect.js

@@ -1,310 +0,0 @@
-/**
- * A class that creates an ASCII effect.
- *
- * The ASCII generation is based on [jsascii](https://github.com/hassadee/jsascii/blob/master/jsascii.js).
- *
- * @three_import import { AsciiEffect } from 'three/addons/effects/AsciiEffect.js';
- */
-class AsciiEffect {
-
-	/**
-	 * Constructs a new ASCII effect.
-	 *
-	 * @param {WebGLRenderer} renderer - The renderer.
-	 * @param {string} [charSet=' .:-=+*#%@'] - The char set.
-	 * @param {AsciiEffect~Options} [options] - The configuration parameter.
-	 */
-	constructor( renderer, charSet = ' .:-=+*#%@', options = {} ) {
-
-		// ' .,:;=|iI+hHOE#`$';
-		// darker bolder character set from https://github.com/saw/Canvas-ASCII-Art/
-		// ' .\'`^",:;Il!i~+_-?][}{1)(|/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$'
-
-		// Some ASCII settings
-
-		const fResolution = options[ 'resolution' ] || 0.15;
-		const iScale = options[ 'scale' ] || 1;
-		const bColor = options[ 'color' ] || false;
-		const bAlpha = options[ 'alpha' ] || false;
-		const bBlock = options[ 'block' ] || false;
-		const bInvert = options[ 'invert' ] || false;
-		const strResolution = options[ 'strResolution' ] || 'low';
-
-		let width, height;
-
-		const domElement = document.createElement( 'div' );
-		domElement.style.cursor = 'default';
-
-		const oAscii = document.createElement( 'table' );
-		domElement.appendChild( oAscii );
-
-		let iWidth, iHeight;
-		let oImg;
-
-		/**
-		 * Resizes the effect.
-		 *
-		 * @param {number} w - The width of the effect in logical pixels.
-		 * @param {number} h - The height of the effect in logical pixels.
-		 */
-		this.setSize = function ( w, h ) {
-
-			width = w;
-			height = h;
-
-			renderer.setSize( w, h );
-
-			initAsciiSize();
-
-		};
-
-		/**
-		 * When using this effect, this method should be called instead of the
-		 * default {@link WebGLRenderer#render}.
-		 *
-		 * @param {Object3D} scene - The scene to render.
-		 * @param {Camera} camera - The camera.
-		 */
-		this.render = function ( scene, camera ) {
-
-			renderer.render( scene, camera );
-			asciifyImage( oAscii );
-
-		};
-
-		/**
-		 * The DOM element of the effect. This element must be used instead of the
-		 * default {@link WebGLRenderer#domElement}.
-		 *
-		 * @type {HTMLDivElement}
-		 */
-		this.domElement = domElement;
-
-
-		// Throw in ascii library from https://github.com/hassadee/jsascii/blob/master/jsascii.js (MIT License)
-
-		function initAsciiSize() {
-
-			iWidth = Math.floor( width * fResolution );
-			iHeight = Math.floor( height * fResolution );
-
-			oCanvas.width = iWidth;
-			oCanvas.height = iHeight;
-			// oCanvas.style.display = "none";
-			// oCanvas.style.width = iWidth;
-			// oCanvas.style.height = iHeight;
-
-			oImg = renderer.domElement;
-
-			if ( oImg.style.backgroundColor ) {
-
-				oAscii.rows[ 0 ].cells[ 0 ].style.backgroundColor = oImg.style.backgroundColor;
-				oAscii.rows[ 0 ].cells[ 0 ].style.color = oImg.style.color;
-
-			}
-
-			oAscii.cellSpacing = '0';
-			oAscii.cellPadding = '0';
-
-			const oStyle = oAscii.style;
-			oStyle.whiteSpace = 'pre';
-			oStyle.margin = '0px';
-			oStyle.padding = '0px';
-			oStyle.letterSpacing = fLetterSpacing + 'px';
-			oStyle.fontFamily = strFont;
-			oStyle.fontSize = fFontSize + 'px';
-			oStyle.lineHeight = fLineHeight + 'px';
-			oStyle.textAlign = 'left';
-			oStyle.textDecoration = 'none';
-
-		}
-
-
-		const strFont = 'courier new, monospace';
-
-		const oCanvasImg = renderer.domElement;
-
-		const oCanvas = document.createElement( 'canvas' );
-		if ( ! oCanvas.getContext ) {
-
-			return;
-
-		}
-
-		const oCtx = oCanvas.getContext( '2d' );
-		if ( ! oCtx.getImageData ) {
-
-			return;
-
-		}
-
-		let aCharList;
-		if ( charSet ) {
-
-			aCharList = ( charSet ).split( '' );
-
-		} else {
-
-			const aDefaultCharList = ( ' .,:;i1tfLCG08@' ).split( '' );
-			const aDefaultColorCharList = ( ' CGO08@' ).split( '' );
-			aCharList = ( bColor ? aDefaultColorCharList : aDefaultCharList );
-
-		}
-
-
-		// Setup dom
-
-		const fFontSize = ( 2 / fResolution ) * iScale;
-		const fLineHeight = ( 2 / fResolution ) * iScale;
-
-		// adjust letter-spacing for all combinations of scale and resolution to get it to fit the image width.
-
-		let fLetterSpacing = 0;
-
-		if ( strResolution == 'low' ) {
-
-			switch ( iScale ) {
-
-				case 1 : fLetterSpacing = - 1; break;
-				case 2 :
-				case 3 : fLetterSpacing = - 2.1; break;
-				case 4 : fLetterSpacing = - 3.1; break;
-				case 5 : fLetterSpacing = - 4.15; break;
-
-			}
-
-		}
-
-		if ( strResolution == 'medium' ) {
-
-			switch ( iScale ) {
-
-				case 1 : fLetterSpacing = 0; break;
-				case 2 : fLetterSpacing = - 1; break;
-				case 3 : fLetterSpacing = - 1.04; break;
-				case 4 :
-				case 5 : fLetterSpacing = - 2.1; break;
-
-			}
-
-		}
-
-		if ( strResolution == 'high' ) {
-
-			switch ( iScale ) {
-
-				case 1 :
-				case 2 : fLetterSpacing = 0; break;
-				case 3 :
-				case 4 :
-				case 5 : fLetterSpacing = - 1; break;
-
-			}
-
-		}
-
-
-		// can't get a span or div to flow like an img element, but a table works?
-
-
-		// convert img element to ascii
-
-		function asciifyImage( oAscii ) {
-
-			oCtx.clearRect( 0, 0, iWidth, iHeight );
-			oCtx.drawImage( oCanvasImg, 0, 0, iWidth, iHeight );
-			const oImgData = oCtx.getImageData( 0, 0, iWidth, iHeight ).data;
-
-			// Coloring loop starts now
-			let strChars = '';
-
-			const maxIdx = aCharList.length - 1;
-
-			// console.time('rendering');
-
-			for ( let y = 0; y < iHeight; y += 2 ) {
-
-				for ( let x = 0; x < iWidth; x ++ ) {
-
-					const iOffset = ( y * iWidth + x ) * 4;
-
-					const iRed = oImgData[ iOffset ];
-					const iGreen = oImgData[ iOffset + 1 ];
-					const iBlue = oImgData[ iOffset + 2 ];
-					const iAlpha = oImgData[ iOffset + 3 ];
-
-					let fBrightness = ( 0.3 * iRed + 0.59 * iGreen + 0.11 * iBlue ) / 255;
-					// fBrightness = (0.3*iRed + 0.5*iGreen + 0.3*iBlue) / 255;
-
-
-					if ( iAlpha == 0 ) {
-
-						// should calculate alpha instead, but quick hack :)
-						//fBrightness *= (iAlpha / 255);
-						fBrightness = 1;
-
-					}
-
-					let iCharIdx = Math.round( ( 1 - fBrightness ) * maxIdx );
-
-					if ( bInvert ) {
-
-						iCharIdx = maxIdx - iCharIdx;
-
-					}
-
-					// good for debugging
-					//fBrightness = Math.floor(fBrightness * 10);
-					//strThisChar = fBrightness;
-
-					let strThisChar = aCharList[ iCharIdx ];
-
-					if ( strThisChar === undefined || strThisChar == ' ' )
-						strThisChar = '&nbsp;';
-
-					if ( bColor ) {
-
-						strChars += '<span style=\''
-							+ 'color:rgb(' + iRed + ',' + iGreen + ',' + iBlue + ');'
-							+ ( bBlock ? 'background-color:rgb(' + iRed + ',' + iGreen + ',' + iBlue + ');' : '' )
-							+ ( bAlpha ? 'opacity:' + ( iAlpha / 255 ) + ';' : '' )
-							+ '\'>' + strThisChar + '</span>';
-
-					} else {
-
-						strChars += strThisChar;
-
-					}
-
-				}
-
-				strChars += '<br/>';
-
-			}
-
-			oAscii.innerHTML = `<tr><td style="display:block;width:${width}px;height:${height}px;overflow:hidden">${strChars}</td></tr>`;
-
-			// console.timeEnd('rendering');
-
-			// return oAscii;
-
-		}
-
-	}
-
-}
-
-/**
- * This type represents configuration settings of `AsciiEffect`.
- *
- * @typedef {Object} AsciiEffect~Options
- * @property {number} [resolution=0.15] - A higher value leads to more details.
- * @property {number} [scale=1] - The scale of the effect.
- * @property {boolean} [color=false] - Whether colors should be enabled or not. Better quality but slows down rendering.
- * @property {boolean} [alpha=false] - Whether transparency should be enabled or not.
- * @property {boolean} [block=false] - Whether blocked characters should be enabled or not.
- * @property {boolean} [invert=false] - Whether colors should be inverted or not.
- * @property {('low'|'medium'|'high')} [strResolution='low'] - The string resolution.
- **/
-
-export { AsciiEffect };

+ 0 - 489
node_modules/three/examples/jsm/effects/OutlineEffect.js

@@ -1,489 +0,0 @@
-import {
-	BackSide,
-	Color,
-	ShaderMaterial,
-	UniformsLib,
-	UniformsUtils
-} from 'three';
-
-/**
- * An outline effect for toon shaders.
- *
- * Note that this class can only be used with {@link WebGLRenderer}.
- * When using {@link WebGPURenderer}, use {@link ToonOutlinePassNode}.
- *
- * ```js
- * const effect = new OutlineEffect( renderer );
- *
- * function render() {
- *
- * 	effect.render( scene, camera );
- *
- * }
- * ```
- *
- * @three_import import { OutlineEffect } from 'three/addons/effects/OutlineEffect.js';
- */
-class OutlineEffect {
-
-	/**
-	 * Constructs a new outline effect.
-	 *
-	 * @param {WebGLRenderer} renderer - The renderer.
-	 * @param {OutlineEffect~Options} [parameters] - The configuration parameter.
-	 */
-	constructor( renderer, parameters = {} ) {
-
-		this.enabled = true;
-
-		const defaultThickness = parameters.defaultThickness !== undefined ? parameters.defaultThickness : 0.003;
-		const defaultColor = new Color().fromArray( parameters.defaultColor !== undefined ? parameters.defaultColor : [ 0, 0, 0 ] );
-		const defaultAlpha = parameters.defaultAlpha !== undefined ? parameters.defaultAlpha : 1.0;
-		const defaultKeepAlive = parameters.defaultKeepAlive !== undefined ? parameters.defaultKeepAlive : false;
-
-		// object.material.uuid -> outlineMaterial or
-		// object.material[ n ].uuid -> outlineMaterial
-		// save at the outline material creation and release
-		// if it's unused removeThresholdCount frames
-		// unless keepAlive is true.
-		const cache = {};
-
-		const removeThresholdCount = 60;
-
-		// outlineMaterial.uuid -> object.material or
-		// outlineMaterial.uuid -> object.material[ n ]
-		// save before render and release after render.
-		const originalMaterials = {};
-
-		// object.uuid -> originalOnBeforeRender
-		// save before render and release after render.
-		const originalOnBeforeRenders = {};
-
-		//this.cache = cache;  // for debug
-
-		const uniformsOutline = {
-			outlineThickness: { value: defaultThickness },
-			outlineColor: { value: defaultColor },
-			outlineAlpha: { value: defaultAlpha }
-		};
-
-		const vertexShader = [
-			'#include <common>',
-			'#include <uv_pars_vertex>',
-			'#include <displacementmap_pars_vertex>',
-			'#include <fog_pars_vertex>',
-			'#include <morphtarget_pars_vertex>',
-			'#include <skinning_pars_vertex>',
-			'#include <logdepthbuf_pars_vertex>',
-			'#include <clipping_planes_pars_vertex>',
-
-			'uniform float outlineThickness;',
-
-			'vec4 calculateOutline( vec4 pos, vec3 normal, vec4 skinned ) {',
-			'	float thickness = outlineThickness;',
-			'	const float ratio = 1.0;', // TODO: support outline thickness ratio for each vertex
-			'	vec4 pos2 = projectionMatrix * modelViewMatrix * vec4( skinned.xyz + normal, 1.0 );',
-			// NOTE: subtract pos2 from pos because BackSide objectNormal is negative
-			'	vec4 norm = normalize( pos - pos2 );',
-			'	return pos + norm * thickness * pos.w * ratio;',
-			'}',
-
-			'void main() {',
-
-			'	#include <uv_vertex>',
-
-			'	#include <beginnormal_vertex>',
-			'	#include <morphnormal_vertex>',
-			'	#include <skinbase_vertex>',
-			'	#include <skinnormal_vertex>',
-
-			'	#include <begin_vertex>',
-			'	#include <morphtarget_vertex>',
-			'	#include <skinning_vertex>',
-			'	#include <displacementmap_vertex>',
-			'	#include <project_vertex>',
-
-			'	vec3 outlineNormal = - objectNormal;', // the outline material is always rendered with BackSide
-
-			'	gl_Position = calculateOutline( gl_Position, outlineNormal, vec4( transformed, 1.0 ) );',
-
-			'	#include <logdepthbuf_vertex>',
-			'	#include <clipping_planes_vertex>',
-			'	#include <fog_vertex>',
-
-			'}',
-
-		].join( '\n' );
-
-		const fragmentShader = [
-
-			'#include <common>',
-			'#include <fog_pars_fragment>',
-			'#include <logdepthbuf_pars_fragment>',
-			'#include <clipping_planes_pars_fragment>',
-
-			'uniform vec3 outlineColor;',
-			'uniform float outlineAlpha;',
-
-			'void main() {',
-
-			'	#include <clipping_planes_fragment>',
-			'	#include <logdepthbuf_fragment>',
-
-			'	gl_FragColor = vec4( outlineColor, outlineAlpha );',
-
-			'	#include <tonemapping_fragment>',
-			'	#include <colorspace_fragment>',
-			'	#include <fog_fragment>',
-			'	#include <premultiplied_alpha_fragment>',
-
-			'}'
-
-		].join( '\n' );
-
-		function createMaterial() {
-
-			return new ShaderMaterial( {
-				type: 'OutlineEffect',
-				uniforms: UniformsUtils.merge( [
-					UniformsLib[ 'fog' ],
-					UniformsLib[ 'displacementmap' ],
-					uniformsOutline
-				] ),
-				vertexShader: vertexShader,
-				fragmentShader: fragmentShader,
-				side: BackSide
-			} );
-
-		}
-
-		function getOutlineMaterialFromCache( originalMaterial ) {
-
-			let data = cache[ originalMaterial.uuid ];
-
-			if ( data === undefined ) {
-
-				data = {
-					material: createMaterial(),
-					used: true,
-					keepAlive: defaultKeepAlive,
-					count: 0
-				};
-
-				cache[ originalMaterial.uuid ] = data;
-
-			}
-
-			data.used = true;
-
-			return data.material;
-
-		}
-
-		function getOutlineMaterial( originalMaterial ) {
-
-			const outlineMaterial = getOutlineMaterialFromCache( originalMaterial );
-
-			originalMaterials[ outlineMaterial.uuid ] = originalMaterial;
-
-			updateOutlineMaterial( outlineMaterial, originalMaterial );
-
-			return outlineMaterial;
-
-		}
-
-		function isCompatible( object ) {
-
-			const geometry = object.geometry;
-			const hasNormals = ( geometry !== undefined ) && ( geometry.attributes.normal !== undefined );
-
-			return ( object.isMesh === true && object.material !== undefined && hasNormals === true );
-
-		}
-
-		function setOutlineMaterial( object ) {
-
-			if ( isCompatible( object ) === false ) return;
-
-			if ( Array.isArray( object.material ) ) {
-
-				for ( let i = 0, il = object.material.length; i < il; i ++ ) {
-
-					object.material[ i ] = getOutlineMaterial( object.material[ i ] );
-
-				}
-
-			} else {
-
-				object.material = getOutlineMaterial( object.material );
-
-			}
-
-			originalOnBeforeRenders[ object.uuid ] = object.onBeforeRender;
-			object.onBeforeRender = onBeforeRender;
-
-		}
-
-		function restoreOriginalMaterial( object ) {
-
-			if ( isCompatible( object ) === false ) return;
-
-			if ( Array.isArray( object.material ) ) {
-
-				for ( let i = 0, il = object.material.length; i < il; i ++ ) {
-
-					object.material[ i ] = originalMaterials[ object.material[ i ].uuid ];
-
-				}
-
-			} else {
-
-				object.material = originalMaterials[ object.material.uuid ];
-
-			}
-
-			object.onBeforeRender = originalOnBeforeRenders[ object.uuid ];
-
-		}
-
-		function onBeforeRender( renderer, scene, camera, geometry, material ) {
-
-			const originalMaterial = originalMaterials[ material.uuid ];
-
-			// just in case
-			if ( originalMaterial === undefined ) return;
-
-			updateUniforms( material, originalMaterial );
-
-		}
-
-		function updateUniforms( material, originalMaterial ) {
-
-			const outlineParameters = originalMaterial.userData.outlineParameters;
-
-			material.uniforms.outlineAlpha.value = originalMaterial.opacity;
-
-			if ( outlineParameters !== undefined ) {
-
-				if ( outlineParameters.thickness !== undefined ) material.uniforms.outlineThickness.value = outlineParameters.thickness;
-				if ( outlineParameters.color !== undefined ) material.uniforms.outlineColor.value.fromArray( outlineParameters.color );
-				if ( outlineParameters.alpha !== undefined ) material.uniforms.outlineAlpha.value = outlineParameters.alpha;
-
-			}
-
-			if ( originalMaterial.displacementMap ) {
-
-				material.uniforms.displacementMap.value = originalMaterial.displacementMap;
-				material.uniforms.displacementScale.value = originalMaterial.displacementScale;
-				material.uniforms.displacementBias.value = originalMaterial.displacementBias;
-
-			}
-
-		}
-
-		function updateOutlineMaterial( material, originalMaterial ) {
-
-			if ( material.name === 'invisible' ) return;
-
-			const outlineParameters = originalMaterial.userData.outlineParameters;
-
-			material.fog = originalMaterial.fog;
-			material.toneMapped = originalMaterial.toneMapped;
-			material.premultipliedAlpha = originalMaterial.premultipliedAlpha;
-			material.displacementMap = originalMaterial.displacementMap;
-
-			if ( outlineParameters !== undefined ) {
-
-				if ( originalMaterial.visible === false ) {
-
-					material.visible = false;
-
-				} else {
-
-					material.visible = ( outlineParameters.visible !== undefined ) ? outlineParameters.visible : true;
-
-				}
-
-				material.transparent = ( outlineParameters.alpha !== undefined && outlineParameters.alpha < 1.0 ) ? true : originalMaterial.transparent;
-
-				if ( outlineParameters.keepAlive !== undefined ) cache[ originalMaterial.uuid ].keepAlive = outlineParameters.keepAlive;
-
-			} else {
-
-				material.transparent = originalMaterial.transparent;
-				material.visible = originalMaterial.visible;
-
-			}
-
-			if ( originalMaterial.wireframe === true || originalMaterial.depthTest === false ) material.visible = false;
-
-			if ( originalMaterial.clippingPlanes ) {
-
-				material.clipping = true;
-
-				material.clippingPlanes = originalMaterial.clippingPlanes;
-				material.clipIntersection = originalMaterial.clipIntersection;
-				material.clipShadows = originalMaterial.clipShadows;
-
-			}
-
-			material.version = originalMaterial.version; // update outline material if necessary
-
-		}
-
-		function cleanupCache() {
-
-			let keys;
-
-			// clear originalMaterials
-			keys = Object.keys( originalMaterials );
-
-			for ( let i = 0, il = keys.length; i < il; i ++ ) {
-
-				originalMaterials[ keys[ i ] ] = undefined;
-
-			}
-
-			// clear originalOnBeforeRenders
-			keys = Object.keys( originalOnBeforeRenders );
-
-			for ( let i = 0, il = keys.length; i < il; i ++ ) {
-
-				originalOnBeforeRenders[ keys[ i ] ] = undefined;
-
-			}
-
-			// remove unused outlineMaterial from cache
-			keys = Object.keys( cache );
-
-			for ( let i = 0, il = keys.length; i < il; i ++ ) {
-
-				const key = keys[ i ];
-
-				if ( cache[ key ].used === false ) {
-
-					cache[ key ].count ++;
-
-					if ( cache[ key ].keepAlive === false && cache[ key ].count > removeThresholdCount ) {
-
-						delete cache[ key ];
-
-					}
-
-				} else {
-
-					cache[ key ].used = false;
-					cache[ key ].count = 0;
-
-				}
-
-			}
-
-		}
-
-		/**
-		 * When using this effect, this method should be called instead of the
-		 * default {@link WebGLRenderer#render}.
-		 *
-		 * @param {Object3D} scene - The scene to render.
-		 * @param {Camera} camera - The camera.
-		 */
-		this.render = function ( scene, camera ) {
-
-			if ( this.enabled === false ) {
-
-				renderer.render( scene, camera );
-				return;
-
-			}
-
-			const currentAutoClear = renderer.autoClear;
-			renderer.autoClear = this.autoClear;
-
-			renderer.render( scene, camera );
-
-			renderer.autoClear = currentAutoClear;
-
-			this.renderOutline( scene, camera );
-
-		};
-
-		/**
-		 * This method can be used to render outlines in VR.
-		 *
-		 * ```js
-		 * const effect = new OutlineEffect( renderer );
-		 * let renderingOutline = false;
-		 *
-		 * scene.onAfterRender = function () {
-		 *
-		 * 	if ( renderingOutline ) return;
-		 *
-		 * 	renderingOutline = true;
-		 * 	effect.renderOutline( scene, camera );
-		 * 	renderingOutline = false;
-		 * };
-		 *
-		 * function render() {
-		 * 	renderer.render( scene, camera );
-		 * }
-		 * ```
-		 *
-		 * @param {Object3D} scene - The scene to render.
-		 * @param {Camera} camera - The camera.
-		 */
-		this.renderOutline = function ( scene, camera ) {
-
-			const currentAutoClear = renderer.autoClear;
-			const currentSceneAutoUpdate = scene.matrixWorldAutoUpdate;
-			const currentSceneBackground = scene.background;
-			const currentShadowMapEnabled = renderer.shadowMap.enabled;
-
-			scene.matrixWorldAutoUpdate = false;
-			scene.background = null;
-			renderer.autoClear = false;
-			renderer.shadowMap.enabled = false;
-
-			scene.traverse( setOutlineMaterial );
-
-			renderer.render( scene, camera );
-
-			scene.traverse( restoreOriginalMaterial );
-
-			cleanupCache();
-
-			scene.matrixWorldAutoUpdate = currentSceneAutoUpdate;
-			scene.background = currentSceneBackground;
-			renderer.autoClear = currentAutoClear;
-			renderer.shadowMap.enabled = currentShadowMapEnabled;
-
-		};
-
-		/**
-		 * Resizes the effect.
-		 *
-		 * @param {number} width - The width of the effect in logical pixels.
-		 * @param {number} height - The height of the effect in logical pixels.
-		 */
-		this.setSize = function ( width, height ) {
-
-			renderer.setSize( width, height );
-
-		};
-
-	}
-
-}
-
-/**
- * This type represents configuration settings of `OutlineEffect`.
- *
- * @typedef {Object} OutlineEffect~Options
- * @property {number} [defaultThickness=0.003] - The outline thickness.
- * @property {Array<number>} [defaultColor=[0,0,0]] - The outline color.
- * @property {number} [defaultAlpha=1] - The outline alpha value.
- * @property {boolean} [defaultKeepAlive=false] - Whether to keep alive cached internal materials or not.
- **/
-
-
-export { OutlineEffect };

+ 0 - 155
node_modules/three/examples/jsm/effects/ParallaxBarrierEffect.js

@@ -1,155 +0,0 @@
-import {
-	LinearFilter,
-	NearestFilter,
-	RGBAFormat,
-	ShaderMaterial,
-	StereoCamera,
-	WebGLRenderTarget
-} from 'three';
-import { FullScreenQuad } from '../postprocessing/Pass.js';
-
-/**
- * A class that creates an parallax barrier effect.
- *
- * Note that this class can only be used with {@link WebGLRenderer}.
- * When using {@link WebGPURenderer}, use {@link ParallaxBarrierPassNode}.
- *
- * @three_import import { ParallaxBarrierEffect } from 'three/addons/effects/ParallaxBarrierEffect.js';
- */
-class ParallaxBarrierEffect {
-
-	/**
-	 * Constructs a new parallax barrier effect.
-	 *
-	 * @param {WebGLRenderer} renderer - The renderer.
-	 */
-	constructor( renderer ) {
-
-		const _stereo = new StereoCamera();
-
-		const _params = { minFilter: LinearFilter, magFilter: NearestFilter, format: RGBAFormat };
-
-		const _renderTargetL = new WebGLRenderTarget( 512, 512, _params );
-		const _renderTargetR = new WebGLRenderTarget( 512, 512, _params );
-
-		const _material = new ShaderMaterial( {
-
-			uniforms: {
-
-				'mapLeft': { value: _renderTargetL.texture },
-				'mapRight': { value: _renderTargetR.texture }
-
-			},
-
-			vertexShader: [
-
-				'varying vec2 vUv;',
-
-				'void main() {',
-
-				'	vUv = vec2( uv.x, uv.y );',
-				'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
-
-				'}'
-
-			].join( '\n' ),
-
-			fragmentShader: [
-
-				'uniform sampler2D mapLeft;',
-				'uniform sampler2D mapRight;',
-				'varying vec2 vUv;',
-
-				'void main() {',
-
-				'	vec2 uv = vUv;',
-
-				'	if ( ( mod( gl_FragCoord.y, 2.0 ) ) > 1.00 ) {',
-
-				'		gl_FragColor = texture2D( mapLeft, uv );',
-
-				'	} else {',
-
-				'		gl_FragColor = texture2D( mapRight, uv );',
-
-				'	}',
-
-				'	#include <tonemapping_fragment>',
-				'	#include <colorspace_fragment>',
-
-				'}'
-
-			].join( '\n' )
-
-		} );
-
-		const _quad = new FullScreenQuad( _material );
-
-		/**
-		 * Resizes the effect.
-		 *
-		 * @param {number} width - The width of the effect in logical pixels.
-		 * @param {number} height - The height of the effect in logical pixels.
-		 */
-		this.setSize = function ( width, height ) {
-
-			renderer.setSize( width, height );
-
-			const pixelRatio = renderer.getPixelRatio();
-
-			_renderTargetL.setSize( width * pixelRatio, height * pixelRatio );
-			_renderTargetR.setSize( width * pixelRatio, height * pixelRatio );
-
-		};
-
-		/**
-		 * When using this effect, this method should be called instead of the
-		 * default {@link WebGLRenderer#render}.
-		 *
-		 * @param {Object3D} scene - The scene to render.
-		 * @param {Camera} camera - The camera.
-		 */
-		this.render = function ( scene, camera ) {
-
-			const currentRenderTarget = renderer.getRenderTarget();
-
-			if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
-
-			if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
-
-			_stereo.update( camera );
-
-			renderer.setRenderTarget( _renderTargetL );
-			renderer.clear();
-			renderer.render( scene, _stereo.cameraL );
-
-			renderer.setRenderTarget( _renderTargetR );
-			renderer.clear();
-			renderer.render( scene, _stereo.cameraR );
-
-			renderer.setRenderTarget( null );
-			_quad.render( renderer );
-
-			renderer.setRenderTarget( currentRenderTarget );
-
-		};
-
-		/**
-		 * Frees internal resources. This method should be called
-		 * when the effect is no longer required.
-		 */
-		this.dispose = function () {
-
-			_renderTargetL.dispose();
-			_renderTargetR.dispose();
-
-			_material.dispose();
-			_quad.dispose();
-
-		};
-
-	}
-
-}
-
-export { ParallaxBarrierEffect };

+ 0 - 91
node_modules/three/examples/jsm/effects/StereoEffect.js

@@ -1,91 +0,0 @@
-import {
-	StereoCamera,
-	Vector2
-} from 'three';
-
-/**
- * A class that creates an stereo effect.
- *
- * Note that this class can only be used with {@link WebGLRenderer}.
- * When using {@link WebGPURenderer}, use {@link StereoPassNode}.
- *
- * @three_import import { StereoEffect } from 'three/addons/effects/StereoEffect.js';
- */
-class StereoEffect {
-
-	/**
-	 * Constructs a new stereo effect.
-	 *
-	 * @param {WebGLRenderer} renderer - The renderer.
-	 */
-	constructor( renderer ) {
-
-		const _stereo = new StereoCamera();
-		_stereo.aspect = 0.5;
-		const size = new Vector2();
-
-		/**
-		 * Sets the given eye separation.
-		 *
-		 * @param {number} eyeSep - The eye separation to set.
-		 */
-		this.setEyeSeparation = function ( eyeSep ) {
-
-			_stereo.eyeSep = eyeSep;
-
-		};
-
-		/**
-		 * Resizes the effect.
-		 *
-		 * @param {number} width - The width of the effect in logical pixels.
-		 * @param {number} height - The height of the effect in logical pixels.
-		 */
-		this.setSize = function ( width, height ) {
-
-			renderer.setSize( width, height );
-
-		};
-
-		/**
-		 * When using this effect, this method should be called instead of the
-		 * default {@link WebGLRenderer#render}.
-		 *
-		 * @param {Object3D} scene - The scene to render.
-		 * @param {Camera} camera - The camera.
-		 */
-		this.render = function ( scene, camera ) {
-
-			if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
-
-			if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
-
-			_stereo.update( camera );
-
-			const currentAutoClear = renderer.autoClear;
-			renderer.getSize( size );
-
-			renderer.autoClear = false;
-			renderer.clear();
-
-			renderer.setScissorTest( true );
-
-			renderer.setScissor( 0, 0, size.width / 2, size.height );
-			renderer.setViewport( 0, 0, size.width / 2, size.height );
-			renderer.render( scene, _stereo.cameraL );
-
-			renderer.setScissor( size.width / 2, 0, size.width / 2, size.height );
-			renderer.setViewport( size.width / 2, 0, size.width / 2, size.height );
-			renderer.render( scene, _stereo.cameraR );
-
-			renderer.setScissorTest( false );
-
-			renderer.autoClear = currentAutoClear;
-
-		};
-
-	}
-
-}
-
-export { StereoEffect };

+ 0 - 59
node_modules/three/examples/jsm/environments/ColorEnvironment.js

@@ -1,59 +0,0 @@
-import {
-	BackSide,
-	Mesh,
-	MeshBasicMaterial,
-	SphereGeometry,
-	Scene
-} from 'three';
-
-/**
- * This class represents a scene with a uniform color that can be used as
- * input for {@link PMREMGenerator#fromScene}. The resulting PMREM represents
- * uniform ambient lighting and can be used for Image Based Lighting by
- * assigning it to {@link Scene#environment}.
- *
- * ```js
- * const environment = new ColorEnvironment( 0x00ff00 );
- * const pmremGenerator = new THREE.PMREMGenerator( renderer );
- *
- * const envMap = pmremGenerator.fromScene( environment ).texture;
- * scene.environment = envMap;
- * ```
- *
- * @augments Scene
- * @three_import import { ColorEnvironment } from 'three/addons/environments/ColorEnvironment.js';
- */
-class ColorEnvironment extends Scene {
-
-	/**
-	 * Constructs a new color environment.
-	 *
-	 * @param {number|Color} color - The color of the environment.
-	 */
-	constructor( color = 0xffffff ) {
-
-		super();
-
-		this.name = 'ColorEnvironment';
-
-		const geometry = new SphereGeometry( 1, 16, 16 );
-		const material = new MeshBasicMaterial( { color: color, side: BackSide } );
-
-		this.add( new Mesh( geometry, material ) );
-
-	}
-
-	/**
-	 * Frees internal resources. This method should be called
-	 * when the environment is no longer required.
-	 */
-	dispose() {
-
-		this.children[ 0 ].geometry.dispose();
-		this.children[ 0 ].material.dispose();
-
-	}
-
-}
-
-export { ColorEnvironment };

+ 0 - 102
node_modules/three/examples/jsm/environments/DebugEnvironment.js

@@ -1,102 +0,0 @@
-import {
-	BackSide,
-	BoxGeometry,
-	Mesh,
-	MeshLambertMaterial,
-	MeshStandardMaterial,
-	PointLight,
-	Scene,
-} from 'three';
-
-/**
- * This class represents a scene with a very basic room setup that can be used as
- * input for {@link PMREMGenerator#fromScene}. The resulting PMREM represents the room's
- * lighting and can be used for Image Based Lighting by assigning it to {@link Scene#environment}
- * or directly as an environment map to PBR materials.
- *
- * This class uses a simple room setup and should only be used for development purposes.
- * A more appropriate setup for production is {@link RoomEnvironment}.
- *
- * ```js
- * const environment = new DebugEnvironment();
- * const pmremGenerator = new THREE.PMREMGenerator( renderer );
- *
- * const envMap = pmremGenerator.fromScene( environment ).texture;
- * scene.environment = envMap;
- * ```
- *
- * @augments Scene
- * @three_import import { DebugEnvironment } from 'three/addons/environments/DebugEnvironment.js';
- */
-class DebugEnvironment extends Scene {
-
-	/**
-	 * Constructs a new debug environment.
-	 */
-	constructor() {
-
-		super();
-
-		const geometry = new BoxGeometry();
-		geometry.deleteAttribute( 'uv' );
-		const roomMaterial = new MeshStandardMaterial( { metalness: 0, side: BackSide } );
-		const room = new Mesh( geometry, roomMaterial );
-		room.scale.setScalar( 10 );
-		this.add( room );
-
-		const mainLight = new PointLight( 0xffffff, 50, 0, 2 );
-		this.add( mainLight );
-
-		const material1 = new MeshLambertMaterial( { color: 0xff0000, emissive: 0xffffff, emissiveIntensity: 10 } );
-
-		const light1 = new Mesh( geometry, material1 );
-		light1.position.set( - 5, 2, 0 );
-		light1.scale.set( 0.1, 1, 1 );
-		this.add( light1 );
-
-		const material2 = new MeshLambertMaterial( { color: 0x00ff00, emissive: 0xffffff, emissiveIntensity: 10 } );
-
-		const light2 = new Mesh( geometry, material2 );
-		light2.position.set( 0, 5, 0 );
-		light2.scale.set( 1, 0.1, 1 );
-		this.add( light2 );
-
-		const material3 = new MeshLambertMaterial( { color: 0x0000ff, emissive: 0xffffff, emissiveIntensity: 10 } );
-
-		const light3 = new Mesh( geometry, material3 );
-		light3.position.set( 2, 1, 5 );
-		light3.scale.set( 1.5, 2, 0.1 );
-		this.add( light3 );
-
-	}
-
-	/**
-	 * Frees internal resources. This method should be called
-	 * when the environment is no longer required.
-	 */
-	dispose() {
-
-		const resources = new Set();
-
-		this.traverse( ( object ) => {
-
-			if ( object.isMesh ) {
-
-				resources.add( object.geometry );
-				resources.add( object.material );
-
-			}
-
-		} );
-
-		for ( const resource of resources ) {
-
-			resource.dispose();
-
-		}
-
-	}
-
-}
-
-export { DebugEnvironment };

+ 0 - 185
node_modules/three/examples/jsm/environments/RoomEnvironment.js

@@ -1,185 +0,0 @@
-import {
- 	BackSide,
- 	BoxGeometry,
- 	InstancedMesh,
- 	Mesh,
-	MeshLambertMaterial,
- 	MeshStandardMaterial,
- 	PointLight,
- 	Scene,
- 	Object3D,
-} from 'three';
-
-/**
- * This class represents a scene with a basic room setup that can be used as
- * input for {@link PMREMGenerator#fromScene}. The resulting PMREM represents the room's
- * lighting and can be used for Image Based Lighting by assigning it to {@link Scene#environment}
- * or directly as an environment map to PBR materials.
- *
- * The implementation is based on the [EnvironmentScene](https://github.com/google/model-viewer/blob/master/packages/model-viewer/src/three-components/EnvironmentScene.ts)
- * component from the `model-viewer` project.
- *
- * ```js
- * const environment = new RoomEnvironment();
- * const pmremGenerator = new THREE.PMREMGenerator( renderer );
- *
- * const envMap = pmremGenerator.fromScene( environment ).texture;
- * scene.environment = envMap;
- * ```
- *
- * @augments Scene
- * @three_import import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';
- */
-class RoomEnvironment extends Scene {
-
-	constructor() {
-
-		super();
-
-		this.name = 'RoomEnvironment';
-		this.position.y = - 3.5;
-
-		const geometry = new BoxGeometry();
-		geometry.deleteAttribute( 'uv' );
-
-		const roomMaterial = new MeshStandardMaterial( { side: BackSide } );
-		const boxMaterial = new MeshStandardMaterial();
-
-		const mainLight = new PointLight( 0xffffff, 900, 28, 2 );
-		mainLight.position.set( 0.418, 16.199, 0.300 );
-		this.add( mainLight );
-
-		const room = new Mesh( geometry, roomMaterial );
-		room.position.set( - 0.757, 13.219, 0.717 );
-		room.scale.set( 31.713, 28.305, 28.591 );
-		this.add( room );
-
-		const boxes = new InstancedMesh( geometry, boxMaterial, 6 );
-		const transform = new Object3D();
-
-		// box1
-		transform.position.set( - 10.906, 2.009, 1.846 );
-		transform.rotation.set( 0, - 0.195, 0 );
-		transform.scale.set( 2.328, 7.905, 4.651 );
-		transform.updateMatrix();
-		boxes.setMatrixAt( 0, transform.matrix );
-
-		// box2
-		transform.position.set( - 5.607, - 0.754, - 0.758 );
-		transform.rotation.set( 0, 0.994, 0 );
-		transform.scale.set( 1.970, 1.534, 3.955 );
-		transform.updateMatrix();
-		boxes.setMatrixAt( 1, transform.matrix );
-
-		// box3
-		transform.position.set( 6.167, 0.857, 7.803 );
-		transform.rotation.set( 0, 0.561, 0 );
-		transform.scale.set( 3.927, 6.285, 3.687 );
-		transform.updateMatrix();
-		boxes.setMatrixAt( 2, transform.matrix );
-
-		// box4
-		transform.position.set( - 2.017, 0.018, 6.124 );
-		transform.rotation.set( 0, 0.333, 0 );
-		transform.scale.set( 2.002, 4.566, 2.064 );
-		transform.updateMatrix();
-		boxes.setMatrixAt( 3, transform.matrix );
-
-		// box5
-		transform.position.set( 2.291, - 0.756, - 2.621 );
-		transform.rotation.set( 0, - 0.286, 0 );
-		transform.scale.set( 1.546, 1.552, 1.496 );
-		transform.updateMatrix();
-		boxes.setMatrixAt( 4, transform.matrix );
-
-		// box6
-		transform.position.set( - 2.193, - 0.369, - 5.547 );
-		transform.rotation.set( 0, 0.516, 0 );
-		transform.scale.set( 3.875, 3.487, 2.986 );
-		transform.updateMatrix();
-		boxes.setMatrixAt( 5, transform.matrix );
-
-		this.add( boxes );
-
-
-		// -x right
-		const light1 = new Mesh( geometry, createAreaLightMaterial( 50 ) );
-		light1.position.set( - 16.116, 14.37, 8.208 );
-		light1.scale.set( 0.1, 2.428, 2.739 );
-		this.add( light1 );
-
-		// -x left
-		const light2 = new Mesh( geometry, createAreaLightMaterial( 50 ) );
-		light2.position.set( - 16.109, 18.021, - 8.207 );
-		light2.scale.set( 0.1, 2.425, 2.751 );
-		this.add( light2 );
-
-		// +x
-		const light3 = new Mesh( geometry, createAreaLightMaterial( 17 ) );
-		light3.position.set( 14.904, 12.198, - 1.832 );
-		light3.scale.set( 0.15, 4.265, 6.331 );
-		this.add( light3 );
-
-		// +z
-		const light4 = new Mesh( geometry, createAreaLightMaterial( 43 ) );
-		light4.position.set( - 0.462, 8.89, 14.520 );
-		light4.scale.set( 4.38, 5.441, 0.088 );
-		this.add( light4 );
-
-		// -z
-		const light5 = new Mesh( geometry, createAreaLightMaterial( 20 ) );
-		light5.position.set( 3.235, 11.486, - 12.541 );
-		light5.scale.set( 2.5, 2.0, 0.1 );
-		this.add( light5 );
-
-		// +y
-		const light6 = new Mesh( geometry, createAreaLightMaterial( 100 ) );
-		light6.position.set( 0.0, 20.0, 0.0 );
-		light6.scale.set( 1.0, 0.1, 1.0 );
-		this.add( light6 );
-
-	}
-
-	/**
-	 * Frees internal resources. This method should be called
-	 * when the environment is no longer required.
-	 */
-	dispose() {
-
-		const resources = new Set();
-
-		this.traverse( ( object ) => {
-
-			if ( object.isMesh ) {
-
-				resources.add( object.geometry );
-				resources.add( object.material );
-
-			}
-
-		} );
-
-		for ( const resource of resources ) {
-
-			resource.dispose();
-
-		}
-
-	}
-
-}
-
-function createAreaLightMaterial( intensity ) {
-
-	// create an emissive-only material. see #31348
-	const material = new MeshLambertMaterial( {
-		color: 0x000000,
-		emissive: 0xffffff,
-		emissiveIntensity: intensity
-	} );
-
-	return material;
-
-}
-
-export { RoomEnvironment };

+ 0 - 311
node_modules/three/examples/jsm/exporters/DRACOExporter.js

@@ -1,311 +0,0 @@
-import { Color, ColorManagement, SRGBColorSpace } from 'three';
-
-/* global DracoEncoderModule */
-
-/**
- * An exporter to compress geometry with the Draco library.
- *
- * [Draco](https://google.github.io/draco/) is an open source library for compressing and
- * decompressing 3D meshes and point clouds. Compressed geometry can be significantly smaller,
- * at the cost of additional decoding time on the client device.
- *
- * Standalone Draco files have a `.drc` extension, and contain vertex positions,
- * normals, colors, and other attributes. Draco files *do not* contain materials,
- * textures, animation, or node hierarchies – to use these features, embed Draco geometry
- * inside of a glTF file. A normal glTF file can be converted to a Draco-compressed glTF file
- * using [glTF-Pipeline](https://github.com/AnalyticalGraphicsInc/gltf-pipeline).
- *
- * ```js
- * const exporter = new DRACOExporter();
- * const data = exporter.parse( mesh, options );
- * ```
- *
- * @three_import import { DRACOExporter } from 'three/addons/exporters/DRACOExporter.js';
- */
-class DRACOExporter {
-
-	/**
-	 * Parses the given mesh or point cloud and generates the Draco output.
-	 *
-	 * @param {(Mesh|Points)} object - The mesh or point cloud to export.
-	 * @param {DRACOExporter~Options} options - The export options.
-	 * @return {Int8Array} The exported Draco.
-	 */
-	parse( object, options = {} ) {
-
-		options = Object.assign( {
-			decodeSpeed: 5,
-			encodeSpeed: 5,
-			encoderMethod: DRACOExporter.MESH_EDGEBREAKER_ENCODING,
-			quantization: [ 16, 8, 8, 8, 8 ],
-			exportUvs: true,
-			exportNormals: true,
-			exportColor: false,
-		}, options );
-
-		if ( DracoEncoderModule === undefined ) {
-
-			throw new Error( 'THREE.DRACOExporter: required the draco_encoder to work.' );
-
-		}
-
-		const geometry = object.geometry;
-
-		const dracoEncoder = DracoEncoderModule();
-		const encoder = new dracoEncoder.Encoder();
-		let builder;
-		let dracoObject;
-
-		if ( object.isMesh === true ) {
-
-			builder = new dracoEncoder.MeshBuilder();
-			dracoObject = new dracoEncoder.Mesh();
-
-			const vertices = geometry.getAttribute( 'position' );
-			builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.POSITION, vertices.count, vertices.itemSize, vertices.array );
-
-			const faces = geometry.getIndex();
-
-			if ( faces !== null ) {
-
-				builder.AddFacesToMesh( dracoObject, faces.count / 3, faces.array );
-
-			} else {
-
-				const faces = new ( vertices.count > 65535 ? Uint32Array : Uint16Array )( vertices.count );
-
-				for ( let i = 0; i < faces.length; i ++ ) {
-
-					faces[ i ] = i;
-
-				}
-
-				builder.AddFacesToMesh( dracoObject, vertices.count, faces );
-
-			}
-
-			if ( options.exportNormals === true ) {
-
-				const normals = geometry.getAttribute( 'normal' );
-
-				if ( normals !== undefined ) {
-
-					builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.NORMAL, normals.count, normals.itemSize, normals.array );
-
-				}
-
-			}
-
-			if ( options.exportUvs === true ) {
-
-				const uvs = geometry.getAttribute( 'uv' );
-
-				if ( uvs !== undefined ) {
-
-					builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.TEX_COORD, uvs.count, uvs.itemSize, uvs.array );
-
-				}
-
-			}
-
-			if ( options.exportColor === true ) {
-
-				const colors = geometry.getAttribute( 'color' );
-
-				if ( colors !== undefined ) {
-
-					const array = createVertexColorSRGBArray( colors );
-
-					builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.COLOR, colors.count, colors.itemSize, array );
-
-				}
-
-			}
-
-		} else if ( object.isPoints === true ) {
-
-			builder = new dracoEncoder.PointCloudBuilder();
-			dracoObject = new dracoEncoder.PointCloud();
-
-			const vertices = geometry.getAttribute( 'position' );
-			builder.AddFloatAttribute( dracoObject, dracoEncoder.POSITION, vertices.count, vertices.itemSize, vertices.array );
-
-			if ( options.exportColor === true ) {
-
-				const colors = geometry.getAttribute( 'color' );
-
-				if ( colors !== undefined ) {
-
-					const array = createVertexColorSRGBArray( colors );
-
-					builder.AddFloatAttribute( dracoObject, dracoEncoder.COLOR, colors.count, colors.itemSize, array );
-
-				}
-
-			}
-
-		} else {
-
-			throw new Error( 'DRACOExporter: Unsupported object type.' );
-
-		}
-
-		//Compress using draco encoder
-
-		const encodedData = new dracoEncoder.DracoInt8Array();
-
-		//Sets the desired encoding and decoding speed for the given options from 0 (slowest speed, but the best compression) to 10 (fastest, but the worst compression).
-
-		const encodeSpeed = ( options.encodeSpeed !== undefined ) ? options.encodeSpeed : 5;
-		const decodeSpeed = ( options.decodeSpeed !== undefined ) ? options.decodeSpeed : 5;
-
-		encoder.SetSpeedOptions( encodeSpeed, decodeSpeed );
-
-		// Sets the desired encoding method for a given geometry.
-
-		if ( options.encoderMethod !== undefined ) {
-
-			encoder.SetEncodingMethod( options.encoderMethod );
-
-		}
-
-		// Sets the quantization (number of bits used to represent) compression options for a named attribute.
-		// The attribute values will be quantized in a box defined by the maximum extent of the attribute values.
-		if ( options.quantization !== undefined ) {
-
-			for ( let i = 0; i < 5; i ++ ) {
-
-				if ( options.quantization[ i ] !== undefined ) {
-
-					encoder.SetAttributeQuantization( i, options.quantization[ i ] );
-
-				}
-
-			}
-
-		}
-
-		let length;
-
-		if ( object.isMesh === true ) {
-
-			length = encoder.EncodeMeshToDracoBuffer( dracoObject, encodedData );
-
-		} else {
-
-			length = encoder.EncodePointCloudToDracoBuffer( dracoObject, true, encodedData );
-
-		}
-
-		dracoEncoder.destroy( dracoObject );
-
-		if ( length === 0 ) {
-
-			throw new Error( 'THREE.DRACOExporter: Draco encoding failed.' );
-
-		}
-
-		//Copy encoded data to buffer.
-		const outputData = new Int8Array( new ArrayBuffer( length ) );
-
-		for ( let i = 0; i < length; i ++ ) {
-
-			outputData[ i ] = encodedData.GetValue( i );
-
-		}
-
-		dracoEncoder.destroy( encodedData );
-		dracoEncoder.destroy( encoder );
-		dracoEncoder.destroy( builder );
-
-		return outputData;
-
-	}
-
-}
-
-function createVertexColorSRGBArray( attribute ) {
-
-	// While .drc files do not specify colorspace, the only 'official' tooling
-	// is PLY and OBJ converters, which use sRGB. We'll assume sRGB is expected
-	// for .drc files, but note that Draco buffers embedded in glTF files will
-	// be Linear-sRGB instead.
-
-	const _color = new Color();
-
-	const count = attribute.count;
-	const itemSize = attribute.itemSize;
-	const array = new Float32Array( count * itemSize );
-
-	for ( let i = 0, il = count; i < il; i ++ ) {
-
-		_color.fromBufferAttribute( attribute, i );
-
-		ColorManagement.workingToColorSpace( _color, SRGBColorSpace );
-
-		array[ i * itemSize ] = _color.r;
-		array[ i * itemSize + 1 ] = _color.g;
-		array[ i * itemSize + 2 ] = _color.b;
-
-		if ( itemSize === 4 ) {
-
-			array[ i * itemSize + 3 ] = attribute.getW( i );
-
-		}
-
-	}
-
-	return array;
-
-}
-
-// Encoder methods
-
-/**
- * Edgebreaker encoding.
- *
- * @static
- * @constant
- * @type {number}
- * @default 1
- */
-DRACOExporter.MESH_EDGEBREAKER_ENCODING = 1;
-
-/**
- * Sequential encoding.
- *
- * @static
- * @constant
- * @type {number}
- * @default 0
- */
-DRACOExporter.MESH_SEQUENTIAL_ENCODING = 0;
-
-// Geometry type
-
-DRACOExporter.POINT_CLOUD = 0;
-DRACOExporter.TRIANGULAR_MESH = 1;
-
-// Attribute type
-
-DRACOExporter.INVALID = - 1;
-DRACOExporter.POSITION = 0;
-DRACOExporter.NORMAL = 1;
-DRACOExporter.COLOR = 2;
-DRACOExporter.TEX_COORD = 3;
-DRACOExporter.GENERIC = 4;
-
-/**
- * Export options of `DRACOExporter`.
- *
- * @typedef {Object} DRACOExporter~Options
- * @property {number} [decodeSpeed=5] - Indicates how to tune the encoder regarding decode speed (0 gives better speed but worst quality).
- * @property {number} [encodeSpeed=5] - Indicates how to tune the encoder parameters (0 gives better speed but worst quality).
- * @property {number} [encoderMethod=1] - Either sequential (very little compression) or Edgebreaker. Edgebreaker traverses the triangles of the mesh in a deterministic, spiral-like way which provides most of the benefits of this data format.
- * @property {Array<number>} [quantization=[ 16, 8, 8, 8, 8 ]] - Indicates the precision of each type of data stored in the draco file in the order (POSITION, NORMAL, COLOR, TEX_COORD, GENERIC).
- * @property {boolean} [exportUvs=true] - Whether to export UVs or not.
- * @property {boolean} [exportNormals=true] - Whether to export normals or not.
- * @property {boolean} [exportColor=false] - Whether to export colors or not.
- **/
-
-export { DRACOExporter };

+ 0 - 618
node_modules/three/examples/jsm/exporters/EXRExporter.js

@@ -1,618 +0,0 @@
-import {
-	FloatType,
-	HalfFloatType,
-	RGBAFormat,
-	DataUtils,
-} from 'three';
-import * as fflate from '../libs/fflate.module.js';
-
-const textEncoder = new TextEncoder();
-
-const NO_COMPRESSION = 0;
-const ZIPS_COMPRESSION = 2;
-const ZIP_COMPRESSION = 3;
-
-/**
- * An exporter for EXR.
- *
- * EXR ( Extended Dynamic Range) is an [open format specification](https://github.com/AcademySoftwareFoundation/openexr)
- * for professional-grade image storage format of the motion picture industry. The purpose of
- * format is to accurately and efficiently represent high-dynamic-range scene-linear image data
- * and associated metadata. The library is widely used in host application software where accuracy
- * is critical, such as photorealistic rendering, texture access, image compositing, deep compositing,
- * and DI.
- *
- * ```js
- * const exporter = new EXRExporter();
- * const result = await exporter.parse( renderer, options );
- * ```
- *
- * @three_import import { EXRExporter } from 'three/addons/exporters/EXRExporter.js';
- */
-class EXRExporter {
-
-	/**
-	 * This method has two variants.
-	 *
-	 * - When exporting a data texture, it receives two parameters. The texture and the exporter options.
-	 * - When exporting a render target (e.g. a PMREM), it receives three parameters. The renderer, the
-	 * render target and the exporter options.
-	 *
-	 * @async
-	 * @param {(DataTexture|WebGPURenderer|WebGLRenderer)} arg1 - The data texture to export or a renderer.
-	 * @param {(EXRExporter~Options|RenderTarget)} arg2 - The exporter options or a render target.
-	 * @param {EXRExporter~Options} [arg3] - The exporter options.
-	 * @return {Promise<Uint8Array>} A Promise that resolves with the exported EXR.
-	 */
-	async parse( arg1, arg2, arg3 ) {
-
-		if ( ! arg1 || ! ( arg1.isWebGLRenderer || arg1.isWebGPURenderer || arg1.isDataTexture ) ) {
-
-			throw Error( 'EXRExporter.parse: Unsupported first parameter, expected instance of WebGLRenderer, WebGPURenderer or DataTexture.' );
-
-		} else if ( arg1.isWebGLRenderer || arg1.isWebGPURenderer ) {
-
-			const renderer = arg1, renderTarget = arg2, options = arg3;
-
-			supportedRTT( renderTarget );
-
-			const info = buildInfoRTT( renderTarget, options ),
-				dataBuffer = await getPixelData( renderer, renderTarget, info ),
-				rawContentBuffer = reorganizeDataBuffer( dataBuffer, info ),
-				chunks = compressData( rawContentBuffer, info );
-
-			return fillData( chunks, info );
-
-		} else if ( arg1.isDataTexture ) {
-
-			const texture = arg1, options = arg2;
-
-			supportedDT( texture );
-
-			const info = buildInfoDT( texture, options ),
-				dataBuffer = texture.image.data,
-				rawContentBuffer = reorganizeDataBuffer( dataBuffer, info ),
-				chunks = compressData( rawContentBuffer, info );
-
-			return fillData( chunks, info );
-
-		}
-
-	}
-
-}
-
-function supportedRTT( renderTarget ) {
-
-	if ( ! renderTarget || ! renderTarget.isRenderTarget ) {
-
-		throw Error( 'EXRExporter.parse: Unsupported second parameter, expected instance of WebGLRenderTarget.' );
-
-	}
-
-	if ( renderTarget.isCubeRenderTarget || renderTarget.isWebGLCubeRenderTarget || renderTarget.isWebGL3DRenderTarget || renderTarget.isWebGLArrayRenderTarget ) {
-
-		throw Error( 'EXRExporter.parse: Unsupported render target type, expected instance of WebGLRenderTarget.' );
-
-	}
-
-	if ( renderTarget.texture.type !== FloatType && renderTarget.texture.type !== HalfFloatType ) {
-
-		throw Error( 'EXRExporter.parse: Unsupported WebGLRenderTarget texture type.' );
-
-	}
-
-	if ( renderTarget.texture.format !== RGBAFormat ) {
-
-		throw Error( 'EXRExporter.parse: Unsupported WebGLRenderTarget texture format, expected RGBAFormat.' );
-
-	}
-
-}
-
-function supportedDT( texture ) {
-
-	if ( texture.type !== FloatType && texture.type !== HalfFloatType ) {
-
-		throw Error( 'EXRExporter.parse: Unsupported DataTexture texture type.' );
-
-	}
-
-	if ( texture.format !== RGBAFormat ) {
-
-		throw Error( 'EXRExporter.parse: Unsupported DataTexture texture format, expected RGBAFormat.' );
-
-	}
-
-	if ( ! texture.image.data ) {
-
-		throw Error( 'EXRExporter.parse: Invalid DataTexture image data.' );
-
-	}
-
-	if ( texture.type === FloatType && texture.image.data.constructor.name !== 'Float32Array' ) {
-
-		throw Error( 'EXRExporter.parse: DataTexture image data doesn\'t match type, expected \'Float32Array\'.' );
-
-	}
-
-	if ( texture.type === HalfFloatType && texture.image.data.constructor.name !== 'Uint16Array' ) {
-
-		throw Error( 'EXRExporter.parse: DataTexture image data doesn\'t match type, expected \'Uint16Array\'.' );
-
-	}
-
-}
-
-function buildInfoRTT( renderTarget, options = {} ) {
-
-	const compressionSizes = {
-		0: 1,
-		2: 1,
-		3: 16
-	};
-
-	const WIDTH = renderTarget.width,
-		HEIGHT = renderTarget.height,
-		TYPE = renderTarget.texture.type,
-		FORMAT = renderTarget.texture.format,
-		COMPRESSION = ( options.compression !== undefined ) ? options.compression : ZIP_COMPRESSION,
-		EXPORTER_TYPE = ( options.type !== undefined ) ? options.type : HalfFloatType,
-		OUT_TYPE = ( EXPORTER_TYPE === FloatType ) ? 2 : 1,
-		COMPRESSION_SIZE = compressionSizes[ COMPRESSION ],
-		NUM_CHANNELS = 4;
-
-	return {
-		width: WIDTH,
-		height: HEIGHT,
-		type: TYPE,
-		format: FORMAT,
-		compression: COMPRESSION,
-		blockLines: COMPRESSION_SIZE,
-		dataType: OUT_TYPE,
-		dataSize: 2 * OUT_TYPE,
-		numBlocks: Math.ceil( HEIGHT / COMPRESSION_SIZE ),
-		numInputChannels: 4,
-		numOutputChannels: NUM_CHANNELS,
-	};
-
-}
-
-function buildInfoDT( texture, options = {} ) {
-
-	const compressionSizes = {
-		0: 1,
-		2: 1,
-		3: 16
-	};
-
-	const WIDTH = texture.image.width,
-		HEIGHT = texture.image.height,
-		TYPE = texture.type,
-		FORMAT = texture.format,
-		COMPRESSION = ( options.compression !== undefined ) ? options.compression : ZIP_COMPRESSION,
-		EXPORTER_TYPE = ( options.type !== undefined ) ? options.type : HalfFloatType,
-		OUT_TYPE = ( EXPORTER_TYPE === FloatType ) ? 2 : 1,
-		COMPRESSION_SIZE = compressionSizes[ COMPRESSION ],
-		NUM_CHANNELS = 4;
-
-	return {
-		width: WIDTH,
-		height: HEIGHT,
-		type: TYPE,
-		format: FORMAT,
-		compression: COMPRESSION,
-		blockLines: COMPRESSION_SIZE,
-		dataType: OUT_TYPE,
-		dataSize: 2 * OUT_TYPE,
-		numBlocks: Math.ceil( HEIGHT / COMPRESSION_SIZE ),
-		numInputChannels: 4,
-		numOutputChannels: NUM_CHANNELS,
-	};
-
-}
-
-async function getPixelData( renderer, rtt, info ) {
-
-	let dataBuffer;
-
-	if ( renderer.isWebGLRenderer ) {
-
-		if ( info.type === FloatType ) {
-
-			dataBuffer = new Float32Array( info.width * info.height * info.numInputChannels );
-
-		} else {
-
-			dataBuffer = new Uint16Array( info.width * info.height * info.numInputChannels );
-
-		}
-
-		await renderer.readRenderTargetPixelsAsync( rtt, 0, 0, info.width, info.height, dataBuffer );
-
-	} else {
-
-		dataBuffer = await renderer.readRenderTargetPixelsAsync( rtt, 0, 0, info.width, info.height );
-
-	}
-
-	return dataBuffer;
-
-}
-
-function reorganizeDataBuffer( inBuffer, info ) {
-
-	const w = info.width,
-		h = info.height,
-		dec = { r: 0, g: 0, b: 0, a: 0 },
-		offset = { value: 0 },
-		cOffset = ( info.numOutputChannels == 4 ) ? 1 : 0,
-		getValue = ( info.type == FloatType ) ? getFloat32 : getFloat16,
-		setValue = ( info.dataType == 1 ) ? setFloat16 : setFloat32,
-		outBuffer = new Uint8Array( info.width * info.height * info.numOutputChannels * info.dataSize ),
-		dv = new DataView( outBuffer.buffer );
-
-	for ( let y = 0; y < h; ++ y ) {
-
-		for ( let x = 0; x < w; ++ x ) {
-
-			const i = y * w * 4 + x * 4;
-
-			const r = getValue( inBuffer, i );
-			const g = getValue( inBuffer, i + 1 );
-			const b = getValue( inBuffer, i + 2 );
-			const a = getValue( inBuffer, i + 3 );
-
-			const line = ( h - y - 1 ) * w * ( 3 + cOffset ) * info.dataSize;
-
-			decodeLinear( dec, r, g, b, a );
-
-			offset.value = line + x * info.dataSize;
-			setValue( dv, dec.a, offset );
-
-			offset.value = line + ( cOffset ) * w * info.dataSize + x * info.dataSize;
-			setValue( dv, dec.b, offset );
-
-			offset.value = line + ( 1 + cOffset ) * w * info.dataSize + x * info.dataSize;
-			setValue( dv, dec.g, offset );
-
-			offset.value = line + ( 2 + cOffset ) * w * info.dataSize + x * info.dataSize;
-			setValue( dv, dec.r, offset );
-
-		}
-
-	}
-
-	return outBuffer;
-
-}
-
-function compressData( inBuffer, info ) {
-
-	let compress,
-		tmpBuffer,
-		sum = 0;
-
-	const chunks = { data: new Array(), totalSize: 0 },
-		size = info.width * info.numOutputChannels * info.blockLines * info.dataSize;
-
-	switch ( info.compression ) {
-
-		case 0:
-			compress = compressNONE;
-			break;
-
-		case 2:
-		case 3:
-			compress = compressZIP;
-			break;
-
-	}
-
-	if ( info.compression !== 0 ) {
-
-		tmpBuffer = new Uint8Array( size );
-
-	}
-
-	for ( let i = 0; i < info.numBlocks; ++ i ) {
-
-		const arr = inBuffer.subarray( size * i, size * ( i + 1 ) );
-
-		const block = compress( arr, tmpBuffer );
-
-		sum += block.length;
-
-		chunks.data.push( { dataChunk: block, size: block.length } );
-
-	}
-
-	chunks.totalSize = sum;
-
-	return chunks;
-
-}
-
-function compressNONE( data ) {
-
-	return data;
-
-}
-
-function compressZIP( data, tmpBuffer ) {
-
-	//
-	// Reorder the pixel data.
-	//
-
-	let t1 = 0,
-		t2 = Math.floor( ( data.length + 1 ) / 2 ),
-		s = 0;
-
-	const stop = data.length - 1;
-
-	while ( true ) {
-
-		if ( s > stop ) break;
-		tmpBuffer[ t1 ++ ] = data[ s ++ ];
-
-		if ( s > stop ) break;
-		tmpBuffer[ t2 ++ ] = data[ s ++ ];
-
-	}
-
-	//
-	// Predictor.
-	//
-
-	let p = tmpBuffer[ 0 ];
-
-	for ( let t = 1; t < tmpBuffer.length; t ++ ) {
-
-		const d = tmpBuffer[ t ] - p + ( 128 + 256 );
-		p = tmpBuffer[ t ];
-		tmpBuffer[ t ] = d;
-
-	}
-
-	const deflate = fflate.zlibSync( tmpBuffer );
-
-	return deflate;
-
-}
-
-function fillHeader( outBuffer, chunks, info ) {
-
-	const offset = { value: 0 };
-	const dv = new DataView( outBuffer.buffer );
-
-	setUint32( dv, 20000630, offset ); // magic
-	setUint32( dv, 2, offset ); // mask
-
-	// = HEADER =
-
-	setString( dv, 'compression', offset );
-	setString( dv, 'compression', offset );
-	setUint32( dv, 1, offset );
-	setUint8( dv, info.compression, offset );
-
-	setString( dv, 'screenWindowCenter', offset );
-	setString( dv, 'v2f', offset );
-	setUint32( dv, 8, offset );
-	setUint32( dv, 0, offset );
-	setUint32( dv, 0, offset );
-
-	setString( dv, 'screenWindowWidth', offset );
-	setString( dv, 'float', offset );
-	setUint32( dv, 4, offset );
-	setFloat32( dv, 1.0, offset );
-
-	setString( dv, 'pixelAspectRatio', offset );
-	setString( dv, 'float', offset );
-	setUint32( dv, 4, offset );
-	setFloat32( dv, 1.0, offset );
-
-	setString( dv, 'lineOrder', offset );
-	setString( dv, 'lineOrder', offset );
-	setUint32( dv, 1, offset );
-	setUint8( dv, 0, offset );
-
-	setString( dv, 'dataWindow', offset );
-	setString( dv, 'box2i', offset );
-	setUint32( dv, 16, offset );
-	setUint32( dv, 0, offset );
-	setUint32( dv, 0, offset );
-	setUint32( dv, info.width - 1, offset );
-	setUint32( dv, info.height - 1, offset );
-
-	setString( dv, 'displayWindow', offset );
-	setString( dv, 'box2i', offset );
-	setUint32( dv, 16, offset );
-	setUint32( dv, 0, offset );
-	setUint32( dv, 0, offset );
-	setUint32( dv, info.width - 1, offset );
-	setUint32( dv, info.height - 1, offset );
-
-	setString( dv, 'channels', offset );
-	setString( dv, 'chlist', offset );
-	setUint32( dv, info.numOutputChannels * 18 + 1, offset );
-
-	setString( dv, 'A', offset );
-	setUint32( dv, info.dataType, offset );
-	offset.value += 4;
-	setUint32( dv, 1, offset );
-	setUint32( dv, 1, offset );
-
-	setString( dv, 'B', offset );
-	setUint32( dv, info.dataType, offset );
-	offset.value += 4;
-	setUint32( dv, 1, offset );
-	setUint32( dv, 1, offset );
-
-	setString( dv, 'G', offset );
-	setUint32( dv, info.dataType, offset );
-	offset.value += 4;
-	setUint32( dv, 1, offset );
-	setUint32( dv, 1, offset );
-
-	setString( dv, 'R', offset );
-	setUint32( dv, info.dataType, offset );
-	offset.value += 4;
-	setUint32( dv, 1, offset );
-	setUint32( dv, 1, offset );
-
-	setUint8( dv, 0, offset );
-
-	// null-byte
-	setUint8( dv, 0, offset );
-
-	// = OFFSET TABLE =
-
-	let sum = offset.value + info.numBlocks * 8;
-
-	for ( let i = 0; i < chunks.data.length; ++ i ) {
-
-		setUint64( dv, sum, offset );
-
-		sum += chunks.data[ i ].size + 8;
-
-	}
-
-}
-
-function fillData( chunks, info ) {
-
-	const TableSize = info.numBlocks * 8,
-		HeaderSize = 259 + ( 18 * info.numOutputChannels ), // 259 + 18 * chlist
-		offset = { value: HeaderSize + TableSize },
-		outBuffer = new Uint8Array( HeaderSize + TableSize + chunks.totalSize + info.numBlocks * 8 ),
-		dv = new DataView( outBuffer.buffer );
-
-	fillHeader( outBuffer, chunks, info );
-
-	for ( let i = 0; i < chunks.data.length; ++ i ) {
-
-		const data = chunks.data[ i ].dataChunk;
-		const size = chunks.data[ i ].size;
-
-		setUint32( dv, i * info.blockLines, offset );
-		setUint32( dv, size, offset );
-
-		outBuffer.set( data, offset.value );
-		offset.value += size;
-
-	}
-
-	return outBuffer;
-
-}
-
-function decodeLinear( dec, r, g, b, a ) {
-
-	dec.r = r;
-	dec.g = g;
-	dec.b = b;
-	dec.a = a;
-
-}
-
-// function decodeSRGB( dec, r, g, b, a ) {
-
-// 	dec.r = r > 0.04045 ? Math.pow( r * 0.9478672986 + 0.0521327014, 2.4 ) : r * 0.0773993808;
-// 	dec.g = g > 0.04045 ? Math.pow( g * 0.9478672986 + 0.0521327014, 2.4 ) : g * 0.0773993808;
-// 	dec.b = b > 0.04045 ? Math.pow( b * 0.9478672986 + 0.0521327014, 2.4 ) : b * 0.0773993808;
-// 	dec.a = a;
-
-// }
-
-
-function setUint8( dv, value, offset ) {
-
-	dv.setUint8( offset.value, value );
-
-	offset.value += 1;
-
-}
-
-function setUint32( dv, value, offset ) {
-
-	dv.setUint32( offset.value, value, true );
-
-	offset.value += 4;
-
-}
-
-function setFloat16( dv, value, offset ) {
-
-	dv.setUint16( offset.value, DataUtils.toHalfFloat( value ), true );
-
-	offset.value += 2;
-
-}
-
-function setFloat32( dv, value, offset ) {
-
-	dv.setFloat32( offset.value, value, true );
-
-	offset.value += 4;
-
-}
-
-function setUint64( dv, value, offset ) {
-
-	dv.setBigUint64( offset.value, BigInt( value ), true );
-
-	offset.value += 8;
-
-}
-
-function setString( dv, string, offset ) {
-
-	const tmp = textEncoder.encode( string + '\0' );
-
-	for ( let i = 0; i < tmp.length; ++ i ) {
-
-		setUint8( dv, tmp[ i ], offset );
-
-	}
-
-}
-
-function decodeFloat16( binary ) {
-
-	const exponent = ( binary & 0x7C00 ) >> 10,
-		fraction = binary & 0x03FF;
-
-	return ( binary >> 15 ? - 1 : 1 ) * (
-		exponent ?
-			(
-				exponent === 0x1F ?
-					fraction ? NaN : Infinity :
-					Math.pow( 2, exponent - 15 ) * ( 1 + fraction / 0x400 )
-			) :
-			6.103515625e-5 * ( fraction / 0x400 )
-	);
-
-}
-
-function getFloat16( arr, i ) {
-
-	return decodeFloat16( arr[ i ] );
-
-}
-
-function getFloat32( arr, i ) {
-
-	return arr[ i ];
-
-}
-
-/**
- * Export options of `EXRExporter`.
- *
- * @typedef {Object} EXRExporter~Options
- * @property {(HalfFloatType|FloatType)} [type=HalfFloatType] - Output data type.
- * @property {(NO_COMPRESSION|ZIP_COMPRESSION|ZIPS_COMPRESSION)} [type=ZIP_COMPRESSION] - The compression algorithm.
- **/
-
-export { EXRExporter, NO_COMPRESSION, ZIP_COMPRESSION, ZIPS_COMPRESSION };

+ 0 - 3738
node_modules/three/examples/jsm/exporters/GLTFExporter.js

@@ -1,3738 +0,0 @@
-import {
-	BufferAttribute,
-	ClampToEdgeWrapping,
-	Color,
-	DoubleSide,
-	InterpolateDiscrete,
-	InterpolateLinear,
-	NoColorSpace,
-	LinearFilter,
-	LinearMipmapLinearFilter,
-	LinearMipmapNearestFilter,
-	MathUtils,
-	Matrix4,
-	MirroredRepeatWrapping,
-	NearestFilter,
-	NearestMipmapLinearFilter,
-	NearestMipmapNearestFilter,
-	PropertyBinding,
-	RGBAFormat,
-	RepeatWrapping,
-	Scene,
-	Source,
-	SRGBColorSpace,
-	CompressedTexture,
-	Vector3,
-	Quaternion,
-	REVISION,
-	ImageUtils
-} from 'three';
-
-/**
- * The KHR_mesh_quantization extension allows these extra attribute component types
- *
- * @see https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_mesh_quantization/README.md#extending-mesh-attributes
- */
-const KHR_mesh_quantization_ExtraAttrTypes = {
-	POSITION: [
-		'byte',
-		'byte normalized',
-		'unsigned byte',
-		'unsigned byte normalized',
-		'short',
-		'short normalized',
-		'unsigned short',
-		'unsigned short normalized',
-	],
-	NORMAL: [
-		'byte normalized',
-		'short normalized',
-	],
-	TANGENT: [
-		'byte normalized',
-		'short normalized',
-	],
-	TEXCOORD: [
-		'byte',
-		'byte normalized',
-		'unsigned byte',
-		'short',
-		'short normalized',
-		'unsigned short',
-	],
-};
-
-/**
- * An exporter for `glTF` 2.0.
- *
- * glTF (GL Transmission Format) is an [open format specification](https://github.com/KhronosGroup/glTF/tree/master/specification/2.0)
- * for efficient delivery and loading of 3D content. Assets may be provided either in JSON (.gltf)
- * or binary (.glb) format. External files store textures (.jpg, .png) and additional binary
- * data (.bin). A glTF asset may deliver one or more scenes, including meshes, materials,
- * textures, skins, skeletons, morph targets, animations, lights, and/or cameras.
- *
- * GLTFExporter supports the [glTF 2.0 extensions](https://github.com/KhronosGroup/glTF/tree/master/extensions/):
- *
- * - KHR_lights_punctual
- * - KHR_materials_clearcoat
- * - KHR_materials_dispersion
- * - KHR_materials_emissive_strength
- * - KHR_materials_ior
- * - KHR_materials_iridescence
- * - KHR_materials_specular
- * - KHR_materials_sheen
- * - KHR_materials_transmission
- * - KHR_materials_unlit
- * - KHR_materials_volume
- * - KHR_mesh_quantization
- * - KHR_texture_transform
- * - EXT_materials_bump
- * - EXT_mesh_gpu_instancing
- * - EXT_texture_webp
- *
- * The following glTF 2.0 extension is supported by an external user plugin:
- *
- * - [KHR_materials_variants](https://github.com/takahirox/three-gltf-extensions)
- *
- * ```js
- * const exporter = new GLTFExporter();
- * const data = await exporter.parseAsync( scene, options );
- * ```
- *
- * @three_import import { GLTFExporter } from 'three/addons/exporters/GLTFExporter.js';
- */
-class GLTFExporter {
-
-	/**
-	 * Constructs a new glTF exporter.
-	 */
-	constructor() {
-
-		/**
-		 * A reference to a texture utils module.
-		 *
-		 * @type {?(WebGLTextureUtils|WebGPUTextureUtils)}
-		 * @default null
-		 */
-		this.textureUtils = null;
-
-		this.pluginCallbacks = [];
-
-		this.register( function ( writer ) {
-
-			return new GLTFLightExtension( writer );
-
-		} );
-
-		this.register( function ( writer ) {
-
-			return new GLTFMaterialsUnlitExtension( writer );
-
-		} );
-
-		this.register( function ( writer ) {
-
-			return new GLTFMaterialsTransmissionExtension( writer );
-
-		} );
-
-		this.register( function ( writer ) {
-
-			return new GLTFMaterialsVolumeExtension( writer );
-
-		} );
-
-		this.register( function ( writer ) {
-
-			return new GLTFMaterialsIorExtension( writer );
-
-		} );
-
-		this.register( function ( writer ) {
-
-			return new GLTFMaterialsSpecularExtension( writer );
-
-		} );
-
-		this.register( function ( writer ) {
-
-			return new GLTFMaterialsClearcoatExtension( writer );
-
-		} );
-
-		this.register( function ( writer ) {
-
-			return new GLTFMaterialsDispersionExtension( writer );
-
-		} );
-
-		this.register( function ( writer ) {
-
-			return new GLTFMaterialsIridescenceExtension( writer );
-
-		} );
-
-		this.register( function ( writer ) {
-
-			return new GLTFMaterialsSheenExtension( writer );
-
-		} );
-
-		this.register( function ( writer ) {
-
-			return new GLTFMaterialsAnisotropyExtension( writer );
-
-		} );
-
-		this.register( function ( writer ) {
-
-			return new GLTFMaterialsEmissiveStrengthExtension( writer );
-
-		} );
-
-		this.register( function ( writer ) {
-
-			return new GLTFMaterialsBumpExtension( writer );
-
-		} );
-
-		this.register( function ( writer ) {
-
-			return new GLTFMeshGpuInstancing( writer );
-
-		} );
-
-	}
-
-	/**
-	 * Registers a plugin callback. This API is internally used to implement the various
-	 * glTF extensions but can also used by third-party code to add additional logic
-	 * to the exporter.
-	 *
-	 * @param {function(writer:GLTFWriter)} callback - The callback function to register.
-	 * @return {GLTFExporter} A reference to this exporter.
-	 */
-	register( callback ) {
-
-		if ( this.pluginCallbacks.indexOf( callback ) === - 1 ) {
-
-			this.pluginCallbacks.push( callback );
-
-		}
-
-		return this;
-
-	}
-
-	/**
-	 * Unregisters a plugin callback.
-	 *
-	 * @param {Function} callback - The callback function to unregister.
-	 * @return {GLTFExporter} A reference to this exporter.
-	 */
-	unregister( callback ) {
-
-		if ( this.pluginCallbacks.indexOf( callback ) !== - 1 ) {
-
-			this.pluginCallbacks.splice( this.pluginCallbacks.indexOf( callback ), 1 );
-
-		}
-
-		return this;
-
-	}
-
-	/**
-	 * Sets the texture utils for this exporter. Only relevant when compressed textures have to be exported.
-	 *
-	 * Depending on whether you use {@link WebGLRenderer} or {@link WebGPURenderer}, you must inject the
-	 * corresponding texture utils {@link WebGLTextureUtils} or {@link WebGPUTextureUtils}.
-	 *
-	 * @param {WebGLTextureUtils|WebGPUTextureUtils} utils - The texture utils.
-	 * @return {GLTFExporter} A reference to this exporter.
-	 */
-	setTextureUtils( utils ) {
-
-		this.textureUtils = utils;
-
-		return this;
-
-	}
-
-	/**
-	 * Parses the given scenes and generates the glTF output.
-	 *
-	 * @param {Scene|Array<Scene>} input - A scene or an array of scenes.
-	 * @param {GLTFExporter~OnDone} onDone - A callback function that is executed when the export has finished.
-	 * @param {GLTFExporter~OnError} onError - A callback function that is executed when an error happens.
-	 * @param {GLTFExporter~Options} options - options
-	 */
-	parse( input, onDone, onError, options ) {
-
-		const writer = new GLTFWriter();
-		const plugins = [];
-
-		for ( let i = 0, il = this.pluginCallbacks.length; i < il; i ++ ) {
-
-			plugins.push( this.pluginCallbacks[ i ]( writer ) );
-
-		}
-
-		writer.setPlugins( plugins );
-		writer.setTextureUtils( this.textureUtils );
-		writer.writeAsync( input, onDone, options ).catch( onError );
-
-	}
-
-	/**
-	 * Async version of {@link GLTFExporter#parse}.
-	 *
-	 * @param {Scene|Array<Scene>} input - A scene or an array of scenes.
-	 * @param {GLTFExporter~Options} options - options.
-	 * @return {Promise<ArrayBuffer|string>} A Promise that resolved with the exported glTF data.
-	 */
-	parseAsync( input, options ) {
-
-		const scope = this;
-
-		return new Promise( function ( resolve, reject ) {
-
-			scope.parse( input, resolve, reject, options );
-
-		} );
-
-	}
-
-}
-
-//------------------------------------------------------------------------------
-// Constants
-//------------------------------------------------------------------------------
-
-const WEBGL_CONSTANTS = {
-	POINTS: 0x0000,
-	LINES: 0x0001,
-	LINE_LOOP: 0x0002,
-	LINE_STRIP: 0x0003,
-	TRIANGLES: 0x0004,
-	TRIANGLE_STRIP: 0x0005,
-	TRIANGLE_FAN: 0x0006,
-
-	BYTE: 0x1400,
-	UNSIGNED_BYTE: 0x1401,
-	SHORT: 0x1402,
-	UNSIGNED_SHORT: 0x1403,
-	INT: 0x1404,
-	UNSIGNED_INT: 0x1405,
-	FLOAT: 0x1406,
-
-	ARRAY_BUFFER: 0x8892,
-	ELEMENT_ARRAY_BUFFER: 0x8893,
-
-	NEAREST: 0x2600,
-	LINEAR: 0x2601,
-	NEAREST_MIPMAP_NEAREST: 0x2700,
-	LINEAR_MIPMAP_NEAREST: 0x2701,
-	NEAREST_MIPMAP_LINEAR: 0x2702,
-	LINEAR_MIPMAP_LINEAR: 0x2703,
-
-	CLAMP_TO_EDGE: 33071,
-	MIRRORED_REPEAT: 33648,
-	REPEAT: 10497
-};
-
-const KHR_MESH_QUANTIZATION = 'KHR_mesh_quantization';
-
-const THREE_TO_WEBGL = {};
-
-THREE_TO_WEBGL[ NearestFilter ] = WEBGL_CONSTANTS.NEAREST;
-THREE_TO_WEBGL[ NearestMipmapNearestFilter ] = WEBGL_CONSTANTS.NEAREST_MIPMAP_NEAREST;
-THREE_TO_WEBGL[ NearestMipmapLinearFilter ] = WEBGL_CONSTANTS.NEAREST_MIPMAP_LINEAR;
-THREE_TO_WEBGL[ LinearFilter ] = WEBGL_CONSTANTS.LINEAR;
-THREE_TO_WEBGL[ LinearMipmapNearestFilter ] = WEBGL_CONSTANTS.LINEAR_MIPMAP_NEAREST;
-THREE_TO_WEBGL[ LinearMipmapLinearFilter ] = WEBGL_CONSTANTS.LINEAR_MIPMAP_LINEAR;
-
-THREE_TO_WEBGL[ ClampToEdgeWrapping ] = WEBGL_CONSTANTS.CLAMP_TO_EDGE;
-THREE_TO_WEBGL[ RepeatWrapping ] = WEBGL_CONSTANTS.REPEAT;
-THREE_TO_WEBGL[ MirroredRepeatWrapping ] = WEBGL_CONSTANTS.MIRRORED_REPEAT;
-
-const PATH_PROPERTIES = {
-	scale: 'scale',
-	position: 'translation',
-	quaternion: 'rotation',
-	morphTargetInfluences: 'weights'
-};
-
-const DEFAULT_SPECULAR_COLOR = new Color();
-
-// GLB constants
-// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification
-
-const GLB_HEADER_BYTES = 12;
-const GLB_HEADER_MAGIC = 0x46546C67;
-const GLB_VERSION = 2;
-
-const GLB_CHUNK_PREFIX_BYTES = 8;
-const GLB_CHUNK_TYPE_JSON = 0x4E4F534A;
-const GLB_CHUNK_TYPE_BIN = 0x004E4942;
-
-//------------------------------------------------------------------------------
-// Utility functions
-//------------------------------------------------------------------------------
-
-/**
- * Compare two arrays
- *
- * @private
- * @param {Array} array1 Array 1 to compare
- * @param {Array} array2 Array 2 to compare
- * @return {boolean}        Returns true if both arrays are equal
- */
-function equalArray( array1, array2 ) {
-
-	return ( array1.length === array2.length ) && array1.every( function ( element, index ) {
-
-		return element === array2[ index ];
-
-	} );
-
-}
-
-/**
- * Converts a string to an ArrayBuffer.
- *
- * @private
- * @param {string} text
- * @return {ArrayBuffer}
- */
-function stringToArrayBuffer( text ) {
-
-	return new TextEncoder().encode( text ).buffer;
-
-}
-
-/**
- * Is identity matrix
- *
- * @private
- * @param {Matrix4} matrix
- * @returns {boolean} Returns true, if parameter is identity matrix
- */
-function isIdentityMatrix( matrix ) {
-
-	return equalArray( matrix.elements, [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] );
-
-}
-
-/**
- * Get the min and max vectors from the given attribute
- *
- * @private
- * @param {BufferAttribute} attribute Attribute to find the min/max in range from start to start + count
- * @param {number} start Start index
- * @param {number} count Range to cover
- * @return {Object} Object containing the `min` and `max` values (As an array of attribute.itemSize components)
- */
-function getMinMax( attribute, start, count ) {
-
-	const output = {
-
-		min: new Array( attribute.itemSize ).fill( Number.POSITIVE_INFINITY ),
-		max: new Array( attribute.itemSize ).fill( Number.NEGATIVE_INFINITY )
-
-	};
-
-	for ( let i = start; i < start + count; i ++ ) {
-
-		for ( let a = 0; a < attribute.itemSize; a ++ ) {
-
-			let value;
-
-			if ( attribute.itemSize > 4 ) {
-
-				 // no support for interleaved data for itemSize > 4
-
-				value = attribute.array[ i * attribute.itemSize + a ];
-
-			} else {
-
-				if ( a === 0 ) value = attribute.getX( i );
-				else if ( a === 1 ) value = attribute.getY( i );
-				else if ( a === 2 ) value = attribute.getZ( i );
-				else if ( a === 3 ) value = attribute.getW( i );
-
-				if ( attribute.normalized === true ) {
-
-					value = MathUtils.normalize( value, attribute.array );
-
-				}
-
-			}
-
-			output.min[ a ] = Math.min( output.min[ a ], value );
-			output.max[ a ] = Math.max( output.max[ a ], value );
-
-		}
-
-	}
-
-	return output;
-
-}
-
-/**
- * Get the required size + padding for a buffer, rounded to the next 4-byte boundary.
- * https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#data-alignment
- *
- * @private
- * @param {number} bufferSize The size the original buffer. Should be an integer.
- * @returns {number} new buffer size with required padding as an integer.
- *
- */
-function getPaddedBufferSize( bufferSize ) {
-
-	return Math.ceil( bufferSize / 4 ) * 4;
-
-}
-
-/**
- * Returns a buffer aligned to 4-byte boundary.
- *
- * @private
- * @param {ArrayBuffer} arrayBuffer Buffer to pad
- * @param {number} [paddingByte=0] Should be an integer
- * @returns {ArrayBuffer} The same buffer if it's already aligned to 4-byte boundary or a new buffer
- */
-function getPaddedArrayBuffer( arrayBuffer, paddingByte = 0 ) {
-
-	const paddedLength = getPaddedBufferSize( arrayBuffer.byteLength );
-
-	if ( paddedLength !== arrayBuffer.byteLength ) {
-
-		const array = new Uint8Array( paddedLength );
-		array.set( new Uint8Array( arrayBuffer ) );
-
-		if ( paddingByte !== 0 ) {
-
-			for ( let i = arrayBuffer.byteLength; i < paddedLength; i ++ ) {
-
-				array[ i ] = paddingByte;
-
-			}
-
-		}
-
-		return array.buffer;
-
-	}
-
-	return arrayBuffer;
-
-}
-
-function getCanvas() {
-
-	if ( typeof document === 'undefined' && typeof OffscreenCanvas !== 'undefined' ) {
-
-		return new OffscreenCanvas( 1, 1 );
-
-	}
-
-	return document.createElement( 'canvas' );
-
-}
-
-function getToBlobPromise( canvas, mimeType ) {
-
-	if ( typeof OffscreenCanvas !== 'undefined' && canvas instanceof OffscreenCanvas ) {
-
-		let quality;
-
-		// Blink's implementation of convertToBlob seems to default to a quality level of 100%
-		// Use the Blink default quality levels of toBlob instead so that file sizes are comparable.
-		if ( mimeType === 'image/jpeg' ) {
-
-			quality = 0.92;
-
-		} else if ( mimeType === 'image/webp' ) {
-
-			quality = 0.8;
-
-		}
-
-		return canvas.convertToBlob( {
-
-			type: mimeType,
-			quality: quality
-
-		} );
-
-	} else {
-
-		// HTMLCanvasElement code path
-
-		return new Promise( ( resolve ) => canvas.toBlob( resolve, mimeType ) );
-
-	}
-
-}
-
-/**
- * Writer
- *
- * @private
- */
-class GLTFWriter {
-
-	constructor() {
-
-		this.plugins = [];
-
-		this.options = {};
-		this.pending = [];
-		this.buffers = [];
-
-		this.byteOffset = 0;
-		this.buffers = [];
-		this.nodeMap = new Map();
-		this.skins = [];
-
-		this.extensionsUsed = {};
-		this.extensionsRequired = {};
-
-		this.uids = new Map();
-		this.uid = 0;
-
-		this.json = {
-			asset: {
-				version: '2.0',
-				generator: 'THREE.GLTFExporter r' + REVISION
-			}
-		};
-
-		this.cache = {
-			meshes: new Map(),
-			attributes: new Map(),
-			attributesNormalized: new Map(),
-			materials: new Map(),
-			textures: new Map(),
-			images: new Map()
-		};
-
-		this.textureUtils = null;
-
-	}
-
-	setPlugins( plugins ) {
-
-		this.plugins = plugins;
-
-	}
-
-	setTextureUtils( utils ) {
-
-		this.textureUtils = utils;
-
-	}
-
-	/**
-	 * Parse scenes and generate GLTF output
-	 *
-	 * @param {Scene|Array<Scene>} input Scene or Array of THREE.Scenes
-	 * @param {Function} onDone Callback on completed
-	 * @param {Object} options options
-	 */
-	async writeAsync( input, onDone, options = {} ) {
-
-		this.options = Object.assign( {
-			// default options
-			binary: false,
-			trs: false,
-			onlyVisible: true,
-			maxTextureSize: Infinity,
-			animations: [],
-			includeCustomExtensions: false
-		}, options );
-
-		if ( this.options.animations.length > 0 ) {
-
-			// Only TRS properties, and not matrices, may be targeted by animation.
-			this.options.trs = true;
-
-		}
-
-		await this.processInputAsync( input );
-
-		await Promise.all( this.pending );
-
-		const writer = this;
-		const buffers = writer.buffers;
-		const json = writer.json;
-		options = writer.options;
-
-		const extensionsUsed = writer.extensionsUsed;
-		const extensionsRequired = writer.extensionsRequired;
-
-		// Merge buffers.
-		const blob = new Blob( buffers, { type: 'application/octet-stream' } );
-
-		// Declare extensions.
-		const extensionsUsedList = Object.keys( extensionsUsed );
-		const extensionsRequiredList = Object.keys( extensionsRequired );
-
-		if ( extensionsUsedList.length > 0 ) json.extensionsUsed = extensionsUsedList;
-		if ( extensionsRequiredList.length > 0 ) json.extensionsRequired = extensionsRequiredList;
-
-		// Update bytelength of the single buffer.
-		if ( json.buffers && json.buffers.length > 0 ) json.buffers[ 0 ].byteLength = blob.size;
-
-		if ( options.binary === true ) {
-
-			// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification
-
-			const reader = new FileReader();
-			reader.readAsArrayBuffer( blob );
-			reader.onloadend = function () {
-
-				// Binary chunk.
-				const binaryChunk = getPaddedArrayBuffer( reader.result );
-				const binaryChunkPrefix = new DataView( new ArrayBuffer( GLB_CHUNK_PREFIX_BYTES ) );
-				binaryChunkPrefix.setUint32( 0, binaryChunk.byteLength, true );
-				binaryChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_BIN, true );
-
-				// JSON chunk.
-				const jsonChunk = getPaddedArrayBuffer( stringToArrayBuffer( JSON.stringify( json ) ), 0x20 );
-				const jsonChunkPrefix = new DataView( new ArrayBuffer( GLB_CHUNK_PREFIX_BYTES ) );
-				jsonChunkPrefix.setUint32( 0, jsonChunk.byteLength, true );
-				jsonChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_JSON, true );
-
-				// GLB header.
-				const header = new ArrayBuffer( GLB_HEADER_BYTES );
-				const headerView = new DataView( header );
-				headerView.setUint32( 0, GLB_HEADER_MAGIC, true );
-				headerView.setUint32( 4, GLB_VERSION, true );
-				const totalByteLength = GLB_HEADER_BYTES
-					+ jsonChunkPrefix.byteLength + jsonChunk.byteLength
-					+ binaryChunkPrefix.byteLength + binaryChunk.byteLength;
-				headerView.setUint32( 8, totalByteLength, true );
-
-				const glbBlob = new Blob( [
-					header,
-					jsonChunkPrefix,
-					jsonChunk,
-					binaryChunkPrefix,
-					binaryChunk
-				], { type: 'application/octet-stream' } );
-
-				const glbReader = new FileReader();
-				glbReader.readAsArrayBuffer( glbBlob );
-				glbReader.onloadend = function () {
-
-					onDone( glbReader.result );
-
-				};
-
-			};
-
-		} else {
-
-			if ( json.buffers && json.buffers.length > 0 ) {
-
-				const reader = new FileReader();
-				reader.readAsDataURL( blob );
-				reader.onloadend = function () {
-
-					const base64data = reader.result;
-					json.buffers[ 0 ].uri = base64data;
-					onDone( json );
-
-				};
-
-			} else {
-
-				onDone( json );
-
-			}
-
-		}
-
-
-	}
-
-	/**
-	 * Serializes a userData.
-	 *
-	 * @param {THREE.Object3D|THREE.Material|THREE.BufferGeometry|THREE.AnimationClip} object
-	 * @param {Object} objectDef
-	 */
-	serializeUserData( object, objectDef ) {
-
-		if ( Object.keys( object.userData ).length === 0 ) return;
-
-		const options = this.options;
-		const extensionsUsed = this.extensionsUsed;
-
-		try {
-
-			const json = JSON.parse( JSON.stringify( object.userData ) );
-
-			if ( options.includeCustomExtensions && json.gltfExtensions ) {
-
-				if ( objectDef.extensions === undefined ) objectDef.extensions = {};
-
-				for ( const extensionName in json.gltfExtensions ) {
-
-					objectDef.extensions[ extensionName ] = json.gltfExtensions[ extensionName ];
-					extensionsUsed[ extensionName ] = true;
-
-				}
-
-				delete json.gltfExtensions;
-
-			}
-
-			if ( Object.keys( json ).length > 0 ) objectDef.extras = json;
-
-		} catch ( error ) {
-
-			console.warn( 'THREE.GLTFExporter: userData of \'' + object.name + '\' ' +
-				'won\'t be serialized because of JSON.stringify error - ' + error.message );
-
-		}
-
-	}
-
-	/**
-	 * Returns ids for buffer attributes.
-	 *
-	 * @param {Object} attribute
-	 * @param {boolean} [isRelativeCopy=false]
-	 * @return {number} An integer
-	 */
-	getUID( attribute, isRelativeCopy = false ) {
-
-		if ( this.uids.has( attribute ) === false ) {
-
-			const uids = new Map();
-
-			uids.set( true, this.uid ++ );
-			uids.set( false, this.uid ++ );
-
-			this.uids.set( attribute, uids );
-
-		}
-
-		const uids = this.uids.get( attribute );
-
-		return uids.get( isRelativeCopy );
-
-	}
-
-	/**
-	 * Checks if normal attribute values are normalized.
-	 *
-	 * @param {BufferAttribute} normal
-	 * @returns {boolean}
-	 */
-	isNormalizedNormalAttribute( normal ) {
-
-		const cache = this.cache;
-
-		if ( cache.attributesNormalized.has( normal ) ) return false;
-
-		const v = new Vector3();
-
-		for ( let i = 0, il = normal.count; i < il; i ++ ) {
-
-			// 0.0005 is from glTF-validator
-			if ( Math.abs( v.fromBufferAttribute( normal, i ).length() - 1.0 ) > 0.0005 ) return false;
-
-		}
-
-		return true;
-
-	}
-
-	/**
-	 * Creates normalized normal buffer attribute.
-	 *
-	 * @param {BufferAttribute} normal
-	 * @returns {BufferAttribute}
-	 *
-	 */
-	createNormalizedNormalAttribute( normal ) {
-
-		const cache = this.cache;
-
-		if ( cache.attributesNormalized.has( normal ) )	return cache.attributesNormalized.get( normal );
-
-		const attribute = normal.clone();
-		const v = new Vector3();
-
-		for ( let i = 0, il = attribute.count; i < il; i ++ ) {
-
-			v.fromBufferAttribute( attribute, i );
-
-			if ( v.x === 0 && v.y === 0 && v.z === 0 ) {
-
-				// if values can't be normalized set (1, 0, 0)
-				v.setX( 1.0 );
-
-			} else {
-
-				v.normalize();
-
-			}
-
-			attribute.setXYZ( i, v.x, v.y, v.z );
-
-		}
-
-		cache.attributesNormalized.set( normal, attribute );
-
-		return attribute;
-
-	}
-
-	/**
-	 * Applies a texture transform, if present, to the map definition. Requires
-	 * the KHR_texture_transform extension.
-	 *
-	 * @param {Object} mapDef
-	 * @param {THREE.Texture} texture
-	 */
-	applyTextureTransform( mapDef, texture ) {
-
-		let didTransform = false;
-		const transformDef = {};
-
-		if ( texture.offset.x !== 0 || texture.offset.y !== 0 ) {
-
-			transformDef.offset = texture.offset.toArray();
-			didTransform = true;
-
-		}
-
-		if ( texture.rotation !== 0 ) {
-
-			transformDef.rotation = texture.rotation;
-			didTransform = true;
-
-		}
-
-		if ( texture.repeat.x !== 1 || texture.repeat.y !== 1 ) {
-
-			transformDef.scale = texture.repeat.toArray();
-			didTransform = true;
-
-		}
-
-		if ( didTransform ) {
-
-			mapDef.extensions = mapDef.extensions || {};
-			mapDef.extensions[ 'KHR_texture_transform' ] = transformDef;
-			this.extensionsUsed[ 'KHR_texture_transform' ] = true;
-
-		}
-
-	}
-
-	async buildMetalRoughTextureAsync( metalnessMap, roughnessMap ) {
-
-		if ( metalnessMap === roughnessMap ) return metalnessMap;
-
-		function getEncodingConversion( map ) {
-
-			if ( map.colorSpace === SRGBColorSpace ) {
-
-				return function SRGBToLinear( c ) {
-
-					return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 );
-
-				};
-
-			}
-
-			return function LinearToLinear( c ) {
-
-				return c;
-
-			};
-
-		}
-
-		if ( metalnessMap instanceof CompressedTexture ) {
-
-			metalnessMap = await this.decompressTextureAsync( metalnessMap );
-
-		}
-
-		if ( roughnessMap instanceof CompressedTexture ) {
-
-			roughnessMap = await this.decompressTextureAsync( roughnessMap );
-
-		}
-
-		const metalness = metalnessMap ? metalnessMap.image : null;
-		const roughness = roughnessMap ? roughnessMap.image : null;
-
-		const width = Math.max( metalness ? metalness.width : 0, roughness ? roughness.width : 0 );
-		const height = Math.max( metalness ? metalness.height : 0, roughness ? roughness.height : 0 );
-
-		const canvas = getCanvas();
-		canvas.width = width;
-		canvas.height = height;
-
-		const context = canvas.getContext( '2d', {
-			willReadFrequently: true,
-		} );
-		context.fillStyle = '#00ffff';
-		context.fillRect( 0, 0, width, height );
-
-		const composite = context.getImageData( 0, 0, width, height );
-
-		if ( metalness ) {
-
-			context.drawImage( metalness, 0, 0, width, height );
-
-			const convert = getEncodingConversion( metalnessMap );
-			const data = context.getImageData( 0, 0, width, height ).data;
-
-			for ( let i = 2; i < data.length; i += 4 ) {
-
-				composite.data[ i ] = convert( data[ i ] / 256 ) * 256;
-
-			}
-
-		}
-
-		if ( roughness ) {
-
-			context.drawImage( roughness, 0, 0, width, height );
-
-			const convert = getEncodingConversion( roughnessMap );
-			const data = context.getImageData( 0, 0, width, height ).data;
-
-			for ( let i = 1; i < data.length; i += 4 ) {
-
-				composite.data[ i ] = convert( data[ i ] / 256 ) * 256;
-
-			}
-
-		}
-
-		context.putImageData( composite, 0, 0 );
-
-		//
-
-		const reference = metalnessMap || roughnessMap;
-
-		const texture = reference.clone();
-
-		texture.source = new Source( canvas );
-		texture.colorSpace = NoColorSpace;
-		texture.channel = ( metalnessMap || roughnessMap ).channel;
-
-		if ( metalnessMap && roughnessMap && metalnessMap.channel !== roughnessMap.channel ) {
-
-			console.warn( 'THREE.GLTFExporter: UV channels for metalnessMap and roughnessMap textures must match.' );
-
-		}
-
-		console.warn( 'THREE.GLTFExporter: Merged metalnessMap and roughnessMap textures.' );
-
-		return texture;
-
-	}
-
-
-	async decompressTextureAsync( texture, maxTextureSize = Infinity ) {
-
-		if ( this.textureUtils === null ) {
-
-			throw new Error( 'THREE.GLTFExporter: setTextureUtils() must be called to process compressed textures.' );
-
-		}
-
-		return await this.textureUtils.decompress( texture, maxTextureSize );
-
-	}
-
-	/**
-	 * Process a buffer to append to the default one.
-	 * @param {ArrayBuffer} buffer
-	 * @return {0}
-	 */
-	processBuffer( buffer ) {
-
-		const json = this.json;
-		const buffers = this.buffers;
-
-		if ( ! json.buffers ) json.buffers = [ { byteLength: 0 } ];
-
-		// All buffers are merged before export.
-		buffers.push( buffer );
-
-		return 0;
-
-	}
-
-	/**
-	 * Process and generate a BufferView
-	 * @param {BufferAttribute} attribute
-	 * @param {number} componentType
-	 * @param {number} start
-	 * @param {number} count
-	 * @param {number} [target] Target usage of the BufferView
-	 * @return {Object}
-	 */
-	processBufferView( attribute, componentType, start, count, target ) {
-
-		const json = this.json;
-
-		if ( ! json.bufferViews ) json.bufferViews = [];
-
-		// Create a new dataview and dump the attribute's array into it
-
-		let componentSize;
-
-		switch ( componentType ) {
-
-			case WEBGL_CONSTANTS.BYTE:
-			case WEBGL_CONSTANTS.UNSIGNED_BYTE:
-
-				componentSize = 1;
-
-				break;
-
-			case WEBGL_CONSTANTS.SHORT:
-			case WEBGL_CONSTANTS.UNSIGNED_SHORT:
-
-				componentSize = 2;
-
-				break;
-
-			default:
-
-				componentSize = 4;
-
-		}
-
-		let byteStride = attribute.itemSize * componentSize;
-
-		if ( target === WEBGL_CONSTANTS.ARRAY_BUFFER ) {
-
-			// Each element of a vertex attribute MUST be aligned to 4-byte boundaries
-			// inside a bufferView
-			byteStride = Math.ceil( byteStride / 4 ) * 4;
-
-		}
-
-		const byteLength = getPaddedBufferSize( count * byteStride );
-		const dataView = new DataView( new ArrayBuffer( byteLength ) );
-		let offset = 0;
-
-		for ( let i = start; i < start + count; i ++ ) {
-
-			for ( let a = 0; a < attribute.itemSize; a ++ ) {
-
-				let value;
-
-				if ( attribute.itemSize > 4 ) {
-
-					 // no support for interleaved data for itemSize > 4
-
-					value = attribute.array[ i * attribute.itemSize + a ];
-
-				} else {
-
-					if ( a === 0 ) value = attribute.getX( i );
-					else if ( a === 1 ) value = attribute.getY( i );
-					else if ( a === 2 ) value = attribute.getZ( i );
-					else if ( a === 3 ) value = attribute.getW( i );
-
-					if ( attribute.normalized === true ) {
-
-						value = MathUtils.normalize( value, attribute.array );
-
-					}
-
-				}
-
-				if ( componentType === WEBGL_CONSTANTS.FLOAT ) {
-
-					dataView.setFloat32( offset, value, true );
-
-				} else if ( componentType === WEBGL_CONSTANTS.INT ) {
-
-					dataView.setInt32( offset, value, true );
-
-				} else if ( componentType === WEBGL_CONSTANTS.UNSIGNED_INT ) {
-
-					dataView.setUint32( offset, value, true );
-
-				} else if ( componentType === WEBGL_CONSTANTS.SHORT ) {
-
-					dataView.setInt16( offset, value, true );
-
-				} else if ( componentType === WEBGL_CONSTANTS.UNSIGNED_SHORT ) {
-
-					dataView.setUint16( offset, value, true );
-
-				} else if ( componentType === WEBGL_CONSTANTS.BYTE ) {
-
-					dataView.setInt8( offset, value );
-
-				} else if ( componentType === WEBGL_CONSTANTS.UNSIGNED_BYTE ) {
-
-					dataView.setUint8( offset, value );
-
-				}
-
-				offset += componentSize;
-
-			}
-
-			if ( ( offset % byteStride ) !== 0 ) {
-
-				offset += byteStride - ( offset % byteStride );
-
-			}
-
-		}
-
-		const bufferViewDef = {
-
-			buffer: this.processBuffer( dataView.buffer ),
-			byteOffset: this.byteOffset,
-			byteLength: byteLength
-
-		};
-
-		if ( target !== undefined ) bufferViewDef.target = target;
-
-		if ( target === WEBGL_CONSTANTS.ARRAY_BUFFER ) {
-
-			// Only define byteStride for vertex attributes.
-			bufferViewDef.byteStride = byteStride;
-
-		}
-
-		this.byteOffset += byteLength;
-
-		json.bufferViews.push( bufferViewDef );
-
-		// @TODO Merge bufferViews where possible.
-		const output = {
-
-			id: json.bufferViews.length - 1,
-			byteLength: 0
-
-		};
-
-		return output;
-
-	}
-
-	/**
-	 * Process and generate a BufferView from an image Blob.
-	 * @param {Blob} blob
-	 * @return {Promise<number>} An integer
-	 */
-	processBufferViewImage( blob ) {
-
-		const writer = this;
-		const json = writer.json;
-
-		if ( ! json.bufferViews ) json.bufferViews = [];
-
-		return new Promise( function ( resolve ) {
-
-			const reader = new FileReader();
-			reader.readAsArrayBuffer( blob );
-			reader.onloadend = function () {
-
-				const buffer = getPaddedArrayBuffer( reader.result );
-
-				const bufferViewDef = {
-					buffer: writer.processBuffer( buffer ),
-					byteOffset: writer.byteOffset,
-					byteLength: buffer.byteLength
-				};
-
-				writer.byteOffset += buffer.byteLength;
-				resolve( json.bufferViews.push( bufferViewDef ) - 1 );
-
-			};
-
-		} );
-
-	}
-
-	/**
-	 * Process attribute to generate an accessor
-	 * @param {BufferAttribute} attribute Attribute to process
-	 * @param {?BufferGeometry} [geometry] Geometry used for truncated draw range
-	 * @param {number} [start=0]
-	 * @param {number} [count=Infinity]
-	 * @return {?number} Index of the processed accessor on the "accessors" array
-	 */
-	processAccessor( attribute, geometry, start, count ) {
-
-		const json = this.json;
-
-		const types = {
-
-			1: 'SCALAR',
-			2: 'VEC2',
-			3: 'VEC3',
-			4: 'VEC4',
-			9: 'MAT3',
-			16: 'MAT4'
-
-		};
-
-		let componentType;
-
-		// Detect the component type of the attribute array
-		if ( attribute.array.constructor === Float32Array ) {
-
-			componentType = WEBGL_CONSTANTS.FLOAT;
-
-		} else if ( attribute.array.constructor === Int32Array ) {
-
-			componentType = WEBGL_CONSTANTS.INT;
-
-		} else if ( attribute.array.constructor === Uint32Array ) {
-
-			componentType = WEBGL_CONSTANTS.UNSIGNED_INT;
-
-		} else if ( attribute.array.constructor === Int16Array ) {
-
-			componentType = WEBGL_CONSTANTS.SHORT;
-
-		} else if ( attribute.array.constructor === Uint16Array ) {
-
-			componentType = WEBGL_CONSTANTS.UNSIGNED_SHORT;
-
-		} else if ( attribute.array.constructor === Int8Array ) {
-
-			componentType = WEBGL_CONSTANTS.BYTE;
-
-		} else if ( attribute.array.constructor === Uint8Array ) {
-
-			componentType = WEBGL_CONSTANTS.UNSIGNED_BYTE;
-
-		} else {
-
-			throw new Error( 'THREE.GLTFExporter: Unsupported bufferAttribute component type: ' + attribute.array.constructor.name );
-
-		}
-
-		if ( start === undefined ) start = 0;
-		if ( count === undefined || count === Infinity ) count = attribute.count;
-
-		// Skip creating an accessor if the attribute doesn't have data to export
-		if ( count === 0 ) return null;
-
-		const minMax = getMinMax( attribute, start, count );
-		let bufferViewTarget;
-
-		// If geometry isn't provided, don't infer the target usage of the bufferView. For
-		// animation samplers, target must not be set.
-		if ( geometry !== undefined ) {
-
-			bufferViewTarget = attribute === geometry.index ? WEBGL_CONSTANTS.ELEMENT_ARRAY_BUFFER : WEBGL_CONSTANTS.ARRAY_BUFFER;
-
-		}
-
-		const bufferView = this.processBufferView( attribute, componentType, start, count, bufferViewTarget );
-
-		const accessorDef = {
-
-			bufferView: bufferView.id,
-			byteOffset: bufferView.byteOffset,
-			componentType: componentType,
-			count: count,
-			max: minMax.max,
-			min: minMax.min,
-			type: types[ attribute.itemSize ]
-
-		};
-
-		if ( attribute.normalized === true ) accessorDef.normalized = true;
-		if ( ! json.accessors ) json.accessors = [];
-
-		return json.accessors.push( accessorDef ) - 1;
-
-	}
-
-	/**
-	 * Process image
-	 * @param {Image} image to process
-	 * @param {number} format Identifier of the format (RGBAFormat)
-	 * @param {boolean} flipY before writing out the image
-	 * @param {string} mimeType export format
-	 * @return {number}     Index of the processed texture in the "images" array
-	 */
-	processImage( image, format, flipY, mimeType = 'image/png' ) {
-
-		if ( image !== null ) {
-
-			const writer = this;
-			const cache = writer.cache;
-			const json = writer.json;
-			const options = writer.options;
-			const pending = writer.pending;
-
-			if ( ! cache.images.has( image ) ) cache.images.set( image, {} );
-
-			const cachedImages = cache.images.get( image );
-
-			const key = mimeType + ':flipY/' + flipY.toString();
-
-			if ( cachedImages[ key ] !== undefined ) return cachedImages[ key ];
-
-			if ( ! json.images ) json.images = [];
-
-			const imageDef = { mimeType: mimeType };
-
-			const canvas = getCanvas();
-
-			canvas.width = Math.min( image.width, options.maxTextureSize );
-			canvas.height = Math.min( image.height, options.maxTextureSize );
-
-			const ctx = canvas.getContext( '2d', {
-				willReadFrequently: true,
-			} );
-
-			if ( flipY === true ) {
-
-				ctx.translate( 0, canvas.height );
-				ctx.scale( 1, - 1 );
-
-			}
-
-			if ( image.data !== undefined ) { // THREE.DataTexture
-
-				if ( format !== RGBAFormat ) {
-
-					console.error( 'GLTFExporter: Only RGBAFormat is supported.', format );
-
-				}
-
-				if ( image.width > options.maxTextureSize || image.height > options.maxTextureSize ) {
-
-					console.warn( 'GLTFExporter: Image size is bigger than maxTextureSize', image );
-
-				}
-
-				const data = new Uint8ClampedArray( image.height * image.width * 4 );
-
-				for ( let i = 0; i < data.length; i += 4 ) {
-
-					data[ i + 0 ] = image.data[ i + 0 ];
-					data[ i + 1 ] = image.data[ i + 1 ];
-					data[ i + 2 ] = image.data[ i + 2 ];
-					data[ i + 3 ] = image.data[ i + 3 ];
-
-				}
-
-				ctx.putImageData( new ImageData( data, image.width, image.height ), 0, 0 );
-
-			} else {
-
-				if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||
-					( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||
-					( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ||
-					( typeof OffscreenCanvas !== 'undefined' && image instanceof OffscreenCanvas ) ) {
-
-					ctx.drawImage( image, 0, 0, canvas.width, canvas.height );
-
-				} else {
-
-					throw new Error( 'THREE.GLTFExporter: Invalid image type. Use HTMLImageElement, HTMLCanvasElement, ImageBitmap or OffscreenCanvas.' );
-
-				}
-
-			}
-
-			if ( options.binary === true ) {
-
-				pending.push(
-
-					getToBlobPromise( canvas, mimeType )
-						.then( blob => writer.processBufferViewImage( blob ) )
-						.then( bufferViewIndex => {
-
-							imageDef.bufferView = bufferViewIndex;
-
-						} )
-
-				);
-
-			} else {
-
-				imageDef.uri = ImageUtils.getDataURL( canvas, mimeType );
-
-			}
-
-			const index = json.images.push( imageDef ) - 1;
-			cachedImages[ key ] = index;
-			return index;
-
-		} else {
-
-			throw new Error( 'THREE.GLTFExporter: No valid image data found. Unable to process texture.' );
-
-		}
-
-	}
-
-	/**
-	 * Process sampler
-	 * @param {Texture} map Texture to process
-	 * @return {number}      Index of the processed texture in the "samplers" array
-	 */
-	processSampler( map ) {
-
-		const json = this.json;
-
-		if ( ! json.samplers ) json.samplers = [];
-
-		const samplerDef = {
-			magFilter: THREE_TO_WEBGL[ map.magFilter ],
-			minFilter: THREE_TO_WEBGL[ map.minFilter ],
-			wrapS: THREE_TO_WEBGL[ map.wrapS ],
-			wrapT: THREE_TO_WEBGL[ map.wrapT ]
-		};
-
-		return json.samplers.push( samplerDef ) - 1;
-
-	}
-
-	/**
-	 * Process texture
-	 * @param {Texture} map Map to process
-	 * @return {Promise<number>} Index of the processed texture in the "textures" array
-	 */
-	async processTextureAsync( map ) {
-
-		const writer = this;
-		const options = writer.options;
-		const cache = this.cache;
-		const json = this.json;
-
-		if ( cache.textures.has( map ) ) return cache.textures.get( map );
-
-		if ( ! json.textures ) json.textures = [];
-
-		// make non-readable textures (e.g. CompressedTexture) readable by blitting them into a new texture
-		if ( map instanceof CompressedTexture ) {
-
-			map = await this.decompressTextureAsync( map, options.maxTextureSize );
-
-		}
-
-		const mimeType = map.userData.mimeType;
-
-		const imageIndex = this.processImage( map.image, map.format, map.flipY, mimeType );
-
-		const textureDef = {
-			sampler: this.processSampler( map )
-		};
-
-		if ( mimeType === 'image/webp' ) {
-
-			textureDef.extensions = textureDef.extensions || {};
-			textureDef.extensions[ 'EXT_texture_webp' ] = {
-				source: imageIndex
-			};
-
-			this.extensionsUsed[ 'EXT_texture_webp' ] = true;
-			this.extensionsRequired[ 'EXT_texture_webp' ] = true;
-
-		} else {
-
-			textureDef.source = imageIndex;
-
-		}
-
-		if ( map.name ) textureDef.name = map.name;
-
-		await this._invokeAllAsync( async function ( ext ) {
-
-			ext.writeTexture && await ext.writeTexture( map, textureDef );
-
-		} );
-
-		const index = json.textures.push( textureDef ) - 1;
-		cache.textures.set( map, index );
-		return index;
-
-	}
-
-	/**
-	 * Process material
-	 * @param {THREE.Material} material Material to process
-	 * @return {Promise<?number>} Index of the processed material in the "materials" array
-	 */
-	async processMaterialAsync( material ) {
-
-		const cache = this.cache;
-		const json = this.json;
-
-		if ( cache.materials.has( material ) ) return cache.materials.get( material );
-
-		if ( material.isShaderMaterial ) {
-
-			console.warn( 'GLTFExporter: THREE.ShaderMaterial not supported.' );
-			return null;
-
-		}
-
-		if ( ! json.materials ) json.materials = [];
-
-		// @QUESTION Should we avoid including any attribute that has the default value?
-		const materialDef = {	pbrMetallicRoughness: {} };
-
-		if ( material.isMeshStandardMaterial !== true && material.isMeshBasicMaterial !== true ) {
-
-			console.warn( 'GLTFExporter: Use MeshStandardMaterial or MeshBasicMaterial for best results.' );
-
-		}
-
-		// pbrMetallicRoughness.baseColorFactor
-		const color = material.color.toArray().concat( [ material.opacity ] );
-
-		if ( ! equalArray( color, [ 1, 1, 1, 1 ] ) ) {
-
-			materialDef.pbrMetallicRoughness.baseColorFactor = color;
-
-		}
-
-		if ( material.isMeshStandardMaterial ) {
-
-			materialDef.pbrMetallicRoughness.metallicFactor = material.metalness;
-			materialDef.pbrMetallicRoughness.roughnessFactor = material.roughness;
-
-		} else {
-
-			materialDef.pbrMetallicRoughness.metallicFactor = 0;
-			materialDef.pbrMetallicRoughness.roughnessFactor = 1;
-
-		}
-
-		// pbrMetallicRoughness.metallicRoughnessTexture
-		if ( material.metalnessMap || material.roughnessMap ) {
-
-			const metalRoughTexture = await this.buildMetalRoughTextureAsync( material.metalnessMap, material.roughnessMap );
-
-			const metalRoughMapDef = {
-				index: await this.processTextureAsync( metalRoughTexture ),
-				texCoord: metalRoughTexture.channel
-			};
-			this.applyTextureTransform( metalRoughMapDef, metalRoughTexture );
-			materialDef.pbrMetallicRoughness.metallicRoughnessTexture = metalRoughMapDef;
-
-		}
-
-		// pbrMetallicRoughness.baseColorTexture
-		if ( material.map ) {
-
-			const baseColorMapDef = {
-				index: await this.processTextureAsync( material.map ),
-				texCoord: material.map.channel
-			};
-			this.applyTextureTransform( baseColorMapDef, material.map );
-			materialDef.pbrMetallicRoughness.baseColorTexture = baseColorMapDef;
-
-		}
-
-		if ( material.emissive ) {
-
-			const emissive = material.emissive;
-			const maxEmissiveComponent = Math.max( emissive.r, emissive.g, emissive.b );
-
-			if ( maxEmissiveComponent > 0 ) {
-
-				materialDef.emissiveFactor = material.emissive.toArray();
-
-			}
-
-			// emissiveTexture
-			if ( material.emissiveMap ) {
-
-				const emissiveMapDef = {
-					index: await this.processTextureAsync( material.emissiveMap ),
-					texCoord: material.emissiveMap.channel
-				};
-				this.applyTextureTransform( emissiveMapDef, material.emissiveMap );
-				materialDef.emissiveTexture = emissiveMapDef;
-
-			}
-
-		}
-
-		// normalTexture
-		if ( material.normalMap ) {
-
-			const normalMapDef = {
-				index: await this.processTextureAsync( material.normalMap ),
-				texCoord: material.normalMap.channel
-			};
-
-			if ( material.normalScale && material.normalScale.x !== 1 ) {
-
-				// glTF normal scale is univariate. Ignore `y`, which may be flipped.
-				// Context: https://github.com/mrdoob/three.js/issues/11438#issuecomment-507003995
-				normalMapDef.scale = material.normalScale.x;
-
-			}
-
-			this.applyTextureTransform( normalMapDef, material.normalMap );
-			materialDef.normalTexture = normalMapDef;
-
-		}
-
-		// occlusionTexture
-		if ( material.aoMap ) {
-
-			const occlusionMapDef = {
-				index: await this.processTextureAsync( material.aoMap ),
-				texCoord: material.aoMap.channel
-			};
-
-			if ( material.aoMapIntensity !== 1.0 ) {
-
-				occlusionMapDef.strength = material.aoMapIntensity;
-
-			}
-
-			this.applyTextureTransform( occlusionMapDef, material.aoMap );
-			materialDef.occlusionTexture = occlusionMapDef;
-
-		}
-
-		// alphaMode
-		if ( material.transparent ) {
-
-			materialDef.alphaMode = 'BLEND';
-
-		} else {
-
-			if ( material.alphaTest > 0.0 ) {
-
-				materialDef.alphaMode = 'MASK';
-				materialDef.alphaCutoff = material.alphaTest;
-
-			}
-
-		}
-
-		// doubleSided
-		if ( material.side === DoubleSide ) materialDef.doubleSided = true;
-		if ( material.name !== '' ) materialDef.name = material.name;
-
-		this.serializeUserData( material, materialDef );
-
-		await this._invokeAllAsync( async function ( ext ) {
-
-			ext.writeMaterialAsync && await ext.writeMaterialAsync( material, materialDef );
-
-		} );
-
-		const index = json.materials.push( materialDef ) - 1;
-		cache.materials.set( material, index );
-		return index;
-
-	}
-
-	/**
-	 * Process mesh
-	 * @param {THREE.Mesh} mesh Mesh to process
-	 * @return {Promise<?number>} Index of the processed mesh in the "meshes" array
-	 */
-	async processMeshAsync( mesh ) {
-
-		const cache = this.cache;
-		const json = this.json;
-
-		const meshCacheKeyParts = [ mesh.geometry.uuid ];
-
-		if ( Array.isArray( mesh.material ) ) {
-
-			for ( let i = 0, l = mesh.material.length; i < l; i ++ ) {
-
-				meshCacheKeyParts.push( mesh.material[ i ].uuid	);
-
-			}
-
-		} else {
-
-			meshCacheKeyParts.push( mesh.material.uuid );
-
-		}
-
-		const meshCacheKey = meshCacheKeyParts.join( ':' );
-
-		if ( cache.meshes.has( meshCacheKey ) ) return cache.meshes.get( meshCacheKey );
-
-		const geometry = mesh.geometry;
-
-		let mode;
-
-		// Use the correct mode
-		if ( mesh.isLineSegments ) {
-
-			mode = WEBGL_CONSTANTS.LINES;
-
-		} else if ( mesh.isLineLoop ) {
-
-			mode = WEBGL_CONSTANTS.LINE_LOOP;
-
-		} else if ( mesh.isLine ) {
-
-			mode = WEBGL_CONSTANTS.LINE_STRIP;
-
-		} else if ( mesh.isPoints ) {
-
-			mode = WEBGL_CONSTANTS.POINTS;
-
-		} else {
-
-			mode = mesh.material.wireframe ? WEBGL_CONSTANTS.LINES : WEBGL_CONSTANTS.TRIANGLES;
-
-		}
-
-		const meshDef = {};
-		const attributes = {};
-		const primitives = [];
-		const targets = [];
-
-		// Conversion between attributes names in threejs and gltf spec
-		const nameConversion = {
-			uv: 'TEXCOORD_0',
-			uv1: 'TEXCOORD_1',
-			uv2: 'TEXCOORD_2',
-			uv3: 'TEXCOORD_3',
-			color: 'COLOR_0',
-			skinWeight: 'WEIGHTS_0',
-			skinIndex: 'JOINTS_0'
-		};
-
-		const originalNormal = geometry.getAttribute( 'normal' );
-
-		if ( originalNormal !== undefined && ! this.isNormalizedNormalAttribute( originalNormal ) ) {
-
-			console.warn( 'THREE.GLTFExporter: Creating normalized normal attribute from the non-normalized one.' );
-
-			geometry.setAttribute( 'normal', this.createNormalizedNormalAttribute( originalNormal ) );
-
-		}
-
-		// @QUESTION Detect if .vertexColors = true?
-		// For every attribute create an accessor
-		let modifiedAttribute = null;
-
-		for ( let attributeName in geometry.attributes ) {
-
-			// Ignore morph target attributes, which are exported later.
-			if ( attributeName.slice( 0, 5 ) === 'morph' ) continue;
-
-			const attribute = geometry.attributes[ attributeName ];
-			attributeName = nameConversion[ attributeName ] || attributeName.toUpperCase();
-
-			// Prefix all geometry attributes except the ones specifically
-			// listed in the spec; non-spec attributes are considered custom.
-			const validVertexAttributes =
-					/^(POSITION|NORMAL|TANGENT|TEXCOORD_\d+|COLOR_\d+|JOINTS_\d+|WEIGHTS_\d+)$/;
-
-			if ( ! validVertexAttributes.test( attributeName ) && ! attributeName.startsWith( '_' ) ) attributeName = '_' + attributeName;
-
-			if ( cache.attributes.has( this.getUID( attribute ) ) ) {
-
-				attributes[ attributeName ] = cache.attributes.get( this.getUID( attribute ) );
-				continue;
-
-			}
-
-			// Enforce glTF vertex attribute requirements:
-			// - JOINTS_0 must be UNSIGNED_BYTE or UNSIGNED_SHORT
-			// - Only custom attributes may be INT or UNSIGNED_INT
-			modifiedAttribute = null;
-			const array = attribute.array;
-
-			if ( attributeName === 'JOINTS_0' &&
-				! ( array instanceof Uint16Array ) &&
-				! ( array instanceof Uint8Array ) ) {
-
-				console.warn( 'GLTFExporter: Attribute "skinIndex" converted to type UNSIGNED_SHORT.' );
-				modifiedAttribute = GLTFExporter.Utils.toTypedBufferAttribute( attribute, Uint16Array );
-
-			} else if ( ( array instanceof Uint32Array || array instanceof Int32Array ) && ! attributeName.startsWith( '_' ) ) {
-
-				console.warn( `GLTFExporter: Attribute "${ attributeName }" converted to type FLOAT.` );
-				modifiedAttribute = GLTFExporter.Utils.toTypedBufferAttribute( attribute, Float32Array );
-
-			}
-
-			const accessor = this.processAccessor( modifiedAttribute || attribute, geometry );
-
-			if ( accessor !== null ) {
-
-				if ( ! attributeName.startsWith( '_' ) ) {
-
-					this.detectMeshQuantization( attributeName, attribute );
-
-				}
-
-				attributes[ attributeName ] = accessor;
-				cache.attributes.set( this.getUID( attribute ), accessor );
-
-			}
-
-		}
-
-		if ( originalNormal !== undefined ) geometry.setAttribute( 'normal', originalNormal );
-
-		// Skip if no exportable attributes found
-		if ( Object.keys( attributes ).length === 0 ) return null;
-
-		// Morph targets
-		if ( mesh.morphTargetInfluences !== undefined && mesh.morphTargetInfluences.length > 0 ) {
-
-			const weights = [];
-			const targetNames = [];
-			const reverseDictionary = {};
-
-			if ( mesh.morphTargetDictionary !== undefined ) {
-
-				for ( const key in mesh.morphTargetDictionary ) {
-
-					reverseDictionary[ mesh.morphTargetDictionary[ key ] ] = key;
-
-				}
-
-			}
-
-			for ( let i = 0; i < mesh.morphTargetInfluences.length; ++ i ) {
-
-				const target = {};
-				let warned = false;
-
-				for ( const attributeName in geometry.morphAttributes ) {
-
-					// glTF 2.0 morph supports only POSITION/NORMAL/TANGENT.
-					// Three.js doesn't support TANGENT yet.
-
-					if ( attributeName !== 'position' && attributeName !== 'normal' ) {
-
-						if ( ! warned ) {
-
-							console.warn( 'GLTFExporter: Only POSITION and NORMAL morph are supported.' );
-							warned = true;
-
-						}
-
-						continue;
-
-					}
-
-					const attribute = geometry.morphAttributes[ attributeName ][ i ];
-					const gltfAttributeName = attributeName.toUpperCase();
-
-					// Three.js morph attribute has absolute values while the one of glTF has relative values.
-					//
-					// glTF 2.0 Specification:
-					// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#morph-targets
-
-					const baseAttribute = geometry.attributes[ attributeName ];
-
-					if ( cache.attributes.has( this.getUID( attribute, true ) ) ) {
-
-						target[ gltfAttributeName ] = cache.attributes.get( this.getUID( attribute, true ) );
-						continue;
-
-					}
-
-					// Clones attribute not to override
-					const relativeAttribute = attribute.clone();
-
-					if ( ! geometry.morphTargetsRelative ) {
-
-						for ( let j = 0, jl = attribute.count; j < jl; j ++ ) {
-
-							for ( let a = 0; a < attribute.itemSize; a ++ ) {
-
-								if ( a === 0 ) relativeAttribute.setX( j, attribute.getX( j ) - baseAttribute.getX( j ) );
-								if ( a === 1 ) relativeAttribute.setY( j, attribute.getY( j ) - baseAttribute.getY( j ) );
-								if ( a === 2 ) relativeAttribute.setZ( j, attribute.getZ( j ) - baseAttribute.getZ( j ) );
-								if ( a === 3 ) relativeAttribute.setW( j, attribute.getW( j ) - baseAttribute.getW( j ) );
-
-							}
-
-						}
-
-					}
-
-					target[ gltfAttributeName ] = this.processAccessor( relativeAttribute, geometry );
-					cache.attributes.set( this.getUID( baseAttribute, true ), target[ gltfAttributeName ] );
-
-				}
-
-				targets.push( target );
-
-				weights.push( mesh.morphTargetInfluences[ i ] );
-
-				if ( mesh.morphTargetDictionary !== undefined ) targetNames.push( reverseDictionary[ i ] );
-
-			}
-
-			meshDef.weights = weights;
-
-			if ( targetNames.length > 0 ) {
-
-				meshDef.extras = {};
-				meshDef.extras.targetNames = targetNames;
-
-			}
-
-		}
-
-		const isMultiMaterial = Array.isArray( mesh.material );
-
-		if ( isMultiMaterial && geometry.groups.length === 0 ) return null;
-
-		let didForceIndices = false;
-
-		if ( isMultiMaterial && geometry.index === null ) {
-
-			const indices = [];
-
-			for ( let i = 0, il = geometry.attributes.position.count; i < il; i ++ ) {
-
-				indices[ i ] = i;
-
-			}
-
-			geometry.setIndex( indices );
-
-			didForceIndices = true;
-
-		}
-
-		const materials = isMultiMaterial ? mesh.material : [ mesh.material ];
-		const groups = isMultiMaterial ? geometry.groups : [ { materialIndex: 0, start: undefined, count: undefined } ];
-
-		for ( let i = 0, il = groups.length; i < il; i ++ ) {
-
-			const primitive = {
-				mode: mode,
-				attributes: attributes,
-			};
-
-			this.serializeUserData( geometry, primitive );
-
-			if ( targets.length > 0 ) primitive.targets = targets;
-
-			if ( geometry.index !== null ) {
-
-				let cacheKey = this.getUID( geometry.index );
-
-				if ( groups[ i ].start !== undefined || groups[ i ].count !== undefined ) {
-
-					cacheKey += ':' + groups[ i ].start + ':' + groups[ i ].count;
-
-				}
-
-				if ( cache.attributes.has( cacheKey ) ) {
-
-					primitive.indices = cache.attributes.get( cacheKey );
-
-				} else {
-
-					primitive.indices = this.processAccessor( geometry.index, geometry, groups[ i ].start, groups[ i ].count );
-					cache.attributes.set( cacheKey, primitive.indices );
-
-				}
-
-				if ( primitive.indices === null ) delete primitive.indices;
-
-			}
-
-			const material = await this.processMaterialAsync( materials[ groups[ i ].materialIndex ] );
-
-			if ( material !== null ) primitive.material = material;
-
-			primitives.push( primitive );
-
-		}
-
-		if ( didForceIndices === true ) {
-
-			geometry.setIndex( null );
-
-		}
-
-		meshDef.primitives = primitives;
-
-		if ( ! json.meshes ) json.meshes = [];
-
-		await this._invokeAllAsync( function ( ext ) {
-
-			ext.writeMesh && ext.writeMesh( mesh, meshDef );
-
-		} );
-
-		const index = json.meshes.push( meshDef ) - 1;
-		cache.meshes.set( meshCacheKey, index );
-		return index;
-
-	}
-
-	/**
-	 * If a vertex attribute with a
-	 * [non-standard data type](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#meshes-overview)
-	 * is used, it is checked whether it is a valid data type according to the
-	 * [KHR_mesh_quantization](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_mesh_quantization/README.md)
-	 * extension.
-	 * In this case the extension is automatically added to the list of used extensions.
-	 *
-	 * @param {string} attributeName
-	 * @param {THREE.BufferAttribute} attribute
-	 */
-	detectMeshQuantization( attributeName, attribute ) {
-
-		if ( this.extensionsUsed[ KHR_MESH_QUANTIZATION ] ) return;
-
-		let attrType = undefined;
-
-		switch ( attribute.array.constructor ) {
-
-			case Int8Array:
-
-				attrType = 'byte';
-
-				break;
-
-			case Uint8Array:
-
-				attrType = 'unsigned byte';
-
-				break;
-
-			case Int16Array:
-
-				attrType = 'short';
-
-				break;
-
-			case Uint16Array:
-
-				attrType = 'unsigned short';
-
-				break;
-
-			default:
-
-				return;
-
-		}
-
-		if ( attribute.normalized ) attrType += ' normalized';
-
-		const attrNamePrefix = attributeName.split( '_', 1 )[ 0 ];
-
-		if ( KHR_mesh_quantization_ExtraAttrTypes[ attrNamePrefix ] && KHR_mesh_quantization_ExtraAttrTypes[ attrNamePrefix ].includes( attrType ) ) {
-
-			this.extensionsUsed[ KHR_MESH_QUANTIZATION ] = true;
-			this.extensionsRequired[ KHR_MESH_QUANTIZATION ] = true;
-
-		}
-
-	}
-
-	/**
-	 * Process camera
-	 * @param {THREE.Camera} camera Camera to process
-	 * @return {number} Index of the processed mesh in the "camera" array
-	 */
-	processCamera( camera ) {
-
-		const json = this.json;
-
-		if ( ! json.cameras ) json.cameras = [];
-
-		const isOrtho = camera.isOrthographicCamera;
-
-		const cameraDef = {
-			type: isOrtho ? 'orthographic' : 'perspective'
-		};
-
-		if ( isOrtho ) {
-
-			cameraDef.orthographic = {
-				xmag: camera.right * 2,
-				ymag: camera.top * 2,
-				zfar: camera.far <= 0 ? 0.001 : camera.far,
-				znear: camera.near < 0 ? 0 : camera.near
-			};
-
-		} else {
-
-			cameraDef.perspective = {
-				aspectRatio: camera.aspect,
-				yfov: MathUtils.degToRad( camera.fov ),
-				zfar: camera.far <= 0 ? 0.001 : camera.far,
-				znear: camera.near < 0 ? 0 : camera.near
-			};
-
-		}
-
-		// Question: Is saving "type" as name intentional?
-		if ( camera.name !== '' ) cameraDef.name = camera.type;
-
-		return json.cameras.push( cameraDef ) - 1;
-
-	}
-
-	/**
-	 * Creates glTF animation entry from AnimationClip object.
-	 *
-	 * Status:
-	 * - Only properties listed in PATH_PROPERTIES may be animated.
-	 *
-	 * @param {THREE.AnimationClip} clip
-	 * @param {THREE.Object3D} root
-	 * @return {?number}
-	 */
-	processAnimation( clip, root ) {
-
-		const json = this.json;
-		const nodeMap = this.nodeMap;
-
-		if ( ! json.animations ) json.animations = [];
-
-		clip = GLTFExporter.Utils.mergeMorphTargetTracks( clip.clone(), root );
-
-		const tracks = clip.tracks;
-		const channels = [];
-		const samplers = [];
-
-		for ( let i = 0; i < tracks.length; ++ i ) {
-
-			const track = tracks[ i ];
-			const trackBinding = PropertyBinding.parseTrackName( track.name );
-			let trackNode = PropertyBinding.findNode( root, trackBinding.nodeName );
-			const trackProperty = PATH_PROPERTIES[ trackBinding.propertyName ];
-
-			if ( trackBinding.objectName === 'bones' ) {
-
-				if ( trackNode.isSkinnedMesh === true ) {
-
-					trackNode = trackNode.skeleton.getBoneByName( trackBinding.objectIndex );
-
-				} else {
-
-					trackNode = undefined;
-
-				}
-
-			}
-
-			if ( ! trackNode || ! trackProperty ) {
-
-				console.warn( 'THREE.GLTFExporter: Could not export animation track "%s".', track.name );
-				continue;
-
-			}
-
-			const inputItemSize = 1;
-			let outputItemSize = track.values.length / track.times.length;
-
-			if ( trackProperty === PATH_PROPERTIES.morphTargetInfluences ) {
-
-				outputItemSize /= trackNode.morphTargetInfluences.length;
-
-			}
-
-			let interpolation;
-
-			// @TODO export CubicInterpolant(InterpolateSmooth) as CUBICSPLINE
-
-			// Detecting glTF cubic spline interpolant by checking factory method's special property
-			// GLTFCubicSplineInterpolant is a custom interpolant and track doesn't return
-			// valid value from .getInterpolation().
-			if ( track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline === true ) {
-
-				interpolation = 'CUBICSPLINE';
-
-				// itemSize of CUBICSPLINE keyframe is 9
-				// (VEC3 * 3: inTangent, splineVertex, and outTangent)
-				// but needs to be stored as VEC3 so dividing by 3 here.
-				outputItemSize /= 3;
-
-			} else if ( track.getInterpolation() === InterpolateDiscrete ) {
-
-				interpolation = 'STEP';
-
-			} else {
-
-				interpolation = 'LINEAR';
-
-			}
-
-			samplers.push( {
-				input: this.processAccessor( new BufferAttribute( track.times, inputItemSize ) ),
-				output: this.processAccessor( new BufferAttribute( track.values, outputItemSize ) ),
-				interpolation: interpolation
-			} );
-
-			channels.push( {
-				sampler: samplers.length - 1,
-				target: {
-					node: nodeMap.get( trackNode ),
-					path: trackProperty
-				}
-			} );
-
-		}
-
-		const animationDef = {
-			name: clip.name || 'clip_' + json.animations.length,
-			samplers: samplers,
-			channels: channels
-		};
-
-		this.serializeUserData( clip, animationDef );
-
-		json.animations.push( animationDef );
-
-		return json.animations.length - 1;
-
-	}
-
-	/**
-	 * @param {THREE.Object3D} object
-	 * @return {?number}
-	 */
-	 processSkin( object ) {
-
-		const json = this.json;
-		const nodeMap = this.nodeMap;
-
-		const node = json.nodes[ nodeMap.get( object ) ];
-
-		const skeleton = object.skeleton;
-
-		if ( skeleton === undefined ) return null;
-
-		const rootJoint = object.skeleton.bones[ 0 ];
-
-		if ( rootJoint === undefined ) return null;
-
-		const joints = [];
-		const inverseBindMatrices = new Float32Array( skeleton.bones.length * 16 );
-		const temporaryBoneInverse = new Matrix4();
-
-		for ( let i = 0; i < skeleton.bones.length; ++ i ) {
-
-			joints.push( nodeMap.get( skeleton.bones[ i ] ) );
-			temporaryBoneInverse.copy( skeleton.boneInverses[ i ] );
-			temporaryBoneInverse.multiply( object.bindMatrix ).toArray( inverseBindMatrices, i * 16 );
-
-		}
-
-		if ( json.skins === undefined ) json.skins = [];
-
-		json.skins.push( {
-			inverseBindMatrices: this.processAccessor( new BufferAttribute( inverseBindMatrices, 16 ) ),
-			joints: joints,
-			skeleton: nodeMap.get( rootJoint )
-		} );
-
-		const skinIndex = node.skin = json.skins.length - 1;
-
-		return skinIndex;
-
-	}
-
-	/**
-	 * Process Object3D node
-	 * @param {THREE.Object3D} object Object3D to processNodeAsync
-	 * @return {Promise<number>} Index of the node in the nodes list
-	 */
-	async processNodeAsync( object ) {
-
-		const json = this.json;
-		const options = this.options;
-		const nodeMap = this.nodeMap;
-
-		if ( ! json.nodes ) json.nodes = [];
-
-		// Handle pivot by creating a container node
-		if ( object.pivot !== null ) {
-
-			return await this._processNodeWithPivotAsync( object );
-
-		}
-
-		const nodeDef = {};
-
-		if ( options.trs ) {
-
-			const rotation = object.quaternion.toArray();
-			const position = object.position.toArray();
-			const scale = object.scale.toArray();
-
-			if ( ! equalArray( rotation, [ 0, 0, 0, 1 ] ) ) {
-
-				nodeDef.rotation = rotation;
-
-			}
-
-			if ( ! equalArray( position, [ 0, 0, 0 ] ) ) {
-
-				nodeDef.translation = position;
-
-			}
-
-			if ( ! equalArray( scale, [ 1, 1, 1 ] ) ) {
-
-				nodeDef.scale = scale;
-
-			}
-
-		} else {
-
-			if ( object.matrixAutoUpdate ) {
-
-				object.updateMatrix();
-
-			}
-
-			if ( isIdentityMatrix( object.matrix ) === false ) {
-
-				nodeDef.matrix = object.matrix.elements;
-
-			}
-
-		}
-
-		// We don't export empty strings name because it represents no-name in Three.js.
-		if ( object.name !== '' ) nodeDef.name = String( object.name );
-
-		this.serializeUserData( object, nodeDef );
-
-		if ( object.isMesh || object.isLine || object.isPoints ) {
-
-			const meshIndex = await this.processMeshAsync( object );
-
-			if ( meshIndex !== null ) nodeDef.mesh = meshIndex;
-
-		} else if ( object.isCamera ) {
-
-			nodeDef.camera = this.processCamera( object );
-
-		}
-
-		if ( object.isSkinnedMesh ) this.skins.push( object );
-
-		const nodeIndex = json.nodes.push( nodeDef ) - 1;
-		nodeMap.set( object, nodeIndex );
-
-		if ( object.children.length > 0 ) {
-
-			const children = [];
-
-			for ( let i = 0, l = object.children.length; i < l; i ++ ) {
-
-				const child = object.children[ i ];
-
-				if ( child.visible || options.onlyVisible === false ) {
-
-					const childNodeIndex = await this.processNodeAsync( child );
-
-					if ( childNodeIndex !== null ) children.push( childNodeIndex );
-
-				}
-
-			}
-
-			if ( children.length > 0 ) nodeDef.children = children;
-
-		}
-
-		await this._invokeAllAsync( function ( ext ) {
-
-			ext.writeNode && ext.writeNode( object, nodeDef );
-
-		} );
-
-		return nodeIndex;
-
-	}
-
-	/**
-	 * Process Object3D node with pivot using container approach
-	 * @param {THREE.Object3D} object Object3D with pivot
-	 * @return {Promise<number>} Index of the container node
-	 */
-	async _processNodeWithPivotAsync( object ) {
-
-		const json = this.json;
-		const options = this.options;
-		const nodeMap = this.nodeMap;
-
-		const pivot = object.pivot;
-
-		// Container node: holds position + pivot offset, rotation, scale
-		// Animations will target this node
-		const containerDef = {};
-
-		const rotation = object.quaternion.toArray();
-		const position = [
-			object.position.x + pivot.x,
-			object.position.y + pivot.y,
-			object.position.z + pivot.z
-		];
-		const scale = object.scale.toArray();
-
-		if ( ! equalArray( rotation, [ 0, 0, 0, 1 ] ) ) {
-
-			containerDef.rotation = rotation;
-
-		}
-
-		if ( ! equalArray( position, [ 0, 0, 0 ] ) ) {
-
-			containerDef.translation = position;
-
-		}
-
-		if ( ! equalArray( scale, [ 1, 1, 1 ] ) ) {
-
-			containerDef.scale = scale;
-
-		}
-
-		// Store pivot in extras for round-trip reconstruction
-		containerDef.extras = { pivot: pivot.toArray() };
-
-		if ( object.name !== '' ) containerDef.name = String( object.name );
-
-		this.serializeUserData( object, containerDef );
-
-		const containerIndex = json.nodes.push( containerDef ) - 1;
-
-		// Map original object to container so animations target it
-		nodeMap.set( object, containerIndex );
-
-		// Child node: holds mesh with -pivot offset
-		const childDef = {};
-
-		const childPosition = [ - pivot.x, - pivot.y, - pivot.z ];
-
-		if ( ! equalArray( childPosition, [ 0, 0, 0 ] ) ) {
-
-			childDef.translation = childPosition;
-
-		}
-
-		if ( object.isMesh || object.isLine || object.isPoints ) {
-
-			const meshIndex = await this.processMeshAsync( object );
-
-			if ( meshIndex !== null ) childDef.mesh = meshIndex;
-
-		} else if ( object.isCamera ) {
-
-			childDef.camera = this.processCamera( object );
-
-		}
-
-		if ( object.isSkinnedMesh ) this.skins.push( object );
-
-		const childIndex = json.nodes.push( childDef ) - 1;
-
-		// Build children array for container
-		const containerChildren = [ childIndex ];
-
-		// Process object's children as children of the child node
-		if ( object.children.length > 0 ) {
-
-			const grandchildren = [];
-
-			for ( let i = 0, l = object.children.length; i < l; i ++ ) {
-
-				const child = object.children[ i ];
-
-				if ( child.visible || options.onlyVisible === false ) {
-
-					const childNodeIndex = await this.processNodeAsync( child );
-
-					if ( childNodeIndex !== null ) grandchildren.push( childNodeIndex );
-
-				}
-
-			}
-
-			if ( grandchildren.length > 0 ) childDef.children = grandchildren;
-
-		}
-
-		containerDef.children = containerChildren;
-
-		await this._invokeAllAsync( function ( ext ) {
-
-			ext.writeNode && ext.writeNode( object, containerDef );
-
-		} );
-
-		return containerIndex;
-
-	}
-
-	/**
-	 * Process Scene
-	 * @param {Scene} scene Scene to process
-	 */
-	async processSceneAsync( scene ) {
-
-		const json = this.json;
-		const options = this.options;
-
-		if ( ! json.scenes ) {
-
-			json.scenes = [];
-			json.scene = 0;
-
-		}
-
-		const sceneDef = {};
-
-		if ( scene.name !== '' ) sceneDef.name = scene.name;
-
-		json.scenes.push( sceneDef );
-
-		const nodes = [];
-
-		for ( let i = 0, l = scene.children.length; i < l; i ++ ) {
-
-			const child = scene.children[ i ];
-
-			if ( child.visible || options.onlyVisible === false ) {
-
-				const nodeIndex = await this.processNodeAsync( child );
-
-				if ( nodeIndex !== null ) nodes.push( nodeIndex );
-
-			}
-
-		}
-
-		if ( nodes.length > 0 ) sceneDef.nodes = nodes;
-
-		this.serializeUserData( scene, sceneDef );
-
-	}
-
-	/**
-	 * Creates a Scene to hold a list of objects and parse it
-	 * @param {Array<THREE.Object3D>} objects List of objects to process
-	 */
-	async processObjectsAsync( objects ) {
-
-		const scene = new Scene();
-		scene.name = 'AuxScene';
-
-		for ( let i = 0; i < objects.length; i ++ ) {
-
-			// We push directly to children instead of calling `add` to prevent
-			// modify the .parent and break its original scene and hierarchy
-			scene.children.push( objects[ i ] );
-
-		}
-
-		await this.processSceneAsync( scene );
-
-	}
-
-	/**
-	 * @param {THREE.Object3D|Array<THREE.Object3D>} input
-	 */
-	async processInputAsync( input ) {
-
-		const options = this.options;
-
-		input = input instanceof Array ? input : [ input ];
-
-		await this._invokeAllAsync( function ( ext ) {
-
-			ext.beforeParse && ext.beforeParse( input );
-
-		} );
-
-		const objectsWithoutScene = [];
-
-		for ( let i = 0; i < input.length; i ++ ) {
-
-			if ( input[ i ] instanceof Scene ) {
-
-				await this.processSceneAsync( input[ i ] );
-
-			} else {
-
-				objectsWithoutScene.push( input[ i ] );
-
-			}
-
-		}
-
-		if ( objectsWithoutScene.length > 0 ) {
-
-			await this.processObjectsAsync( objectsWithoutScene );
-
-		}
-
-		for ( let i = 0; i < this.skins.length; ++ i ) {
-
-			this.processSkin( this.skins[ i ] );
-
-		}
-
-		for ( let i = 0; i < options.animations.length; ++ i ) {
-
-			this.processAnimation( options.animations[ i ], input[ 0 ] );
-
-		}
-
-		await this._invokeAllAsync( function ( ext ) {
-
-			ext.afterParse && ext.afterParse( input );
-
-		} );
-
-	}
-
-	async _invokeAllAsync( func ) {
-
-		for ( let i = 0, il = this.plugins.length; i < il; i ++ ) {
-
-			await func( this.plugins[ i ] );
-
-		}
-
-	}
-
-}
-
-/**
- * Punctual Lights Extension
- *
- * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual
- *
- * @private
- */
-class GLTFLightExtension {
-
-	constructor( writer ) {
-
-		this.writer = writer;
-		this.name = 'KHR_lights_punctual';
-
-	}
-
-	writeNode( light, nodeDef ) {
-
-		if ( ! light.isLight ) return;
-
-		if ( ! light.isDirectionalLight && ! light.isPointLight && ! light.isSpotLight ) {
-
-			console.warn( 'THREE.GLTFExporter: Only directional, point, and spot lights are supported.', light );
-			return;
-
-		}
-
-		const writer = this.writer;
-		const json = writer.json;
-		const extensionsUsed = writer.extensionsUsed;
-
-		const lightDef = {};
-
-		if ( light.name ) lightDef.name = light.name;
-
-		lightDef.color = light.color.toArray();
-
-		lightDef.intensity = light.intensity;
-
-		if ( light.isDirectionalLight ) {
-
-			lightDef.type = 'directional';
-
-		} else if ( light.isPointLight ) {
-
-			lightDef.type = 'point';
-
-			if ( light.distance > 0 ) lightDef.range = light.distance;
-
-		} else if ( light.isSpotLight ) {
-
-			lightDef.type = 'spot';
-
-			if ( light.distance > 0 ) lightDef.range = light.distance;
-
-			lightDef.spot = {};
-			lightDef.spot.innerConeAngle = ( 1.0 - light.penumbra ) * light.angle;
-			lightDef.spot.outerConeAngle = light.angle;
-
-		}
-
-		if ( light.decay !== undefined && light.decay !== 2 ) {
-
-			console.warn( 'THREE.GLTFExporter: Light decay may be lost. glTF is physically-based, '
-				+ 'and expects light.decay=2.' );
-
-		}
-
-		if ( light.target
-				&& ( light.target.parent !== light
-				|| light.target.position.x !== 0
-				|| light.target.position.y !== 0
-				|| light.target.position.z !== - 1 ) ) {
-
-			console.warn( 'THREE.GLTFExporter: Light direction may be lost. For best results, '
-				+ 'make light.target a child of the light with position 0,0,-1.' );
-
-		}
-
-		if ( ! extensionsUsed[ this.name ] ) {
-
-			json.extensions = json.extensions || {};
-			json.extensions[ this.name ] = { lights: [] };
-			extensionsUsed[ this.name ] = true;
-
-		}
-
-		const lights = json.extensions[ this.name ].lights;
-		lights.push( lightDef );
-
-		nodeDef.extensions = nodeDef.extensions || {};
-		nodeDef.extensions[ this.name ] = { light: lights.length - 1 };
-
-	}
-
-}
-
-/**
- * Unlit Materials Extension
- *
- * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit
- *
- * @private
- */
-class GLTFMaterialsUnlitExtension {
-
-	constructor( writer ) {
-
-		this.writer = writer;
-		this.name = 'KHR_materials_unlit';
-
-	}
-
-	async writeMaterialAsync( material, materialDef ) {
-
-		if ( ! material.isMeshBasicMaterial ) return;
-
-		const writer = this.writer;
-		const extensionsUsed = writer.extensionsUsed;
-
-		materialDef.extensions = materialDef.extensions || {};
-		materialDef.extensions[ this.name ] = {};
-
-		extensionsUsed[ this.name ] = true;
-
-		materialDef.pbrMetallicRoughness.metallicFactor = 0.0;
-		materialDef.pbrMetallicRoughness.roughnessFactor = 0.9;
-
-	}
-
-}
-
-/**
- * Clearcoat Materials Extension
- *
- * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat
- *
- * @private
- */
-class GLTFMaterialsClearcoatExtension {
-
-	constructor( writer ) {
-
-		this.writer = writer;
-		this.name = 'KHR_materials_clearcoat';
-
-	}
-
-	async writeMaterialAsync( material, materialDef ) {
-
-		if ( ! material.isMeshPhysicalMaterial || material.clearcoat === 0 ) return;
-
-		const writer = this.writer;
-		const extensionsUsed = writer.extensionsUsed;
-
-		const extensionDef = {};
-
-		extensionDef.clearcoatFactor = material.clearcoat;
-
-		if ( material.clearcoatMap ) {
-
-			const clearcoatMapDef = {
-				index: await writer.processTextureAsync( material.clearcoatMap ),
-				texCoord: material.clearcoatMap.channel
-			};
-			writer.applyTextureTransform( clearcoatMapDef, material.clearcoatMap );
-			extensionDef.clearcoatTexture = clearcoatMapDef;
-
-		}
-
-		extensionDef.clearcoatRoughnessFactor = material.clearcoatRoughness;
-
-		if ( material.clearcoatRoughnessMap ) {
-
-			const clearcoatRoughnessMapDef = {
-				index: await writer.processTextureAsync( material.clearcoatRoughnessMap ),
-				texCoord: material.clearcoatRoughnessMap.channel
-			};
-			writer.applyTextureTransform( clearcoatRoughnessMapDef, material.clearcoatRoughnessMap );
-			extensionDef.clearcoatRoughnessTexture = clearcoatRoughnessMapDef;
-
-		}
-
-		if ( material.clearcoatNormalMap ) {
-
-			const clearcoatNormalMapDef = {
-				index: await writer.processTextureAsync( material.clearcoatNormalMap ),
-				texCoord: material.clearcoatNormalMap.channel
-			};
-
-			if ( material.clearcoatNormalScale.x !== 1 ) clearcoatNormalMapDef.scale = material.clearcoatNormalScale.x;
-
-			writer.applyTextureTransform( clearcoatNormalMapDef, material.clearcoatNormalMap );
-			extensionDef.clearcoatNormalTexture = clearcoatNormalMapDef;
-
-		}
-
-		materialDef.extensions = materialDef.extensions || {};
-		materialDef.extensions[ this.name ] = extensionDef;
-
-		extensionsUsed[ this.name ] = true;
-
-
-	}
-
-}
-
-/**
- * Materials dispersion Extension
- *
- * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_dispersion
- *
- * @private
- */
-class GLTFMaterialsDispersionExtension {
-
-	constructor( writer ) {
-
-		this.writer = writer;
-		this.name = 'KHR_materials_dispersion';
-
-	}
-
-	async writeMaterialAsync( material, materialDef ) {
-
-		if ( ! material.isMeshPhysicalMaterial || material.dispersion === 0 ) return;
-
-		const writer = this.writer;
-		const extensionsUsed = writer.extensionsUsed;
-
-		const extensionDef = {};
-
-		extensionDef.dispersion = material.dispersion;
-
-		materialDef.extensions = materialDef.extensions || {};
-		materialDef.extensions[ this.name ] = extensionDef;
-
-		extensionsUsed[ this.name ] = true;
-
-	}
-
-}
-
-/**
- * Iridescence Materials Extension
- *
- * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_iridescence
- *
- * @private
- */
-class GLTFMaterialsIridescenceExtension {
-
-	constructor( writer ) {
-
-		this.writer = writer;
-		this.name = 'KHR_materials_iridescence';
-
-	}
-
-	async writeMaterialAsync( material, materialDef ) {
-
-		if ( ! material.isMeshPhysicalMaterial || material.iridescence === 0 ) return;
-
-		const writer = this.writer;
-		const extensionsUsed = writer.extensionsUsed;
-
-		const extensionDef = {};
-
-		extensionDef.iridescenceFactor = material.iridescence;
-
-		if ( material.iridescenceMap ) {
-
-			const iridescenceMapDef = {
-				index: await writer.processTextureAsync( material.iridescenceMap ),
-				texCoord: material.iridescenceMap.channel
-			};
-			writer.applyTextureTransform( iridescenceMapDef, material.iridescenceMap );
-			extensionDef.iridescenceTexture = iridescenceMapDef;
-
-		}
-
-		extensionDef.iridescenceIor = material.iridescenceIOR;
-		extensionDef.iridescenceThicknessMinimum = material.iridescenceThicknessRange[ 0 ];
-		extensionDef.iridescenceThicknessMaximum = material.iridescenceThicknessRange[ 1 ];
-
-		if ( material.iridescenceThicknessMap ) {
-
-			const iridescenceThicknessMapDef = {
-				index: await writer.processTextureAsync( material.iridescenceThicknessMap ),
-				texCoord: material.iridescenceThicknessMap.channel
-			};
-			writer.applyTextureTransform( iridescenceThicknessMapDef, material.iridescenceThicknessMap );
-			extensionDef.iridescenceThicknessTexture = iridescenceThicknessMapDef;
-
-		}
-
-		materialDef.extensions = materialDef.extensions || {};
-		materialDef.extensions[ this.name ] = extensionDef;
-
-		extensionsUsed[ this.name ] = true;
-
-	}
-
-}
-
-/**
- * Transmission Materials Extension
- *
- * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_transmission
- *
- * @private
- */
-class GLTFMaterialsTransmissionExtension {
-
-	constructor( writer ) {
-
-		this.writer = writer;
-		this.name = 'KHR_materials_transmission';
-
-	}
-
-	async writeMaterialAsync( material, materialDef ) {
-
-		if ( ! material.isMeshPhysicalMaterial || material.transmission === 0 ) return;
-
-		const writer = this.writer;
-		const extensionsUsed = writer.extensionsUsed;
-
-		const extensionDef = {};
-
-		extensionDef.transmissionFactor = material.transmission;
-
-		if ( material.transmissionMap ) {
-
-			const transmissionMapDef = {
-				index: await writer.processTextureAsync( material.transmissionMap ),
-				texCoord: material.transmissionMap.channel
-			};
-			writer.applyTextureTransform( transmissionMapDef, material.transmissionMap );
-			extensionDef.transmissionTexture = transmissionMapDef;
-
-		}
-
-		materialDef.extensions = materialDef.extensions || {};
-		materialDef.extensions[ this.name ] = extensionDef;
-
-		extensionsUsed[ this.name ] = true;
-
-	}
-
-}
-
-/**
- * Materials Volume Extension
- *
- * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_volume
- *
- * @private
- */
-class GLTFMaterialsVolumeExtension {
-
-	constructor( writer ) {
-
-		this.writer = writer;
-		this.name = 'KHR_materials_volume';
-
-	}
-
-	async writeMaterialAsync( material, materialDef ) {
-
-		if ( ! material.isMeshPhysicalMaterial || material.transmission === 0 ) return;
-
-		const writer = this.writer;
-		const extensionsUsed = writer.extensionsUsed;
-
-		const extensionDef = {};
-
-		extensionDef.thicknessFactor = material.thickness;
-
-		if ( material.thicknessMap ) {
-
-			const thicknessMapDef = {
-				index: await writer.processTextureAsync( material.thicknessMap ),
-				texCoord: material.thicknessMap.channel
-			};
-			writer.applyTextureTransform( thicknessMapDef, material.thicknessMap );
-			extensionDef.thicknessTexture = thicknessMapDef;
-
-		}
-
-		if ( material.attenuationDistance !== Infinity ) {
-
-			extensionDef.attenuationDistance = material.attenuationDistance;
-
-		}
-
-		extensionDef.attenuationColor = material.attenuationColor.toArray();
-
-		materialDef.extensions = materialDef.extensions || {};
-		materialDef.extensions[ this.name ] = extensionDef;
-
-		extensionsUsed[ this.name ] = true;
-
-	}
-
-}
-
-/**
- * Materials ior Extension
- *
- * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_ior
- *
- * @private
- */
-class GLTFMaterialsIorExtension {
-
-	constructor( writer ) {
-
-		this.writer = writer;
-		this.name = 'KHR_materials_ior';
-
-	}
-
-	async writeMaterialAsync( material, materialDef ) {
-
-		if ( ! material.isMeshPhysicalMaterial || material.ior === 1.5 ) return;
-
-		const writer = this.writer;
-		const extensionsUsed = writer.extensionsUsed;
-
-		const extensionDef = {};
-
-		extensionDef.ior = material.ior;
-
-		materialDef.extensions = materialDef.extensions || {};
-		materialDef.extensions[ this.name ] = extensionDef;
-
-		extensionsUsed[ this.name ] = true;
-
-	}
-
-}
-
-/**
- * Materials specular Extension
- *
- * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_specular
- *
- * @private
- */
-class GLTFMaterialsSpecularExtension {
-
-	constructor( writer ) {
-
-		this.writer = writer;
-		this.name = 'KHR_materials_specular';
-
-	}
-
-	async writeMaterialAsync( material, materialDef ) {
-
-		if ( ! material.isMeshPhysicalMaterial || ( material.specularIntensity === 1.0 &&
-		       material.specularColor.equals( DEFAULT_SPECULAR_COLOR ) &&
-		     ! material.specularIntensityMap && ! material.specularColorMap ) ) return;
-
-		const writer = this.writer;
-		const extensionsUsed = writer.extensionsUsed;
-
-		const extensionDef = {};
-
-		if ( material.specularIntensityMap ) {
-
-			const specularIntensityMapDef = {
-				index: await writer.processTextureAsync( material.specularIntensityMap ),
-				texCoord: material.specularIntensityMap.channel
-			};
-			writer.applyTextureTransform( specularIntensityMapDef, material.specularIntensityMap );
-			extensionDef.specularTexture = specularIntensityMapDef;
-
-		}
-
-		if ( material.specularColorMap ) {
-
-			const specularColorMapDef = {
-				index: await writer.processTextureAsync( material.specularColorMap ),
-				texCoord: material.specularColorMap.channel
-			};
-			writer.applyTextureTransform( specularColorMapDef, material.specularColorMap );
-			extensionDef.specularColorTexture = specularColorMapDef;
-
-		}
-
-		extensionDef.specularFactor = material.specularIntensity;
-		extensionDef.specularColorFactor = material.specularColor.toArray();
-
-		materialDef.extensions = materialDef.extensions || {};
-		materialDef.extensions[ this.name ] = extensionDef;
-
-		extensionsUsed[ this.name ] = true;
-
-	}
-
-}
-
-/**
- * Sheen Materials Extension
- *
- * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_sheen
- *
- * @private
- */
-class GLTFMaterialsSheenExtension {
-
-	constructor( writer ) {
-
-		this.writer = writer;
-		this.name = 'KHR_materials_sheen';
-
-	}
-
-	async writeMaterialAsync( material, materialDef ) {
-
-		if ( ! material.isMeshPhysicalMaterial || material.sheen == 0.0 ) return;
-
-		const writer = this.writer;
-		const extensionsUsed = writer.extensionsUsed;
-
-		const extensionDef = {};
-
-		if ( material.sheenRoughnessMap ) {
-
-			const sheenRoughnessMapDef = {
-				index: await writer.processTextureAsync( material.sheenRoughnessMap ),
-				texCoord: material.sheenRoughnessMap.channel
-			};
-			writer.applyTextureTransform( sheenRoughnessMapDef, material.sheenRoughnessMap );
-			extensionDef.sheenRoughnessTexture = sheenRoughnessMapDef;
-
-		}
-
-		if ( material.sheenColorMap ) {
-
-			const sheenColorMapDef = {
-				index: await writer.processTextureAsync( material.sheenColorMap ),
-				texCoord: material.sheenColorMap.channel
-			};
-			writer.applyTextureTransform( sheenColorMapDef, material.sheenColorMap );
-			extensionDef.sheenColorTexture = sheenColorMapDef;
-
-		}
-
-		extensionDef.sheenRoughnessFactor = material.sheenRoughness;
-		extensionDef.sheenColorFactor = material.sheenColor.toArray();
-
-		materialDef.extensions = materialDef.extensions || {};
-		materialDef.extensions[ this.name ] = extensionDef;
-
-		extensionsUsed[ this.name ] = true;
-
-	}
-
-}
-
-/**
- * Anisotropy Materials Extension
- *
- * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_anisotropy
- *
- * @private
- */
-class GLTFMaterialsAnisotropyExtension {
-
-	constructor( writer ) {
-
-		this.writer = writer;
-		this.name = 'KHR_materials_anisotropy';
-
-	}
-
-	async writeMaterialAsync( material, materialDef ) {
-
-		if ( ! material.isMeshPhysicalMaterial || material.anisotropy == 0.0 ) return;
-
-		const writer = this.writer;
-		const extensionsUsed = writer.extensionsUsed;
-
-		const extensionDef = {};
-
-		if ( material.anisotropyMap ) {
-
-			const anisotropyMapDef = { index: await writer.processTextureAsync( material.anisotropyMap ) };
-			writer.applyTextureTransform( anisotropyMapDef, material.anisotropyMap );
-			extensionDef.anisotropyTexture = anisotropyMapDef;
-
-		}
-
-		extensionDef.anisotropyStrength = material.anisotropy;
-		extensionDef.anisotropyRotation = material.anisotropyRotation;
-
-		materialDef.extensions = materialDef.extensions || {};
-		materialDef.extensions[ this.name ] = extensionDef;
-
-		extensionsUsed[ this.name ] = true;
-
-	}
-
-}
-
-/**
- * Materials Emissive Strength Extension
- *
- * Specification: https://github.com/KhronosGroup/glTF/blob/5768b3ce0ef32bc39cdf1bef10b948586635ead3/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md
- *
- * @private
- */
-class GLTFMaterialsEmissiveStrengthExtension {
-
-	constructor( writer ) {
-
-		this.writer = writer;
-		this.name = 'KHR_materials_emissive_strength';
-
-	}
-
-	async writeMaterialAsync( material, materialDef ) {
-
-		if ( ! material.isMeshStandardMaterial || material.emissiveIntensity === 1.0 ) return;
-
-		const writer = this.writer;
-		const extensionsUsed = writer.extensionsUsed;
-
-		const extensionDef = {};
-
-		extensionDef.emissiveStrength = material.emissiveIntensity;
-
-		materialDef.extensions = materialDef.extensions || {};
-		materialDef.extensions[ this.name ] = extensionDef;
-
-		extensionsUsed[ this.name ] = true;
-
-	}
-
-}
-
-
-/**
- * Materials bump Extension
- *
- * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/EXT_materials_bump
- *
- * @private
- */
-class GLTFMaterialsBumpExtension {
-
-	constructor( writer ) {
-
-		this.writer = writer;
-		this.name = 'EXT_materials_bump';
-
-	}
-
-	async writeMaterialAsync( material, materialDef ) {
-
-		if ( ! material.isMeshStandardMaterial || (
-		       material.bumpScale === 1 &&
-		     ! material.bumpMap ) ) return;
-
-		const writer = this.writer;
-		const extensionsUsed = writer.extensionsUsed;
-
-		const extensionDef = {};
-
-		if ( material.bumpMap ) {
-
-			const bumpMapDef = {
-				index: await writer.processTextureAsync( material.bumpMap ),
-				texCoord: material.bumpMap.channel
-			};
-			writer.applyTextureTransform( bumpMapDef, material.bumpMap );
-			extensionDef.bumpTexture = bumpMapDef;
-
-		}
-
-		extensionDef.bumpFactor = material.bumpScale;
-
-		materialDef.extensions = materialDef.extensions || {};
-		materialDef.extensions[ this.name ] = extensionDef;
-
-		extensionsUsed[ this.name ] = true;
-
-	}
-
-}
-
-/**
- * GPU Instancing Extension
- *
- * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_mesh_gpu_instancing
- *
- * @private
- */
-class GLTFMeshGpuInstancing {
-
-	constructor( writer ) {
-
-		this.writer = writer;
-		this.name = 'EXT_mesh_gpu_instancing';
-
-	}
-
-	writeNode( object, nodeDef ) {
-
-		if ( ! object.isInstancedMesh ) return;
-
-		const writer = this.writer;
-
-		const mesh = object;
-
-		const translationAttr = new Float32Array( mesh.count * 3 );
-		const rotationAttr = new Float32Array( mesh.count * 4 );
-		const scaleAttr = new Float32Array( mesh.count * 3 );
-
-		const matrix = new Matrix4();
-		const position = new Vector3();
-		const quaternion = new Quaternion();
-		const scale = new Vector3();
-
-		for ( let i = 0; i < mesh.count; i ++ ) {
-
-			mesh.getMatrixAt( i, matrix );
-			matrix.decompose( position, quaternion, scale );
-
-			position.toArray( translationAttr, i * 3 );
-			quaternion.toArray( rotationAttr, i * 4 );
-			scale.toArray( scaleAttr, i * 3 );
-
-		}
-
-		const attributes = {
-			TRANSLATION: writer.processAccessor( new BufferAttribute( translationAttr, 3 ) ),
-			ROTATION: writer.processAccessor( new BufferAttribute( rotationAttr, 4 ) ),
-			SCALE: writer.processAccessor( new BufferAttribute( scaleAttr, 3 ) ),
-		};
-
-		if ( mesh.instanceColor )
-			attributes._COLOR_0 = writer.processAccessor( mesh.instanceColor );
-
-		nodeDef.extensions = nodeDef.extensions || {};
-		nodeDef.extensions[ this.name ] = { attributes };
-
-		writer.extensionsUsed[ this.name ] = true;
-		writer.extensionsRequired[ this.name ] = true;
-
-	}
-
-}
-
-/**
- * Static utility functions
- *
- * @private
- */
-GLTFExporter.Utils = {
-
-	insertKeyframe: function ( track, time ) {
-
-		const tolerance = 0.001; // 1ms
-		const valueSize = track.getValueSize();
-
-		const times = new track.TimeBufferType( track.times.length + 1 );
-		const values = new track.ValueBufferType( track.values.length + valueSize );
-		const interpolant = track.createInterpolant( new track.ValueBufferType( valueSize ) );
-
-		let index;
-
-		if ( track.times.length === 0 ) {
-
-			times[ 0 ] = time;
-
-			for ( let i = 0; i < valueSize; i ++ ) {
-
-				values[ i ] = 0;
-
-			}
-
-			index = 0;
-
-		} else if ( time < track.times[ 0 ] ) {
-
-			if ( Math.abs( track.times[ 0 ] - time ) < tolerance ) return 0;
-
-			times[ 0 ] = time;
-			times.set( track.times, 1 );
-
-			values.set( interpolant.evaluate( time ), 0 );
-			values.set( track.values, valueSize );
-
-			index = 0;
-
-		} else if ( time > track.times[ track.times.length - 1 ] ) {
-
-			if ( Math.abs( track.times[ track.times.length - 1 ] - time ) < tolerance ) {
-
-				return track.times.length - 1;
-
-			}
-
-			times[ times.length - 1 ] = time;
-			times.set( track.times, 0 );
-
-			values.set( track.values, 0 );
-			values.set( interpolant.evaluate( time ), track.values.length );
-
-			index = times.length - 1;
-
-		} else {
-
-			for ( let i = 0; i < track.times.length; i ++ ) {
-
-				if ( Math.abs( track.times[ i ] - time ) < tolerance ) return i;
-
-				if ( track.times[ i ] < time && track.times[ i + 1 ] > time ) {
-
-					times.set( track.times.slice( 0, i + 1 ), 0 );
-					times[ i + 1 ] = time;
-					times.set( track.times.slice( i + 1 ), i + 2 );
-
-					values.set( track.values.slice( 0, ( i + 1 ) * valueSize ), 0 );
-					values.set( interpolant.evaluate( time ), ( i + 1 ) * valueSize );
-					values.set( track.values.slice( ( i + 1 ) * valueSize ), ( i + 2 ) * valueSize );
-
-					index = i + 1;
-
-					break;
-
-				}
-
-			}
-
-		}
-
-		track.times = times;
-		track.values = values;
-
-		return index;
-
-	},
-
-	mergeMorphTargetTracks: function ( clip, root ) {
-
-		const tracks = [];
-		const mergedTracks = {};
-		const sourceTracks = clip.tracks;
-
-		for ( let i = 0; i < sourceTracks.length; ++ i ) {
-
-			let sourceTrack = sourceTracks[ i ];
-			const sourceTrackBinding = PropertyBinding.parseTrackName( sourceTrack.name );
-			const sourceTrackNode = PropertyBinding.findNode( root, sourceTrackBinding.nodeName );
-
-			if ( sourceTrackBinding.propertyName !== 'morphTargetInfluences' || sourceTrackBinding.propertyIndex === undefined ) {
-
-				// Tracks that don't affect morph targets, or that affect all morph targets together, can be left as-is.
-				tracks.push( sourceTrack );
-				continue;
-
-			}
-
-			if ( sourceTrack.createInterpolant !== sourceTrack.InterpolantFactoryMethodDiscrete
-				&& sourceTrack.createInterpolant !== sourceTrack.InterpolantFactoryMethodLinear ) {
-
-				if ( sourceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline ) {
-
-					// This should never happen, because glTF morph target animations
-					// affect all targets already.
-					throw new Error( 'THREE.GLTFExporter: Cannot merge tracks with glTF CUBICSPLINE interpolation.' );
-
-				}
-
-				console.warn( 'THREE.GLTFExporter: Morph target interpolation mode not yet supported. Using LINEAR instead.' );
-
-				sourceTrack = sourceTrack.clone();
-				sourceTrack.setInterpolation( InterpolateLinear );
-
-			}
-
-			const targetCount = sourceTrackNode.morphTargetInfluences.length;
-			const targetIndex = sourceTrackNode.morphTargetDictionary[ sourceTrackBinding.propertyIndex ];
-
-			if ( targetIndex === undefined ) {
-
-				throw new Error( 'THREE.GLTFExporter: Morph target name not found: ' + sourceTrackBinding.propertyIndex );
-
-			}
-
-			let mergedTrack;
-
-			// If this is the first time we've seen this object, create a new
-			// track to store merged keyframe data for each morph target.
-			if ( mergedTracks[ sourceTrackNode.uuid ] === undefined ) {
-
-				mergedTrack = sourceTrack.clone();
-
-				const values = new mergedTrack.ValueBufferType( targetCount * mergedTrack.times.length );
-
-				for ( let j = 0; j < mergedTrack.times.length; j ++ ) {
-
-					values[ j * targetCount + targetIndex ] = mergedTrack.values[ j ];
-
-				}
-
-				// We need to take into consideration the intended target node
-				// of our original un-merged morphTarget animation.
-				mergedTrack.name = ( sourceTrackBinding.nodeName || '' ) + '.morphTargetInfluences';
-				mergedTrack.values = values;
-
-				mergedTracks[ sourceTrackNode.uuid ] = mergedTrack;
-				tracks.push( mergedTrack );
-
-				continue;
-
-			}
-
-			const sourceInterpolant = sourceTrack.createInterpolant( new sourceTrack.ValueBufferType( 1 ) );
-
-			mergedTrack = mergedTracks[ sourceTrackNode.uuid ];
-
-			// For every existing keyframe of the merged track, write a (possibly
-			// interpolated) value from the source track.
-			for ( let j = 0; j < mergedTrack.times.length; j ++ ) {
-
-				mergedTrack.values[ j * targetCount + targetIndex ] = sourceInterpolant.evaluate( mergedTrack.times[ j ] );
-
-			}
-
-			// For every existing keyframe of the source track, write a (possibly
-			// new) keyframe to the merged track. Values from the previous loop may
-			// be written again, but keyframes are de-duplicated.
-			for ( let j = 0; j < sourceTrack.times.length; j ++ ) {
-
-				const keyframeIndex = this.insertKeyframe( mergedTrack, sourceTrack.times[ j ] );
-				mergedTrack.values[ keyframeIndex * targetCount + targetIndex ] = sourceTrack.values[ j ];
-
-			}
-
-		}
-
-		clip.tracks = tracks;
-
-		return clip;
-
-	},
-
-	toTypedBufferAttribute: function ( srcAttribute, TypedArray ) {
-
-		const dstAttribute = new BufferAttribute( new TypedArray( srcAttribute.count * srcAttribute.itemSize ), srcAttribute.itemSize, false );
-
-		if ( ! srcAttribute.normalized && ! srcAttribute.isInterleavedBufferAttribute ) {
-
-			dstAttribute.array.set( srcAttribute.array );
-
-			return dstAttribute;
-
-		}
-
-		for ( let i = 0, il = srcAttribute.count; i < il; i ++ ) {
-
-			for ( let j = 0; j < srcAttribute.itemSize; j ++ ) {
-
-				dstAttribute.setComponent( i, j, srcAttribute.getComponent( i, j ) );
-
-			}
-
-		}
-
-		return dstAttribute;
-
-	}
-
-};
-
-/**
- * Export options of `GLTFExporter`.
- *
- * @typedef {Object} GLTFExporter~Options
- * @property {boolean} [trs=false] - Export position, rotation and scale instead of matrix per node.
- * @property {boolean} [onlyVisible=true] - Export only visible 3D objects.
- * @property {boolean} [binary=false] - Export in binary (.glb) format, returning an ArrayBuffer.
- * @property {number} [maxTextureSize=Infinity] - Restricts the image maximum size (both width and height) to the given value.
- * @property {Array<AnimationClip>} [animations=[]] - List of animations to be included in the export.
- * @property {boolean} [includeCustomExtensions=false] - Export custom glTF extensions defined on an object's `userData.gltfExtensions` property.
- **/
-
-/**
- * onDone callback of `GLTFExporter`.
- *
- * @callback GLTFExporter~OnDone
- * @param {ArrayBuffer|string} result - The generated .gltf (JSON) or .glb (binary).
- */
-
-/**
- * onError callback of `GLTFExporter`.
- *
- * @callback GLTFExporter~OnError
- * @param {Error} error - The error object.
- */
-
-export { GLTFExporter };

+ 0 - 347
node_modules/three/examples/jsm/exporters/KTX2Exporter.js

@@ -1,347 +0,0 @@
-import {
-	ColorManagement,
-	FloatType,
-	HalfFloatType,
-	UnsignedByteType,
-	RGBAFormat,
-	RGFormat,
-	RGIntegerFormat,
-	RedFormat,
-	RedIntegerFormat,
-	NoColorSpace,
-	LinearSRGBColorSpace,
-	SRGBColorSpace,
-	SRGBTransfer,
-	DataTexture,
-	REVISION,
-} from 'three';
-
-import {
-	createDefaultContainer,
-	write,
-	KHR_DF_CHANNEL_RGBSDA_ALPHA,
-	KHR_DF_CHANNEL_RGBSDA_BLUE,
-	KHR_DF_CHANNEL_RGBSDA_GREEN,
-	KHR_DF_CHANNEL_RGBSDA_RED,
-	KHR_DF_MODEL_RGBSDA,
-	KHR_DF_PRIMARIES_BT709,
-	KHR_DF_PRIMARIES_UNSPECIFIED,
-	KHR_DF_SAMPLE_DATATYPE_FLOAT,
-	KHR_DF_SAMPLE_DATATYPE_LINEAR,
-	KHR_DF_SAMPLE_DATATYPE_SIGNED,
-	KHR_DF_TRANSFER_LINEAR,
-	KHR_DF_TRANSFER_SRGB,
-	VK_FORMAT_R16_SFLOAT,
-	VK_FORMAT_R16G16_SFLOAT,
-	VK_FORMAT_R16G16B16A16_SFLOAT,
-	VK_FORMAT_R32_SFLOAT,
-	VK_FORMAT_R32G32_SFLOAT,
-	VK_FORMAT_R32G32B32A32_SFLOAT,
-	VK_FORMAT_R8_SRGB,
-	VK_FORMAT_R8_UNORM,
-	VK_FORMAT_R8G8_SRGB,
-	VK_FORMAT_R8G8_UNORM,
-	VK_FORMAT_R8G8B8A8_SRGB,
-	VK_FORMAT_R8G8B8A8_UNORM,
-} from '../libs/ktx-parse.module.js';
-
-/**
- * References:
- * - https://github.khronos.org/KTX-Specification/ktxspec.v2.html
- * - https://registry.khronos.org/DataFormat/specs/1.3/dataformat.1.3.html
- * - https://github.com/donmccurdy/KTX-Parse
- */
-
-const VK_FORMAT_MAP = {
-
-	[ RGBAFormat ]: {
-		[ FloatType ]: {
-			[ NoColorSpace ]: VK_FORMAT_R32G32B32A32_SFLOAT,
-			[ LinearSRGBColorSpace ]: VK_FORMAT_R32G32B32A32_SFLOAT,
-		},
-		[ HalfFloatType ]: {
-			[ NoColorSpace ]: VK_FORMAT_R16G16B16A16_SFLOAT,
-			[ LinearSRGBColorSpace ]: VK_FORMAT_R16G16B16A16_SFLOAT,
-		},
-		[ UnsignedByteType ]: {
-			[ NoColorSpace ]: VK_FORMAT_R8G8B8A8_UNORM,
-			[ LinearSRGBColorSpace ]: VK_FORMAT_R8G8B8A8_UNORM,
-			[ SRGBColorSpace ]: VK_FORMAT_R8G8B8A8_SRGB,
-		},
-	},
-
-	[ RGFormat ]: {
-		[ FloatType ]: {
-			[ NoColorSpace ]: VK_FORMAT_R32G32_SFLOAT,
-			[ LinearSRGBColorSpace ]: VK_FORMAT_R32G32_SFLOAT,
-		},
-		[ HalfFloatType ]: {
-			[ NoColorSpace ]: VK_FORMAT_R16G16_SFLOAT,
-			[ LinearSRGBColorSpace ]: VK_FORMAT_R16G16_SFLOAT,
-		},
-		[ UnsignedByteType ]: {
-			[ NoColorSpace ]: VK_FORMAT_R8G8_UNORM,
-			[ LinearSRGBColorSpace ]: VK_FORMAT_R8G8_UNORM,
-			[ SRGBColorSpace ]: VK_FORMAT_R8G8_SRGB,
-		},
-	},
-
-	[ RedFormat ]: {
-		[ FloatType ]: {
-			[ NoColorSpace ]: VK_FORMAT_R32_SFLOAT,
-			[ LinearSRGBColorSpace ]: VK_FORMAT_R32_SFLOAT,
-		},
-		[ HalfFloatType ]: {
-			[ NoColorSpace ]: VK_FORMAT_R16_SFLOAT,
-			[ LinearSRGBColorSpace ]: VK_FORMAT_R16_SFLOAT,
-		},
-		[ UnsignedByteType ]: {
-			[ NoColorSpace ]: VK_FORMAT_R8_UNORM,
-			[ LinearSRGBColorSpace ]: VK_FORMAT_R8_UNORM,
-			[ SRGBColorSpace ]: VK_FORMAT_R8_SRGB,
-		},
-	},
-
-};
-
-const KHR_DF_CHANNEL_MAP = [
-
-	KHR_DF_CHANNEL_RGBSDA_RED,
-	KHR_DF_CHANNEL_RGBSDA_GREEN,
-	KHR_DF_CHANNEL_RGBSDA_BLUE,
-	KHR_DF_CHANNEL_RGBSDA_ALPHA,
-
-];
-
-// TODO: sampleLower and sampleUpper may change based on color space.
-const KHR_DF_CHANNEL_SAMPLE_LOWER_UPPER = {
-
-	[ FloatType ]: [ 0xbf800000, 0x3f800000 ],
-	[ HalfFloatType ]: [ 0xbf800000, 0x3f800000 ],
-	[ UnsignedByteType ]: [ 0, 255 ],
-
-};
-
-const ERROR_INPUT = 'THREE.KTX2Exporter: Supported inputs are DataTexture, Data3DTexture, or WebGLRenderer and WebGLRenderTarget.';
-const ERROR_FORMAT = 'THREE.KTX2Exporter: Supported formats are RGBAFormat, RGFormat, or RedFormat.';
-const ERROR_TYPE = 'THREE.KTX2Exporter: Supported types are FloatType, HalfFloatType, or UnsignedByteType."';
-const ERROR_COLOR_SPACE = 'THREE.KTX2Exporter: Supported color spaces are SRGBColorSpace (UnsignedByteType only), LinearSRGBColorSpace, or NoColorSpace.';
-
-/**
- * An exporter for KTX2.
- *
- * ```js
- * const exporter = new KTX2Exporter();
- * const result = await exporter.parse( dataTexture );
- * ```
- *
- * @three_import import { KTX2Exporter } from 'three/addons/exporters/KTX2Exporter.js';
- */
-export class KTX2Exporter {
-
-	/**
-	 * This method has two variants.
-	 *
-	 * - When exporting a data texture, it receives one parameter. The data or 3D data texture.
-	 * - When exporting a render target (e.g. a PMREM), it receives two parameters. The renderer and the
-	 * render target.
-	 *
-	 * @async
-	 * @param {(DataTexture|Data3DTexture|WebGPURenderer|WebGLRenderer)} arg1 - The data texture to export or a renderer.
-	 * @param {RenderTarget} [arg2] - The render target that should be exported
-	 * @return {Promise<Uint8Array>} A Promise that resolves with the exported KTX2.
-	 */
-	async parse( arg1, arg2 ) {
-
-		let texture;
-
-		if ( arg1.isDataTexture || arg1.isData3DTexture ) {
-
-			texture = arg1;
-
-		} else if ( ( arg1.isWebGLRenderer || arg1.isWebGPURenderer ) && arg2.isRenderTarget ) {
-
-			texture = await toDataTexture( arg1, arg2 );
-
-		} else {
-
-			throw new Error( ERROR_INPUT );
-
-		}
-
-		if ( VK_FORMAT_MAP[ texture.format ] === undefined ) {
-
-			throw new Error( ERROR_FORMAT );
-
-		}
-
-		if ( VK_FORMAT_MAP[ texture.format ][ texture.type ] === undefined ) {
-
-			throw new Error( ERROR_TYPE );
-
-		}
-
-		if ( VK_FORMAT_MAP[ texture.format ][ texture.type ][ texture.colorSpace ] === undefined ) {
-
-			throw new Error( ERROR_COLOR_SPACE );
-
-		}
-
-		//
-
-		const array = texture.image.data;
-		const channelCount = getChannelCount( texture );
-		const container = createDefaultContainer();
-
-		container.vkFormat = VK_FORMAT_MAP[ texture.format ][ texture.type ][ texture.colorSpace ];
-		container.typeSize = array.BYTES_PER_ELEMENT;
-		container.pixelWidth = texture.image.width;
-		container.pixelHeight = texture.image.height;
-
-		if ( texture.isData3DTexture ) {
-
-			container.pixelDepth = texture.image.depth;
-
-		}
-
-		//
-
-		const basicDesc = container.dataFormatDescriptor[ 0 ];
-
-		basicDesc.colorModel = KHR_DF_MODEL_RGBSDA;
-		basicDesc.colorPrimaries = texture.colorSpace === NoColorSpace
-			? KHR_DF_PRIMARIES_UNSPECIFIED
-			: KHR_DF_PRIMARIES_BT709;
-		basicDesc.transferFunction = ColorManagement.getTransfer( texture.colorSpace ) === SRGBTransfer
-			? KHR_DF_TRANSFER_SRGB
-			: KHR_DF_TRANSFER_LINEAR;
-
-		basicDesc.texelBlockDimension = [ 0, 0, 0, 0 ];
-
-		basicDesc.bytesPlane = [
-
-			container.typeSize * channelCount, 0, 0, 0, 0, 0, 0, 0,
-
-		];
-
-		for ( let i = 0; i < channelCount; ++ i ) {
-
-			let channelType = KHR_DF_CHANNEL_MAP[ i ];
-
-			// Assign KHR_DF_SAMPLE_DATATYPE_LINEAR if the channel is linear _and_ differs from the transfer function.
-			if ( channelType === KHR_DF_CHANNEL_RGBSDA_ALPHA && basicDesc.transferFunction !== KHR_DF_TRANSFER_LINEAR ) {
-
-				channelType |= KHR_DF_SAMPLE_DATATYPE_LINEAR;
-
-			}
-
-			if ( texture.type === FloatType || texture.type === HalfFloatType ) {
-
-				channelType |= KHR_DF_SAMPLE_DATATYPE_FLOAT;
-				channelType |= KHR_DF_SAMPLE_DATATYPE_SIGNED;
-
-			}
-
-			basicDesc.samples.push( {
-
-				channelType: channelType,
-				bitOffset: i * array.BYTES_PER_ELEMENT * 8,
-				bitLength: array.BYTES_PER_ELEMENT * 8 - 1,
-				samplePosition: [ 0, 0, 0, 0 ],
-				sampleLower: KHR_DF_CHANNEL_SAMPLE_LOWER_UPPER[ texture.type ][ 0 ],
-				sampleUpper: KHR_DF_CHANNEL_SAMPLE_LOWER_UPPER[ texture.type ][ 1 ],
-
-			} );
-
-		}
-
-		//
-
-		container.levelCount = 1;
-
-		container.levels = [ {
-
-			levelData: new Uint8Array( array.buffer, array.byteOffset, array.byteLength ),
-			uncompressedByteLength: array.byteLength,
-
-		} ];
-
-		//
-
-		container.keyValue[ 'KTXwriter' ] = `three.js ${ REVISION }`;
-
-		//
-
-		return write( container, { keepWriter: true } );
-
-	}
-
-}
-
-async function toDataTexture( renderer, rtt ) {
-
-	const channelCount = getChannelCount( rtt.texture );
-
-	let view;
-
-	if ( renderer.isWebGLRenderer ) {
-
-		if ( rtt.texture.type === FloatType ) {
-
-			view = new Float32Array( rtt.width * rtt.height * channelCount );
-
-		} else if ( rtt.texture.type === HalfFloatType ) {
-
-			view = new Uint16Array( rtt.width * rtt.height * channelCount );
-
-		} else if ( rtt.texture.type === UnsignedByteType ) {
-
-			view = new Uint8Array( rtt.width * rtt.height * channelCount );
-
-		} else {
-
-			throw new Error( ERROR_TYPE );
-
-		}
-
-		await renderer.readRenderTargetPixelsAsync( rtt, 0, 0, rtt.width, rtt.height, view );
-
-	} else {
-
-		view = await renderer.readRenderTargetPixelsAsync( rtt, 0, 0, rtt.width, rtt.height );
-
-	}
-
-	const texture = new DataTexture( view, rtt.width, rtt.height, rtt.texture.format, rtt.texture.type );
-
-	texture.colorSpace = rtt.texture.colorSpace;
-
-	return texture;
-
-}
-
-function getChannelCount( texture ) {
-
-	switch ( texture.format ) {
-
-		case RGBAFormat:
-
-			return 4;
-
-		case RGFormat:
-		case RGIntegerFormat:
-
-			return 2;
-
-		case RedFormat:
-		case RedIntegerFormat:
-
-			return 1;
-
-		default:
-
-			throw new Error( ERROR_FORMAT );
-
-	}
-
-}

+ 0 - 308
node_modules/three/examples/jsm/exporters/OBJExporter.js

@@ -1,308 +0,0 @@
-import {
-	Color,
-	ColorManagement,
-	Matrix3,
-	SRGBColorSpace,
-	Vector2,
-	Vector3
-} from 'three';
-
-/**
- * An exporter for OBJ.
- *
- * `OBJExporter` is not able to export material data into MTL files so only geometry data are supported.
- *
- * ```js
- * const exporter = new OBJExporter();
- * const data = exporter.parse( scene );
- * ```
- *
- * @three_import import { OBJExporter } from 'three/addons/exporters/OBJExporter.js';
- */
-class OBJExporter {
-
-	/**
-	 * Parses the given 3D object and generates the OBJ output.
-	 *
-	 * If the 3D object is composed of multiple children and geometry, they are merged into a single mesh in the file.
-	 *
-	 * @param {Object3D} object - The 3D object to export.
-	 * @return {string} The exported OBJ.
-	 */
-	parse( object ) {
-
-		let output = '';
-
-		let indexVertex = 0;
-		let indexVertexUvs = 0;
-		let indexNormals = 0;
-
-		const vertex = new Vector3();
-		const color = new Color();
-		const normal = new Vector3();
-		const uv = new Vector2();
-
-		const face = [];
-
-		function parseMesh( mesh ) {
-
-			let nbVertex = 0;
-			let nbNormals = 0;
-			let nbVertexUvs = 0;
-
-			const geometry = mesh.geometry;
-
-			const normalMatrixWorld = new Matrix3();
-
-			// shortcuts
-			const vertices = geometry.getAttribute( 'position' );
-			const normals = geometry.getAttribute( 'normal' );
-			const uvs = geometry.getAttribute( 'uv' );
-			const indices = geometry.getIndex();
-
-			// name of the mesh object
-			output += 'o ' + mesh.name + '\n';
-
-			// name of the mesh material
-			if ( mesh.material && mesh.material.name ) {
-
-				output += 'usemtl ' + mesh.material.name + '\n';
-
-			}
-
-			// vertices
-
-			if ( vertices !== undefined ) {
-
-				for ( let i = 0, l = vertices.count; i < l; i ++, nbVertex ++ ) {
-
-					vertex.fromBufferAttribute( vertices, i );
-
-					// transform the vertex to world space
-					vertex.applyMatrix4( mesh.matrixWorld );
-
-					// transform the vertex to export format
-					output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n';
-
-				}
-
-			}
-
-			// uvs
-
-			if ( uvs !== undefined ) {
-
-				for ( let i = 0, l = uvs.count; i < l; i ++, nbVertexUvs ++ ) {
-
-					uv.fromBufferAttribute( uvs, i );
-
-					// transform the uv to export format
-					output += 'vt ' + uv.x + ' ' + uv.y + '\n';
-
-				}
-
-			}
-
-			// normals
-
-			if ( normals !== undefined ) {
-
-				normalMatrixWorld.getNormalMatrix( mesh.matrixWorld );
-
-				for ( let i = 0, l = normals.count; i < l; i ++, nbNormals ++ ) {
-
-					normal.fromBufferAttribute( normals, i );
-
-					// transform the normal to world space
-					normal.applyMatrix3( normalMatrixWorld ).normalize();
-
-					// transform the normal to export format
-					output += 'vn ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n';
-
-				}
-
-			}
-
-			// faces
-
-			if ( indices !== null ) {
-
-				for ( let i = 0, l = indices.count; i < l; i += 3 ) {
-
-					for ( let m = 0; m < 3; m ++ ) {
-
-						const j = indices.getX( i + m ) + 1;
-
-						face[ m ] = ( indexVertex + j ) + ( normals || uvs ? '/' + ( uvs ? ( indexVertexUvs + j ) : '' ) + ( normals ? '/' + ( indexNormals + j ) : '' ) : '' );
-
-					}
-
-					// transform the face to export format
-					output += 'f ' + face.join( ' ' ) + '\n';
-
-				}
-
-			} else {
-
-				for ( let i = 0, l = vertices.count; i < l; i += 3 ) {
-
-					for ( let m = 0; m < 3; m ++ ) {
-
-						const j = i + m + 1;
-
-						face[ m ] = ( indexVertex + j ) + ( normals || uvs ? '/' + ( uvs ? ( indexVertexUvs + j ) : '' ) + ( normals ? '/' + ( indexNormals + j ) : '' ) : '' );
-
-					}
-
-					// transform the face to export format
-					output += 'f ' + face.join( ' ' ) + '\n';
-
-				}
-
-			}
-
-			// update index
-			indexVertex += nbVertex;
-			indexVertexUvs += nbVertexUvs;
-			indexNormals += nbNormals;
-
-		}
-
-		function parseLine( line ) {
-
-			let nbVertex = 0;
-
-			const geometry = line.geometry;
-			const type = line.type;
-
-			// shortcuts
-			const vertices = geometry.getAttribute( 'position' );
-
-			// name of the line object
-			output += 'o ' + line.name + '\n';
-
-			if ( vertices !== undefined ) {
-
-				for ( let i = 0, l = vertices.count; i < l; i ++, nbVertex ++ ) {
-
-					vertex.fromBufferAttribute( vertices, i );
-
-					// transform the vertex to world space
-					vertex.applyMatrix4( line.matrixWorld );
-
-					// transform the vertex to export format
-					output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n';
-
-				}
-
-			}
-
-			if ( type === 'Line' ) {
-
-				output += 'l ';
-
-				for ( let j = 1, l = vertices.count; j <= l; j ++ ) {
-
-					output += ( indexVertex + j ) + ' ';
-
-				}
-
-				output += '\n';
-
-			}
-
-			if ( type === 'LineSegments' ) {
-
-				for ( let j = 1, k = j + 1, l = vertices.count; j < l; j += 2, k = j + 1 ) {
-
-					output += 'l ' + ( indexVertex + j ) + ' ' + ( indexVertex + k ) + '\n';
-
-				}
-
-			}
-
-			// update index
-			indexVertex += nbVertex;
-
-		}
-
-		function parsePoints( points ) {
-
-			let nbVertex = 0;
-
-			const geometry = points.geometry;
-
-			const vertices = geometry.getAttribute( 'position' );
-			const colors = geometry.getAttribute( 'color' );
-
-			output += 'o ' + points.name + '\n';
-
-			if ( vertices !== undefined ) {
-
-				for ( let i = 0, l = vertices.count; i < l; i ++, nbVertex ++ ) {
-
-					vertex.fromBufferAttribute( vertices, i );
-					vertex.applyMatrix4( points.matrixWorld );
-
-					output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z;
-
-					if ( colors !== undefined ) {
-
-						color.fromBufferAttribute( colors, i );
-
-						ColorManagement.workingToColorSpace( color, SRGBColorSpace );
-
-						output += ' ' + color.r + ' ' + color.g + ' ' + color.b;
-
-					}
-
-					output += '\n';
-
-				}
-
-				output += 'p ';
-
-				for ( let j = 1, l = vertices.count; j <= l; j ++ ) {
-
-					output += ( indexVertex + j ) + ' ';
-
-				}
-
-				output += '\n';
-
-			}
-
-			// update index
-			indexVertex += nbVertex;
-
-		}
-
-		object.traverse( function ( child ) {
-
-			if ( child.isMesh === true ) {
-
-				parseMesh( child );
-
-			}
-
-			if ( child.isLine === true ) {
-
-				parseLine( child );
-
-			}
-
-			if ( child.isPoints === true ) {
-
-				parsePoints( child );
-
-			}
-
-		} );
-
-		return output;
-
-	}
-
-}
-
-export { OBJExporter };

+ 0 - 562
node_modules/three/examples/jsm/exporters/PLYExporter.js

@@ -1,562 +0,0 @@
-import {
-	Matrix3,
-	Vector3,
-	Color,
-	ColorManagement,
-	SRGBColorSpace
-} from 'three';
-
-/**
- * An exporter for PLY.
- *
- * PLY (Polygon or Stanford Triangle Format) is a file format for efficient delivery and
- * loading of simple, static 3D content in a dense format. Both binary and ascii formats are
- * supported. PLY can store vertex positions, colors, normals and uv coordinates. No textures
- * or texture references are saved.
- *
- * ```js
- * const exporter = new PLYExporter();
- * const data = exporter.parse( scene, options );
- * ```
- *
- * @three_import import { PLYExporter } from 'three/addons/exporters/PLYExporter.js';
- */
-class PLYExporter {
-
-	/**
-	 * Parses the given 3D object and generates the PLY output.
-	 *
-	 * If the 3D object is composed of multiple children and geometry, they are merged into a single mesh in the file.
-	 *
-	 * @param {Object3D} object - The 3D object to export.
-	 * @param {PLYExporter~OnDone} onDone - A callback function that is executed when the export has finished.
-	 * @param {PLYExporter~Options} options - The export options.
-	 * @return {?(string|ArrayBuffer)} The exported PLY.
-	 */
-	parse( object, onDone, options = {} ) {
-
-		// reference https://github.com/gkjohnson/ply-exporter-js
-
-		// Iterate over the valid meshes in the object
-		function traverseMeshes( cb ) {
-
-			object.traverse( function ( child ) {
-
-				if ( child.isMesh === true || child.isPoints ) {
-
-					const mesh = child;
-					const geometry = mesh.geometry;
-
-					if ( geometry.hasAttribute( 'position' ) === true ) {
-
-						cb( mesh, geometry );
-
-					}
-
-				}
-
-			} );
-
-		}
-
-		// Default options
-		const defaultOptions = {
-			binary: false,
-			excludeAttributes: [], // normal, uv, color, index
-			littleEndian: false
-		};
-
-		options = Object.assign( defaultOptions, options );
-
-		const excludeAttributes = options.excludeAttributes;
-		let includeIndices = true;
-		let includeNormals = false;
-		let includeColors = false;
-		let includeUVs = false;
-
-		// count the vertices, check which properties are used,
-		// and cache the BufferGeometry
-		let vertexCount = 0;
-		let faceCount = 0;
-
-		object.traverse( function ( child ) {
-
-			if ( child.isMesh === true ) {
-
-				const mesh = child;
-				const geometry = mesh.geometry;
-
-				const vertices = geometry.getAttribute( 'position' );
-				const normals = geometry.getAttribute( 'normal' );
-				const uvs = geometry.getAttribute( 'uv' );
-				const colors = geometry.getAttribute( 'color' );
-				const indices = geometry.getIndex();
-
-				if ( vertices === undefined ) {
-
-					return;
-
-				}
-
-				vertexCount += vertices.count;
-				faceCount += indices ? indices.count / 3 : vertices.count / 3;
-
-				if ( normals !== undefined ) includeNormals = true;
-
-				if ( uvs !== undefined ) includeUVs = true;
-
-				if ( colors !== undefined ) includeColors = true;
-
-			} else if ( child.isPoints ) {
-
-				const mesh = child;
-				const geometry = mesh.geometry;
-
-				const vertices = geometry.getAttribute( 'position' );
-				const normals = geometry.getAttribute( 'normal' );
-				const colors = geometry.getAttribute( 'color' );
-
-				vertexCount += vertices.count;
-
-				if ( normals !== undefined ) includeNormals = true;
-
-				if ( colors !== undefined ) includeColors = true;
-
-				includeIndices = false;
-
-			}
-
-		} );
-
-		const tempColor = new Color();
-		includeIndices = includeIndices && excludeAttributes.indexOf( 'index' ) === - 1;
-		includeNormals = includeNormals && excludeAttributes.indexOf( 'normal' ) === - 1;
-		includeColors = includeColors && excludeAttributes.indexOf( 'color' ) === - 1;
-		includeUVs = includeUVs && excludeAttributes.indexOf( 'uv' ) === - 1;
-
-
-		if ( includeIndices && faceCount !== Math.floor( faceCount ) ) {
-
-			// point cloud meshes will not have an index array and may not have a
-			// number of vertices that is divisible by 3 (and therefore representable
-			// as triangles)
-			console.error(
-
-				'PLYExporter: Failed to generate a valid PLY file with triangle indices because the ' +
-				'number of indices is not divisible by 3.'
-
-			);
-
-			return null;
-
-		}
-
-		const indexByteCount = 4;
-
-		let header =
-			'ply\n' +
-			`format ${ options.binary ? ( options.littleEndian ? 'binary_little_endian' : 'binary_big_endian' ) : 'ascii' } 1.0\n` +
-			`element vertex ${vertexCount}\n` +
-
-			// position
-			'property float x\n' +
-			'property float y\n' +
-			'property float z\n';
-
-		if ( includeNormals === true ) {
-
-			// normal
-			header +=
-				'property float nx\n' +
-				'property float ny\n' +
-				'property float nz\n';
-
-		}
-
-		if ( includeUVs === true ) {
-
-			// uvs
-			header +=
-				'property float s\n' +
-				'property float t\n';
-
-		}
-
-		if ( includeColors === true ) {
-
-			// colors
-			header +=
-				'property uchar red\n' +
-				'property uchar green\n' +
-				'property uchar blue\n';
-
-		}
-
-		if ( includeIndices === true ) {
-
-			// faces
-			header +=
-				`element face ${faceCount}\n` +
-				'property list uchar int vertex_index\n';
-
-		}
-
-		header += 'end_header\n';
-
-
-		// Generate attribute data
-		const vertex = new Vector3();
-		const normalMatrixWorld = new Matrix3();
-		let result = null;
-
-		if ( options.binary === true ) {
-
-			// Binary File Generation
-			const headerBin = new TextEncoder().encode( header );
-
-			// 3 position values at 4 bytes
-			// 3 normal values at 4 bytes
-			// 3 color channels with 1 byte
-			// 2 uv values at 4 bytes
-			const vertexListLength = vertexCount * ( 4 * 3 + ( includeNormals ? 4 * 3 : 0 ) + ( includeColors ? 3 : 0 ) + ( includeUVs ? 4 * 2 : 0 ) );
-
-			// 1 byte shape descriptor
-			// 3 vertex indices at ${indexByteCount} bytes
-			const faceListLength = includeIndices ? faceCount * ( indexByteCount * 3 + 1 ) : 0;
-			const output = new DataView( new ArrayBuffer( headerBin.length + vertexListLength + faceListLength ) );
-			new Uint8Array( output.buffer ).set( headerBin, 0 );
-
-
-			let vOffset = headerBin.length;
-			let fOffset = headerBin.length + vertexListLength;
-			let writtenVertices = 0;
-			traverseMeshes( function ( mesh, geometry ) {
-
-				const vertices = geometry.getAttribute( 'position' );
-				const normals = geometry.getAttribute( 'normal' );
-				const uvs = geometry.getAttribute( 'uv' );
-				const colors = geometry.getAttribute( 'color' );
-				const indices = geometry.getIndex();
-
-				normalMatrixWorld.getNormalMatrix( mesh.matrixWorld );
-
-				for ( let i = 0, l = vertices.count; i < l; i ++ ) {
-
-					vertex.fromBufferAttribute( vertices, i );
-
-					vertex.applyMatrix4( mesh.matrixWorld );
-
-
-					// Position information
-					output.setFloat32( vOffset, vertex.x, options.littleEndian );
-					vOffset += 4;
-
-					output.setFloat32( vOffset, vertex.y, options.littleEndian );
-					vOffset += 4;
-
-					output.setFloat32( vOffset, vertex.z, options.littleEndian );
-					vOffset += 4;
-
-					// Normal information
-					if ( includeNormals === true ) {
-
-						if ( normals != null ) {
-
-							vertex.fromBufferAttribute( normals, i );
-
-							vertex.applyMatrix3( normalMatrixWorld ).normalize();
-
-							output.setFloat32( vOffset, vertex.x, options.littleEndian );
-							vOffset += 4;
-
-							output.setFloat32( vOffset, vertex.y, options.littleEndian );
-							vOffset += 4;
-
-							output.setFloat32( vOffset, vertex.z, options.littleEndian );
-							vOffset += 4;
-
-						} else {
-
-							output.setFloat32( vOffset, 0, options.littleEndian );
-							vOffset += 4;
-
-							output.setFloat32( vOffset, 0, options.littleEndian );
-							vOffset += 4;
-
-							output.setFloat32( vOffset, 0, options.littleEndian );
-							vOffset += 4;
-
-						}
-
-					}
-
-					// UV information
-					if ( includeUVs === true ) {
-
-						if ( uvs != null ) {
-
-							output.setFloat32( vOffset, uvs.getX( i ), options.littleEndian );
-							vOffset += 4;
-
-							output.setFloat32( vOffset, uvs.getY( i ), options.littleEndian );
-							vOffset += 4;
-
-						} else {
-
-							output.setFloat32( vOffset, 0, options.littleEndian );
-							vOffset += 4;
-
-							output.setFloat32( vOffset, 0, options.littleEndian );
-							vOffset += 4;
-
-						}
-
-					}
-
-					// Color information
-					if ( includeColors === true ) {
-
-						if ( colors != null ) {
-
-							tempColor.fromBufferAttribute( colors, i );
-
-							ColorManagement.workingToColorSpace( tempColor, SRGBColorSpace );
-
-							output.setUint8( vOffset, Math.floor( tempColor.r * 255 ) );
-							vOffset += 1;
-
-							output.setUint8( vOffset, Math.floor( tempColor.g * 255 ) );
-							vOffset += 1;
-
-							output.setUint8( vOffset, Math.floor( tempColor.b * 255 ) );
-							vOffset += 1;
-
-						} else {
-
-							output.setUint8( vOffset, 255 );
-							vOffset += 1;
-
-							output.setUint8( vOffset, 255 );
-							vOffset += 1;
-
-							output.setUint8( vOffset, 255 );
-							vOffset += 1;
-
-						}
-
-					}
-
-				}
-
-				if ( includeIndices === true ) {
-
-					// Create the face list
-
-					if ( indices !== null ) {
-
-						for ( let i = 0, l = indices.count; i < l; i += 3 ) {
-
-							output.setUint8( fOffset, 3 );
-							fOffset += 1;
-
-							output.setUint32( fOffset, indices.getX( i + 0 ) + writtenVertices, options.littleEndian );
-							fOffset += indexByteCount;
-
-							output.setUint32( fOffset, indices.getX( i + 1 ) + writtenVertices, options.littleEndian );
-							fOffset += indexByteCount;
-
-							output.setUint32( fOffset, indices.getX( i + 2 ) + writtenVertices, options.littleEndian );
-							fOffset += indexByteCount;
-
-						}
-
-					} else {
-
-						for ( let i = 0, l = vertices.count; i < l; i += 3 ) {
-
-							output.setUint8( fOffset, 3 );
-							fOffset += 1;
-
-							output.setUint32( fOffset, writtenVertices + i, options.littleEndian );
-							fOffset += indexByteCount;
-
-							output.setUint32( fOffset, writtenVertices + i + 1, options.littleEndian );
-							fOffset += indexByteCount;
-
-							output.setUint32( fOffset, writtenVertices + i + 2, options.littleEndian );
-							fOffset += indexByteCount;
-
-						}
-
-					}
-
-				}
-
-
-				// Save the amount of verts we've already written so we can offset
-				// the face index on the next mesh
-				writtenVertices += vertices.count;
-
-			} );
-
-			result = output.buffer;
-
-		} else {
-
-			// Ascii File Generation
-			// count the number of vertices
-			let writtenVertices = 0;
-			let vertexList = '';
-			let faceList = '';
-
-			traverseMeshes( function ( mesh, geometry ) {
-
-				const vertices = geometry.getAttribute( 'position' );
-				const normals = geometry.getAttribute( 'normal' );
-				const uvs = geometry.getAttribute( 'uv' );
-				const colors = geometry.getAttribute( 'color' );
-				const indices = geometry.getIndex();
-
-				normalMatrixWorld.getNormalMatrix( mesh.matrixWorld );
-
-				// form each line
-				for ( let i = 0, l = vertices.count; i < l; i ++ ) {
-
-					vertex.fromBufferAttribute( vertices, i );
-
-					vertex.applyMatrix4( mesh.matrixWorld );
-
-
-					// Position information
-					let line =
-						vertex.x + ' ' +
-						vertex.y + ' ' +
-						vertex.z;
-
-					// Normal information
-					if ( includeNormals === true ) {
-
-						if ( normals != null ) {
-
-							vertex.fromBufferAttribute( normals, i );
-
-							vertex.applyMatrix3( normalMatrixWorld ).normalize();
-
-							line += ' ' +
-								vertex.x + ' ' +
-								vertex.y + ' ' +
-								vertex.z;
-
-						} else {
-
-							line += ' 0 0 0';
-
-						}
-
-					}
-
-					// UV information
-					if ( includeUVs === true ) {
-
-						if ( uvs != null ) {
-
-							line += ' ' +
-								uvs.getX( i ) + ' ' +
-								uvs.getY( i );
-
-						} else {
-
-							line += ' 0 0';
-
-						}
-
-					}
-
-					// Color information
-					if ( includeColors === true ) {
-
-						if ( colors != null ) {
-
-							tempColor.fromBufferAttribute( colors, i );
-
-							ColorManagement.workingToColorSpace( tempColor, SRGBColorSpace );
-
-							line += ' ' +
-								Math.floor( tempColor.r * 255 ) + ' ' +
-								Math.floor( tempColor.g * 255 ) + ' ' +
-								Math.floor( tempColor.b * 255 );
-
-						} else {
-
-							line += ' 255 255 255';
-
-						}
-
-					}
-
-					vertexList += line + '\n';
-
-				}
-
-				// Create the face list
-				if ( includeIndices === true ) {
-
-					if ( indices !== null ) {
-
-						for ( let i = 0, l = indices.count; i < l; i += 3 ) {
-
-							faceList += `3 ${ indices.getX( i + 0 ) + writtenVertices }`;
-							faceList += ` ${ indices.getX( i + 1 ) + writtenVertices }`;
-							faceList += ` ${ indices.getX( i + 2 ) + writtenVertices }\n`;
-
-						}
-
-					} else {
-
-						for ( let i = 0, l = vertices.count; i < l; i += 3 ) {
-
-							faceList += `3 ${ writtenVertices + i } ${ writtenVertices + i + 1 } ${ writtenVertices + i + 2 }\n`;
-
-						}
-
-					}
-
-					faceCount += indices ? indices.count / 3 : vertices.count / 3;
-
-				}
-
-				writtenVertices += vertices.count;
-
-			} );
-
-			result = `${ header }${vertexList}${ includeIndices ? `${faceList}\n` : '\n' }`;
-
-		}
-
-		if ( typeof onDone === 'function' ) requestAnimationFrame( () => onDone( result ) );
-
-		return result;
-
-	}
-
-}
-
-/**
- * Export options of `PLYExporter`.
- *
- * @typedef {Object} PLYExporter~Options
- * @property {boolean} [binary=false] - Whether to export in binary format or ASCII.
- * @property {Array<string>} [excludeAttributes] - Which properties to explicitly exclude from
- * the exported PLY file. Valid values are `'color'`, `'normal'`, `'uv'`, and `'index'`. If triangle
- * indices are excluded, then a point cloud is exported.
- * @property {boolean} [littleEndian=false] - Whether the binary export uses little or big endian.
- **/
-
-/**
- * onDone callback of `PLYExporter`.
- *
- * @callback PLYExporter~OnDone
- * @param {string|ArrayBuffer} result - The generated PLY ascii or binary.
- */
-
-export { PLYExporter };

+ 0 - 221
node_modules/three/examples/jsm/exporters/STLExporter.js

@@ -1,221 +0,0 @@
-import { Vector3 } from 'three';
-
-/**
- * An exporter for STL.
- *
- * STL files describe only the surface geometry of a three-dimensional object without
- * any representation of color, texture or other common model attributes. The STL format
- * specifies both ASCII and binary representations, with binary being more compact.
- * STL files contain no scale information or indexes, and the units are arbitrary.
- *
- * ```js
- * const exporter = new STLExporter();
- * const data = exporter.parse( mesh, { binary: true } );
- * ```
- *
- * @three_import import { STLExporter } from 'three/addons/exporters/STLExporter.js';
- */
-class STLExporter {
-
-	/**
-	 * Parses the given 3D object and generates the STL output.
-	 *
-	 * If the 3D object is composed of multiple children and geometry, they are merged into a single mesh in the file.
-	 *
-	 * @param {Object3D} scene - A scene, mesh or any other 3D object containing meshes to encode.
-	 * @param {STLExporter~Options} options - The export options.
-	 * @return {string|ArrayBuffer} The exported STL.
-	 */
-	parse( scene, options = {} ) {
-
-		options = Object.assign( {
-			binary: false
-		}, options );
-
-		const binary = options.binary;
-
-		//
-
-		const objects = [];
-		let triangles = 0;
-
-		scene.traverse( function ( object ) {
-
-			if ( object.isMesh ) {
-
-				const geometry = object.geometry;
-
-				const index = geometry.index;
-				const positionAttribute = geometry.getAttribute( 'position' );
-
-				triangles += ( index !== null ) ? ( index.count / 3 ) : ( positionAttribute.count / 3 );
-
-				objects.push( {
-					object3d: object,
-					geometry: geometry
-				} );
-
-			}
-
-		} );
-
-		let output;
-		let offset = 80; // skip header
-
-		if ( binary === true ) {
-
-			const bufferLength = triangles * 2 + triangles * 3 * 4 * 4 + 80 + 4;
-			const arrayBuffer = new ArrayBuffer( bufferLength );
-			output = new DataView( arrayBuffer );
-			output.setUint32( offset, triangles, true ); offset += 4;
-
-		} else {
-
-			output = '';
-			output += 'solid exported\n';
-
-		}
-
-		const vA = new Vector3();
-		const vB = new Vector3();
-		const vC = new Vector3();
-		const cb = new Vector3();
-		const ab = new Vector3();
-		const normal = new Vector3();
-
-		for ( let i = 0, il = objects.length; i < il; i ++ ) {
-
-			const object = objects[ i ].object3d;
-			const geometry = objects[ i ].geometry;
-
-			const index = geometry.index;
-			const positionAttribute = geometry.getAttribute( 'position' );
-
-			if ( index !== null ) {
-
-				// indexed geometry
-
-				for ( let j = 0; j < index.count; j += 3 ) {
-
-					const a = index.getX( j + 0 );
-					const b = index.getX( j + 1 );
-					const c = index.getX( j + 2 );
-
-					writeFace( a, b, c, positionAttribute, object );
-
-				}
-
-			} else {
-
-				// non-indexed geometry
-
-				for ( let j = 0; j < positionAttribute.count; j += 3 ) {
-
-					const a = j + 0;
-					const b = j + 1;
-					const c = j + 2;
-
-					writeFace( a, b, c, positionAttribute, object );
-
-				}
-
-			}
-
-		}
-
-		if ( binary === false ) {
-
-			output += 'endsolid exported\n';
-
-		}
-
-		return output;
-
-		function writeFace( a, b, c, positionAttribute, object ) {
-
-			vA.fromBufferAttribute( positionAttribute, a );
-			vB.fromBufferAttribute( positionAttribute, b );
-			vC.fromBufferAttribute( positionAttribute, c );
-
-			if ( object.isSkinnedMesh === true ) {
-
-				object.applyBoneTransform( a, vA );
-				object.applyBoneTransform( b, vB );
-				object.applyBoneTransform( c, vC );
-
-			}
-
-			vA.applyMatrix4( object.matrixWorld );
-			vB.applyMatrix4( object.matrixWorld );
-			vC.applyMatrix4( object.matrixWorld );
-
-			writeNormal( vA, vB, vC );
-
-			writeVertex( vA );
-			writeVertex( vB );
-			writeVertex( vC );
-
-			if ( binary === true ) {
-
-				output.setUint16( offset, 0, true ); offset += 2;
-
-			} else {
-
-				output += '\t\tendloop\n';
-				output += '\tendfacet\n';
-
-			}
-
-		}
-
-		function writeNormal( vA, vB, vC ) {
-
-			cb.subVectors( vC, vB );
-			ab.subVectors( vA, vB );
-			cb.cross( ab ).normalize();
-
-			normal.copy( cb ).normalize();
-
-			if ( binary === true ) {
-
-				output.setFloat32( offset, normal.x, true ); offset += 4;
-				output.setFloat32( offset, normal.y, true ); offset += 4;
-				output.setFloat32( offset, normal.z, true ); offset += 4;
-
-			} else {
-
-				output += '\tfacet normal ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n';
-				output += '\t\touter loop\n';
-
-			}
-
-		}
-
-		function writeVertex( vertex ) {
-
-			if ( binary === true ) {
-
-				output.setFloat32( offset, vertex.x, true ); offset += 4;
-				output.setFloat32( offset, vertex.y, true ); offset += 4;
-				output.setFloat32( offset, vertex.z, true ); offset += 4;
-
-			} else {
-
-				output += '\t\t\tvertex ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n';
-
-			}
-
-		}
-
-	}
-
-}
-
-/**
- * Export options of `STLExporter`.
- *
- * @typedef {Object} STLExporter~Options
- * @property {boolean} [binary=false] - Whether to export in binary format or ASCII.
- **/
-
-export { STLExporter };

+ 0 - 1254
node_modules/three/examples/jsm/exporters/USDZExporter.js

@@ -1,1254 +0,0 @@
-import {
-	NoColorSpace,
-	DoubleSide,
-	Color,
-} from 'three';
-
-import {
-	strToU8,
-	zipSync,
-} from '../libs/fflate.module.js';
-
-class USDNode {
-
-	constructor( name, type = '', metadata = [], properties = [] ) {
-
-		this.name = name;
-		this.type = type;
-		this.metadata = metadata;
-		this.properties = properties;
-		this.children = [];
-
-	}
-
-	addMetadata( key, value ) {
-
-		this.metadata.push( { key, value } );
-
-	}
-
-	addProperty( property, metadata = [] ) {
-
-		this.properties.push( { property, metadata } );
-
-	}
-
-	addChild( child ) {
-
-		this.children.push( child );
-
-	}
-
-	toString( indent = 0 ) {
-
-		const pad = '\t'.repeat( indent );
-
-		const formattedMetadata = this.metadata.map( ( item ) => {
-
-			const key = item.key;
-			const value = item.value;
-
-			if ( Array.isArray( value ) ) {
-
-				const lines = [];
-				lines.push( `${key} = {` );
-				value.forEach( ( line ) => {
-
-					lines.push( `${pad}\t\t${line}` );
-
-				} );
-				lines.push( `${pad}\t}` );
-				return lines.join( '\n' );
-
-			} else {
-
-				return `${key} = ${value}`;
-
-			}
-
-		} );
-
-		const meta = formattedMetadata.length
-			? ` (\n${formattedMetadata
-				.map( ( l ) => `${pad}\t${l}` )
-				.join( '\n' )}\n${pad})`
-			: '';
-
-		const properties = this.properties.map( ( l ) => {
-
-			const property = l.property;
-			const metadata = l.metadata.length
-				? ` (\n${l.metadata.map( ( m ) => `${pad}\t\t${m}` ).join( '\n' )}\n${pad}\t)`
-				: '';
-			return `${pad}\t${property}${metadata}`;
-
-		} );
-		const children = this.children.map( ( c ) => c.toString( indent + 1 ) );
-
-		const bodyLines = [];
-
-		if ( properties.length > 0 ) {
-
-			bodyLines.push( ...properties );
-
-		}
-
-		if ( children.length > 0 ) {
-
-			if ( properties.length > 0 ) {
-
-				bodyLines.push( '' );
-
-			}
-
-			for ( let i = 0; i < children.length; i ++ ) {
-
-				bodyLines.push( children[ i ] );
-				if ( i < children.length - 1 ) {
-
-					bodyLines.push( '' );
-
-				}
-
-			}
-
-		}
-
-		const bodyContent = bodyLines.join( '\n' );
-
-		const type = this.type ? this.type + ' ' : '';
-
-		return `${pad}def ${type}"${this.name}"${meta}\n${pad}{\n${bodyContent}\n${pad}}`;
-
-	}
-
-}
-
-/**
- * An exporter for USDZ.
- *
- * ```js
- * const exporter = new USDZExporter();
- * const arraybuffer = await exporter.parseAsync( scene );
- * ```
- *
- * @three_import import { USDZExporter } from 'three/addons/exporters/USDZExporter.js';
- */
-class USDZExporter {
-
-	/**
-	 * Constructs a new USDZ exporter.
-	 */
-	constructor() {
-
-		/**
-		 * A reference to a texture utils module.
-		 *
-		 * @type {?(WebGLTextureUtils|WebGPUTextureUtils)}
-		 * @default null
-		 */
-		this.textureUtils = null;
-
-	}
-
-	/**
-	 * Sets the texture utils for this exporter. Only relevant when compressed textures have to be exported.
-	 *
-	 * Depending on whether you use {@link WebGLRenderer} or {@link WebGPURenderer}, you must inject the
-	 * corresponding texture utils {@link WebGLTextureUtils} or {@link WebGPUTextureUtils}.
-	 *
-	 * @param {WebGLTextureUtils|WebGPUTextureUtils} utils - The texture utils.
-	 */
-	setTextureUtils( utils ) {
-
-		this.textureUtils = utils;
-
-	}
-
-	/**
-	 * Parse the given 3D object and generates the USDZ output.
-	 *
-	 * @param {Object3D} scene - The 3D object to export.
-	 * @param {USDZExporter~OnDone} onDone - A callback function that is executed when the export has finished.
-	 * @param {USDZExporter~OnError} onError - A callback function that is executed when an error happens.
-	 * @param {USDZExporter~Options} options - The export options.
-	 */
-	parse( scene, onDone, onError, options ) {
-
-		this.parseAsync( scene, options ).then( onDone ).catch( onError );
-
-	}
-
-	/**
-	 * Async version of {@link USDZExporter#parse}.
-	 *
-	 * @async
-	 * @param {Object3D} scene - The 3D object to export.
-	 * @param {USDZExporter~Options} options - The export options.
-	 * @return {Promise<ArrayBuffer>} A Promise that resolved with the exported USDZ data.
-	 */
-	async parseAsync( scene, options = {} ) {
-
-		options = Object.assign(
-			{
-				ar: {
-					anchoring: { type: 'plane' },
-					planeAnchoring: { alignment: 'horizontal' },
-				},
-				includeAnchoringProperties: true,
-				onlyVisible: true,
-				quickLookCompatible: false,
-				maxTextureSize: 1024,
-			},
-			options
-		);
-
-		const usedNames = new Set();
-
-		const files = {};
-		const modelFileName = 'model.usda';
-
-		// model file should be first in USDZ archive so we init it here
-		files[ modelFileName ] = null;
-
-		const root = new USDNode( 'Root', 'Xform' );
-		const scenesNode = new USDNode( 'Scenes', 'Scope' );
-		scenesNode.addMetadata( 'kind', '"sceneLibrary"' );
-		root.addChild( scenesNode );
-
-		const sceneName = 'Scene';
-		const sceneNode = new USDNode( sceneName, 'Xform' );
-		sceneNode.addMetadata( 'customData', [
-			'bool preliminary_collidesWithEnvironment = 0',
-			`string sceneName = "${sceneName}"`,
-		] );
-		sceneNode.addMetadata( 'sceneName', `"${sceneName}"` );
-		if ( options.includeAnchoringProperties ) {
-
-			sceneNode.addProperty(
-				`token preliminary:anchoring:type = "${options.ar.anchoring.type}"`
-			);
-			sceneNode.addProperty(
-				`token preliminary:planeAnchoring:alignment = "${options.ar.planeAnchoring.alignment}"`
-			);
-
-		}
-
-		scenesNode.addChild( sceneNode );
-
-		let output;
-
-		const materials = {};
-		const textures = {};
-
-		buildHierarchy( scene, sceneNode, materials, usedNames, files, options );
-
-		const materialsNode = buildMaterials(
-			materials,
-			textures,
-			options.quickLookCompatible
-		);
-
-		output =
-			buildHeader() +
-			'\n' +
-			root.toString() +
-			'\n\n' +
-			materialsNode.toString();
-
-		files[ modelFileName ] = strToU8( output );
-		output = null;
-
-		for ( const id in textures ) {
-
-			let texture = textures[ id ];
-
-			if ( texture.isCompressedTexture === true ) {
-
-				if ( this.textureUtils === null ) {
-
-					throw new Error(
-						'THREE.USDZExporter: setTextureUtils() must be called to process compressed textures.'
-					);
-
-				} else {
-
-					texture = await this.textureUtils.decompress( texture );
-
-				}
-
-			}
-
-			const canvas = imageToCanvas(
-				texture.image,
-				texture.flipY,
-				options.maxTextureSize
-			);
-			const blob = await new Promise( ( resolve ) =>
-				canvas.toBlob( resolve, 'image/png', 1 )
-			);
-
-			files[ `textures/Texture_${id}.png` ] = new Uint8Array(
-				await blob.arrayBuffer()
-			);
-
-		}
-
-		// 64 byte alignment
-		// https://github.com/101arrowz/fflate/issues/39#issuecomment-777263109
-
-		let offset = 0;
-
-		for ( const filename in files ) {
-
-			const file = files[ filename ];
-			const headerSize = 34 + filename.length;
-
-			offset += headerSize;
-
-			const offsetMod64 = offset & 63;
-
-			if ( offsetMod64 !== 4 ) {
-
-				const padLength = 64 - offsetMod64;
-				const padding = new Uint8Array( padLength );
-
-				files[ filename ] = [ file, { extra: { 12345: padding } } ];
-
-			}
-
-			offset = file.length;
-
-		}
-
-		return zipSync( files, { level: 0 } );
-
-	}
-
-}
-
-function getName( object, namesSet ) {
-
-	let name = object.name;
-	name = name.replace( /[^A-Za-z0-9_]/g, '' );
-	if ( /^[0-9]/.test( name ) ) {
-
-		name = '_' + name;
-
-	}
-
-	if ( name === '' ) {
-
-		if ( object.isCamera ) {
-
-			name = 'Camera';
-
-		} else {
-
-			name = 'Object';
-
-		}
-
-	}
-
-	if ( namesSet.has( name ) ) {
-
-		name = name + '_' + object.id;
-
-	}
-
-	namesSet.add( name );
-
-	return name;
-
-}
-
-function imageToCanvas( image, flipY, maxTextureSize ) {
-
-	if (
-		( typeof HTMLImageElement !== 'undefined' &&
-			image instanceof HTMLImageElement ) ||
-		( typeof HTMLCanvasElement !== 'undefined' &&
-			image instanceof HTMLCanvasElement ) ||
-		( typeof OffscreenCanvas !== 'undefined' &&
-			image instanceof OffscreenCanvas ) ||
-		( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap )
-	) {
-
-		const scale = maxTextureSize / Math.max( image.width, image.height );
-
-		const canvas = document.createElement( 'canvas' );
-		canvas.width = image.width * Math.min( 1, scale );
-		canvas.height = image.height * Math.min( 1, scale );
-
-		const context = canvas.getContext( '2d' );
-
-		// TODO: We should be able to do this in the UsdTransform2d?
-
-		if ( flipY === true ) {
-
-			context.translate( 0, canvas.height );
-			context.scale( 1, - 1 );
-
-		}
-
-		context.drawImage( image, 0, 0, canvas.width, canvas.height );
-
-		return canvas;
-
-	} else {
-
-		throw new Error(
-			'THREE.USDZExporter: No valid image data found. Unable to process texture.'
-		);
-
-	}
-
-}
-
-//
-
-const PRECISION = 7;
-
-function buildHeader() {
-
-	return `#usda 1.0
-(
-	customLayerData = {
-		string creator = "Three.js USDZExporter"
-	}
-	defaultPrim = "Root"
-	metersPerUnit = 1
-	upAxis = "Y"
-)
-`;
-
-}
-
-// Xform
-
-function buildHierarchy( object, parentNode, materials, usedNames, files, options ) {
-
-	for ( let i = 0, l = object.children.length; i < l; i ++ ) {
-
-		const child = object.children[ i ];
-
-		if ( child.visible === false && options.onlyVisible === true ) continue;
-
-		let childNode;
-
-		if ( child.isMesh ) {
-
-			const geometry = child.geometry;
-			const material = child.material;
-
-			if ( material.isMeshStandardMaterial ) {
-
-				const geometryFileName = 'geometries/Geometry_' + geometry.id + '.usda';
-
-				if ( ! ( geometryFileName in files ) ) {
-
-					const meshObject = buildMeshObject( geometry );
-					files[ geometryFileName ] = strToU8(
-						buildHeader() + '\n' + meshObject.toString()
-					);
-
-				}
-
-				if ( ! ( material.uuid in materials ) ) {
-
-					materials[ material.uuid ] = material;
-
-				}
-
-				childNode = buildMesh(
-					child,
-					geometry,
-					materials[ material.uuid ],
-					usedNames
-				);
-
-			} else {
-
-				console.warn(
-					'THREE.USDZExporter: Unsupported material type (USDZ only supports MeshStandardMaterial)',
-					child
-				);
-
-			}
-
-		} else if ( child.isCamera ) {
-
-			childNode = buildCamera( child, usedNames );
-
-		} else {
-
-			childNode = buildXform( child, usedNames );
-
-		}
-
-		if ( childNode ) {
-
-			parentNode.addChild( childNode );
-			buildHierarchy( child, childNode, materials, usedNames, files, options );
-
-		}
-
-	}
-
-}
-
-function buildXform( object, usedNames ) {
-
-	const name = getName( object, usedNames );
-
-	if ( object.matrix.determinant() < 0 ) {
-
-		console.warn(
-			'THREE.USDZExporter: USDZ does not support negative scales',
-			object
-		);
-
-	}
-
-	const node = new USDNode( name, 'Xform' );
-
-	if ( object.pivot !== null ) {
-
-		// Export with pivot using separate transform ops
-		const p = object.position;
-		const q = object.quaternion;
-		const s = object.scale;
-		const piv = object.pivot;
-
-		node.addProperty( `float3 xformOp:translate = (${p.x.toPrecision( PRECISION )}, ${p.y.toPrecision( PRECISION )}, ${p.z.toPrecision( PRECISION )})` );
-		node.addProperty( `float3 xformOp:translate:pivot = (${piv.x.toPrecision( PRECISION )}, ${piv.y.toPrecision( PRECISION )}, ${piv.z.toPrecision( PRECISION )})` );
-		node.addProperty( `quatf xformOp:orient = (${q.w.toPrecision( PRECISION )}, ${q.x.toPrecision( PRECISION )}, ${q.y.toPrecision( PRECISION )}, ${q.z.toPrecision( PRECISION )})` );
-		node.addProperty( `float3 xformOp:scale = (${s.x.toPrecision( PRECISION )}, ${s.y.toPrecision( PRECISION )}, ${s.z.toPrecision( PRECISION )})` );
-		node.addProperty( 'uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:translate:pivot", "xformOp:orient", "xformOp:scale", "!invert!xformOp:translate:pivot"]' );
-
-	} else {
-
-		// Export as single transform matrix
-		const transform = buildMatrix( object.matrix );
-		node.addProperty( `matrix4d xformOp:transform = ${transform}` );
-		node.addProperty( 'uniform token[] xformOpOrder = ["xformOp:transform"]' );
-
-	}
-
-	return node;
-
-}
-
-function buildMesh( object, geometry, material, usedNames ) {
-
-	const node = buildXform( object, usedNames );
-
-	node.addMetadata(
-		'prepend references',
-		`@./geometries/Geometry_${geometry.id}.usda@</Geometry>`
-	);
-	node.addMetadata( 'prepend apiSchemas', '["MaterialBindingAPI"]' );
-
-	node.addProperty(
-		`rel material:binding = </Materials/Material_${material.id}>`
-	);
-
-	return node;
-
-}
-
-function buildMatrix( matrix ) {
-
-	const array = matrix.elements;
-
-	return `( ${buildMatrixRow( array, 0 )}, ${buildMatrixRow(
-		array,
-		4
-	)}, ${buildMatrixRow( array, 8 )}, ${buildMatrixRow( array, 12 )} )`;
-
-}
-
-function buildMatrixRow( array, offset ) {
-
-	return `(${array[ offset + 0 ]}, ${array[ offset + 1 ]}, ${array[ offset + 2 ]}, ${
-		array[ offset + 3 ]
-	})`;
-
-}
-
-// Mesh
-
-function buildMeshObject( geometry ) {
-
-	const node = new USDNode( 'Geometry' );
-
-	const meshNode = buildMeshNode( geometry );
-	node.addChild( meshNode );
-
-	return node;
-
-}
-
-function buildMeshNode( geometry ) {
-
-	const name = 'Geometry';
-	const attributes = geometry.attributes;
-	const count = attributes.position.count;
-
-	const node = new USDNode( name, 'Mesh' );
-
-	node.addProperty(
-		`int[] faceVertexCounts = [${buildMeshVertexCount( geometry )}]`
-	);
-	node.addProperty(
-		`int[] faceVertexIndices = [${buildMeshVertexIndices( geometry )}]`
-	);
-	node.addProperty(
-		`normal3f[] normals = [${buildVector3Array( attributes.normal, count )}]`,
-		[ 'interpolation = "vertex"' ]
-	);
-	node.addProperty(
-		`point3f[] points = [${buildVector3Array( attributes.position, count )}]`
-	);
-
-	for ( let i = 0; i < 4; i ++ ) {
-
-		const id = i > 0 ? i : '';
-		const attribute = attributes[ 'uv' + id ];
-		if ( attribute !== undefined ) {
-
-			node.addProperty(
-				`texCoord2f[] primvars:st${id} = [${buildVector2Array( attribute )}]`,
-				[ 'interpolation = "vertex"' ]
-			);
-
-		}
-
-	}
-
-	const colorAttribute = attributes.color;
-	if ( colorAttribute !== undefined ) {
-
-		node.addProperty(
-			`color3f[] primvars:displayColor = [${buildVector3Array(
-				colorAttribute,
-				count
-			)}]`,
-			[ 'interpolation = "vertex"' ]
-		);
-
-	}
-
-	node.addProperty( 'uniform token subdivisionScheme = "none"' );
-
-	return node;
-
-}
-
-function buildMeshVertexCount( geometry ) {
-
-	const count =
-		geometry.index !== null
-			? geometry.index.count
-			: geometry.attributes.position.count;
-
-	return Array( count / 3 )
-		.fill( 3 )
-		.join( ', ' );
-
-}
-
-function buildMeshVertexIndices( geometry ) {
-
-	const index = geometry.index;
-	const array = [];
-
-	if ( index !== null ) {
-
-		for ( let i = 0; i < index.count; i ++ ) {
-
-			array.push( index.getX( i ) );
-
-		}
-
-	} else {
-
-		const length = geometry.attributes.position.count;
-
-		for ( let i = 0; i < length; i ++ ) {
-
-			array.push( i );
-
-		}
-
-	}
-
-	return array.join( ', ' );
-
-}
-
-function buildVector3Array( attribute, count ) {
-
-	if ( attribute === undefined ) {
-
-		console.warn( 'USDZExporter: Normals missing.' );
-		return Array( count ).fill( '(0, 0, 0)' ).join( ', ' );
-
-	}
-
-	const array = [];
-
-	for ( let i = 0; i < attribute.count; i ++ ) {
-
-		const x = attribute.getX( i );
-		const y = attribute.getY( i );
-		const z = attribute.getZ( i );
-
-		array.push(
-			`(${x.toPrecision( PRECISION )}, ${y.toPrecision(
-				PRECISION
-			)}, ${z.toPrecision( PRECISION )})`
-		);
-
-	}
-
-	return array.join( ', ' );
-
-}
-
-function buildVector2Array( attribute ) {
-
-	const array = [];
-
-	for ( let i = 0; i < attribute.count; i ++ ) {
-
-		const x = attribute.getX( i );
-		const y = attribute.getY( i );
-
-		array.push(
-			`(${x.toPrecision( PRECISION )}, ${1 - y.toPrecision( PRECISION )})`
-		);
-
-	}
-
-	return array.join( ', ' );
-
-}
-
-// Materials
-
-function buildMaterials( materials, textures, quickLookCompatible = false ) {
-
-	const materialsNode = new USDNode( 'Materials' );
-
-	for ( const uuid in materials ) {
-
-		const material = materials[ uuid ];
-
-		materialsNode.addChild(
-			buildMaterial( material, textures, quickLookCompatible )
-		);
-
-	}
-
-	return materialsNode;
-
-}
-
-function buildMaterial( material, textures, quickLookCompatible = false ) {
-
-	// https://graphics.pixar.com/usd/docs/UsdPreviewSurface-Proposal.html
-
-	const materialNode = new USDNode( `Material_${material.id}`, 'Material' );
-
-	function buildTextureNodes( texture, mapType, color ) {
-
-		const id = texture.source.id + '_' + texture.flipY;
-
-		textures[ id ] = texture;
-
-		const uv = texture.channel > 0 ? 'st' + texture.channel : 'st';
-
-		const WRAPPINGS = {
-			1000: 'repeat', // RepeatWrapping
-			1001: 'clamp', // ClampToEdgeWrapping
-			1002: 'mirror', // MirroredRepeatWrapping
-		};
-
-		const repeat = texture.repeat.clone();
-		const offset = texture.offset.clone();
-		const rotation = texture.rotation;
-
-		// rotation is around the wrong point. after rotation we need to shift offset again so that we're rotating around the right spot
-		const xRotationOffset = Math.sin( rotation );
-		const yRotationOffset = Math.cos( rotation );
-
-		// texture coordinates start in the opposite corner, need to correct
-		offset.y = 1 - offset.y - repeat.y;
-
-		// turns out QuickLook is buggy and interprets texture repeat inverted/applies operations in a different order.
-		// Apple Feedback: 	FB10036297 and FB11442287
-		if ( quickLookCompatible ) {
-
-			// This is NOT correct yet in QuickLook, but comes close for a range of models.
-			// It becomes more incorrect the bigger the offset is
-
-			offset.x = offset.x / repeat.x;
-			offset.y = offset.y / repeat.y;
-
-			offset.x += xRotationOffset / repeat.x;
-			offset.y += yRotationOffset - 1;
-
-		} else {
-
-			// results match glTF results exactly. verified correct in usdview.
-			offset.x += xRotationOffset * repeat.x;
-			offset.y += ( 1 - yRotationOffset ) * repeat.y;
-
-		}
-
-		const primvarReaderNode = new USDNode( `PrimvarReader_${mapType}`, 'Shader' );
-		primvarReaderNode.addProperty(
-			'uniform token info:id = "UsdPrimvarReader_float2"'
-		);
-		primvarReaderNode.addProperty( 'float2 inputs:fallback = (0.0, 0.0)' );
-		primvarReaderNode.addProperty( `string inputs:varname = "${uv}"` );
-		primvarReaderNode.addProperty( 'float2 outputs:result' );
-
-		const transform2dNode = new USDNode( `Transform2d_${mapType}`, 'Shader' );
-		transform2dNode.addProperty( 'uniform token info:id = "UsdTransform2d"' );
-		transform2dNode.addProperty(
-			`float2 inputs:in.connect = </Materials/Material_${material.id}/PrimvarReader_${mapType}.outputs:result>`
-		);
-		transform2dNode.addProperty(
-			`float inputs:rotation = ${( rotation * ( 180 / Math.PI ) ).toFixed(
-				PRECISION
-			)}`
-		);
-		transform2dNode.addProperty(
-			`float2 inputs:scale = ${buildVector2( repeat )}`
-		);
-		transform2dNode.addProperty(
-			`float2 inputs:translation = ${buildVector2( offset )}`
-		);
-		transform2dNode.addProperty( 'float2 outputs:result' );
-
-		const textureNode = new USDNode(
-			`Texture_${texture.id}_${mapType}`,
-			'Shader'
-		);
-		textureNode.addProperty( 'uniform token info:id = "UsdUVTexture"' );
-		textureNode.addProperty( `asset inputs:file = @textures/Texture_${id}.png@` );
-		textureNode.addProperty(
-			`float2 inputs:st.connect = </Materials/Material_${material.id}/Transform2d_${mapType}.outputs:result>`
-		);
-
-		if ( color !== undefined ) {
-
-			textureNode.addProperty( `float4 inputs:scale = ${buildColor4( color )}` );
-
-		}
-
-		if ( mapType === 'normal' ) {
-
-			textureNode.addProperty( 'float4 inputs:scale = (2, 2, 2, 1)' );
-			textureNode.addProperty( 'float4 inputs:bias = (-1, -1, -1, 0)' );
-
-		}
-
-		textureNode.addProperty(
-			`token inputs:sourceColorSpace = "${
-				texture.colorSpace === NoColorSpace ? 'raw' : 'sRGB'
-			}"`
-		);
-		textureNode.addProperty(
-			`token inputs:wrapS = "${WRAPPINGS[ texture.wrapS ]}"`
-		);
-		textureNode.addProperty(
-			`token inputs:wrapT = "${WRAPPINGS[ texture.wrapT ]}"`
-		);
-		textureNode.addProperty( 'float outputs:r' );
-		textureNode.addProperty( 'float outputs:g' );
-		textureNode.addProperty( 'float outputs:b' );
-		textureNode.addProperty( 'float3 outputs:rgb' );
-
-		if ( material.transparent || material.alphaTest > 0.0 ) {
-
-			textureNode.addProperty( 'float outputs:a' );
-
-		}
-
-		return [ primvarReaderNode, transform2dNode, textureNode ];
-
-	}
-
-	if ( material.side === DoubleSide ) {
-
-		console.warn(
-			'THREE.USDZExporter: USDZ does not support double sided materials',
-			material
-		);
-
-	}
-
-	const previewSurfaceNode = new USDNode( 'PreviewSurface', 'Shader' );
-	previewSurfaceNode.addProperty( 'uniform token info:id = "UsdPreviewSurface"' );
-
-	if ( material.map !== null ) {
-
-		previewSurfaceNode.addProperty(
-			`color3f inputs:diffuseColor.connect = </Materials/Material_${material.id}/Texture_${material.map.id}_diffuse.outputs:rgb>`
-		);
-
-		if ( material.transparent ) {
-
-			previewSurfaceNode.addProperty(
-				`float inputs:opacity.connect = </Materials/Material_${material.id}/Texture_${material.map.id}_diffuse.outputs:a>`
-			);
-
-		} else if ( material.alphaTest > 0.0 ) {
-
-			previewSurfaceNode.addProperty(
-				`float inputs:opacity.connect = </Materials/Material_${material.id}/Texture_${material.map.id}_diffuse.outputs:a>`
-			);
-			previewSurfaceNode.addProperty(
-				`float inputs:opacityThreshold = ${material.alphaTest}`
-			);
-
-		}
-
-		const textureNodes = buildTextureNodes(
-			material.map,
-			'diffuse',
-			material.color
-		);
-		textureNodes.forEach( ( node ) => materialNode.addChild( node ) );
-
-	} else {
-
-		previewSurfaceNode.addProperty(
-			`color3f inputs:diffuseColor = ${buildColor( material.color )}`
-		);
-
-	}
-
-	if ( material.emissiveMap !== null ) {
-
-		previewSurfaceNode.addProperty(
-			`color3f inputs:emissiveColor.connect = </Materials/Material_${material.id}/Texture_${material.emissiveMap.id}_emissive.outputs:rgb>`
-		);
-
-		const emissiveColor = new Color(
-			material.emissive.r * material.emissiveIntensity,
-			material.emissive.g * material.emissiveIntensity,
-			material.emissive.b * material.emissiveIntensity
-		);
-		const textureNodes = buildTextureNodes(
-			material.emissiveMap,
-			'emissive',
-			emissiveColor
-		);
-		textureNodes.forEach( ( node ) => materialNode.addChild( node ) );
-
-	} else if ( material.emissive.getHex() > 0 ) {
-
-		previewSurfaceNode.addProperty(
-			`color3f inputs:emissiveColor = ${buildColor( material.emissive )}`
-		);
-
-	}
-
-	if ( material.normalMap !== null ) {
-
-		previewSurfaceNode.addProperty(
-			`normal3f inputs:normal.connect = </Materials/Material_${material.id}/Texture_${material.normalMap.id}_normal.outputs:rgb>`
-		);
-
-		const textureNodes = buildTextureNodes( material.normalMap, 'normal' );
-		textureNodes.forEach( ( node ) => materialNode.addChild( node ) );
-
-	}
-
-	if ( material.aoMap !== null ) {
-
-		previewSurfaceNode.addProperty(
-			`float inputs:occlusion.connect = </Materials/Material_${material.id}/Texture_${material.aoMap.id}_occlusion.outputs:r>`
-		);
-
-		const aoColor = new Color(
-			material.aoMapIntensity,
-			material.aoMapIntensity,
-			material.aoMapIntensity
-		);
-		const textureNodes = buildTextureNodes(
-			material.aoMap,
-			'occlusion',
-			aoColor
-		);
-		textureNodes.forEach( ( node ) => materialNode.addChild( node ) );
-
-	}
-
-	if ( material.roughnessMap !== null ) {
-
-		previewSurfaceNode.addProperty(
-			`float inputs:roughness.connect = </Materials/Material_${material.id}/Texture_${material.roughnessMap.id}_roughness.outputs:g>`
-		);
-
-		const roughnessColor = new Color(
-			material.roughness,
-			material.roughness,
-			material.roughness
-		);
-		const textureNodes = buildTextureNodes(
-			material.roughnessMap,
-			'roughness',
-			roughnessColor
-		);
-		textureNodes.forEach( ( node ) => materialNode.addChild( node ) );
-
-	} else {
-
-		previewSurfaceNode.addProperty(
-			`float inputs:roughness = ${material.roughness}`
-		);
-
-	}
-
-	if ( material.metalnessMap !== null ) {
-
-		previewSurfaceNode.addProperty(
-			`float inputs:metallic.connect = </Materials/Material_${material.id}/Texture_${material.metalnessMap.id}_metallic.outputs:b>`
-		);
-
-		const metalnessColor = new Color(
-			material.metalness,
-			material.metalness,
-			material.metalness
-		);
-		const textureNodes = buildTextureNodes(
-			material.metalnessMap,
-			'metallic',
-			metalnessColor
-		);
-		textureNodes.forEach( ( node ) => materialNode.addChild( node ) );
-
-	} else {
-
-		previewSurfaceNode.addProperty(
-			`float inputs:metallic = ${material.metalness}`
-		);
-
-	}
-
-	if ( material.alphaMap !== null ) {
-
-		previewSurfaceNode.addProperty(
-			`float inputs:opacity.connect = </Materials/Material_${material.id}/Texture_${material.alphaMap.id}_opacity.outputs:r>`
-		);
-		previewSurfaceNode.addProperty( 'float inputs:opacityThreshold = 0.0001' );
-
-		const textureNodes = buildTextureNodes( material.alphaMap, 'opacity' );
-		textureNodes.forEach( ( node ) => materialNode.addChild( node ) );
-
-	} else {
-
-		previewSurfaceNode.addProperty(
-			`float inputs:opacity = ${material.opacity}`
-		);
-
-	}
-
-	if ( material.isMeshPhysicalMaterial ) {
-
-		if ( material.clearcoatMap !== null ) {
-
-			previewSurfaceNode.addProperty(
-				`float inputs:clearcoat.connect = </Materials/Material_${material.id}/Texture_${material.clearcoatMap.id}_clearcoat.outputs:r>`
-			);
-
-			const clearcoatColor = new Color(
-				material.clearcoat,
-				material.clearcoat,
-				material.clearcoat
-			);
-			const textureNodes = buildTextureNodes(
-				material.clearcoatMap,
-				'clearcoat',
-				clearcoatColor
-			);
-			textureNodes.forEach( ( node ) => materialNode.addChild( node ) );
-
-		} else {
-
-			previewSurfaceNode.addProperty(
-				`float inputs:clearcoat = ${material.clearcoat}`
-			);
-
-		}
-
-		if ( material.clearcoatRoughnessMap !== null ) {
-
-			previewSurfaceNode.addProperty(
-				`float inputs:clearcoatRoughness.connect = </Materials/Material_${material.id}/Texture_${material.clearcoatRoughnessMap.id}_clearcoatRoughness.outputs:g>`
-			);
-
-			const clearcoatRoughnessColor = new Color(
-				material.clearcoatRoughness,
-				material.clearcoatRoughness,
-				material.clearcoatRoughness
-			);
-			const textureNodes = buildTextureNodes(
-				material.clearcoatRoughnessMap,
-				'clearcoatRoughness',
-				clearcoatRoughnessColor
-			);
-			textureNodes.forEach( ( node ) => materialNode.addChild( node ) );
-
-		} else {
-
-			previewSurfaceNode.addProperty(
-				`float inputs:clearcoatRoughness = ${material.clearcoatRoughness}`
-			);
-
-		}
-
-		previewSurfaceNode.addProperty( `float inputs:ior = ${material.ior}` );
-
-	}
-
-	previewSurfaceNode.addProperty( 'int inputs:useSpecularWorkflow = 0' );
-	previewSurfaceNode.addProperty( 'token outputs:surface' );
-
-	materialNode.addChild( previewSurfaceNode );
-
-	materialNode.addProperty(
-		`token outputs:surface.connect = </Materials/Material_${material.id}/PreviewSurface.outputs:surface>`
-	);
-
-	return materialNode;
-
-}
-
-function buildColor( color ) {
-
-	return `(${color.r}, ${color.g}, ${color.b})`;
-
-}
-
-function buildColor4( color ) {
-
-	return `(${color.r}, ${color.g}, ${color.b}, 1.0)`;
-
-}
-
-function buildVector2( vector ) {
-
-	return `(${vector.x}, ${vector.y})`;
-
-}
-
-function buildCamera( camera, usedNames ) {
-
-	const name = getName( camera, usedNames );
-
-	const transform = buildMatrix( camera.matrix );
-
-	if ( camera.matrix.determinant() < 0 ) {
-
-		console.warn(
-			'THREE.USDZExporter: USDZ does not support negative scales',
-			camera
-		);
-
-	}
-
-	const node = new USDNode( name, 'Camera' );
-	node.addProperty( `matrix4d xformOp:transform = ${transform}` );
-	node.addProperty( 'uniform token[] xformOpOrder = ["xformOp:transform"]' );
-
-	const projection = camera.isOrthographicCamera
-		? 'orthographic'
-		: 'perspective';
-	node.addProperty( `token projection = "${projection}"` );
-
-	const clippingRange = `(${camera.near.toPrecision(
-		PRECISION
-	)}, ${camera.far.toPrecision( PRECISION )})`;
-	node.addProperty( `float2 clippingRange = ${clippingRange}` );
-
-	let horizontalAperture;
-	if ( camera.isOrthographicCamera ) {
-
-		horizontalAperture = (
-			( Math.abs( camera.left ) + Math.abs( camera.right ) ) *
-			10
-		).toPrecision( PRECISION );
-
-	} else {
-
-		horizontalAperture = camera.getFilmWidth().toPrecision( PRECISION );
-
-	}
-
-	node.addProperty( `float horizontalAperture = ${horizontalAperture}` );
-
-	let verticalAperture;
-	if ( camera.isOrthographicCamera ) {
-
-		verticalAperture = (
-			( Math.abs( camera.top ) + Math.abs( camera.bottom ) ) *
-			10
-		).toPrecision( PRECISION );
-
-	} else {
-
-		verticalAperture = camera.getFilmHeight().toPrecision( PRECISION );
-
-	}
-
-	node.addProperty( `float verticalAperture = ${verticalAperture}` );
-
-	if ( camera.isPerspectiveCamera ) {
-
-		const focalLength = camera.getFocalLength().toPrecision( PRECISION );
-		node.addProperty( `float focalLength = ${focalLength}` );
-
-		const focusDistance = camera.focus.toPrecision( PRECISION );
-		node.addProperty( `float focusDistance = ${focusDistance}` );
-
-	}
-
-	return node;
-
-}
-
-/**
- * Export options of `USDZExporter`.
- *
- * @typedef {Object} USDZExporter~Options
- * @property {number} [maxTextureSize=1024] - The maximum texture size that is going to be exported.
- * @property {boolean} [includeAnchoringProperties=true] - Whether to include anchoring properties or not.
- * @property {boolean} [onlyVisible=true] - Export only visible 3D objects.
- * @property {Object} [ar] - If `includeAnchoringProperties` is set to `true`, the anchoring type and alignment
- * can be configured via `ar.anchoring.type` and `ar.planeAnchoring.alignment`.
- * @property {boolean} [quickLookCompatible=false] - Whether to make the exported USDZ compatible to QuickLook
- * which means the asset is modified to accommodate the bugs FB10036297 and FB11442287 (Apple Feedback).
- **/
-
-/**
- * onDone callback of `USDZExporter`.
- *
- * @callback USDZExporter~OnDone
- * @param {ArrayBuffer} result - The generated USDZ.
- */
-
-/**
- * onError callback of `USDZExporter`.
- *
- * @callback USDZExporter~OnError
- * @param {Error} error - The error object.
- */
-
-export { USDZExporter };

+ 0 - 92
node_modules/three/examples/jsm/geometries/BoxLineGeometry.js

@@ -1,92 +0,0 @@
-import {
-	BufferGeometry,
-	Float32BufferAttribute
-} from 'three';
-
-/**
- * A special type of box geometry intended for {@link LineSegments}.
- *
- * ```js
- * const geometry = new THREE.BoxLineGeometry();
- * const material = new THREE.LineBasicMaterial( { color: 0x00ff00 } );
- * const lines = new THREE.LineSegments( geometry, material );
- * scene.add( lines );
- * ```
- *
- * @augments BufferGeometry
- * @three_import import { BoxLineGeometry } from 'three/addons/geometries/BoxLineGeometry.js';
- */
-class BoxLineGeometry extends BufferGeometry {
-
-	/**
-	 * Constructs a new box line geometry.
-	 *
-	 * @param {number} [width=1] - The width. That is, the length of the edges parallel to the X axis.
-	 * @param {number} [height=1] - The height. That is, the length of the edges parallel to the Y axis.
-	 * @param {number} [depth=1] - The depth. That is, the length of the edges parallel to the Z axis.
-	 * @param {number} [widthSegments=1] - Number of segmented rectangular sections along the width of the sides.
-	 * @param {number} [heightSegments=1] - Number of segmented rectangular sections along the height of the sides.
-	 * @param {number} [depthSegments=1] - Number of segmented rectangular sections along the depth of the sides.
-	 */
-	constructor( width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1 ) {
-
-		super();
-
-		widthSegments = Math.floor( widthSegments );
-		heightSegments = Math.floor( heightSegments );
-		depthSegments = Math.floor( depthSegments );
-
-		const widthHalf = width / 2;
-		const heightHalf = height / 2;
-		const depthHalf = depth / 2;
-
-		const segmentWidth = width / widthSegments;
-		const segmentHeight = height / heightSegments;
-		const segmentDepth = depth / depthSegments;
-
-		const vertices = [];
-
-		let x = - widthHalf;
-		let y = - heightHalf;
-		let z = - depthHalf;
-
-		for ( let i = 0; i <= widthSegments; i ++ ) {
-
-			vertices.push( x, - heightHalf, - depthHalf, x, heightHalf, - depthHalf );
-			vertices.push( x, heightHalf, - depthHalf, x, heightHalf, depthHalf );
-			vertices.push( x, heightHalf, depthHalf, x, - heightHalf, depthHalf );
-			vertices.push( x, - heightHalf, depthHalf, x, - heightHalf, - depthHalf );
-
-			x += segmentWidth;
-
-		}
-
-		for ( let i = 0; i <= heightSegments; i ++ ) {
-
-			vertices.push( - widthHalf, y, - depthHalf, widthHalf, y, - depthHalf );
-			vertices.push( widthHalf, y, - depthHalf, widthHalf, y, depthHalf );
-			vertices.push( widthHalf, y, depthHalf, - widthHalf, y, depthHalf );
-			vertices.push( - widthHalf, y, depthHalf, - widthHalf, y, - depthHalf );
-
-			y += segmentHeight;
-
-		}
-
-		for ( let i = 0; i <= depthSegments; i ++ ) {
-
-			vertices.push( - widthHalf, - heightHalf, z, - widthHalf, heightHalf, z );
-			vertices.push( - widthHalf, heightHalf, z, widthHalf, heightHalf, z );
-			vertices.push( widthHalf, heightHalf, z, widthHalf, - heightHalf, z );
-			vertices.push( widthHalf, - heightHalf, z, - widthHalf, - heightHalf, z );
-
-			z += segmentDepth;
-
-		}
-
-		this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
-
-	}
-
-}
-
-export { BoxLineGeometry };

+ 0 - 72
node_modules/three/examples/jsm/geometries/ConvexGeometry.js

@@ -1,72 +0,0 @@
-import {
-	BufferGeometry,
-	Float32BufferAttribute
-} from 'three';
-import { ConvexHull } from '../math/ConvexHull.js';
-
-/**
- * This class can be used to generate a convex hull for a given array of 3D points.
- * The average time complexity for this task is considered to be O(nlog(n)).
- *
- * ```js
- * const geometry = new ConvexGeometry( points );
- * const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
- * const mesh = new THREE.Mesh( geometry, material );
- * scene.add( mesh );
- * ```
- *
- * @augments BufferGeometry
- * @three_import import { ConvexGeometry } from 'three/addons/geometries/ConvexGeometry.js';
- */
-class ConvexGeometry extends BufferGeometry {
-
-	/**
-	 * Constructs a new convex geometry.
-	 *
-	 * @param {Array<Vector3>} points - An array of points in 3D space which should be enclosed by the convex hull.
-	 */
-	constructor( points = [] ) {
-
-		super();
-
-		// buffers
-
-		const vertices = [];
-		const normals = [];
-
-		const convexHull = new ConvexHull().setFromPoints( points );
-
-		// generate vertices and normals
-
-		const faces = convexHull.faces;
-
-		for ( let i = 0; i < faces.length; i ++ ) {
-
-			const face = faces[ i ];
-			let edge = face.edge;
-
-			// we move along a doubly-connected edge list to access all face points (see HalfEdge docs)
-
-			do {
-
-				const point = edge.head().point;
-
-				vertices.push( point.x, point.y, point.z );
-				normals.push( face.normal.x, face.normal.y, face.normal.z );
-
-				edge = edge.next;
-
-			} while ( edge !== face.edge );
-
-		}
-
-		// build geometry
-
-		this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
-		this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
-
-	}
-
-}
-
-export { ConvexGeometry };

+ 0 - 420
node_modules/three/examples/jsm/geometries/DecalGeometry.js

@@ -1,420 +0,0 @@
-import {
-	BufferGeometry,
-	Euler,
-	Float32BufferAttribute,
-	Matrix3,
-	Matrix4,
-	Mesh,
-	Vector3
-} from 'three';
-
-/**
- * This class can be used to create a decal mesh that serves different kinds of purposes e.g.
- * adding unique details to models, performing dynamic visual environmental changes or covering seams.
- *
- * Please not that decal projections can be distorted when used around corners. More information at
- * this GitHub issue: [Decal projections without distortions](https://github.com/mrdoob/three.js/issues/21187).
- *
- * Reference: [How to project decals](http://blog.wolfire.com/2009/06/how-to-project-decals/)
- *
- * ```js
- * const geometry = new DecalGeometry( mesh, position, orientation, size );
- * const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
- * const mesh = new THREE.Mesh( geometry, material );
- * scene.add( mesh );
- * ```
- *
- * @augments BufferGeometry
- * @three_import import { DecalGeometry } from 'three/addons/geometries/DecalGeometry.js';
- */
-class DecalGeometry extends BufferGeometry {
-
-	/**
-	 * Constructs a new decal geometry.
-	 *
-	 * @param {Mesh} [mesh] - The base mesh the decal should be projected on.
-	 * @param {Vector3} [position] - The position of the decal projector.
-	 * @param {Euler} [orientation] - The orientation of the decal projector.
-	 * @param {Vector3} [size] - The scale of the decal projector.
-	 */
-	constructor( mesh = new Mesh(), position = new Vector3(), orientation = new Euler(), size = new Vector3( 1, 1, 1 ) ) {
-
-		super();
-
-		// buffers
-
-		const vertices = [];
-		const normals = [];
-		const uvs = [];
-
-		// helpers
-
-		const plane = new Vector3();
-
-		const normalMatrix = new Matrix3().getNormalMatrix( mesh.matrixWorld );
-
-		// this matrix represents the transformation of the decal projector
-
-		const projectorMatrix = new Matrix4();
-		projectorMatrix.makeRotationFromEuler( orientation );
-		projectorMatrix.setPosition( position );
-
-		const projectorMatrixInverse = new Matrix4();
-		projectorMatrixInverse.copy( projectorMatrix ).invert();
-
-		// generate buffers
-
-		generate();
-
-		// build geometry
-
-		this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
-		this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
-
-		if ( normals.length > 0 ) {
-
-			this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
-
-		}
-
-		//
-
-		function generate() {
-
-			let decalVertices = [];
-
-			const vertex = new Vector3();
-			const normal = new Vector3();
-
-			// handle different geometry types
-
-			const geometry = mesh.geometry;
-
-			const positionAttribute = geometry.attributes.position;
-			const normalAttribute = geometry.attributes.normal;
-
-			// first, create an array of 'DecalVertex' objects
-			// three consecutive 'DecalVertex' objects represent a single face
-			//
-			// this data structure will be later used to perform the clipping
-
-			if ( geometry.index !== null ) {
-
-				// indexed BufferGeometry
-
-				const index = geometry.index;
-
-				for ( let i = 0; i < index.count; i ++ ) {
-
-					vertex.fromBufferAttribute( positionAttribute, index.getX( i ) );
-
-					if ( normalAttribute ) {
-
-						normal.fromBufferAttribute( normalAttribute, index.getX( i ) );
-						pushDecalVertex( decalVertices, vertex, normal );
-
-					} else {
-
-						pushDecalVertex( decalVertices, vertex );
-
-					}
-
-				}
-
-			} else {
-
-				if ( positionAttribute === undefined ) return; // empty geometry
-
-				// non-indexed BufferGeometry
-
-				for ( let i = 0; i < positionAttribute.count; i ++ ) {
-
-					vertex.fromBufferAttribute( positionAttribute, i );
-
-					if ( normalAttribute ) {
-
-						normal.fromBufferAttribute( normalAttribute, i );
-						pushDecalVertex( decalVertices, vertex, normal );
-
-					} else {
-
-						pushDecalVertex( decalVertices, vertex );
-
-					}
-
-				}
-
-			}
-
-			// second, clip the geometry so that it doesn't extend out from the projector
-
-			decalVertices = clipGeometry( decalVertices, plane.set( 1, 0, 0 ) );
-			decalVertices = clipGeometry( decalVertices, plane.set( - 1, 0, 0 ) );
-			decalVertices = clipGeometry( decalVertices, plane.set( 0, 1, 0 ) );
-			decalVertices = clipGeometry( decalVertices, plane.set( 0, - 1, 0 ) );
-			decalVertices = clipGeometry( decalVertices, plane.set( 0, 0, 1 ) );
-			decalVertices = clipGeometry( decalVertices, plane.set( 0, 0, - 1 ) );
-
-			// third, generate final vertices, normals and uvs
-
-			for ( let i = 0; i < decalVertices.length; i ++ ) {
-
-				const decalVertex = decalVertices[ i ];
-
-				// create texture coordinates (we are still in projector space)
-
-				uvs.push(
-					0.5 + ( decalVertex.position.x / size.x ),
-					0.5 + ( decalVertex.position.y / size.y )
-				);
-
-				// transform the vertex back to world space
-
-				decalVertex.position.applyMatrix4( projectorMatrix );
-
-				// now create vertex and normal buffer data
-
-				vertices.push( decalVertex.position.x, decalVertex.position.y, decalVertex.position.z );
-
-				if ( decalVertex.normal !== null ) {
-
-					normals.push( decalVertex.normal.x, decalVertex.normal.y, decalVertex.normal.z );
-
-				}
-
-			}
-
-		}
-
-		function pushDecalVertex( decalVertices, vertex, normal = null ) {
-
-			// transform the vertex to world space, then to projector space
-
-			vertex.applyMatrix4( mesh.matrixWorld );
-			vertex.applyMatrix4( projectorMatrixInverse );
-
-			if ( normal ) {
-
-				normal.applyNormalMatrix( normalMatrix );
-				decalVertices.push( new DecalVertex( vertex.clone(), normal.clone() ) );
-
-			} else {
-
-				decalVertices.push( new DecalVertex( vertex.clone() ) );
-
-			}
-
-		}
-
-		function clipGeometry( inVertices, plane ) {
-
-			const outVertices = [];
-
-			const s = 0.5 * Math.abs( size.dot( plane ) );
-
-			// a single iteration clips one face,
-			// which consists of three consecutive 'DecalVertex' objects
-
-			for ( let i = 0; i < inVertices.length; i += 3 ) {
-
-				let total = 0;
-				let nV1;
-				let nV2;
-				let nV3;
-				let nV4;
-
-				const d1 = inVertices[ i + 0 ].position.dot( plane ) - s;
-				const d2 = inVertices[ i + 1 ].position.dot( plane ) - s;
-				const d3 = inVertices[ i + 2 ].position.dot( plane ) - s;
-
-				const v1Out = d1 > 0;
-				const v2Out = d2 > 0;
-				const v3Out = d3 > 0;
-
-				// calculate, how many vertices of the face lie outside of the clipping plane
-
-				total = ( v1Out ? 1 : 0 ) + ( v2Out ? 1 : 0 ) + ( v3Out ? 1 : 0 );
-
-				switch ( total ) {
-
-					case 0: {
-
-						// the entire face lies inside of the plane, no clipping needed
-
-						outVertices.push( inVertices[ i ] );
-						outVertices.push( inVertices[ i + 1 ] );
-						outVertices.push( inVertices[ i + 2 ] );
-						break;
-
-					}
-
-					case 1: {
-
-						// one vertex lies outside of the plane, perform clipping
-
-						if ( v1Out ) {
-
-							nV1 = inVertices[ i + 1 ];
-							nV2 = inVertices[ i + 2 ];
-							nV3 = clip( inVertices[ i ], nV1, plane, s );
-							nV4 = clip( inVertices[ i ], nV2, plane, s );
-
-						}
-
-						if ( v2Out ) {
-
-							nV1 = inVertices[ i ];
-							nV2 = inVertices[ i + 2 ];
-							nV3 = clip( inVertices[ i + 1 ], nV1, plane, s );
-							nV4 = clip( inVertices[ i + 1 ], nV2, plane, s );
-
-							outVertices.push( nV3 );
-							outVertices.push( nV2.clone() );
-							outVertices.push( nV1.clone() );
-
-							outVertices.push( nV2.clone() );
-							outVertices.push( nV3.clone() );
-							outVertices.push( nV4 );
-							break;
-
-						}
-
-						if ( v3Out ) {
-
-							nV1 = inVertices[ i ];
-							nV2 = inVertices[ i + 1 ];
-							nV3 = clip( inVertices[ i + 2 ], nV1, plane, s );
-							nV4 = clip( inVertices[ i + 2 ], nV2, plane, s );
-
-						}
-
-						outVertices.push( nV1.clone() );
-						outVertices.push( nV2.clone() );
-						outVertices.push( nV3 );
-
-						outVertices.push( nV4 );
-						outVertices.push( nV3.clone() );
-						outVertices.push( nV2.clone() );
-
-						break;
-
-					}
-
-					case 2: {
-
-						// two vertices lies outside of the plane, perform clipping
-
-						if ( ! v1Out ) {
-
-							nV1 = inVertices[ i ].clone();
-							nV2 = clip( nV1, inVertices[ i + 1 ], plane, s );
-							nV3 = clip( nV1, inVertices[ i + 2 ], plane, s );
-							outVertices.push( nV1 );
-							outVertices.push( nV2 );
-							outVertices.push( nV3 );
-
-						}
-
-						if ( ! v2Out ) {
-
-							nV1 = inVertices[ i + 1 ].clone();
-							nV2 = clip( nV1, inVertices[ i + 2 ], plane, s );
-							nV3 = clip( nV1, inVertices[ i ], plane, s );
-							outVertices.push( nV1 );
-							outVertices.push( nV2 );
-							outVertices.push( nV3 );
-
-						}
-
-						if ( ! v3Out ) {
-
-							nV1 = inVertices[ i + 2 ].clone();
-							nV2 = clip( nV1, inVertices[ i ], plane, s );
-							nV3 = clip( nV1, inVertices[ i + 1 ], plane, s );
-							outVertices.push( nV1 );
-							outVertices.push( nV2 );
-							outVertices.push( nV3 );
-
-						}
-
-						break;
-
-					}
-
-					case 3: {
-
-						// the entire face lies outside of the plane, so let's discard the corresponding vertices
-
-						break;
-
-					}
-
-				}
-
-			}
-
-			return outVertices;
-
-		}
-
-		function clip( v0, v1, p, s ) {
-
-			const d0 = v0.position.dot( p ) - s;
-			const d1 = v1.position.dot( p ) - s;
-
-			const s0 = d0 / ( d0 - d1 );
-
-			const position = new Vector3(
-				v0.position.x + s0 * ( v1.position.x - v0.position.x ),
-				v0.position.y + s0 * ( v1.position.y - v0.position.y ),
-				v0.position.z + s0 * ( v1.position.z - v0.position.z )
-			);
-
-			let normal = null;
-
-			if ( v0.normal !== null && v1.normal !== null ) {
-
-				normal = new Vector3(
-					v0.normal.x + s0 * ( v1.normal.x - v0.normal.x ),
-					v0.normal.y + s0 * ( v1.normal.y - v0.normal.y ),
-					v0.normal.z + s0 * ( v1.normal.z - v0.normal.z )
-				);
-
-			}
-
-			const v = new DecalVertex( position, normal );
-
-			// need to clip more values (texture coordinates)? do it this way:
-			// intersectpoint.value = a.value + s * ( b.value - a.value );
-
-			return v;
-
-		}
-
-	}
-
-}
-
-// helper
-
-class DecalVertex {
-
-	constructor( position, normal = null ) {
-
-		this.position = position;
-		this.normal = normal;
-
-	}
-
-	clone() {
-
-		const position = this.position.clone();
-		const normal = ( this.normal !== null ) ? this.normal.clone() : null;
-
-		return new this.constructor( position, normal );
-
-	}
-
-}
-
-export { DecalGeometry, DecalVertex };

+ 0 - 100
node_modules/three/examples/jsm/geometries/ParametricFunctions.js

@@ -1,100 +0,0 @@
-
-/**
- * @module ParametricFunctions
- * @three_import import * as ParametricFunctions from 'three/addons/geometries/ParametricFunctions.js';
- */
-
-/**
- * A parametric function representing the Klein bottle.
- *
- * @param {number} v - The `v` coordinate on the surface in the range `[0,1]`.
- * @param {number} u - The `u` coordinate on the surface in the range `[0,1]`.
- * @param {Vector3} target - The target vector that is used to store the method's result.
- */
-function klein( v, u, target ) {
-
-	u *= Math.PI;
-	v *= 2 * Math.PI;
-
-	u = u * 2;
-	let x, z;
-	if ( u < Math.PI ) {
-
-		x = 3 * Math.cos( u ) * ( 1 + Math.sin( u ) ) + ( 2 * ( 1 - Math.cos( u ) / 2 ) ) * Math.cos( u ) * Math.cos( v );
-		z = - 8 * Math.sin( u ) - 2 * ( 1 - Math.cos( u ) / 2 ) * Math.sin( u ) * Math.cos( v );
-
-	} else {
-
-		x = 3 * Math.cos( u ) * ( 1 + Math.sin( u ) ) + ( 2 * ( 1 - Math.cos( u ) / 2 ) ) * Math.cos( v + Math.PI );
-		z = - 8 * Math.sin( u );
-
-	}
-
-	const y = - 2 * ( 1 - Math.cos( u ) / 2 ) * Math.sin( v );
-
-	target.set( x, y, z );
-
-}
-
-/**
- * A parametric function representing a flat plane.
- *
- * @param {number} u - The `u` coordinate on the surface in the range `[0,1]`.
- * @param {number} v - The `v` coordinate on the surface in the range `[0,1]`.
- * @param {Vector3} target - The target vector that is used to store the method's result.
- */
-function plane( u, v, target ) {
-
-	target.set( u, 0, v );
-
-}
-
-/**
- * A parametric function representing a flat mobius strip.
- *
- * @param {number} u - The `u` coordinate on the surface in the range `[0,1]`.
- * @param {number} t - The `v` coordinate on the surface in the range `[0,1]`.
- * @param {Vector3} target - The target vector that is used to store the method's result.
- */
-function mobius( u, t, target ) {
-
-	// http://www.wolframalpha.com/input/?i=M%C3%B6bius+strip+parametric+equations&lk=1&a=ClashPrefs_*Surface.MoebiusStrip.SurfaceProperty.ParametricEquations-
-	u = u - 0.5;
-	const v = 2 * Math.PI * t;
-
-	const a = 2;
-
-	const x = Math.cos( v ) * ( a + u * Math.cos( v / 2 ) );
-	const y = Math.sin( v ) * ( a + u * Math.cos( v / 2 ) );
-	const z = u * Math.sin( v / 2 );
-
-	target.set( x, y, z );
-
-}
-
-/**
- * A parametric function representing a volumetric mobius strip.
- *
- * @param {number} u - The `u` coordinate on the surface in the range `[0,1]`.
- * @param {number} t - The `v` coordinate on the surface in the range `[0,1]`.
- * @param {Vector3} target - The target vector that is used to store the method's result.
- */
-function mobius3d( u, t, target ) {
-
-	u *= Math.PI;
-	t *= 2 * Math.PI;
-
-	u = u * 2;
-	const phi = u / 2;
-	const major = 2.25, a = 0.125, b = 0.65;
-
-	let x = a * Math.cos( t ) * Math.cos( phi ) - b * Math.sin( t ) * Math.sin( phi );
-	const z = a * Math.cos( t ) * Math.sin( phi ) + b * Math.sin( t ) * Math.cos( phi );
-	const y = ( major + x ) * Math.sin( u );
-	x = ( major + x ) * Math.cos( u );
-
-	target.set( x, y, z );
-
-}
-
-export { klein, plane, mobius, mobius3d };

+ 0 - 172
node_modules/three/examples/jsm/geometries/ParametricGeometry.js

@@ -1,172 +0,0 @@
-import {
-	BufferGeometry,
-	Float32BufferAttribute,
-	Vector3
-} from 'three';
-
-/**
- * This class can be used to generate a geometry based on a parametric surface.
- *
- * Reference: [Mesh Generation with Python](https://prideout.net/blog/old/blog/index.html@p=44.html)
- *
- * ```js
- * const geometry = new THREE.ParametricGeometry( klein, 25, 25 );
- * const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
- * const klein = new THREE.Mesh( geometry, material );
- * scene.add( klein );
- * ```
- *
- * @augments BufferGeometry
- * @three_import import { ParametricGeometry } from 'three/addons/geometries/ParametricGeometry.js';
- */
-class ParametricGeometry extends BufferGeometry {
-
-	/**
-	 * Constructs a new parametric geometry.
-	 *
-	 * @param {ParametricGeometry~Func} func - The parametric function. Default is a function that generates a curved plane surface.
-	 * @param {number} [slices=8] - The number of slices to use for the parametric function.
-	 * @param {number} [stacks=8] - The stacks of slices to use for the parametric function.
-	 */
-	constructor( func = ( u, v, target ) => target.set( u, v, Math.cos( u ) * Math.sin( v ) ), slices = 8, stacks = 8 ) {
-
-		super();
-
-		this.type = 'ParametricGeometry';
-
-		/**
-		 * Holds the constructor parameters that have been
-		 * used to generate the geometry. Any modification
-		 * after instantiation does not change the geometry.
-		 *
-		 * @type {Object}
-		 */
-		this.parameters = {
-			func: func,
-			slices: slices,
-			stacks: stacks
-		};
-
-		// buffers
-
-		const indices = [];
-		const vertices = [];
-		const normals = [];
-		const uvs = [];
-
-		const EPS = 0.00001;
-
-		const normal = new Vector3();
-
-		const p0 = new Vector3(), p1 = new Vector3();
-		const pu = new Vector3(), pv = new Vector3();
-
-		// generate vertices, normals and uvs
-
-		const sliceCount = slices + 1;
-
-		for ( let i = 0; i <= stacks; i ++ ) {
-
-			const v = i / stacks;
-
-			for ( let j = 0; j <= slices; j ++ ) {
-
-				const u = j / slices;
-
-				// vertex
-
-				func( u, v, p0 );
-				vertices.push( p0.x, p0.y, p0.z );
-
-				// normal
-
-				// approximate tangent vectors via finite differences
-
-				if ( u - EPS >= 0 ) {
-
-					func( u - EPS, v, p1 );
-					pu.subVectors( p0, p1 );
-
-				} else {
-
-					func( u + EPS, v, p1 );
-					pu.subVectors( p1, p0 );
-
-				}
-
-				if ( v - EPS >= 0 ) {
-
-					func( u, v - EPS, p1 );
-					pv.subVectors( p0, p1 );
-
-				} else {
-
-					func( u, v + EPS, p1 );
-					pv.subVectors( p1, p0 );
-
-				}
-
-				// cross product of tangent vectors returns surface normal
-
-				normal.crossVectors( pu, pv ).normalize();
-				normals.push( normal.x, normal.y, normal.z );
-
-				// uv
-
-				uvs.push( u, v );
-
-			}
-
-		}
-
-		// generate indices
-
-		for ( let i = 0; i < stacks; i ++ ) {
-
-			for ( let j = 0; j < slices; j ++ ) {
-
-				const a = i * sliceCount + j;
-				const b = i * sliceCount + j + 1;
-				const c = ( i + 1 ) * sliceCount + j + 1;
-				const d = ( i + 1 ) * sliceCount + j;
-
-				// faces one and two
-
-				indices.push( a, b, d );
-				indices.push( b, c, d );
-
-			}
-
-		}
-
-		// build geometry
-
-		this.setIndex( indices );
-		this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
-		this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
-		this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
-
-	}
-
-	copy( source ) {
-
-		super.copy( source );
-
-		this.parameters = Object.assign( {}, source.parameters );
-
-		return this;
-
-	}
-
-}
-
-/**
- * Parametric function definition of `ParametricGeometry`.
- *
- * @callback ParametricGeometry~Func
- * @param {number} u - The `u` coordinate on the surface in the range `[0,1]`.
- * @param {number} v - The `v` coordinate on the surface in the range `[0,1]`.
- * @param {Vector3} target - The target vector that is used to store the method's result.
- */
-
-export { ParametricGeometry };

+ 0 - 216
node_modules/three/examples/jsm/geometries/RoundedBoxGeometry.js

@@ -1,216 +0,0 @@
-import {
-	BoxGeometry,
-	Vector3
-} from 'three';
-
-const _tempNormal = new Vector3();
-
-function getUv( faceDirVector, normal, uvAxis, projectionAxis, radius, sideLength ) {
-
-	const totArcLength = 2 * Math.PI * radius / 4;
-
-	// length of the planes between the arcs on each axis
-	const centerLength = Math.max( sideLength - 2 * radius, 0 );
-	const halfArc = Math.PI / 4;
-
-	// Get the vector projected onto the Y plane
-	_tempNormal.copy( normal );
-	_tempNormal[ projectionAxis ] = 0;
-	_tempNormal.normalize();
-
-	// total amount of UV space alloted to a single arc
-	const arcUvRatio = 0.5 * totArcLength / ( totArcLength + centerLength );
-
-	// the distance along one arc the point is at
-	const arcAngleRatio = 1.0 - ( _tempNormal.angleTo( faceDirVector ) / halfArc );
-
-	if ( Math.sign( _tempNormal[ uvAxis ] ) === 1 ) {
-
-		return arcAngleRatio * arcUvRatio;
-
-	} else {
-
-		// total amount of UV space alloted to the plane between the arcs
-		const lenUv = centerLength / ( totArcLength + centerLength );
-		return lenUv + arcUvRatio + arcUvRatio * ( 1.0 - arcAngleRatio );
-
-	}
-
-}
-
-/**
- * A special type of box geometry with rounded corners and edges.
- *
- * ```js
- * const geometry = new THREE.RoundedBoxGeometry();
- * const material = new THREE.MeshStandardMaterial( { color: 0x00ff00 } );
- * const cube = new THREE.Mesh( geometry, material );
- * scene.add( cube );
- * ```
- *
- * @augments BoxGeometry
- * @three_import import { RoundedBoxGeometry } from 'three/addons/geometries/RoundedBoxGeometry.js';
- */
-class RoundedBoxGeometry extends BoxGeometry {
-
-	/**
-	 * Constructs a new rounded box geometry.
-	 *
-	 * @param {number} [width=1] - The width. That is, the length of the edges parallel to the X axis.
-	 * @param {number} [height=1] - The height. That is, the length of the edges parallel to the Y axis.
-	 * @param {number} [depth=1] - The depth. That is, the length of the edges parallel to the Z axis.
-	 * @param {number} [segments=2] - Number of segments that form the rounded corners.
-	 * @param {number} [radius=0.1] - The radius of the rounded corners.
-	 */
-	constructor( width = 1, height = 1, depth = 1, segments = 2, radius = 0.1 ) {
-
-		// calculate total segments needed &
-		// ensure it's odd so that we have a plane connecting the rounded corners
-		const totalSegments = segments * 2 + 1;
-
-		// ensure radius isn't bigger than shortest side
-		radius = Math.min( width / 2, height / 2, depth / 2, radius );
-
-		// start with a unit box geometry, its vertices will be modified to form the rounded box
-		super( 1, 1, 1, totalSegments, totalSegments, totalSegments );
-
-		this.type = 'RoundedBoxGeometry';
-
-		/**
-		 * Holds the constructor parameters that have been
-		 * used to generate the geometry. Any modification
-		 * after instantiation does not change the geometry.
-		 *
-		 * @type {Object}
-		 */
-		this.parameters = {
-			width: width,
-			height: height,
-			depth: depth,
-			segments: segments,
-			radius: radius,
-		};
-
-		// if totalSegments is 1, no rounding is needed - return regular box
-		if ( totalSegments === 1 ) return;
-
-		const geometry2 = this.toNonIndexed();
-
-		this.index = null;
-		this.attributes.position = geometry2.attributes.position;
-		this.attributes.normal = geometry2.attributes.normal;
-		this.attributes.uv = geometry2.attributes.uv;
-
-		//
-
-		const position = new Vector3();
-		const normal = new Vector3();
-
-		const box = new Vector3( width, height, depth ).divideScalar( 2 ).subScalar( radius );
-
-		const positions = this.attributes.position.array;
-		const normals = this.attributes.normal.array;
-		const uvs = this.attributes.uv.array;
-
-		const faceTris = positions.length / 6;
-		const faceDirVector = new Vector3();
-		const halfSegmentSize = 0.5 / totalSegments;
-
-		for ( let i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {
-
-			position.fromArray( positions, i );
-			normal.copy( position );
-			normal.x -= Math.sign( normal.x ) * halfSegmentSize;
-			normal.y -= Math.sign( normal.y ) * halfSegmentSize;
-			normal.z -= Math.sign( normal.z ) * halfSegmentSize;
-			normal.normalize();
-
-			positions[ i + 0 ] = box.x * Math.sign( position.x ) + normal.x * radius;
-			positions[ i + 1 ] = box.y * Math.sign( position.y ) + normal.y * radius;
-			positions[ i + 2 ] = box.z * Math.sign( position.z ) + normal.z * radius;
-
-			normals[ i + 0 ] = normal.x;
-			normals[ i + 1 ] = normal.y;
-			normals[ i + 2 ] = normal.z;
-
-			const side = Math.floor( i / faceTris );
-
-			switch ( side ) {
-
-				case 0: // right
-
-					// generate UVs along Z then Y
-					faceDirVector.set( 1, 0, 0 );
-					uvs[ j + 0 ] = getUv( faceDirVector, normal, 'z', 'y', radius, depth );
-					uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'z', radius, height );
-					break;
-
-				case 1: // left
-
-					// generate UVs along Z then Y
-					faceDirVector.set( - 1, 0, 0 );
-					uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'z', 'y', radius, depth );
-					uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'z', radius, height );
-					break;
-
-				case 2: // top
-
-					// generate UVs along X then Z
-					faceDirVector.set( 0, 1, 0 );
-					uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'x', 'z', radius, width );
-					uvs[ j + 1 ] = getUv( faceDirVector, normal, 'z', 'x', radius, depth );
-					break;
-
-				case 3: // bottom
-
-					// generate UVs along X then Z
-					faceDirVector.set( 0, - 1, 0 );
-					uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'x', 'z', radius, width );
-					uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'z', 'x', radius, depth );
-					break;
-
-				case 4: // front
-
-					// generate UVs along X then Y
-					faceDirVector.set( 0, 0, 1 );
-					uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'x', 'y', radius, width );
-					uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'x', radius, height );
-					break;
-
-				case 5: // back
-
-					// generate UVs along X then Y
-					faceDirVector.set( 0, 0, - 1 );
-					uvs[ j + 0 ] = getUv( faceDirVector, normal, 'x', 'y', radius, width );
-					uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'x', radius, height );
-					break;
-
-			}
-
-		}
-
-	}
-
-	/**
-	 * Factory method for creating an instance of this class from the given
-	 * JSON object.
-	 *
-	 * @param {Object} data - A JSON object representing the serialized geometry.
-	 * @returns {RoundedBoxGeometry} A new instance.
-	 */
-	static fromJSON( data ) {
-
-		return new RoundedBoxGeometry(
-			data.width,
-			data.height,
-			data.depth,
-			data.segments,
-			data.radius
-		);
-
-	}
-
-
-}
-
-export { RoundedBoxGeometry };

+ 0 - 689
node_modules/three/examples/jsm/geometries/TeapotGeometry.js

@@ -1,689 +0,0 @@
-import {
-	BufferAttribute,
-	BufferGeometry,
-	Matrix4,
-	Vector3,
-	Vector4
-} from 'three';
-
-/**
- * Tessellates the famous Utah teapot database by Martin Newell into triangles.
- *
- * The teapot should normally be rendered as a double sided object, since for some
- * patches both sides can be seen, e.g., the gap around the lid and inside the spout.
- *
- * Segments 'n' determines the number of triangles output. Total triangles = 32*2*n*n - 8*n
- * (degenerates at the top and bottom cusps are deleted).
- *
- * Code based on [SPD software](http://tog.acm.org/resources/SPD/)
- * Created for the Udacity course [Interactive Rendering](http://bit.ly/ericity)
- *
- * ```js
- * const geometry = new TeapotGeometry( 50, 18 );
- * const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
- * const teapot = new THREE.Mesh( geometry, material );
- * scene.add( teapot );
- * ```
- *
- * @augments BufferGeometry
- * @three_import import { TeapotGeometry } from 'three/addons/geometries/TeapotGeometry.js';
- */
-class TeapotGeometry extends BufferGeometry {
-
-	/**
-	 * Constructs a new teapot geometry.
-	 *
-	 * @param {number} [size=50] - Relative scale of the teapot.
-	 * @param {number} [segments=10] - Number of line segments to subdivide each patch edge.
-	 * @param {boolean} [bottom=true] - Whether the bottom of the teapot is generated or not.
-	 * @param {boolean} [lid=true] - Whether the lid is generated or not.
-	 * @param {boolean} [body=true] - Whether the body is generated or not.
-	 * @param {boolean} [fitLid=true] - Whether the lid is slightly stretched to prevent gaps between the body and lid or not.
-	 * @param {boolean} [blinn=true] -  Whether the teapot is scaled vertically for better aesthetics or not.
-	 */
-	constructor( size = 50, segments = 10, bottom = true, lid = true, body = true, fitLid = true, blinn = true ) {
-
-		// 32 * 4 * 4 Bezier spline patches
-		const teapotPatches = [
-			/*rim*/
-			0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
-			3, 16, 17, 18, 7, 19, 20, 21, 11, 22, 23, 24, 15, 25, 26, 27,
-			18, 28, 29, 30, 21, 31, 32, 33, 24, 34, 35, 36, 27, 37, 38, 39,
-			30, 40, 41, 0, 33, 42, 43, 4, 36, 44, 45, 8, 39, 46, 47, 12,
-			/*body*/
-			12, 13, 14, 15, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
-			15, 25, 26, 27, 51, 60, 61, 62, 55, 63, 64, 65, 59, 66, 67, 68,
-			27, 37, 38, 39, 62, 69, 70, 71, 65, 72, 73, 74, 68, 75, 76, 77,
-			39, 46, 47, 12, 71, 78, 79, 48, 74, 80, 81, 52, 77, 82, 83, 56,
-			56, 57, 58, 59, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
-			59, 66, 67, 68, 87, 96, 97, 98, 91, 99, 100, 101, 95, 102, 103, 104,
-			68, 75, 76, 77, 98, 105, 106, 107, 101, 108, 109, 110, 104, 111, 112, 113,
-			77, 82, 83, 56, 107, 114, 115, 84, 110, 116, 117, 88, 113, 118, 119, 92,
-			/*handle*/
-			120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135,
-			123, 136, 137, 120, 127, 138, 139, 124, 131, 140, 141, 128, 135, 142, 143, 132,
-			132, 133, 134, 135, 144, 145, 146, 147, 148, 149, 150, 151, 68, 152, 153, 154,
-			135, 142, 143, 132, 147, 155, 156, 144, 151, 157, 158, 148, 154, 159, 160, 68,
-			/*spout*/
-			161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176,
-			164, 177, 178, 161, 168, 179, 180, 165, 172, 181, 182, 169, 176, 183, 184, 173,
-			173, 174, 175, 176, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,
-			176, 183, 184, 173, 188, 197, 198, 185, 192, 199, 200, 189, 196, 201, 202, 193,
-			/*lid*/
-			203, 203, 203, 203, 204, 205, 206, 207, 208, 208, 208, 208, 209, 210, 211, 212,
-			203, 203, 203, 203, 207, 213, 214, 215, 208, 208, 208, 208, 212, 216, 217, 218,
-			203, 203, 203, 203, 215, 219, 220, 221, 208, 208, 208, 208, 218, 222, 223, 224,
-			203, 203, 203, 203, 221, 225, 226, 204, 208, 208, 208, 208, 224, 227, 228, 209,
-			209, 210, 211, 212, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240,
-			212, 216, 217, 218, 232, 241, 242, 243, 236, 244, 245, 246, 240, 247, 248, 249,
-			218, 222, 223, 224, 243, 250, 251, 252, 246, 253, 254, 255, 249, 256, 257, 258,
-			224, 227, 228, 209, 252, 259, 260, 229, 255, 261, 262, 233, 258, 263, 264, 237,
-			/*bottom*/
-			265, 265, 265, 265, 266, 267, 268, 269, 270, 271, 272, 273, 92, 119, 118, 113,
-			265, 265, 265, 265, 269, 274, 275, 276, 273, 277, 278, 279, 113, 112, 111, 104,
-			265, 265, 265, 265, 276, 280, 281, 282, 279, 283, 284, 285, 104, 103, 102, 95,
-			265, 265, 265, 265, 282, 286, 287, 266, 285, 288, 289, 270, 95, 94, 93, 92
-		];
-
-		const teapotVertices = [
-			1.4, 0, 2.4,
-			1.4, - 0.784, 2.4,
-			0.784, - 1.4, 2.4,
-			0, - 1.4, 2.4,
-			1.3375, 0, 2.53125,
-			1.3375, - 0.749, 2.53125,
-			0.749, - 1.3375, 2.53125,
-			0, - 1.3375, 2.53125,
-			1.4375, 0, 2.53125,
-			1.4375, - 0.805, 2.53125,
-			0.805, - 1.4375, 2.53125,
-			0, - 1.4375, 2.53125,
-			1.5, 0, 2.4,
-			1.5, - 0.84, 2.4,
-			0.84, - 1.5, 2.4,
-			0, - 1.5, 2.4,
-			- 0.784, - 1.4, 2.4,
-			- 1.4, - 0.784, 2.4,
-			- 1.4, 0, 2.4,
-			- 0.749, - 1.3375, 2.53125,
-			- 1.3375, - 0.749, 2.53125,
-			- 1.3375, 0, 2.53125,
-			- 0.805, - 1.4375, 2.53125,
-			- 1.4375, - 0.805, 2.53125,
-			- 1.4375, 0, 2.53125,
-			- 0.84, - 1.5, 2.4,
-			- 1.5, - 0.84, 2.4,
-			- 1.5, 0, 2.4,
-			- 1.4, 0.784, 2.4,
-			- 0.784, 1.4, 2.4,
-			0, 1.4, 2.4,
-			- 1.3375, 0.749, 2.53125,
-			- 0.749, 1.3375, 2.53125,
-			0, 1.3375, 2.53125,
-			- 1.4375, 0.805, 2.53125,
-			- 0.805, 1.4375, 2.53125,
-			0, 1.4375, 2.53125,
-			- 1.5, 0.84, 2.4,
-			- 0.84, 1.5, 2.4,
-			0, 1.5, 2.4,
-			0.784, 1.4, 2.4,
-			1.4, 0.784, 2.4,
-			0.749, 1.3375, 2.53125,
-			1.3375, 0.749, 2.53125,
-			0.805, 1.4375, 2.53125,
-			1.4375, 0.805, 2.53125,
-			0.84, 1.5, 2.4,
-			1.5, 0.84, 2.4,
-			1.75, 0, 1.875,
-			1.75, - 0.98, 1.875,
-			0.98, - 1.75, 1.875,
-			0, - 1.75, 1.875,
-			2, 0, 1.35,
-			2, - 1.12, 1.35,
-			1.12, - 2, 1.35,
-			0, - 2, 1.35,
-			2, 0, 0.9,
-			2, - 1.12, 0.9,
-			1.12, - 2, 0.9,
-			0, - 2, 0.9,
-			- 0.98, - 1.75, 1.875,
-			- 1.75, - 0.98, 1.875,
-			- 1.75, 0, 1.875,
-			- 1.12, - 2, 1.35,
-			- 2, - 1.12, 1.35,
-			- 2, 0, 1.35,
-			- 1.12, - 2, 0.9,
-			- 2, - 1.12, 0.9,
-			- 2, 0, 0.9,
-			- 1.75, 0.98, 1.875,
-			- 0.98, 1.75, 1.875,
-			0, 1.75, 1.875,
-			- 2, 1.12, 1.35,
-			- 1.12, 2, 1.35,
-			0, 2, 1.35,
-			- 2, 1.12, 0.9,
-			- 1.12, 2, 0.9,
-			0, 2, 0.9,
-			0.98, 1.75, 1.875,
-			1.75, 0.98, 1.875,
-			1.12, 2, 1.35,
-			2, 1.12, 1.35,
-			1.12, 2, 0.9,
-			2, 1.12, 0.9,
-			2, 0, 0.45,
-			2, - 1.12, 0.45,
-			1.12, - 2, 0.45,
-			0, - 2, 0.45,
-			1.5, 0, 0.225,
-			1.5, - 0.84, 0.225,
-			0.84, - 1.5, 0.225,
-			0, - 1.5, 0.225,
-			1.5, 0, 0.15,
-			1.5, - 0.84, 0.15,
-			0.84, - 1.5, 0.15,
-			0, - 1.5, 0.15,
-			- 1.12, - 2, 0.45,
-			- 2, - 1.12, 0.45,
-			- 2, 0, 0.45,
-			- 0.84, - 1.5, 0.225,
-			- 1.5, - 0.84, 0.225,
-			- 1.5, 0, 0.225,
-			- 0.84, - 1.5, 0.15,
-			- 1.5, - 0.84, 0.15,
-			- 1.5, 0, 0.15,
-			- 2, 1.12, 0.45,
-			- 1.12, 2, 0.45,
-			0, 2, 0.45,
-			- 1.5, 0.84, 0.225,
-			- 0.84, 1.5, 0.225,
-			0, 1.5, 0.225,
-			- 1.5, 0.84, 0.15,
-			- 0.84, 1.5, 0.15,
-			0, 1.5, 0.15,
-			1.12, 2, 0.45,
-			2, 1.12, 0.45,
-			0.84, 1.5, 0.225,
-			1.5, 0.84, 0.225,
-			0.84, 1.5, 0.15,
-			1.5, 0.84, 0.15,
-			- 1.6, 0, 2.025,
-			- 1.6, - 0.3, 2.025,
-			- 1.5, - 0.3, 2.25,
-			- 1.5, 0, 2.25,
-			- 2.3, 0, 2.025,
-			- 2.3, - 0.3, 2.025,
-			- 2.5, - 0.3, 2.25,
-			- 2.5, 0, 2.25,
-			- 2.7, 0, 2.025,
-			- 2.7, - 0.3, 2.025,
-			- 3, - 0.3, 2.25,
-			- 3, 0, 2.25,
-			- 2.7, 0, 1.8,
-			- 2.7, - 0.3, 1.8,
-			- 3, - 0.3, 1.8,
-			- 3, 0, 1.8,
-			- 1.5, 0.3, 2.25,
-			- 1.6, 0.3, 2.025,
-			- 2.5, 0.3, 2.25,
-			- 2.3, 0.3, 2.025,
-			- 3, 0.3, 2.25,
-			- 2.7, 0.3, 2.025,
-			- 3, 0.3, 1.8,
-			- 2.7, 0.3, 1.8,
-			- 2.7, 0, 1.575,
-			- 2.7, - 0.3, 1.575,
-			- 3, - 0.3, 1.35,
-			- 3, 0, 1.35,
-			- 2.5, 0, 1.125,
-			- 2.5, - 0.3, 1.125,
-			- 2.65, - 0.3, 0.9375,
-			- 2.65, 0, 0.9375,
-			- 2, - 0.3, 0.9,
-			- 1.9, - 0.3, 0.6,
-			- 1.9, 0, 0.6,
-			- 3, 0.3, 1.35,
-			- 2.7, 0.3, 1.575,
-			- 2.65, 0.3, 0.9375,
-			- 2.5, 0.3, 1.125,
-			- 1.9, 0.3, 0.6,
-			- 2, 0.3, 0.9,
-			1.7, 0, 1.425,
-			1.7, - 0.66, 1.425,
-			1.7, - 0.66, 0.6,
-			1.7, 0, 0.6,
-			2.6, 0, 1.425,
-			2.6, - 0.66, 1.425,
-			3.1, - 0.66, 0.825,
-			3.1, 0, 0.825,
-			2.3, 0, 2.1,
-			2.3, - 0.25, 2.1,
-			2.4, - 0.25, 2.025,
-			2.4, 0, 2.025,
-			2.7, 0, 2.4,
-			2.7, - 0.25, 2.4,
-			3.3, - 0.25, 2.4,
-			3.3, 0, 2.4,
-			1.7, 0.66, 0.6,
-			1.7, 0.66, 1.425,
-			3.1, 0.66, 0.825,
-			2.6, 0.66, 1.425,
-			2.4, 0.25, 2.025,
-			2.3, 0.25, 2.1,
-			3.3, 0.25, 2.4,
-			2.7, 0.25, 2.4,
-			2.8, 0, 2.475,
-			2.8, - 0.25, 2.475,
-			3.525, - 0.25, 2.49375,
-			3.525, 0, 2.49375,
-			2.9, 0, 2.475,
-			2.9, - 0.15, 2.475,
-			3.45, - 0.15, 2.5125,
-			3.45, 0, 2.5125,
-			2.8, 0, 2.4,
-			2.8, - 0.15, 2.4,
-			3.2, - 0.15, 2.4,
-			3.2, 0, 2.4,
-			3.525, 0.25, 2.49375,
-			2.8, 0.25, 2.475,
-			3.45, 0.15, 2.5125,
-			2.9, 0.15, 2.475,
-			3.2, 0.15, 2.4,
-			2.8, 0.15, 2.4,
-			0, 0, 3.15,
-			0.8, 0, 3.15,
-			0.8, - 0.45, 3.15,
-			0.45, - 0.8, 3.15,
-			0, - 0.8, 3.15,
-			0, 0, 2.85,
-			0.2, 0, 2.7,
-			0.2, - 0.112, 2.7,
-			0.112, - 0.2, 2.7,
-			0, - 0.2, 2.7,
-			- 0.45, - 0.8, 3.15,
-			- 0.8, - 0.45, 3.15,
-			- 0.8, 0, 3.15,
-			- 0.112, - 0.2, 2.7,
-			- 0.2, - 0.112, 2.7,
-			- 0.2, 0, 2.7,
-			- 0.8, 0.45, 3.15,
-			- 0.45, 0.8, 3.15,
-			0, 0.8, 3.15,
-			- 0.2, 0.112, 2.7,
-			- 0.112, 0.2, 2.7,
-			0, 0.2, 2.7,
-			0.45, 0.8, 3.15,
-			0.8, 0.45, 3.15,
-			0.112, 0.2, 2.7,
-			0.2, 0.112, 2.7,
-			0.4, 0, 2.55,
-			0.4, - 0.224, 2.55,
-			0.224, - 0.4, 2.55,
-			0, - 0.4, 2.55,
-			1.3, 0, 2.55,
-			1.3, - 0.728, 2.55,
-			0.728, - 1.3, 2.55,
-			0, - 1.3, 2.55,
-			1.3, 0, 2.4,
-			1.3, - 0.728, 2.4,
-			0.728, - 1.3, 2.4,
-			0, - 1.3, 2.4,
-			- 0.224, - 0.4, 2.55,
-			- 0.4, - 0.224, 2.55,
-			- 0.4, 0, 2.55,
-			- 0.728, - 1.3, 2.55,
-			- 1.3, - 0.728, 2.55,
-			- 1.3, 0, 2.55,
-			- 0.728, - 1.3, 2.4,
-			- 1.3, - 0.728, 2.4,
-			- 1.3, 0, 2.4,
-			- 0.4, 0.224, 2.55,
-			- 0.224, 0.4, 2.55,
-			0, 0.4, 2.55,
-			- 1.3, 0.728, 2.55,
-			- 0.728, 1.3, 2.55,
-			0, 1.3, 2.55,
-			- 1.3, 0.728, 2.4,
-			- 0.728, 1.3, 2.4,
-			0, 1.3, 2.4,
-			0.224, 0.4, 2.55,
-			0.4, 0.224, 2.55,
-			0.728, 1.3, 2.55,
-			1.3, 0.728, 2.55,
-			0.728, 1.3, 2.4,
-			1.3, 0.728, 2.4,
-			0, 0, 0,
-			1.425, 0, 0,
-			1.425, 0.798, 0,
-			0.798, 1.425, 0,
-			0, 1.425, 0,
-			1.5, 0, 0.075,
-			1.5, 0.84, 0.075,
-			0.84, 1.5, 0.075,
-			0, 1.5, 0.075,
-			- 0.798, 1.425, 0,
-			- 1.425, 0.798, 0,
-			- 1.425, 0, 0,
-			- 0.84, 1.5, 0.075,
-			- 1.5, 0.84, 0.075,
-			- 1.5, 0, 0.075,
-			- 1.425, - 0.798, 0,
-			- 0.798, - 1.425, 0,
-			0, - 1.425, 0,
-			- 1.5, - 0.84, 0.075,
-			- 0.84, - 1.5, 0.075,
-			0, - 1.5, 0.075,
-			0.798, - 1.425, 0,
-			1.425, - 0.798, 0,
-			0.84, - 1.5, 0.075,
-			1.5, - 0.84, 0.075
-		];
-
-		super();
-
-		// number of segments per patch
-		segments = Math.max( 2, Math.floor( segments ) );
-
-		// Jim Blinn scaled the teapot down in size by about 1.3 for
-		// some rendering tests. He liked the new proportions that he kept
-		// the data in this form. The model was distributed with these new
-		// proportions and became the norm. Trivia: comparing images of the
-		// real teapot and the computer model, the ratio for the bowl of the
-		// real teapot is more like 1.25, but since 1.3 is the traditional
-		// value given, we use it here.
-		const blinnScale = 1.3;
-
-		// scale the size to be the real scaling factor
-		const maxHeight = 3.15 * ( blinn ? 1 : blinnScale );
-
-		const maxHeight2 = maxHeight / 2;
-		const trueSize = size / maxHeight2;
-
-		// Number of elements depends on what is needed. Subtract degenerate
-		// triangles at tip of bottom and lid out in advance.
-		let numTriangles = bottom ? ( 8 * segments - 4 ) * segments : 0;
-		numTriangles += lid ? ( 16 * segments - 4 ) * segments : 0;
-		numTriangles += body ? 40 * segments * segments : 0;
-
-		const indices = new Uint32Array( numTriangles * 3 );
-
-		let numVertices = bottom ? 4 : 0;
-		numVertices += lid ? 8 : 0;
-		numVertices += body ? 20 : 0;
-		numVertices *= ( segments + 1 ) * ( segments + 1 );
-
-		const vertices = new Float32Array( numVertices * 3 );
-		const normals = new Float32Array( numVertices * 3 );
-		const uvs = new Float32Array( numVertices * 2 );
-
-		// Bezier form
-		const ms = new Matrix4();
-		ms.set(
-			- 1.0, 3.0, - 3.0, 1.0,
-			3.0, - 6.0, 3.0, 0.0,
-			- 3.0, 3.0, 0.0, 0.0,
-			1.0, 0.0, 0.0, 0.0 );
-
-		const g = [];
-
-		const sp = [];
-		const tp = [];
-		const dsp = [];
-		const dtp = [];
-
-		// M * G * M matrix, sort of see
-		// http://www.cs.helsinki.fi/group/goa/mallinnus/curves/surfaces.html
-		const mgm = [];
-
-		const vert = [];
-		const sdir = [];
-		const tdir = [];
-
-		const norm = new Vector3();
-
-		let tcoord;
-
-		let sval;
-		let tval;
-		let p;
-		let dsval = 0;
-		let dtval = 0;
-
-		const normOut = new Vector3();
-
-		const gmx = new Matrix4();
-		const tmtx = new Matrix4();
-
-		const vsp = new Vector4();
-		const vtp = new Vector4();
-		const vdsp = new Vector4();
-		const vdtp = new Vector4();
-
-		const vsdir = new Vector3();
-		const vtdir = new Vector3();
-
-		const mst = ms.clone();
-		mst.transpose();
-
-		// internal function: test if triangle has any matching vertices;
-		// if so, don't save triangle, since it won't display anything.
-		const notDegenerate = ( vtx1, vtx2, vtx3 ) => // if any vertex matches, return false
-			! ( ( ( vertices[ vtx1 * 3 ] === vertices[ vtx2 * 3 ] ) &&
-					( vertices[ vtx1 * 3 + 1 ] === vertices[ vtx2 * 3 + 1 ] ) &&
-					( vertices[ vtx1 * 3 + 2 ] === vertices[ vtx2 * 3 + 2 ] ) ) ||
-					( ( vertices[ vtx1 * 3 ] === vertices[ vtx3 * 3 ] ) &&
-					( vertices[ vtx1 * 3 + 1 ] === vertices[ vtx3 * 3 + 1 ] ) &&
-					( vertices[ vtx1 * 3 + 2 ] === vertices[ vtx3 * 3 + 2 ] ) ) || ( vertices[ vtx2 * 3 ] === vertices[ vtx3 * 3 ] ) &&
-					( vertices[ vtx2 * 3 + 1 ] === vertices[ vtx3 * 3 + 1 ] ) &&
-					( vertices[ vtx2 * 3 + 2 ] === vertices[ vtx3 * 3 + 2 ] ) );
-
-
-		for ( let i = 0; i < 3; i ++ ) {
-
-			mgm[ i ] = new Matrix4();
-
-		}
-
-		const minPatches = body ? 0 : 20;
-		const maxPatches = bottom ? 32 : 28;
-
-		const vertPerRow = segments + 1;
-
-		let surfCount = 0;
-
-		let vertCount = 0;
-		let normCount = 0;
-		let uvCount = 0;
-
-		let indexCount = 0;
-
-		for ( let surf = minPatches; surf < maxPatches; surf ++ ) {
-
-			// lid is in the middle of the data, patches 20-27,
-			// so ignore it for this part of the loop if the lid is not desired
-			if ( lid || ( surf < 20 || surf >= 28 ) ) {
-
-				// get M * G * M matrix for x,y,z
-				for ( let i = 0; i < 3; i ++ ) {
-
-					// get control patches
-					for ( let r = 0; r < 4; r ++ ) {
-
-						for ( let c = 0; c < 4; c ++ ) {
-
-							// transposed
-							g[ c * 4 + r ] = teapotVertices[ teapotPatches[ surf * 16 + r * 4 + c ] * 3 + i ];
-
-							// is the lid to be made larger, and is this a point on the lid
-							// that is X or Y?
-							if ( fitLid && ( surf >= 20 && surf < 28 ) && ( i !== 2 ) ) {
-
-								// increase XY size by 7.7%, found empirically. I don't
-								// increase Z so that the teapot will continue to fit in the
-								// space -1 to 1 for Y (Y is up for the final model).
-								g[ c * 4 + r ] *= 1.077;
-
-							}
-
-							// Blinn "fixed" the teapot by dividing Z by blinnScale, and that's the
-							// data we now use. The original teapot is taller. Fix it:
-							if ( ! blinn && ( i === 2 ) ) {
-
-								g[ c * 4 + r ] *= blinnScale;
-
-							}
-
-						}
-
-					}
-
-					gmx.set( g[ 0 ], g[ 1 ], g[ 2 ], g[ 3 ], g[ 4 ], g[ 5 ], g[ 6 ], g[ 7 ], g[ 8 ], g[ 9 ], g[ 10 ], g[ 11 ], g[ 12 ], g[ 13 ], g[ 14 ], g[ 15 ] );
-
-					tmtx.multiplyMatrices( gmx, ms );
-					mgm[ i ].multiplyMatrices( mst, tmtx );
-
-				}
-
-				// step along, get points, and output
-				for ( let sstep = 0; sstep <= segments; sstep ++ ) {
-
-					const s = sstep / segments;
-
-					for ( let tstep = 0; tstep <= segments; tstep ++ ) {
-
-						const t = tstep / segments;
-
-						// point from basis
-						// get power vectors and their derivatives
-						for ( p = 4, sval = tval = 1.0; p --; ) {
-
-							sp[ p ] = sval;
-							tp[ p ] = tval;
-							sval *= s;
-							tval *= t;
-
-							if ( p === 3 ) {
-
-								dsp[ p ] = dtp[ p ] = 0.0;
-								dsval = dtval = 1.0;
-
-							} else {
-
-								dsp[ p ] = dsval * ( 3 - p );
-								dtp[ p ] = dtval * ( 3 - p );
-								dsval *= s;
-								dtval *= t;
-
-							}
-
-						}
-
-						vsp.fromArray( sp );
-						vtp.fromArray( tp );
-						vdsp.fromArray( dsp );
-						vdtp.fromArray( dtp );
-
-						// do for x,y,z
-						for ( let i = 0; i < 3; i ++ ) {
-
-							// multiply power vectors times matrix to get value
-							tcoord = vsp.clone();
-							tcoord.applyMatrix4( mgm[ i ] );
-							vert[ i ] = tcoord.dot( vtp );
-
-							// get s and t tangent vectors
-							tcoord = vdsp.clone();
-							tcoord.applyMatrix4( mgm[ i ] );
-							sdir[ i ] = tcoord.dot( vtp );
-
-							tcoord = vsp.clone();
-							tcoord.applyMatrix4( mgm[ i ] );
-							tdir[ i ] = tcoord.dot( vdtp );
-
-						}
-
-						// find normal
-						vsdir.fromArray( sdir );
-						vtdir.fromArray( tdir );
-						norm.crossVectors( vtdir, vsdir );
-						norm.normalize();
-
-						// if X and Z length is 0, at the cusp, so point the normal up or down, depending on patch number
-						if ( vert[ 0 ] === 0 && vert[ 1 ] === 0 ) {
-
-							// if above the middle of the teapot, normal points up, else down
-							normOut.set( 0, vert[ 2 ] > maxHeight2 ? 1 : - 1, 0 );
-
-						} else {
-
-							// standard output: rotate on X axis
-							normOut.set( norm.x, norm.z, - norm.y );
-
-						}
-
-						// store it all
-						vertices[ vertCount ++ ] = trueSize * vert[ 0 ];
-						vertices[ vertCount ++ ] = trueSize * ( vert[ 2 ] - maxHeight2 );
-						vertices[ vertCount ++ ] = - trueSize * vert[ 1 ];
-
-						normals[ normCount ++ ] = normOut.x;
-						normals[ normCount ++ ] = normOut.y;
-						normals[ normCount ++ ] = normOut.z;
-
-						uvs[ uvCount ++ ] = 1 - t;
-						uvs[ uvCount ++ ] = 1 - s;
-
-					}
-
-				}
-
-				// save the faces
-				for ( let sstep = 0; sstep < segments; sstep ++ ) {
-
-					for ( let tstep = 0; tstep < segments; tstep ++ ) {
-
-						const v1 = surfCount * vertPerRow * vertPerRow + sstep * vertPerRow + tstep;
-						const v2 = v1 + 1;
-						const v3 = v2 + vertPerRow;
-						const v4 = v1 + vertPerRow;
-
-						// Normals and UVs cannot be shared. Without clone(), you can see the consequences
-						// of sharing if you call geometry.applyMatrix4( matrix ).
-						if ( notDegenerate( v1, v2, v3 ) ) {
-
-							indices[ indexCount ++ ] = v1;
-							indices[ indexCount ++ ] = v2;
-							indices[ indexCount ++ ] = v3;
-
-						}
-
-						if ( notDegenerate( v1, v3, v4 ) ) {
-
-							indices[ indexCount ++ ] = v1;
-							indices[ indexCount ++ ] = v3;
-							indices[ indexCount ++ ] = v4;
-
-						}
-
-					}
-
-				}
-
-				// increment only if a surface was used
-				surfCount ++;
-
-			}
-
-		}
-
-		this.setIndex( new BufferAttribute( indices, 1 ) );
-		this.setAttribute( 'position', new BufferAttribute( vertices, 3 ) );
-		this.setAttribute( 'normal', new BufferAttribute( normals, 3 ) );
-		this.setAttribute( 'uv', new BufferAttribute( uvs, 2 ) );
-
-		this.computeBoundingSphere();
-
-	}
-
-}
-
-export { TeapotGeometry };

+ 0 - 102
node_modules/three/examples/jsm/geometries/TextGeometry.js

@@ -1,102 +0,0 @@
-import {
-	ExtrudeGeometry
-} from 'three';
-
-import { Font } from '../loaders/FontLoader.js';
-
-/**
- * A class for generating text as a single geometry. It is constructed by providing a string of text, and a set of
- * parameters consisting of a loaded font and extrude settings.
- *
- * See the {@link FontLoader} page for additional details.
- *
- * `TextGeometry` uses [typeface.json](http://gero3.github.io/facetype.js/) generated fonts.
- * Some existing fonts can be found located in `/examples/fonts`.
- *
- * ```js
- * const loader = new FontLoader();
- * const font = await loader.loadAsync( 'fonts/helvetiker_regular.typeface.json' );
- * const geometry = new TextGeometry( 'Hello three.js!', {
- * 	font: font,
- * 	size: 80,
- * 	depth: 5,
- * 	curveSegments: 12
- * } );
- * ```
- *
- * @augments ExtrudeGeometry
- * @three_import import { TextGeometry } from 'three/addons/geometries/TextGeometry.js';
- */
-class TextGeometry extends ExtrudeGeometry {
-
-	/**
-	 * Constructs a new text geometry.
-	 *
-	 * @param {string} text - The text that should be transformed into a geometry.
-	 * @param {TextGeometry~Options} [parameters] - The text settings.
-	 */
-	constructor( text, parameters = {} ) {
-
-		const font = parameters.font;
-
-		if ( font === undefined ) {
-
-			super(); // generate default extrude geometry
-
-		} else {
-
-			const shapes = font.generateShapes( text, parameters.size, parameters.direction );
-
-			// defaults
-
-			if ( parameters.depth === undefined ) parameters.depth = 50;
-			if ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;
-			if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;
-			if ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;
-
-			super( shapes, parameters );
-
-		}
-
-		this.type = 'TextGeometry';
-
-	}
-
-	toJSON() {
-
-		const data = super.toJSON();
-		return data;
-
-	}
-
-	static fromJSON( data ) {
-
-		const options = data.options;
-
-		options.font = new Font( options.font.data );
-		return new TextGeometry( options.text, options );
-
-	}
-
-}
-
-/**
- * Represents the `options` type of the geometry's constructor.
- *
- * @typedef {Object} TextGeometry~Options
- * @property {Font} [font] - The font.
- * @property {number} [size=100] - The text size.
- * @property {number} [depth=50] - Depth to extrude the shape.
- * @property {number} [curveSegments=12] - Number of points on the curves.
- * @property {number} [steps=1] - Number of points used for subdividing segments along the depth of the extruded spline.
- * @property {boolean} [bevelEnabled=false] - Whether to beveling to the shape or not.
- * @property {number} [bevelThickness=10] - How deep into the original shape the bevel goes.
- * @property {number} [bevelSize=8] - Distance from the shape outline that the bevel extends.
- * @property {number} [bevelOffset=0] - Distance from the shape outline that the bevel starts.
- * @property {number} [bevelSegments=3] - Number of bevel layers.
- * @property {string} [direction='ltr'] - Char direction: ltr(left to right), rtl(right to left) & tb(top bottom).
- * @property {?Curve} [extrudePath=null] - A 3D spline path along which the shape should be extruded. Bevels not supported for path extrusion.
- * @property {Object} [UVGenerator] - An object that provides UV generator functions for custom UV generation.
- **/
-
-export { TextGeometry };

+ 0 - 715
node_modules/three/examples/jsm/gpgpu/BitonicSort.js

@@ -1,715 +0,0 @@
-import { Fn, uvec2, If, instancedArray, instanceIndex, invocationLocalIndex, Loop, workgroupArray, workgroupBarrier, workgroupId, uint, select, min, max } from 'three/tsl';
-
-const StepType = {
-	NONE: 0,
-	// Swap all values within the local range of workgroupSize * 2
-	SWAP_LOCAL: 1,
-	DISPERSE_LOCAL: 2,
-	// Swap values within global data buffer.
-	FLIP_GLOBAL: 3,
-	DISPERSE_GLOBAL: 4,
-};
-
-
-/**
- * Returns the indices that will be compared in a bitonic flip operation.
- *
- * @tsl
- * @private
- * @param {Node<uint>} index - The compute thread's invocation id.
- * @param {Node<uint>} blockHeight - The height of the block within which elements are being swapped.
- * @returns {Node<uvec2>} The indices of the elements in the data buffer being compared.
- */
-export const getBitonicFlipIndices = /*@__PURE__*/ Fn( ( [ index, blockHeight ] ) => {
-
-	const blockOffset = ( index.mul( 2 ).div( blockHeight ) ).mul( blockHeight );
-	const halfHeight = blockHeight.div( 2 );
-	const idx = uvec2(
-		index.mod( halfHeight ),
-		blockHeight.sub( index.mod( halfHeight ) ).sub( 1 )
-	);
-	idx.x.addAssign( blockOffset );
-	idx.y.addAssign( blockOffset );
-
-	return idx;
-
-} ).setLayout( {
-	name: 'getBitonicFlipIndices',
-	type: 'uvec2',
-	inputs: [
-		{ name: 'index', type: 'uint' },
-		{ name: 'blockHeight', type: 'uint' }
-	]
-} );
-
-/**
- * Returns the indices that will be compared in a bitonic sort's disperse operation.
- *
- * @tsl
- * @private
- * @param {Node<uint>} index - The compute thread's invocation id.
- * @param {Node<uint>} swapSpan - The maximum span over which elements are being swapped.
- * @returns {Node<uvec2>} The indices of the elements in the data buffer being compared.
- */
-export const getBitonicDisperseIndices = /*@__PURE__*/ Fn( ( [ index, swapSpan ] ) => {
-
-	const blockOffset = ( ( index.mul( 2 ) ).div( swapSpan ) ).mul( swapSpan );
-	const halfHeight = swapSpan.div( 2 );
-	const idx = uvec2(
-		index.mod( halfHeight ),
-		( index.mod( halfHeight ) ).add( halfHeight )
-	);
-
-	idx.x.addAssign( blockOffset );
-	idx.y.addAssign( blockOffset );
-
-	return idx;
-
-} ).setLayout( {
-	name: 'getBitonicDisperseIndices',
-	type: 'uvec2',
-	inputs: [
-		{ name: 'index', type: 'uint' },
-		{ name: 'blockHeight', type: 'uint' }
-	]
-} );
-
-export class BitonicSort {
-
-	/**
-	 * Constructs a new light probe helper.
-	 *
-	 * @param {Renderer} renderer - The current scene's renderer.
-	 * @param {StorageBufferNode} dataBuffer - The data buffer to sort.
-	 * @param {Object} [options={}] - Options that modify the bitonic sort.
-	 */
-	constructor( renderer, dataBuffer, options = {} ) {
-
-		/**
-		 * A reference to the renderer.
-		 *
-		 * @type {Renderer}
-		 */
-		this.renderer = renderer;
-
-		/**
-		 * A reference to the StorageBufferNode holding the data that will be sorted  .
-		 *
-		 * @type {StorageBufferNode}
-		 */
-		this.dataBuffer = dataBuffer;
-
-		/**
-		 * The size of the data.
-		 *
-		 * @type {StorageBufferNode}
-		 */
-		this.count = dataBuffer.value.count;
-
-		/**
-		 *
-		 * The size of each compute dispatch.
-		 * @type {number}
-		 */
-
-		 this.dispatchSize = this.count / 2;
-
-		/**
-		 * The workgroup size of the compute shaders executed during the sort.
-		 *
-		 * @type {StorageBufferNode}
-		*/
-		this.workgroupSize = options.workgroupSize ? Math.min( this.dispatchSize, options.workgroupSize ) : Math.min( this.dispatchSize, 64 );
-
-		/**
-		 * A node representing a workgroup scoped buffer that holds locally sorted elements.
-		 *
-		 * @type {WorkgroupInfoNode}
-		*/
-		this.localStorage = workgroupArray( dataBuffer.nodeType, this.workgroupSize * 2 );
-
-		this._tempArray = new Uint32Array( this.count );
-		for ( let i = 0; i < this.count; i ++ ) {
-
-			this._tempArray[ i ] = 0;
-
-		}
-
-		/**
-		 * A node representing a storage buffer used for transferring the result of the global sort back to the original data buffer.
-		 *
-		 * @type {StorageBufferNode}
-		*/
-		this.tempBuffer = instancedArray( this.count, dataBuffer.nodeType ).setName( 'TempStorage' );
-
-		/**
-		 * A node containing the current algorithm type, the current swap span, and the highest swap span.
-		 *
-		 * @type {StorageBufferNode}
-		*/
-		this.infoStorage = instancedArray( new Uint32Array( [ 1, 2, 2 ] ), 'uint' ).setName( 'BitonicSortInfo' );
-
-
-		/**
-		 * The number of distinct swap operations ('flips' and 'disperses') executed in an in-place
-		 * bitonic sort of the current data buffer.
-		 *
-		 * @type {number}
-		*/
-		this.swapOpCount = this._getSwapOpCount();
-
-		/**
-		 * The number of steps (i.e prepping and/or executing a swap) needed to fully execute an in-place bitonic sort of the current data buffer.
-		 *
-		 * @type {number}
-		*/
-		this.stepCount = this._getStepCount();
-
-		/**
-		 * The number of the buffer being read from.
-		 *
-		 * @type {string}
-		*/
-		this.readBufferName = 'Data';
-
-		/**
-		 * An object containing compute shaders that execute a 'flip' swap within a global address space on elements in the data buffer.
-		 *
-		 * @type {Object<string, ComputeNode>}
-		*/
-		this.flipGlobalNodes = {
-			'Data': this._getFlipGlobal( this.dataBuffer, this.tempBuffer ),
-			'Temp': this._getFlipGlobal( this.tempBuffer, this.dataBuffer )
-		};
-
-		/**
-		 * An object containing compute shaders that execute a 'disperse' swap within a global address space on elements in the data buffer.
-		 *
-		 * @type {Object<string, ComputeNode>}
-		*/
-		this.disperseGlobalNodes = {
-			'Data': this._getDisperseGlobal( this.dataBuffer, this.tempBuffer ),
-			'Temp': this._getDisperseGlobal( this.tempBuffer, this.dataBuffer )
-		};
-
-		/**
-		 * A compute shader that executes a sequence of flip and disperse swaps within a local address space on elements in the data buffer.
-		 *
-		 * @type {ComputeNode}
-		*/
-		this.swapLocalFn = this._getSwapLocal();
-
-		/**
-		 * A compute shader that executes a sequence of disperse swaps within a local address space on elements in the data buffer.
-		 *
-		 * @type {Object<string, ComputeNode>}
-		*/
-		this.disperseLocalNodes = {
-			'Data': this._getDisperseLocal( this.dataBuffer ),
-			'Temp': this._getDisperseLocal( this.tempBuffer ),
-		};
-
-		// Utility functions
-
-		/**
-		 * A compute shader that sets up the algorithm and the swap span for the next swap operation.
-		 *
-		 * @type {ComputeNode}
-		*/
-		this.setAlgoFn = this._getSetAlgoFn();
-
-		/**
-		 * A compute shader that aligns the result of the global swap operation with the current buffer.
-		 *
-		 * @type {ComputeNode}
-		*/
-		this.alignFn = this._getAlignFn();
-
-
-		/**
-		 * A compute shader that resets the algorithm and swap span information.
-		 *
-		 * @type {ComputeNode}
-		*/
-		this.resetFn = this._getResetFn();
-
-
-		/**
-		 * The current compute shader dispatch within the list of dispatches needed to complete the sort.
-		 *
-		 * @type {number}
-		*/
-		this.currentDispatch = 0;
-
-		/**
-		 * The number of global swap operations that must be executed before the sort
-		 * can swap in local address space.
-		 *
-		 * @type {number}
-		*/
-		this.globalOpsRemaining = 0;
-
-		/**
-		 * The total number of global operations needed to sort elements within the current swap span.
-		 *
-		 * @type {number}
-		*/
-		this.globalOpsInSpan = 0;
-
-
-	}
-
-	/**
-	 * Get total number of distinct swaps that occur in a bitonic sort.
-	 *
-	 * @private
-	 * @returns {number} - The total number of distinct swaps in a bitonic sort
-	 */
-	_getSwapOpCount() {
-
-		const n = Math.log2( this.count );
-		return ( n * ( n + 1 ) ) / 2;
-
-	}
-
-	/**
-	 * Get the number of steps it takes to execute a complete bitonic sort.
-	 *
-	 * @private
-	 * @returns {number} The number of steps it takes to execute a complete bitonic sort.
-	 */
-	_getStepCount() {
-
-		const logElements = Math.log2( this.count );
-		const logSwapSpan = Math.log2( this.workgroupSize * 2 );
-
-		const numGlobalFlips = logElements - logSwapSpan;
-
-		// Start with 1 for initial sort over all local elements
-		let numSteps = 1;
-		let numGlobalDisperses = 0;
-
-		for ( let i = 1; i <= numGlobalFlips; i ++ ) {
-
-			// Increment by the global flip that starts each global block
-			numSteps += 1;
-			// Increment by number of global disperses following the global flip
-			numSteps += numGlobalDisperses;
-			// Increment by local disperse that occurs after all global swaps are finished
-			numSteps += 1;
-
-			// Number of global disperse increases as swapSpan increases by factor of 2
-			numGlobalDisperses += 1;
-
-		}
-
-		return numSteps;
-
-	}
-
-	/**
-	 * Compares and swaps two data points in the data buffer within the global address space.
-	 * @param {Node<uint>} idxBefore - The index of the first data element in the data buffer.
-	 * @param {Node<uint>} idxAfter - The index of the second data element in the data buffer.
-	 * @param {StorageBufferNode} dataBuffer - The buffer of data to read from.
-	 * @param {StorageBufferNode} tempBuffer - The buffer of data to write to.
-	 * @private
-	 *
-	 */
-	_globalCompareAndSwapTSL( idxBefore, idxAfter, dataBuffer, tempBuffer ) {
-
-		const data1 = dataBuffer.element( idxBefore );
-		const data2 = dataBuffer.element( idxAfter );
-
-		tempBuffer.element( idxBefore ).assign( min( data1, data2 ) );
-		tempBuffer.element( idxAfter ).assign( max( data1, data2 ) );
-
-	}
-
-	/**
-	 * Compares and swaps two data points in the data buffer within the local address space.
-	 *
-	 * @private
-	 * @param {Node<uint>} idxBefore - The index of the first data element in the data buffer.
-	 * @param {Node<uint>} idxAfter - The index of the second data element in the data buffer
-	 */
-	_localCompareAndSwapTSL( idxBefore, idxAfter ) {
-
-		const { localStorage } = this;
-
-		const data1 = localStorage.element( idxBefore ).toVar();
-		const data2 = localStorage.element( idxAfter ).toVar();
-
-		localStorage.element( idxBefore ).assign( min( data1, data2 ) );
-		localStorage.element( idxAfter ).assign( max( data1, data2 ) );
-
-	}
-
-
-	/**
-	 * Create the compute shader that performs a global disperse swap on the data buffer.
-	 *
-	 * @private
-	 * @param {StorageBufferNode} readBuffer - The data buffer to read from.
-	 * @param {StorageBufferNode} writeBuffer - The data buffer to read from.
-	 * @returns {ComputeNode} - A compute shader that performs a global disperse swap on the data buffer.
-	 */
-	_getDisperseGlobal( readBuffer, writeBuffer ) {
-
-		const { infoStorage } = this;
-
-		const currentSwapSpan = infoStorage.element( 1 );
-
-		const fnDef = Fn( () => {
-
-			const idx = getBitonicDisperseIndices( instanceIndex, currentSwapSpan );
-			this._globalCompareAndSwapTSL( idx.x, idx.y, readBuffer, writeBuffer );
-
-		} )().compute( this.dispatchSize, [ this.workgroupSize ] );
-
-		return fnDef;
-
-	}
-
-	/**
-	 * Create the compute shader that performs a global flip swap on the data buffer.
-	 *
-	 * @private
-	 * @param {StorageBufferNode} readBuffer - The data buffer to read from.
-	 * @param {StorageBufferNode} writeBuffer - The data buffer to read from.
-	 * @returns {ComputeNode} - A compute shader that executes a global flip swap.
-	 */
-	_getFlipGlobal( readBuffer, writeBuffer ) {
-
-		const { infoStorage } = this;
-
-		const currentSwapSpan = infoStorage.element( 1 );
-
-		const fnDef = Fn( () => {
-
-			const idx = getBitonicFlipIndices( instanceIndex, currentSwapSpan );
-			this._globalCompareAndSwapTSL( idx.x, idx.y, readBuffer, writeBuffer );
-
-		} )().compute( this.dispatchSize, [ this.workgroupSize ] );
-
-		return fnDef;
-
-	}
-
-
-	/**
-	 * Create the compute shader that performs a complete local swap on the data buffer.
-	 *
-	 * @private
-	 * @returns {ComputeNode} - A compute shader that executes a full local swap.
-	 */
-	_getSwapLocal() {
-
-		const { localStorage, dataBuffer, workgroupSize } = this;
-
-		const fnDef = Fn( () => {
-
-			// Get ids of indices needed to populate workgroup local buffer.
-			// Use .toVar() to prevent these values from being recalculated multiple times.
-			const localOffset = uint( workgroupSize ).mul( 2 ).mul( workgroupId.x ).toVar();
-
-			const localID1 = invocationLocalIndex.mul( 2 );
-			const localID2 = invocationLocalIndex.mul( 2 ).add( 1 );
-
-			localStorage.element( localID1 ).assign( dataBuffer.element( localOffset.add( localID1 ) ) );
-			localStorage.element( localID2 ).assign( dataBuffer.element( localOffset.add( localID2 ) ) );
-
-			// Ensure that all local data has been populated
-			workgroupBarrier();
-
-			// Perform a chunk of the sort in a single pass that operates entirely in workgroup local space
-			// SWAP_LOCAL will always be first pass, so we start with known block height of 2
-			const flipBlockHeight = uint( 2 );
-
-			Loop( { start: uint( 2 ), end: uint( workgroupSize * 2 ), type: 'uint', condition: '<=', update: '<<= 1' }, () => {
-
-				// Ensure that last dispatch block executed
-				workgroupBarrier();
-
-				const flipIdx = getBitonicFlipIndices( invocationLocalIndex, flipBlockHeight );
-
-				this._localCompareAndSwapTSL( flipIdx.x, flipIdx.y );
-
-				const localBlockHeight = flipBlockHeight.div( 2 );
-
-				Loop( { start: localBlockHeight, end: uint( 1 ), type: 'uint', condition: '>', update: '>>= 1' }, () => {
-
-					// Ensure that last dispatch op executed
-					workgroupBarrier();
-
-					const disperseIdx = getBitonicDisperseIndices( invocationLocalIndex, localBlockHeight );
-					this._localCompareAndSwapTSL( disperseIdx.x, disperseIdx.y );
-
-					localBlockHeight.divAssign( 2 );
-
-				} );
-
-				// flipBlockHeight *= 2;
-				flipBlockHeight.shiftLeftAssign( 1 );
-
-			} );
-
-			// Ensure that all invocations have swapped their own regions of data
-			workgroupBarrier();
-
-			dataBuffer.element( localOffset.add( localID1 ) ).assign( localStorage.element( localID1 ) );
-			dataBuffer.element( localOffset.add( localID2 ) ).assign( localStorage.element( localID2 ) );
-
-		} )().compute( this.dispatchSize, [ this.workgroupSize ] );
-
-		return fnDef;
-
-	}
-
-	/**
-	 * Create the compute shader that performs a local disperse swap on the data buffer.
-	 *
-	 * @private
-	 * @param {StorageBufferNode} readWriteBuffer - The data buffer to read from and write to.
-	 * @returns {ComputeNode} - A compute shader that executes a local disperse swap.
-	 */
-	_getDisperseLocal( readWriteBuffer ) {
-
-		const { localStorage, workgroupSize } = this;
-
-		const fnDef = Fn( () => {
-
-			// Get ids of indices needed to populate workgroup local buffer.
-			// Use .toVar() to prevent these values from being recalculated multiple times.
-			const localOffset = uint( workgroupSize ).mul( 2 ).mul( workgroupId.x ).toVar();
-
-			const localID1 = invocationLocalIndex.mul( 2 );
-			const localID2 = invocationLocalIndex.mul( 2 ).add( 1 );
-
-			localStorage.element( localID1 ).assign( readWriteBuffer.element( localOffset.add( localID1 ) ) );
-			localStorage.element( localID2 ).assign( readWriteBuffer.element( localOffset.add( localID2 ) ) );
-
-			// Ensure that all local data has been populated
-			workgroupBarrier();
-
-			const localBlockHeight = uint( workgroupSize * 2 );
-
-			Loop( { start: localBlockHeight, end: uint( 1 ), type: 'uint', condition: '>', update: '>>= 1' }, () => {
-
-				// Ensure that last dispatch op executed
-				workgroupBarrier();
-
-				const disperseIdx = getBitonicDisperseIndices( invocationLocalIndex, localBlockHeight );
-				this._localCompareAndSwapTSL( disperseIdx.x, disperseIdx.y );
-
-				localBlockHeight.divAssign( 2 );
-
-			} );
-
-			// Ensure that all invocations have swapped their own regions of data
-			workgroupBarrier();
-
-			readWriteBuffer.element( localOffset.add( localID1 ) ).assign( localStorage.element( localID1 ) );
-			readWriteBuffer.element( localOffset.add( localID2 ) ).assign( localStorage.element( localID2 ) );
-
-		} )().compute( this.dispatchSize, [ this.workgroupSize ] );
-
-		return fnDef;
-
-	}
-
-	/**
-	 * Create the compute shader that resets the sort's algorithm information.
-	 *
-	 * @private
-	 * @returns {ComputeNode} - A compute shader that resets the bitonic sort's algorithm information.
-	 */
-	_getResetFn() {
-
-		const fnDef = Fn( () => {
-
-			const { infoStorage } = this;
-
-			const currentAlgo = infoStorage.element( 0 );
-			const currentSwapSpan = infoStorage.element( 1 );
-			const maxSwapSpan = infoStorage.element( 2 );
-
-			currentAlgo.assign( StepType.SWAP_LOCAL );
-			currentSwapSpan.assign( 2 );
-			maxSwapSpan.assign( 2 );
-
-		} )().compute( 1 );
-
-		return fnDef;
-
-	}
-
-	/**
-	 * Create the compute shader that copies the state of the last global swap to the data buffer.
-	 *
-	 * @private
-	 * @returns {ComputeNode} - A compute shader that copies the state of the last global swap to the data buffer.
-	 */
-	_getAlignFn() {
-
-		const { dataBuffer, tempBuffer } = this;
-
-		// TODO: Only do this in certain instances by ping-ponging which buffer gets sorted
-		// And only aligning if numDispatches % 2 === 1
-		const fnDef = Fn( () => {
-
-			dataBuffer.element( instanceIndex ).assign( tempBuffer.element( instanceIndex ) );
-
-		} )().compute( this.count, [ this.workgroupSize ] );
-
-		return fnDef;
-
-	}
-
-	/**
-	 * Create the compute shader that sets the bitonic sort algorithm's information.
-	 *
-	 * @private
-	 * @returns {ComputeNode} - A compute shader that sets the bitonic sort algorithm's information.
-	 */
-	_getSetAlgoFn() {
-
-		const fnDef = Fn( () => {
-
-			const { infoStorage, workgroupSize } = this;
-
-			const currentAlgo = infoStorage.element( 0 );
-			const currentSwapSpan = infoStorage.element( 1 );
-			const maxSwapSpan = infoStorage.element( 2 );
-
-			If( currentAlgo.equal( StepType.SWAP_LOCAL ), () => {
-
-				const nextHighestSwapSpan = uint( workgroupSize * 4 );
-
-				currentAlgo.assign( StepType.FLIP_GLOBAL );
-				currentSwapSpan.assign( nextHighestSwapSpan );
-				maxSwapSpan.assign( nextHighestSwapSpan );
-
-			} ).ElseIf( currentAlgo.equal( StepType.DISPERSE_LOCAL ), () => {
-
-				currentAlgo.assign( StepType.FLIP_GLOBAL );
-
-				const nextHighestSwapSpan = maxSwapSpan.mul( 2 );
-
-				currentSwapSpan.assign( nextHighestSwapSpan );
-				maxSwapSpan.assign( nextHighestSwapSpan );
-
-			} ).Else( () => {
-
-				const nextSwapSpan = currentSwapSpan.div( 2 );
-				currentAlgo.assign(
-					select(
-						nextSwapSpan.lessThanEqual( uint( workgroupSize * 2 ) ),
-						StepType.DISPERSE_LOCAL,
-						StepType.DISPERSE_GLOBAL
-					).uniformFlow()
-				);
-				currentSwapSpan.assign( nextSwapSpan );
-
-			} );
-
-		} )().compute( 1 );
-
-		return fnDef;
-
-	}
-
-	/**
-	 * Executes a step of the bitonic sort operation.
-	 *
-	 * @param {Renderer} renderer - The current scene's renderer.
-	 */
-	computeStep( renderer ) {
-
-		// Swap local only runs once
-		if ( this.currentDispatch === 0 ) {
-
-			renderer.compute( this.swapLocalFn );
-
-			this.globalOpsRemaining = 1;
-			this.globalOpsInSpan = 1;
-
-		} else if ( this.globalOpsRemaining > 0 ) {
-
-			const swapType = this.globalOpsRemaining === this.globalOpsInSpan ? 'Flip' : 'Disperse';
-
-			renderer.compute( swapType === 'Flip' ? this.flipGlobalNodes[ this.readBufferName ] : this.disperseGlobalNodes[ this.readBufferName ] );
-
-			if ( this.readBufferName === 'Data' ) {
-
-				this.readBufferName = 'Temp';
-
-			} else {
-
-				this.readBufferName = 'Data';
-
-			}
-
-			this.globalOpsRemaining -= 1;
-
-		} else {
-
-			// Then run local disperses when we've finished all global swaps
-			renderer.compute( this.disperseLocalNodes[ this.readBufferName ] );
-
-			const nextSpanGlobalOps = this.globalOpsInSpan + 1;
-			this.globalOpsInSpan = nextSpanGlobalOps;
-			this.globalOpsRemaining = nextSpanGlobalOps;
-
-		}
-
-
-		this.currentDispatch += 1;
-
-		if ( this.currentDispatch === this.stepCount ) {
-
-			// If our last swap addressed only addressed the temp buffer, then re-align it with the data buffer
-			// to fulfill the requirement of an in-place sort.
-			if ( this.readBufferName === 'Temp' ) {
-
-				renderer.compute( this.alignFn );
-				this.readBufferName = 'Data';
-
-			}
-
-			// Just reset the algorithm information
-			renderer.compute( this.resetFn );
-
-			this.currentDispatch = 0;
-			this.globalOpsRemaining = 0;
-			this.globalOpsInSpan = 0;
-
-		} else {
-
-			// Otherwise, determine what next swap span is
-			renderer.compute( this.setAlgoFn );
-
-		}
-
-	}
-
-	/**
-	 * Executes a complete bitonic sort on the data buffer.
-	 *
-	 * @param {Renderer} renderer - The current scene's renderer.
-	 */
-	compute( renderer ) {
-
-		this.globalOpsRemaining = 0;
-		this.globalOpsInSpan = 0;
-		this.currentDispatch = 0;
-
-		for ( let i = 0; i < this.stepCount; i ++ ) {
-
-			this.computeStep( renderer );
-
-		}
-
-	}
-
-}

+ 0 - 302
node_modules/three/examples/jsm/helpers/AnimationPathHelper.js

@@ -1,302 +0,0 @@
-import {
-	BufferGeometry,
-	Float32BufferAttribute,
-	Line,
-	LineBasicMaterial,
-	Object3D,
-	Points,
-	PointsMaterial
-} from 'three';
-
-/**
- * Visualizes the motion path of an animated object based on position keyframes
- * from an AnimationClip.
- *
- * ```js
- * const clip = model.animations[ 0 ];
- * const helper = new AnimationPathHelper( model, clip, object );
- * scene.add( helper );
- * ```
- *
- * @augments Object3D
- * @three_import import { AnimationPathHelper } from 'three/addons/helpers/AnimationPathHelper.js';
- */
-class AnimationPathHelper extends Object3D {
-
-	/**
-	 * Constructs a new animation path helper.
-	 *
-	 * @param {Object3D} root - The root object containing the animation clips.
-	 * @param {AnimationClip} clip - The animation clip containing position keyframes.
-	 * @param {Object3D} object - The specific object to show the path for.
-	 * @param {Object} [options={}] - Configuration options.
-	 * @param {number|Color|string} [options.color=0x00ff00] - The path line color.
-	 * @param {number|Color|string} [options.markerColor=0xff0000] - The keyframe marker color.
-	 * @param {number} [options.divisions=100] - Number of samples for smooth path interpolation.
-	 * @param {boolean} [options.showMarkers=true] - Whether to show markers at keyframe positions.
-	 * @param {number} [options.markerSize=5] - Size of keyframe markers in pixels.
-	 */
-	constructor( root, clip, object, options = {} ) {
-
-		super();
-
-		const {
-			color = 0x00ff00,
-			markerColor = 0xff0000,
-			divisions = 100,
-			showMarkers = true,
-			markerSize = 5
-		} = options;
-
-		/**
-		 * This flag can be used for type testing.
-		 *
-		 * @type {boolean}
-		 * @readonly
-		 * @default true
-		 */
-		this.isAnimationPathHelper = true;
-
-		this.type = 'AnimationPathHelper';
-
-		/**
-		 * The root object containing the animation clips.
-		 *
-		 * @type {Object3D}
-		 */
-		this.root = root;
-
-		/**
-		 * The animation clip containing position keyframes.
-		 *
-		 * @type {AnimationClip}
-		 */
-		this.clip = clip;
-
-		/**
-		 * The object whose path is being visualized.
-		 *
-		 * @type {Object3D}
-		 */
-		this.object = object;
-
-		/**
-		 * Number of samples for smooth path interpolation.
-		 *
-		 * @type {number}
-		 * @default 100
-		 */
-		this.divisions = divisions;
-
-		/**
-		 * The position track for the object.
-		 *
-		 * @type {KeyframeTrack|null}
-		 * @private
-		 */
-		this._track = this._findTrackForObject( object );
-
-		if ( this._track === null ) {
-
-			console.warn( 'AnimationPathHelper: No position track found for object', object.name );
-			return;
-
-		}
-
-		// Create line for path
-		const lineGeometry = new BufferGeometry();
-		const lineMaterial = new LineBasicMaterial( {
-			color: color,
-			toneMapped: false
-		} );
-
-		/**
-		 * The line representing the animation path.
-		 *
-		 * @type {Line}
-		 */
-		this.line = new Line( lineGeometry, lineMaterial );
-		this.add( this.line );
-
-		// Create points for keyframe markers
-		if ( showMarkers ) {
-
-			const pointsGeometry = new BufferGeometry();
-			const pointsMaterial = new PointsMaterial( {
-				color: markerColor,
-				size: markerSize,
-				sizeAttenuation: false,
-				toneMapped: false
-			} );
-
-			/**
-			 * Points marking keyframe positions.
-			 *
-			 * @type {Points|null}
-			 */
-			this.points = new Points( pointsGeometry, pointsMaterial );
-			this.add( this.points );
-
-		} else {
-
-			this.points = null;
-
-		}
-
-		// Sync matrix with object's parent
-		this.matrixAutoUpdate = false;
-
-		this._updateGeometry();
-
-	}
-
-	/**
-	 * Finds the position track for the given object.
-	 *
-	 * @private
-	 * @param {Object3D} object - The object to find the track for.
-	 * @returns {KeyframeTrack|null} The position track, or null if not found.
-	 */
-	_findTrackForObject( object ) {
-
-		const targetName = object.uuid + '.position';
-
-		for ( const track of this.clip.tracks ) {
-
-			if ( track.name === targetName && track.getValueSize() === 3 ) {
-
-				return track;
-
-			}
-
-		}
-
-		return null;
-
-	}
-
-	/**
-	 * Samples the track at regular intervals.
-	 *
-	 * @private
-	 * @returns {Float32Array} Array of sampled positions.
-	 */
-	_sampleTrack() {
-
-		const track = this._track;
-		const interpolant = track.createInterpolant();
-		const duration = this.clip.duration;
-		const positions = [];
-
-		for ( let i = 0; i <= this.divisions; i ++ ) {
-
-			const t = ( i / this.divisions ) * duration;
-			const result = interpolant.evaluate( t );
-			positions.push( result[ 0 ], result[ 1 ], result[ 2 ] );
-
-		}
-
-		return new Float32Array( positions );
-
-	}
-
-	/**
-	 * Updates the geometry with sampled path data.
-	 *
-	 * @private
-	 */
-	_updateGeometry() {
-
-		if ( this._track === null ) return;
-
-		// Update line geometry
-		const sampledPositions = this._sampleTrack();
-		this.line.geometry.setAttribute( 'position', new Float32BufferAttribute( sampledPositions, 3 ) );
-		this.line.geometry.computeBoundingSphere();
-
-		// Update keyframe markers
-		if ( this.points !== null ) {
-
-			this.points.geometry.setAttribute( 'position', new Float32BufferAttribute( new Float32Array( this._track.values ), 3 ) );
-			this.points.geometry.computeBoundingSphere();
-
-		}
-
-	}
-
-	/**
-	 * Updates the helper's transform to match the object's parent.
-	 *
-	 * @param {boolean} force - Force matrix update.
-	 */
-	updateMatrixWorld( force ) {
-
-		// Position the helper at the object's parent so the path appears in correct local space
-		if ( this.object && this.object.parent ) {
-
-			this.object.parent.updateWorldMatrix( true, false );
-			this.matrix.copy( this.object.parent.matrixWorld );
-
-		} else {
-
-			this.matrix.identity();
-
-		}
-
-		this.matrixWorld.copy( this.matrix );
-
-		// Update children
-		for ( let i = 0; i < this.children.length; i ++ ) {
-
-			this.children[ i ].updateMatrixWorld( force );
-
-		}
-
-	}
-
-	/**
-	 * Sets the path line color.
-	 *
-	 * @param {number|Color|string} color - The new color.
-	 */
-	setColor( color ) {
-
-		if ( this.line ) this.line.material.color.set( color );
-
-	}
-
-	/**
-	 * Sets the keyframe marker color.
-	 *
-	 * @param {number|Color|string} color - The new color.
-	 */
-	setMarkerColor( color ) {
-
-		if ( this.points ) this.points.material.color.set( color );
-
-	}
-
-	/**
-	 * Frees the GPU-related resources allocated by this instance.
-	 */
-	dispose() {
-
-		if ( this.line ) {
-
-			this.line.geometry.dispose();
-			this.line.material.dispose();
-
-		}
-
-		if ( this.points ) {
-
-			this.points.geometry.dispose();
-			this.points.material.dispose();
-
-		}
-
-	}
-
-}
-
-export { AnimationPathHelper };

+ 0 - 221
node_modules/three/examples/jsm/helpers/LightProbeGridHelper.js

@@ -1,221 +0,0 @@
-import {
-	InstancedBufferAttribute,
-	InstancedMesh,
-	Matrix4,
-	ShaderMaterial,
-	SphereGeometry,
-	Vector3
-} from 'three';
-
-/**
- * Visualizes an {@link LightProbeGrid} by rendering a sphere at each
- * probe position, shaded with the probe's L1 spherical harmonics.
- *
- * Uses a single `InstancedMesh` draw call for all probes.
- *
- * ```js
- * const helper = new LightProbeGridHelper( probes );
- * scene.add( helper );
- * ```
- *
- * @augments InstancedMesh
- * @three_import import { LightProbeGridHelper } from 'three/addons/helpers/LightProbeGridHelper.js';
- */
-class LightProbeGridHelper extends InstancedMesh {
-
-	/**
-	 * Constructs a new irradiance probe grid helper.
-	 *
-	 * @param {LightProbeGrid} probes - The probe grid to visualize.
-	 * @param {number} [sphereSize=0.12] - The radius of each probe sphere.
-	 */
-	constructor( probes, sphereSize = 0.12 ) {
-
-		const geometry = new SphereGeometry( sphereSize, 16, 16 );
-
-		const material = new ShaderMaterial( {
-
-			uniforms: {
-
-				probesSH: { value: null },
-				probesResolution: { value: new Vector3() },
-
-			},
-
-			vertexShader: /* glsl */`
-
-				attribute vec3 instanceUVW;
-
-				varying vec3 vWorldNormal;
-				varying vec3 vUVW;
-
-				void main() {
-
-					vUVW = instanceUVW;
-					vWorldNormal = normalize( mat3( modelMatrix ) * normal );
-					gl_Position = projectionMatrix * modelViewMatrix * instanceMatrix * vec4( position, 1.0 );
-
-				}
-
-			`,
-
-			fragmentShader: /* glsl */`
-
-				precision highp sampler3D;
-
-				uniform sampler3D probesSH;
-				uniform vec3 probesResolution;
-
-				varying vec3 vWorldNormal;
-				varying vec3 vUVW;
-
-				void main() {
-
-					// Atlas UV mapping — must match lightprobes_pars_fragment.glsl.js
-					float nz          = probesResolution.z;
-					float paddedSlices = nz + 2.0;
-					float atlasDepth  = 7.0 * paddedSlices;
-					float uvZBase     = vUVW.z * nz + 1.0;
-
-					vec4 s0 = texture( probesSH, vec3( vUVW.xy, ( uvZBase                       ) / atlasDepth ) );
-					vec4 s1 = texture( probesSH, vec3( vUVW.xy, ( uvZBase +       paddedSlices   ) / atlasDepth ) );
-					vec4 s2 = texture( probesSH, vec3( vUVW.xy, ( uvZBase + 2.0 * paddedSlices   ) / atlasDepth ) );
-					vec4 s3 = texture( probesSH, vec3( vUVW.xy, ( uvZBase + 3.0 * paddedSlices   ) / atlasDepth ) );
-					vec4 s4 = texture( probesSH, vec3( vUVW.xy, ( uvZBase + 4.0 * paddedSlices   ) / atlasDepth ) );
-					vec4 s5 = texture( probesSH, vec3( vUVW.xy, ( uvZBase + 5.0 * paddedSlices   ) / atlasDepth ) );
-					vec4 s6 = texture( probesSH, vec3( vUVW.xy, ( uvZBase + 6.0 * paddedSlices   ) / atlasDepth ) );
-
-					// Unpack 9 vec3 SH L2 coefficients
-
-					vec3 c0 = s0.xyz;
-					vec3 c1 = vec3( s0.w, s1.xy );
-					vec3 c2 = vec3( s1.zw, s2.x );
-					vec3 c3 = s2.yzw;
-					vec3 c4 = s3.xyz;
-					vec3 c5 = vec3( s3.w, s4.xy );
-					vec3 c6 = vec3( s4.zw, s5.x );
-					vec3 c7 = s5.yzw;
-					vec3 c8 = s6.xyz;
-
-					vec3 n = normalize( vWorldNormal );
-
-					float x = n.x, y = n.y, z = n.z;
-
-					// band 0
-					vec3 result = c0 * 0.886227;
-
-					// band 1,
-					result += c1 * 2.0 * 0.511664 * y;
-					result += c2 * 2.0 * 0.511664 * z;
-					result += c3 * 2.0 * 0.511664 * x;
-
-					// band 2,
-					result += c4 * 2.0 * 0.429043 * x * y;
-					result += c5 * 2.0 * 0.429043 * y * z;
-					result += c6 * ( 0.743125 * z * z - 0.247708 );
-					result += c7 * 2.0 * 0.429043 * x * z;
-					result += c8 * 0.429043 * ( x * x - y * y );
-
-					gl_FragColor = vec4( max( result, vec3( 0.0 ) ), 1.0 );
-
-					#include <tonemapping_fragment>
-					#include <colorspace_fragment>
-
-				}
-
-			`
-
-		} );
-
-		const res = probes.resolution;
-		const count = res.x * res.y * res.z;
-
-		super( geometry, material, count );
-
-		/**
-		 * The probe grid to visualize.
-		 *
-		 * @type {LightProbeGrid}
-		 */
-		this.probes = probes;
-
-		this.type = 'LightProbeGridHelper';
-
-		this.update();
-
-	}
-
-	/**
-	 * Rebuilds instance matrices and UVW attributes from the current probe grid.
-	 * Call this after changing `probes` or after re-baking.
-	 */
-	update() {
-
-		const probes = this.probes;
-		const res = probes.resolution;
-		const count = res.x * res.y * res.z;
-
-		// Resize instance matrix buffer if needed
-
-		if ( this.instanceMatrix.count !== count ) {
-
-			this.instanceMatrix = new InstancedBufferAttribute( new Float32Array( count * 16 ), 16 );
-
-		}
-
-		this.count = count;
-
-		const uvwArray = new Float32Array( count * 3 );
-		const matrix = new Matrix4();
-		const probePos = new Vector3();
-
-		let i = 0;
-
-		for ( let iz = 0; iz < res.z; iz ++ ) {
-
-			for ( let iy = 0; iy < res.y; iy ++ ) {
-
-				for ( let ix = 0; ix < res.x; ix ++ ) {
-
-					// Remap to texel centers (must match lightprobes_pars_fragment.glsl.js)
-					uvwArray[ i * 3 ] = ( ix + 0.5 ) / res.x;
-					uvwArray[ i * 3 + 1 ] = ( iy + 0.5 ) / res.y;
-					uvwArray[ i * 3 + 2 ] = ( iz + 0.5 ) / res.z;
-
-					probes.getProbePosition( ix, iy, iz, probePos );
-					matrix.makeTranslation( probePos.x, probePos.y, probePos.z );
-					this.setMatrixAt( i, matrix );
-
-					i ++;
-
-				}
-
-			}
-
-		}
-
-		this.instanceMatrix.needsUpdate = true;
-
-		this.geometry.setAttribute( 'instanceUVW', new InstancedBufferAttribute( uvwArray, 3 ) );
-
-		// Update texture uniforms
-
-		this.material.uniforms.probesSH.value = probes.texture;
-		this.material.uniforms.probesResolution.value.copy( probes.resolution );
-
-	}
-
-	/**
-	 * Frees the GPU-related resources allocated by this instance. Call this
-	 * method whenever this instance is no longer used in your app.
-	 */
-	dispose() {
-
-		this.geometry.dispose();
-		this.material.dispose();
-
-	}
-
-}
-
-export { LightProbeGridHelper };

+ 0 - 165
node_modules/three/examples/jsm/helpers/LightProbeHelper.js

@@ -1,165 +0,0 @@
-import {
-	Mesh,
-	ShaderMaterial,
-	SphereGeometry
-} from 'three';
-
-/**
- * Renders a sphere to visualize a light probe in the scene.
- *
- * This helper can only be used with {@link WebGLRenderer}.
- * When using {@link WebGPURenderer}, import from `LightProbeHelperGPU.js`.
- *
- * ```js
- * const helper = new LightProbeHelper( lightProbe );
- * scene.add( helper );
- * ```
- *
- * @augments Mesh
- * @three_import import { LightProbeHelper } from 'three/addons/helpers/LightProbeHelper.js';
- */
-class LightProbeHelper extends Mesh {
-
-	/**
-	 * Constructs a new light probe helper.
-	 *
-	 * @param {LightProbe} lightProbe - The light probe to visualize.
-	 * @param {number} [size=1] - The size of the helper.
-	 */
-	constructor( lightProbe, size = 1 ) {
-
-		const material = new ShaderMaterial( {
-
-			type: 'LightProbeHelperMaterial',
-
-			uniforms: {
-
-				sh: { value: lightProbe.sh.coefficients }, // by reference
-
-				intensity: { value: lightProbe.intensity }
-
-			},
-
-			vertexShader: /* glsl */`
-
-				varying vec3 vNormal;
-
-				void main() {
-
-					vNormal = normalize( normalMatrix * normal );
-
-					gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
-
-				}
-
-			`,
-
-			fragmentShader: /* glsl */`
-
-				#define RECIPROCAL_PI 0.318309886
-
-				vec3 inverseTransformDirection( in vec3 normal, in mat4 matrix ) {
-
-					// matrix is assumed to be orthogonal
-
-					return normalize( ( vec4( normal, 0.0 ) * matrix ).xyz );
-
-				}
-
-				// source: https://graphics.stanford.edu/papers/envmap/envmap.pdf,
-				vec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {
-
-					// normal is assumed to have unit length,
-
-					float x = normal.x, y = normal.y, z = normal.z;
-
-					// band 0,
-					vec3 result = shCoefficients[ 0 ] * 0.886227;
-
-					// band 1,
-					result += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;
-					result += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;
-					result += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;
-
-					// band 2,
-					result += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;
-					result += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;
-					result += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );
-					result += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;
-					result += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );
-					return result;
-
-				}
-
-				uniform vec3 sh[ 9 ]; // sh coefficients
-
-				uniform float intensity; // light probe intensity
-
-				varying vec3 vNormal;
-
-				void main() {
-
-					vec3 normal = normalize( vNormal );
-
-					vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );
-
-					vec3 irradiance = shGetIrradianceAt( worldNormal, sh );
-
-					vec3 outgoingLight = RECIPROCAL_PI * irradiance * intensity;
-
-					gl_FragColor = linearToOutputTexel( vec4( outgoingLight, 1.0 ) );
-
-				}
-
-			`,
-
-		} );
-
-		const geometry = new SphereGeometry( 1, 32, 16 );
-
-		super( geometry, material );
-
-		/**
-		 * The light probe to visualize.
-		 *
-		 * @type {LightProbe}
-		 */
-		this.lightProbe = lightProbe;
-
-		/**
-		 * The size of the helper.
-		 *
-		 * @type {number}
-		 * @default 1
-		 */
-		this.size = size;
-		this.type = 'LightProbeHelper';
-
-		this.onBeforeRender();
-
-	}
-
-	/**
-	 * Frees the GPU-related resources allocated by this instance. Call this
-	 * method whenever this instance is no longer used in your app.
-	 */
-	dispose() {
-
-		this.geometry.dispose();
-		this.material.dispose();
-
-	}
-
-	onBeforeRender() {
-
-		this.position.copy( this.lightProbe.position );
-
-		this.scale.set( 1, 1, 1 ).multiplyScalar( this.size );
-
-		this.material.uniforms.intensity.value = this.lightProbe.intensity;
-
-	}
-
-}
-
-export { LightProbeHelper };

+ 0 - 102
node_modules/three/examples/jsm/helpers/LightProbeHelperGPU.js

@@ -1,102 +0,0 @@
-import {
-	Mesh,
-	NodeMaterial,
-	SphereGeometry
-} from 'three/webgpu';
-import { float, Fn, getShIrradianceAt, normalWorld, uniformArray, uniform, vec4 } from 'three/tsl';
-
-/**
- * Renders a sphere to visualize a light probe in the scene.
- *
- * This helper can only be used with {@link WebGPURenderer}.
- * When using {@link WebGLRenderer}, import from `LightProbeHelper.js`.
- *
- * ```js
- * const helper = new LightProbeHelper( lightProbe );
- * scene.add( helper );
- * ```
- *
- * @private
- * @augments Mesh
- * @three_import import { LightProbeHelper } from 'three/addons/helpers/LightProbeHelperGPU.js';
- */
-class LightProbeHelper extends Mesh {
-
-	/**
-	 * Constructs a new light probe helper.
-	 *
-	 * @param {LightProbe} lightProbe - The light probe to visualize.
-	 * @param {number} [size=1] - The size of the helper.
-	 */
-	constructor( lightProbe, size = 1 ) {
-
-		const sh = uniformArray( lightProbe.sh.coefficients );
-		const intensity = uniform( lightProbe.intensity );
-
-		const RECIPROCAL_PI = float( 1 / Math.PI );
-
-		const fragmentNode = Fn( () => {
-
-			const irradiance = getShIrradianceAt( normalWorld, sh );
-
-			const outgoingLight = RECIPROCAL_PI.mul( irradiance ).mul( intensity );
-
-			return vec4( outgoingLight, 1.0 );
-
-		} )();
-
-		const material = new NodeMaterial();
-		material.fragmentNode = fragmentNode;
-
-		const geometry = new SphereGeometry( 1, 32, 16 );
-
-		super( geometry, material );
-
-		/**
-		 * The light probe to visualize.
-		 *
-		 * @type {LightProbe}
-		 */
-		this.lightProbe = lightProbe;
-
-		/**
-		 * The size of the helper.
-		 *
-		 * @type {number}
-		 * @default 1
-		 */
-		this.size = size;
-		this.type = 'LightProbeHelper';
-
-		this._intensity = intensity;
-		this._sh = sh;
-
-		this.onBeforeRender();
-
-	}
-
-	/**
-	 * Frees the GPU-related resources allocated by this instance. Call this
-	 * method whenever this instance is no longer used in your app.
-	 */
-	dispose() {
-
-		this.geometry.dispose();
-		this.material.dispose();
-
-	}
-
-	onBeforeRender() {
-
-		this.position.copy( this.lightProbe.position );
-
-		this.scale.set( 1, 1, 1 ).multiplyScalar( this.size );
-
-		this._intensity.value = this.lightProbe.intensity;
-		this._sh.array = this.lightProbe.sh.coefficients;
-
-	}
-
-}
-
-export { LightProbeHelper };

+ 0 - 109
node_modules/three/examples/jsm/helpers/OctreeHelper.js

@@ -1,109 +0,0 @@
-import {
-	LineSegments,
-	BufferGeometry,
-	Float32BufferAttribute,
-	LineBasicMaterial
-} from 'three';
-
-/**
- * A helper for visualizing an Octree.
- *
- * ```js
- * const helper = new OctreeHelper( octree );
- * scene.add( helper );
- * ```
- *
- * @augments LineSegments
- * @three_import import { OctreeHelper } from 'three/addons/helpers/OctreeHelper.js';
- */
-class OctreeHelper extends LineSegments {
-
-	/**
-	 * Constructs a new Octree helper.
-	 *
-	 * @param {Octree} octree - The octree to visualize.
-	 * @param {number|Color|string} [color=0xffff00] - The helper's color.
-	 */
-	constructor( octree, color = 0xffff00 ) {
-
-		super( new BufferGeometry(), new LineBasicMaterial( { color: color, toneMapped: false } ) );
-
-		/**
-		 * The octree to visualize.
-		 *
-		 * @type {Octree}
-		 */
-		this.octree = octree;
-
-		/**
-		 * The helper's color.
-		 *
-		 * @type {number|Color|string}
-		 */
-		this.color = color;
-
-		this.type = 'OctreeHelper';
-
-		this.update();
-
-	}
-
-	/**
-	 * Updates the helper. This method must be called whenever the Octree's
-	 * structure is changed.
-	 */
-	update() {
-
-		const vertices = [];
-
-		function traverse( tree ) {
-
-			for ( let i = 0; i < tree.length; i ++ ) {
-
-				const min = tree[ i ].box.min;
-				const max = tree[ i ].box.max;
-
-				vertices.push( max.x, max.y, max.z ); vertices.push( min.x, max.y, max.z ); // 0, 1
-				vertices.push( min.x, max.y, max.z ); vertices.push( min.x, min.y, max.z ); // 1, 2
-				vertices.push( min.x, min.y, max.z ); vertices.push( max.x, min.y, max.z ); // 2, 3
-				vertices.push( max.x, min.y, max.z ); vertices.push( max.x, max.y, max.z ); // 3, 0
-
-				vertices.push( max.x, max.y, min.z ); vertices.push( min.x, max.y, min.z ); // 4, 5
-				vertices.push( min.x, max.y, min.z ); vertices.push( min.x, min.y, min.z ); // 5, 6
-				vertices.push( min.x, min.y, min.z ); vertices.push( max.x, min.y, min.z ); // 6, 7
-				vertices.push( max.x, min.y, min.z ); vertices.push( max.x, max.y, min.z ); // 7, 4
-
-				vertices.push( max.x, max.y, max.z ); vertices.push( max.x, max.y, min.z ); // 0, 4
-				vertices.push( min.x, max.y, max.z ); vertices.push( min.x, max.y, min.z ); // 1, 5
-				vertices.push( min.x, min.y, max.z ); vertices.push( min.x, min.y, min.z ); // 2, 6
-				vertices.push( max.x, min.y, max.z ); vertices.push( max.x, min.y, min.z ); // 3, 7
-
-				traverse( tree[ i ].subTrees );
-
-			}
-
-		}
-
-		traverse( this.octree.subTrees );
-
-		this.geometry.dispose();
-
-		this.geometry = new BufferGeometry();
-		this.geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
-
-	}
-
-	/**
-	 * Frees the GPU-related resources allocated by this instance. Call this
-	 * method whenever this instance is no longer used in your app.
-	 */
-	dispose() {
-
-		this.geometry.dispose();
-		this.material.dispose();
-
-	}
-
-}
-
-export { OctreeHelper };

+ 0 - 169
node_modules/three/examples/jsm/helpers/PositionalAudioHelper.js

@@ -1,169 +0,0 @@
-import {
-	BufferGeometry,
-	BufferAttribute,
-	LineBasicMaterial,
-	Line,
-	MathUtils
-} from 'three';
-
-/**
- * This helper displays the directional cone of a positional audio.
- *
- * `PositionalAudioHelper` must be added as a child of the positional audio.
- *
- * ```js
- * const positionalAudio = new THREE.PositionalAudio( listener );
- * positionalAudio.setDirectionalCone( 180, 230, 0.1 );
- * scene.add( positionalAudio );
- *
- * const helper = new PositionalAudioHelper( positionalAudio );
- * positionalAudio.add( helper );
- * ```
- *
- * @augments Line
- * @three_import import { PositionalAudioHelper } from 'three/addons/helpers/PositionalAudioHelper.js';
- */
-class PositionalAudioHelper extends Line {
-
-	/**
-	 * Constructs a new positional audio helper.
-	 *
-	 * @param {PositionalAudio} audio - The audio to visualize.
-	 * @param {number} [range=1] - The range of the directional cone.
-	 * @param {number} [divisionsInnerAngle=16] - The number of divisions of the inner part of the directional cone.
-	 * @param {number} [divisionsOuterAngle=2] The number of divisions of the outer part of the directional cone.
-	 */
-	constructor( audio, range = 1, divisionsInnerAngle = 16, divisionsOuterAngle = 2 ) {
-
-		const geometry = new BufferGeometry();
-		const divisions = divisionsInnerAngle + divisionsOuterAngle * 2;
-		const positions = new Float32Array( ( divisions * 3 + 3 ) * 3 );
-		geometry.setAttribute( 'position', new BufferAttribute( positions, 3 ) );
-
-		const materialInnerAngle = new LineBasicMaterial( { color: 0x00ff00 } );
-		const materialOuterAngle = new LineBasicMaterial( { color: 0xffff00 } );
-
-		super( geometry, [ materialOuterAngle, materialInnerAngle ] );
-
-		/**
-		 * The audio to visualize.
-		 *
-		 * @type {PositionalAudio}
-		 */
-		this.audio = audio;
-
-		/**
-		 * The range of the directional cone.
-		 *
-		 * @type {number}
-		 * @default 1
-		 */
-		this.range = range;
-
-		/**
-		 * The number of divisions of the inner part of the directional cone.
-		 *
-		 * @type {number}
-		 * @default 16
-		 */
-		this.divisionsInnerAngle = divisionsInnerAngle;
-
-		/**
-		 * The number of divisions of the outer part of the directional cone.
-		 *
-		 * @type {number}
-		 * @default 2
-		 */
-		this.divisionsOuterAngle = divisionsOuterAngle;
-
-		this.type = 'PositionalAudioHelper';
-
-		this.update();
-
-	}
-
-	/**
-	 * Updates the helper. This method must be called whenever the directional cone
-	 * of the positional audio is changed.
-	 */
-	update() {
-
-		const audio = this.audio;
-		const range = this.range;
-		const divisionsInnerAngle = this.divisionsInnerAngle;
-		const divisionsOuterAngle = this.divisionsOuterAngle;
-
-		const coneInnerAngle = MathUtils.degToRad( audio.panner.coneInnerAngle );
-		const coneOuterAngle = MathUtils.degToRad( audio.panner.coneOuterAngle );
-
-		const halfConeInnerAngle = coneInnerAngle / 2;
-		const halfConeOuterAngle = coneOuterAngle / 2;
-
-		let start = 0;
-		let count = 0;
-		let i;
-		let stride;
-
-		const geometry = this.geometry;
-		const positionAttribute = geometry.attributes.position;
-
-		geometry.clearGroups();
-
-		//
-
-		function generateSegment( from, to, divisions, materialIndex ) {
-
-			const step = ( to - from ) / divisions;
-
-			positionAttribute.setXYZ( start, 0, 0, 0 );
-			count ++;
-
-			for ( i = from; i < to; i += step ) {
-
-				stride = start + count;
-
-				positionAttribute.setXYZ( stride, Math.sin( i ) * range, 0, Math.cos( i ) * range );
-				positionAttribute.setXYZ( stride + 1, Math.sin( Math.min( i + step, to ) ) * range, 0, Math.cos( Math.min( i + step, to ) ) * range );
-				positionAttribute.setXYZ( stride + 2, 0, 0, 0 );
-
-				count += 3;
-
-			}
-
-			geometry.addGroup( start, count, materialIndex );
-
-			start += count;
-			count = 0;
-
-		}
-
-		//
-
-		generateSegment( - halfConeOuterAngle, - halfConeInnerAngle, divisionsOuterAngle, 0 );
-		generateSegment( - halfConeInnerAngle, halfConeInnerAngle, divisionsInnerAngle, 1 );
-		generateSegment( halfConeInnerAngle, halfConeOuterAngle, divisionsOuterAngle, 0 );
-
-		//
-
-		positionAttribute.needsUpdate = true;
-
-		if ( coneInnerAngle === coneOuterAngle ) this.material[ 0 ].visible = false;
-
-	}
-
-	/**
-	 * Frees the GPU-related resources allocated by this instance. Call this
-	 * method whenever this instance is no longer used in your app.
-	 */
-	dispose() {
-
-		this.geometry.dispose();
-		this.material[ 0 ].dispose();
-		this.material[ 1 ].dispose();
-
-	}
-
-}
-
-
-export { PositionalAudioHelper };

+ 0 - 59
node_modules/three/examples/jsm/helpers/RapierHelper.js

@@ -1,59 +0,0 @@
-import { LineSegments, LineBasicMaterial, BufferAttribute } from 'three';
-/**
- * This class displays all Rapier Colliders in outline.
- *
- * @augments LineSegments
- * @three_import import { RapierHelper } from 'three/addons/helpers/RapierHelper.js';
- */
-class RapierHelper extends LineSegments {
-
-	/**
-	 * Constructs a new Rapier debug helper.
-	 *
-	 * @param {RAPIER.world} world - The Rapier world to visualize.
-	 */
-	constructor( world ) {
-
-		super();
-
-		/**
-		 * The Rapier world to visualize.
-		 *
-		 * @type {RAPIER.world}
-		 */
-		this.world = world;
-
-		this.material = new LineBasicMaterial( { vertexColors: true } );
-		this.frustumCulled = false;
-
-	}
-
-	/**
-	 * Call this in the render loop to update the outlines.
-	 */
-	update() {
-
-		const { vertices, colors } = this.world.debugRender();
-
-		this.geometry.deleteAttribute( 'position' );
-		this.geometry.deleteAttribute( 'color' );
-
-		this.geometry.setAttribute( 'position', new BufferAttribute( vertices, 3 ) );
-		this.geometry.setAttribute( 'color', new BufferAttribute( colors, 4 ) );
-
-	}
-
-	/**
-	 * Frees the GPU-related resources allocated by this instance. Call this
-	 * method whenever this instance is no longer used in your app.
-	 */
-	dispose() {
-
-		this.geometry.dispose();
-		this.material.dispose();
-
-	}
-
-}
-
-export { RapierHelper };

+ 0 - 118
node_modules/three/examples/jsm/helpers/RectAreaLightHelper.js

@@ -1,118 +0,0 @@
-import {
-	BackSide,
-	BufferGeometry,
-	Float32BufferAttribute,
-	Line,
-	LineBasicMaterial,
-	Mesh,
-	MeshBasicMaterial
-} from 'three';
-
-/**
- * Creates a visual aid for rect area lights.
- *
- * `RectAreaLightHelper` must be added as a child of the light.
- *
- * ```js
- * const light = new THREE.RectAreaLight( 0xffffbb, 1.0, 5, 5 );
- * const helper = new RectAreaLightHelper( light );
- * light.add( helper );
- * ```
- *
- * @augments Line
- * @three_import import { RectAreaLightHelper } from 'three/addons/helpers/RectAreaLightHelper.js';
- */
-class RectAreaLightHelper extends Line {
-
-	/**
-	 * Constructs a new rect area light helper.
-	 *
-	 * @param {RectAreaLight} light - The light to visualize.
-	 * @param {number|Color|string} [color] - The helper's color.
-	 * If this is not the set, the helper will take the color of the light.
-	 */
-	constructor( light, color ) {
-
-		const positions = [ 1, 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, - 1, 0, 1, 1, 0 ];
-
-		const geometry = new BufferGeometry();
-		geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
-		geometry.computeBoundingSphere();
-
-		const material = new LineBasicMaterial( { fog: false } );
-
-		super( geometry, material );
-
-		/**
-		 * The light to visualize.
-		 *
-		 * @type {RectAreaLight}
-		 */
-		this.light = light;
-
-		/**
-		 * The helper's color. If `undefined`, the helper will take the color of the light.
-		 *
-		 * @type {number|Color|string|undefined}
-		 */
-		this.color = color;
-
-		this.type = 'RectAreaLightHelper';
-
-		//
-
-		const positions2 = [ 1, 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, 1, 0, - 1, - 1, 0, 1, - 1, 0 ];
-
-		const geometry2 = new BufferGeometry();
-		geometry2.setAttribute( 'position', new Float32BufferAttribute( positions2, 3 ) );
-		geometry2.computeBoundingSphere();
-
-		this.add( new Mesh( geometry2, new MeshBasicMaterial( { side: BackSide, fog: false } ) ) );
-
-	}
-
-	updateMatrixWorld() {
-
-		this.scale.set( 0.5 * this.light.width, 0.5 * this.light.height, 1 );
-
-		if ( this.color !== undefined ) {
-
-			this.material.color.set( this.color );
-			this.children[ 0 ].material.color.set( this.color );
-
-		} else {
-
-			this.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );
-
-			// prevent hue shift
-			const c = this.material.color;
-			const max = Math.max( c.r, c.g, c.b );
-			if ( max > 1 ) c.multiplyScalar( 1 / max );
-
-			this.children[ 0 ].material.color.copy( this.material.color );
-
-		}
-
-		// ignore world scale on light
-		this.matrixWorld.extractRotation( this.light.matrixWorld ).scale( this.scale ).copyPosition( this.light.matrixWorld );
-
-		this.children[ 0 ].matrixWorld.copy( this.matrixWorld );
-
-	}
-
-	/**
-	 * Frees the GPU-related resources allocated by this instance. Call this
-	 * method whenever this instance is no longer used in your app.
-	 */
-	dispose() {
-
-		this.geometry.dispose();
-		this.material.dispose();
-		this.children[ 0 ].geometry.dispose();
-		this.children[ 0 ].material.dispose();
-
-	}
-
-}
-
-export { RectAreaLightHelper };

+ 0 - 265
node_modules/three/examples/jsm/helpers/TextureHelper.js

@@ -1,265 +0,0 @@
-import {
-	BoxGeometry,
-	BufferAttribute,
-	DoubleSide,
-	Mesh,
-	PlaneGeometry,
-	ShaderMaterial,
-	Vector3,
-} from 'three';
-import { mergeGeometries } from '../utils/BufferGeometryUtils.js';
-
-/**
- * A helper that can be used to display any type of texture for
- * debugging purposes. Depending on the type of texture (2D, 3D, Array),
- * the helper becomes a plane or box mesh.
- *
- * This helper can only be used with {@link WebGLRenderer}.
- * When using {@link WebGPURenderer}, import from `TextureHelperGPU.js`.
- *
- * @augments Mesh
- * @three_import import { TextureHelper } from 'three/addons/helpers/TextureHelper.js';
- */
-class TextureHelper extends Mesh {
-
-	/**
-	 * Constructs a new texture helper.
-	 *
-	 * @param {Texture} texture - The texture to visualize.
-	 * @param {number} [width=1] - The helper's width.
-	 * @param {number} [height=1] - The helper's height.
-	 * @param {number} [depth=1] - The helper's depth.
-	 */
-	constructor( texture, width = 1, height = 1, depth = 1 ) {
-
-		const material = new ShaderMaterial( {
-
-			type: 'TextureHelperMaterial',
-
-			side: DoubleSide,
-			transparent: true,
-
-			uniforms: {
-
-				map: { value: texture },
-				alpha: { value: getAlpha( texture ) },
-
-			},
-
-			vertexShader: [
-
-				'attribute vec3 uvw;',
-
-				'varying vec3 vUvw;',
-
-				'void main() {',
-
-				'	vUvw = uvw;',
-
-				'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
-
-				'}',
-
-			].join( '\n' ),
-
-			fragmentShader: [
-
-				'precision highp float;',
-
-				'precision highp sampler2DArray;',
-
-				'precision highp sampler3D;',
-
-				'uniform {samplerType} map;',
-
-				'uniform float alpha;',
-
-				'varying vec3 vUvw;',
-
-				'vec4 textureHelper( in sampler2D map ) { return texture( map, vUvw.xy ); }',
-
-				'vec4 textureHelper( in sampler2DArray map ) { return texture( map, vUvw ); }',
-
-				'vec4 textureHelper( in sampler3D map ) { return texture( map, vUvw ); }',
-
-				'vec4 textureHelper( in samplerCube map ) { return texture( map, vUvw ); }',
-
-				'void main() {',
-
-				'	gl_FragColor = linearToOutputTexel( vec4( textureHelper( map ).xyz, alpha ) );',
-
-				'}'
-
-			].join( '\n' ).replace( '{samplerType}', getSamplerType( texture ) )
-
-		} );
-
-		const geometry = texture.isCubeTexture
-			? createCubeGeometry( width, height, depth )
-			: createSliceGeometry( texture, width, height, depth );
-
-		super( geometry, material );
-
-		/**
-		 * The texture to visualize.
-		 *
-		 * @type {Texture}
-		 */
-		this.texture = texture;
-		this.type = 'TextureHelper';
-
-	}
-
-	/**
-	 * Frees the GPU-related resources allocated by this instance. Call this
-	 * method whenever this instance is no longer used in your app.
-	 */
-	dispose() {
-
-		this.geometry.dispose();
-		this.material.dispose();
-
-	}
-
-}
-
-function getSamplerType( texture ) {
-
-	if ( texture.isCubeTexture ) {
-
-		return 'samplerCube';
-
-	} else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
-
-		return 'sampler2DArray';
-
-	} else if ( texture.isData3DTexture || texture.isCompressed3DTexture ) {
-
-		return 'sampler3D';
-
-	} else {
-
-		return 'sampler2D';
-
-	}
-
-}
-
-function getImageCount( texture ) {
-
-	if ( texture.isCubeTexture ) {
-
-		return 6;
-
-	} else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
-
-		return texture.image.depth;
-
-	} else if ( texture.isData3DTexture || texture.isCompressed3DTexture ) {
-
-		return texture.image.depth;
-
-	} else {
-
-		return 1;
-
-	}
-
-}
-
-function getAlpha( texture ) {
-
-	if ( texture.isCubeTexture ) {
-
-		return 1;
-
-	} else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
-
-		return Math.max( 1 / texture.image.depth, 0.25 );
-
-	} else if ( texture.isData3DTexture || texture.isCompressed3DTexture ) {
-
-		return Math.max( 1 / texture.image.depth, 0.25 );
-
-	} else {
-
-		return 1;
-
-	}
-
-}
-
-function createCubeGeometry( width, height, depth ) {
-
-	const geometry = new BoxGeometry( width, height, depth );
-
-	const position = geometry.attributes.position;
-	const uv = geometry.attributes.uv;
-	const uvw = new BufferAttribute( new Float32Array( uv.count * 3 ), 3 );
-
-	const _direction = new Vector3();
-
-	for ( let j = 0, jl = uv.count; j < jl; ++ j ) {
-
-		_direction.fromBufferAttribute( position, j ).normalize();
-
-		const u = _direction.x;
-		const v = _direction.y;
-		const w = _direction.z;
-
-		uvw.setXYZ( j, u, v, w );
-
-	}
-
-	geometry.deleteAttribute( 'uv' );
-	geometry.setAttribute( 'uvw', uvw );
-
-	return geometry;
-
-}
-
-function createSliceGeometry( texture, width, height, depth ) {
-
-	const sliceCount = getImageCount( texture );
-
-	const geometries = [];
-
-	for ( let i = 0; i < sliceCount; ++ i ) {
-
-		const geometry = new PlaneGeometry( width, height );
-
-		if ( sliceCount > 1 ) {
-
-			geometry.translate( 0, 0, depth * ( i / ( sliceCount - 1 ) - 0.5 ) );
-
-		}
-
-		const uv = geometry.attributes.uv;
-		const uvw = new BufferAttribute( new Float32Array( uv.count * 3 ), 3 );
-
-		for ( let j = 0, jl = uv.count; j < jl; ++ j ) {
-
-			const u = uv.getX( j );
-			const v = texture.flipY ? uv.getY( j ) : 1 - uv.getY( j );
-			const w = sliceCount === 1
-				? 1
-				: texture.isDataArrayTexture || texture.isCompressedArrayTexture
-					? i
-					: i / ( sliceCount - 1 );
-
-			uvw.setXYZ( j, u, v, w );
-
-		}
-
-		geometry.deleteAttribute( 'uv' );
-		geometry.setAttribute( 'uvw', uvw );
-
-		geometries.push( geometry );
-
-	}
-
-	return mergeGeometries( geometries );
-
-}
-
-export { TextureHelper };

+ 0 - 214
node_modules/three/examples/jsm/helpers/TextureHelperGPU.js

@@ -1,214 +0,0 @@
-import {
-	NodeMaterial,
-	BoxGeometry,
-	BufferAttribute,
-	Mesh,
-	PlaneGeometry,
-	DoubleSide,
-	Vector3,
-} from 'three/webgpu';
-import { texture as textureNode, cubeTexture, texture3D, float, vec4, attribute } from 'three/tsl';
-import { mergeGeometries } from '../utils/BufferGeometryUtils.js';
-
-/**
- * A helper that can be used to display any type of texture for
- * debugging purposes. Depending on the type of texture (2D, 3D, Array),
- * the helper becomes a plane or box mesh.
- *
- * This helper can only be used with {@link WebGPURenderer}.
- * When using {@link WebGLRenderer}, import from `TextureHelper.js`.
- *
- * @private
- * @augments Mesh
- * @three_import import { TextureHelper } from 'three/addons/helpers/TextureHelperGPU.js';
- */
-class TextureHelper extends Mesh {
-
-	/**
-	 * Constructs a new texture helper.
-	 *
-	 * @param {Texture} texture - The texture to visualize.
-	 * @param {number} [width=1] - The helper's width.
-	 * @param {number} [height=1] - The helper's height.
-	 * @param {number} [depth=1] - The helper's depth.
-	 */
-	constructor( texture, width = 1, height = 1, depth = 1 ) {
-
-		const material = new NodeMaterial();
-		material.side = DoubleSide;
-		material.transparent = true;
-		material.name = 'TextureHelper';
-
-		let colorNode;
-
-		const uvw = attribute( 'uvw' );
-
-		if ( texture.isCubeTexture ) {
-
-			colorNode = cubeTexture( texture ).sample( uvw );
-
-		} else if ( texture.isData3DTexture || texture.isCompressed3DTexture ) {
-
-			colorNode = texture3D( texture ).sample( uvw );
-
-		} else if ( texture.isArrayTexture || texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
-
-			colorNode = textureNode( texture ).sample( uvw.xy ).depth( uvw.z );
-
-		} else {
-
-			colorNode = textureNode( texture );
-
-		}
-
-		const alphaNode = float( getAlpha( texture ) );
-
-		material.colorNode = vec4( colorNode.rgb, alphaNode );
-
-		const geometry = texture.isCubeTexture
-			? createCubeGeometry( width, height, depth )
-			: createSliceGeometry( texture, width, height, depth );
-
-		super( geometry, material );
-
-		/**
-		 * The texture to visualize.
-		 *
-		 * @type {Texture}
-		 */
-		this.texture = texture;
-		this.type = 'TextureHelper';
-
-	}
-
-	/**
-	 * Frees the GPU-related resources allocated by this instance. Call this
-	 * method whenever this instance is no longer used in your app.
-	 */
-	dispose() {
-
-		this.geometry.dispose();
-		this.material.dispose();
-
-	}
-
-}
-
-function getImageCount( texture ) {
-
-	if ( texture.isCubeTexture ) {
-
-		return 6;
-
-	} else if ( texture.isArrayTexture || texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
-
-		return texture.image.depth;
-
-	} else if ( texture.isData3DTexture || texture.isCompressed3DTexture ) {
-
-		return texture.image.depth;
-
-	} else {
-
-		return 1;
-
-	}
-
-}
-
-function getAlpha( texture ) {
-
-	if ( texture.isCubeTexture ) {
-
-		return 1;
-
-	} else if ( texture.isArrayTexture || texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
-
-		return Math.max( 1 / texture.image.depth, 0.25 );
-
-	} else if ( texture.isData3DTexture || texture.isCompressed3DTexture ) {
-
-		return Math.max( 1 / texture.image.depth, 0.25 );
-
-	} else {
-
-		return 1;
-
-	}
-
-}
-
-function createCubeGeometry( width, height, depth ) {
-
-	const geometry = new BoxGeometry( width, height, depth );
-
-	const position = geometry.attributes.position;
-	const uv = geometry.attributes.uv;
-	const uvw = new BufferAttribute( new Float32Array( uv.count * 3 ), 3 );
-
-	const _direction = new Vector3();
-
-	for ( let j = 0, jl = uv.count; j < jl; ++ j ) {
-
-		_direction.fromBufferAttribute( position, j ).normalize();
-
-		const u = _direction.x;
-		const v = _direction.y;
-		const w = _direction.z;
-
-		uvw.setXYZ( j, u, v, w );
-
-	}
-
-	geometry.deleteAttribute( 'uv' );
-	geometry.setAttribute( 'uvw', uvw );
-
-	return geometry;
-
-}
-
-function createSliceGeometry( texture, width, height, depth ) {
-
-	const sliceCount = getImageCount( texture );
-
-	const geometries = [];
-
-	for ( let i = 0; i < sliceCount; ++ i ) {
-
-		const geometry = new PlaneGeometry( width, height );
-
-		if ( sliceCount > 1 ) {
-
-			geometry.translate( 0, 0, depth * ( i / ( sliceCount - 1 ) - 0.5 ) );
-
-		}
-
-		const uv = geometry.attributes.uv;
-		const uvw = new BufferAttribute( new Float32Array( uv.count * 3 ), 3 );
-
-		for ( let j = 0, jl = uv.count; j < jl; ++ j ) {
-
-			const u = uv.getX( j );
-			const v = texture.flipY ? uv.getY( j ) : 1 - uv.getY( j );
-			const w = sliceCount === 1
-				? 1
-				: texture.isArrayTexture || texture.isDataArrayTexture || texture.isCompressedArrayTexture
-					? i
-					: i / ( sliceCount - 1 );
-
-			uvw.setXYZ( j, u, v, w );
-
-		}
-
-		geometry.deleteAttribute( 'uv' );
-		geometry.setAttribute( 'uvw', uvw );
-
-		geometries.push( geometry );
-
-	}
-
-	return mergeGeometries( geometries );
-
-}
-
-export { TextureHelper };

+ 0 - 155
node_modules/three/examples/jsm/helpers/VertexNormalsHelper.js

@@ -1,155 +0,0 @@
-import {
-	BufferGeometry,
-	Float32BufferAttribute,
-	LineSegments,
-	LineBasicMaterial,
-	Matrix3,
-	Vector3
-} from 'three';
-
-const _v1 = new Vector3();
-const _v2 = new Vector3();
-const _normalMatrix = new Matrix3();
-
-/**
- * Visualizes an object's vertex normals.
- *
- * Requires that normals have been specified in the geometry as a buffer attribute or
- * have been calculated using {@link BufferGeometry#computeVertexNormals}.
- * ```js
- * const geometry = new THREE.BoxGeometry( 10, 10, 10, 2, 2, 2 );
- * const material = new THREE.MeshStandardMaterial();
- * const mesh = new THREE.Mesh( geometry, material );
- * scene.add( mesh );
- *
- * const helper = new VertexNormalsHelper( mesh, 1, 0xff0000 );
- * scene.add( helper );
- * ```
- *
- * @augments LineSegments
- * @three_import import { VertexNormalsHelper } from 'three/addons/helpers/VertexNormalsHelper.js';
- */
-class VertexNormalsHelper extends LineSegments {
-
-	/**
-	 * Constructs a new vertex normals helper.
-	 *
-	 * @param {Object3D} object - The object for which to visualize vertex normals.
-	 * @param {number} [size=1] - The helper's size.
-	 * @param {number|Color|string} [color=0xff0000] - The helper's color.
-	 */
-	constructor( object, size = 1, color = 0xff0000 ) {
-
-		const geometry = new BufferGeometry();
-
-		const nNormals = object.geometry.attributes.normal.count;
-		const positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );
-
-		geometry.setAttribute( 'position', positions );
-
-		super( geometry, new LineBasicMaterial( { color, toneMapped: false } ) );
-
-		/**
-		 * The object for which to visualize vertex normals.
-		 *
-		 * @type {Object3D}
-		 */
-		this.object = object;
-
-		/**
-		 * The helper's size.
-		 *
-		 * @type {number}
-		 * @default 1
-		 */
-		this.size = size;
-
-		this.type = 'VertexNormalsHelper';
-
-		/**
-		 * Overwritten and set to `false` since the object's world transformation
-		 * is encoded in the helper's geometry data.
-		 *
-		 * @type {boolean}
-		 * @default false
-		 */
-		this.matrixAutoUpdate = false;
-
-		/**
-		 * This flag can be used for type testing.
-		 *
-		 * @type {boolean}
-		 * @readonly
-		 * @default true
-		 */
-		this.isVertexNormalsHelper = true;
-
-		this.update();
-
-	}
-
-	/**
-	 * Updates the vertex normals preview based on the object's world transform.
-	 */
-	update() {
-
-		this.object.updateMatrixWorld( true );
-
-		_normalMatrix.getNormalMatrix( this.object.matrixWorld );
-
-		const matrixWorld = this.object.matrixWorld;
-
-		const position = this.geometry.attributes.position;
-
-		//
-
-		const objGeometry = this.object.geometry;
-
-		if ( objGeometry ) {
-
-			const objPos = objGeometry.attributes.position;
-
-			const objNorm = objGeometry.attributes.normal;
-
-			let idx = 0;
-
-			// for simplicity, ignore index and drawcalls, and render every normal
-
-			for ( let j = 0, jl = objPos.count; j < jl; j ++ ) {
-
-				_v1.fromBufferAttribute( objPos, j ).applyMatrix4( matrixWorld );
-
-				_v2.fromBufferAttribute( objNorm, j );
-
-				_v2.applyMatrix3( _normalMatrix ).normalize().multiplyScalar( this.size ).add( _v1 );
-
-				position.setXYZ( idx, _v1.x, _v1.y, _v1.z );
-
-				idx = idx + 1;
-
-				position.setXYZ( idx, _v2.x, _v2.y, _v2.z );
-
-				idx = idx + 1;
-
-			}
-
-		}
-
-		position.needsUpdate = true;
-
-	}
-
-	/**
-	 * Frees the GPU-related resources allocated by this instance. Call this
-	 * method whenever this instance is no longer used in your app.
-	 */
-	dispose() {
-
-		this.geometry.dispose();
-		this.material.dispose();
-
-	}
-
-}
-
-export { VertexNormalsHelper };

+ 0 - 133
node_modules/three/examples/jsm/helpers/VertexTangentsHelper.js

@@ -1,133 +0,0 @@
-import {
-	BufferGeometry,
-	Float32BufferAttribute,
-	LineSegments,
-	LineBasicMaterial,
-	Vector3
-} from 'three';
-
-const _v1 = new Vector3();
-const _v2 = new Vector3();
-
-/**
- * Visualizes an object's vertex tangents.
- *
- * Requires that tangents have been specified in the geometry as a buffer attribute or
- * have been calculated using {@link BufferGeometry#computeTangents}.
- * ```js
- * const helper = new VertexTangentsHelper( mesh, 1, 0xff0000 );
- * scene.add( helper );
- * ```
- *
- * @augments LineSegments
- * @three_import import { VertexTangentsHelper } from 'three/addons/helpers/VertexTangentsHelper.js';
- */
-class VertexTangentsHelper extends LineSegments {
-
-	/**
-	 * Constructs a new vertex tangents helper.
-	 *
-	 * @param {Object3D} object - The object for which to visualize vertex tangents.
-	 * @param {number} [size=1] - The helper's size.
-	 * @param {number|Color|string} [color=0xff0000] - The helper's color.
-	 */
-	constructor( object, size = 1, color = 0x00ffff ) {
-
-		const geometry = new BufferGeometry();
-
-		const nTangents = object.geometry.attributes.tangent.count;
-		const positions = new Float32BufferAttribute( nTangents * 2 * 3, 3 );
-
-		geometry.setAttribute( 'position', positions );
-
-		super( geometry, new LineBasicMaterial( { color, toneMapped: false } ) );
-
-		/**
-		 * The object for which to visualize vertex tangents.
-		 *
-		 * @type {Object3D}
-		 */
-		this.object = object;
-
-		/**
-		 * The helper's size.
-		 *
-		 * @type {number}
-		 * @default 1
-		 */
-		this.size = size;
-
-		this.type = 'VertexTangentsHelper';
-
-		/**
-		 * Overwritten and set to `false` since the object's world transformation
-		 * is encoded in the helper's geometry data.
-		 *
-		 * @type {boolean}
-		 * @default false
-		 */
-		this.matrixAutoUpdate = false;
-
-		this.update();
-
-	}
-
-	/**
-	 * Updates the vertex normals preview based on the object's world transform.
-	 */
-	update() {
-
-		this.object.updateMatrixWorld( true );
-
-		const matrixWorld = this.object.matrixWorld;
-
-		const position = this.geometry.attributes.position;
-
-		//
-
-		const objGeometry = this.object.geometry;
-
-		const objPos = objGeometry.attributes.position;
-
-		const objTan = objGeometry.attributes.tangent;
-
-		let idx = 0;
-
-		// for simplicity, ignore index and drawcalls, and render every tangent
-
-		for ( let j = 0, jl = objPos.count; j < jl; j ++ ) {
-
-			_v1.fromBufferAttribute( objPos, j ).applyMatrix4( matrixWorld );
-
-			_v2.fromBufferAttribute( objTan, j );
-
-			_v2.transformDirection( matrixWorld ).multiplyScalar( this.size ).add( _v1 );
-
-			position.setXYZ( idx, _v1.x, _v1.y, _v1.z );
-
-			idx = idx + 1;
-
-			position.setXYZ( idx, _v2.x, _v2.y, _v2.z );
-
-			idx = idx + 1;
-
-		}
-
-		position.needsUpdate = true;
-
-	}
-
-	/**
-	 * Frees the GPU-related resources allocated by this instance. Call this
-	 * method whenever this instance is no longer used in your app.
-	 */
-	dispose() {
-
-		this.geometry.dispose();
-		this.material.dispose();
-
-	}
-
-}
-
-export { VertexTangentsHelper };

+ 0 - 519
node_modules/three/examples/jsm/helpers/ViewHelper.js

@@ -1,519 +0,0 @@
-import {
-	CylinderGeometry,
-	CanvasTexture,
-	Color,
-	Euler,
-	Mesh,
-	MeshBasicMaterial,
-	Object3D,
-	OrthographicCamera,
-	Quaternion,
-	Raycaster,
-	Sprite,
-	SpriteMaterial,
-	SRGBColorSpace,
-	Vector2,
-	Vector3,
-	Vector4
-} from 'three';
-
-/**
- * A special type of helper that visualizes the camera's transformation
- * in a small viewport area as an axes helper. Such a helper is often wanted
- * in 3D modeling tools or scene editors like the [three.js editor](https://threejs.org/editor).
- *
- * The helper allows to click on the X, Y and Z axes which animates the camera
- * so it looks along the selected axis.
- *
- * @augments Object3D
- * @three_import import { ViewHelper } from 'three/addons/helpers/ViewHelper.js';
- */
-class ViewHelper extends Object3D {
-
-	/**
-	 * Constructs a new view helper.
-	 *
-	 * @param {Camera} camera - The camera whose transformation should be visualized.
-	 * @param {HTMLElement} [domElement] - The DOM element that is used to render the view.
-	 */
-	constructor( camera, domElement ) {
-
-		super();
-
-		/**
-		 * This flag can be used for type testing.
-		 *
-		 * @type {boolean}
-		 * @readonly
-		 * @default true
-		 */
-		this.isViewHelper = true;
-
-		/**
-		 * Whether the helper is currently animating or not.
-		 *
-		 * @type {boolean}
-		 * @readonly
-		 * @default false
-		 */
-		this.animating = false;
-
-		/**
-		 * The helper's center point.
-		 *
-		 * @type {Vector3}
-		 */
-		this.center = new Vector3();
-
-		/**
-		 * Controls the position of the helper in the viewport.
-		 * Use `top`/`bottom` for vertical positioning and `left`/`right` for horizontal.
-		 * If `left` is `null`, `right` is used. If `top` is `null`, `bottom` is used.
-		 *
-		 * @type {{top: number|null, right: number, bottom: number, left: number|null}}
-		 */
-		this.location = {
-			top: null,
-			right: 0,
-			bottom: 0,
-			left: null
-		};
-
-		const color1 = new Color( '#ff4466' );
-		const color2 = new Color( '#88ff44' );
-		const color3 = new Color( '#4488ff' );
-		const color4 = new Color( '#000000' );
-
-		const options = {};
-
-		const interactiveObjects = [];
-		const raycaster = new Raycaster();
-		const mouse = new Vector2();
-		const dummy = new Object3D();
-
-		const orthoCamera = new OrthographicCamera( - 2, 2, 2, - 2, 0, 4 );
-		orthoCamera.position.set( 0, 0, 2 );
-
-		const geometry = new CylinderGeometry( 0.04, 0.04, 0.8, 5 ).rotateZ( - Math.PI / 2 ).translate( 0.4, 0, 0 );
-
-		const xAxis = new Mesh( geometry, getAxisMaterial( color1 ) );
-		const yAxis = new Mesh( geometry, getAxisMaterial( color2 ) );
-		const zAxis = new Mesh( geometry, getAxisMaterial( color3 ) );
-
-		yAxis.rotation.z = Math.PI / 2;
-		zAxis.rotation.y = - Math.PI / 2;
-
-		this.add( xAxis );
-		this.add( zAxis );
-		this.add( yAxis );
-
-		const spriteMaterial1 = getSpriteMaterial( color1 );
-		const spriteMaterial2 = getSpriteMaterial( color2 );
-		const spriteMaterial3 = getSpriteMaterial( color3 );
-		const spriteMaterial4 = getSpriteMaterial( color4 );
-
-		const posXAxisHelper = new Sprite( spriteMaterial1 );
-		const posYAxisHelper = new Sprite( spriteMaterial2 );
-		const posZAxisHelper = new Sprite( spriteMaterial3 );
-		const negXAxisHelper = new Sprite( spriteMaterial4 );
-		const negYAxisHelper = new Sprite( spriteMaterial4 );
-		const negZAxisHelper = new Sprite( spriteMaterial4 );
-
-		posXAxisHelper.position.x = 1;
-		posYAxisHelper.position.y = 1;
-		posZAxisHelper.position.z = 1;
-		negXAxisHelper.position.x = - 1;
-		negYAxisHelper.position.y = - 1;
-		negZAxisHelper.position.z = - 1;
-
-		negXAxisHelper.material.opacity = 0.2;
-		negYAxisHelper.material.opacity = 0.2;
-		negZAxisHelper.material.opacity = 0.2;
-
-		posXAxisHelper.userData.type = 'posX';
-		posYAxisHelper.userData.type = 'posY';
-		posZAxisHelper.userData.type = 'posZ';
-		negXAxisHelper.userData.type = 'negX';
-		negYAxisHelper.userData.type = 'negY';
-		negZAxisHelper.userData.type = 'negZ';
-
-		this.add( posXAxisHelper );
-		this.add( posYAxisHelper );
-		this.add( posZAxisHelper );
-		this.add( negXAxisHelper );
-		this.add( negYAxisHelper );
-		this.add( negZAxisHelper );
-
-		interactiveObjects.push( posXAxisHelper );
-		interactiveObjects.push( posYAxisHelper );
-		interactiveObjects.push( posZAxisHelper );
-		interactiveObjects.push( negXAxisHelper );
-		interactiveObjects.push( negYAxisHelper );
-		interactiveObjects.push( negZAxisHelper );
-
-		const point = new Vector3();
-		const dim = 128;
-		const turnRate = 2 * Math.PI; // turn rate in angles per second
-
-		/**
-		 * Renders the helper in a separate view in the viewport.
-		 * Position is controlled by the `location` property.
-		 *
-		 * @param {WebGLRenderer|WebGPURenderer} renderer - The renderer.
-		 */
-		this.render = function ( renderer ) {
-
-			this.quaternion.copy( camera.quaternion ).invert();
-			this.updateMatrixWorld();
-
-			point.set( 0, 0, 1 );
-			point.applyQuaternion( camera.quaternion );
-
-			//
-
-			const location = this.location;
-
-			let x, y;
-
-			if ( location.left !== null ) {
-
-				x = location.left;
-
-			} else {
-
-				x = domElement.offsetWidth - dim - location.right;
-
-			}
-
-			if ( location.top !== null ) {
-
-				// Position from top
-				y = renderer.isWebGPURenderer ? location.top : domElement.offsetHeight - dim - location.top;
-
-			} else {
-
-				// Position from bottom
-				y = renderer.isWebGPURenderer ? domElement.offsetHeight - dim - location.bottom : location.bottom;
-
-			}
-
-			renderer.clearDepth();
-
-			renderer.getViewport( viewport );
-			renderer.setViewport( x, y, dim, dim );
-
-			renderer.render( this, orthoCamera );
-
-			renderer.setViewport( viewport.x, viewport.y, viewport.z, viewport.w );
-
-		};
-
-		const targetPosition = new Vector3();
-		const targetQuaternion = new Quaternion();
-
-		const q1 = new Quaternion();
-		const q2 = new Quaternion();
-		const viewport = new Vector4();
-		let radius = 0;
-
-		/**
-		 * This method should be called when a click or pointer event
-		 * has happened in the app.
-		 *
-		 * @param {PointerEvent} event - The event to process.
-		 * @return {boolean} Whether an intersection with the helper has been detected or not.
-		 */
-		this.handleClick = function ( event ) {
-
-			if ( this.animating === true ) return false;
-
-			const rect = domElement.getBoundingClientRect();
-			const location = this.location;
-
-			let offsetX, offsetY;
-
-			if ( location.left !== null ) {
-
-				offsetX = rect.left + location.left;
-
-			} else {
-
-				offsetX = rect.left + domElement.offsetWidth - dim - location.right;
-
-			}
-
-			if ( location.top !== null ) {
-
-				offsetY = rect.top + location.top;
-
-			} else {
-
-				offsetY = rect.top + domElement.offsetHeight - dim - location.bottom;
-
-			}
-
-			mouse.x = ( ( event.clientX - offsetX ) / dim ) * 2 - 1;
-			mouse.y = - ( ( event.clientY - offsetY ) / dim ) * 2 + 1;
-
-			raycaster.setFromCamera( mouse, orthoCamera );
-
-			const intersects = raycaster.intersectObjects( interactiveObjects );
-
-			if ( intersects.length > 0 ) {
-
-				const intersection = intersects[ 0 ];
-				const object = intersection.object;
-
-				prepareAnimationData( object, this.center );
-
-				this.animating = true;
-
-				return true;
-
-			} else {
-
-				return false;
-
-			}
-
-		};
-
-		/**
-		 * Sets labels for each axis. By default, they are unlabeled.
-		 *
-		 * @param {string|undefined} labelX - The label for the x-axis.
-		 * @param {string|undefined} labelY - The label for the y-axis.
-		 * @param {string|undefined} labelZ - The label for the z-axis.
-		 */
-		this.setLabels = function ( labelX, labelY, labelZ ) {
-
-			options.labelX = labelX;
-			options.labelY = labelY;
-			options.labelZ = labelZ;
-
-			updateLabels();
-
-		};
-
-		/**
-		 * Sets the label style. Has no effect when the axes are unlabeled.
-		 *
-		 * @param {string} [font='24px Arial'] - The label font.
-		 * @param {string} [color='#000000'] - The label color.
-		 * @param {number} [radius=14] - The label radius.
-		 */
-		this.setLabelStyle = function ( font, color, radius ) {
-
-			options.font = font;
-			options.color = color;
-			options.radius = radius;
-
-			updateLabels();
-
-		};
-
-		/**
-		 * Updates the helper. This method should be called in the app's animation
-		 * loop.
-		 *
-		 * @param {number} delta - The delta time in seconds.
-		 */
-		this.update = function ( delta ) {
-
-			const step = delta * turnRate;
-
-			// animate position by doing a slerp and then scaling the position on the unit sphere
-
-			q1.rotateTowards( q2, step );
-			camera.position.set( 0, 0, 1 ).applyQuaternion( q1 ).multiplyScalar( radius ).add( this.center );
-
-			// animate orientation
-
-			camera.quaternion.rotateTowards( targetQuaternion, step );
-
-			if ( q1.angleTo( q2 ) === 0 ) {
-
-				this.animating = false;
-
-			}
-
-		};
-
-		/**
-		 * Frees the GPU-related resources allocated by this instance. Call this
-		 * method whenever this instance is no longer used in your app.
-		 */
-		this.dispose = function () {
-
-			geometry.dispose();
-
-			xAxis.material.dispose();
-			yAxis.material.dispose();
-			zAxis.material.dispose();
-
-			posXAxisHelper.material.map.dispose();
-			posYAxisHelper.material.map.dispose();
-			posZAxisHelper.material.map.dispose();
-			negXAxisHelper.material.map.dispose();
-			negYAxisHelper.material.map.dispose();
-			negZAxisHelper.material.map.dispose();
-
-			posXAxisHelper.material.dispose();
-			posYAxisHelper.material.dispose();
-			posZAxisHelper.material.dispose();
-			negXAxisHelper.material.dispose();
-			negYAxisHelper.material.dispose();
-			negZAxisHelper.material.dispose();
-
-		};
-
-		function prepareAnimationData( object, focusPoint ) {
-
-			switch ( object.userData.type ) {
-
-				case 'posX':
-					targetPosition.set( 1, 0, 0 );
-					targetQuaternion.setFromEuler( new Euler( 0, Math.PI * 0.5, 0 ) );
-					break;
-
-				case 'posY':
-					targetPosition.set( 0, 1, 0 );
-					targetQuaternion.setFromEuler( new Euler( - Math.PI * 0.5, 0, 0 ) );
-					break;
-
-				case 'posZ':
-					targetPosition.set( 0, 0, 1 );
-					targetQuaternion.setFromEuler( new Euler() );
-					break;
-
-				case 'negX':
-					targetPosition.set( - 1, 0, 0 );
-					targetQuaternion.setFromEuler( new Euler( 0, - Math.PI * 0.5, 0 ) );
-					break;
-
-				case 'negY':
-					targetPosition.set( 0, - 1, 0 );
-					targetQuaternion.setFromEuler( new Euler( Math.PI * 0.5, 0, 0 ) );
-					break;
-
-				case 'negZ':
-					targetPosition.set( 0, 0, - 1 );
-					targetQuaternion.setFromEuler( new Euler( 0, Math.PI, 0 ) );
-					break;
-
-				default:
-					console.error( 'ViewHelper: Invalid axis.' );
-
-			}
-
-			//
-
-			radius = camera.position.distanceTo( focusPoint );
-			targetPosition.multiplyScalar( radius ).add( focusPoint );
-
-			dummy.position.copy( focusPoint );
-
-			dummy.lookAt( camera.position );
-			q1.copy( dummy.quaternion );
-
-			dummy.lookAt( targetPosition );
-			q2.copy( dummy.quaternion );
-
-		}
-
-		function getAxisMaterial( color ) {
-
-			return new MeshBasicMaterial( { color: color, toneMapped: false } );
-
-		}
-
-		function useOffscreenCanvas() {
-
-			let result = false;
-
-			try {
-
-				// this check has been adapted from WebGLTextures
-
-				result = typeof OffscreenCanvas !== 'undefined' && ( new OffscreenCanvas( 1, 1 ).getContext( '2d' ) ) !== null;
-
-			} catch ( err ) {
-
-				// Ignore any errors
-
-			}
-
-			return result;
-
-		}
-
-		function createCanvas( width, height ) {
-
-			let canvas;
-
-			if ( useOffscreenCanvas() ) {
-
-				canvas = new OffscreenCanvas( width, height );
-
-			} else {
-
-				canvas = document.createElement( 'canvas' );
-				canvas.width = width;
-				canvas.height = height;
-
-			}
-
-			return canvas;
-
-		}
-
-		function getSpriteMaterial( color, text ) {
-
-			const { font = '24px Arial', color: labelColor = '#000000', radius = 14 } = options;
-
-			const canvas = createCanvas( 64, 64 );
-
-			const context = canvas.getContext( '2d' );
-			context.beginPath();
-			context.arc( 32, 32, radius, 0, 2 * Math.PI );
-			context.closePath();
-			context.fillStyle = color.getStyle();
-			context.fill();
-
-			if ( text ) {
-
-				context.font = font;
-				context.textAlign = 'center';
-				context.fillStyle = labelColor;
-				context.fillText( text, 32, 41 );
-
-			}
-
-			const texture = new CanvasTexture( canvas );
-			texture.colorSpace = SRGBColorSpace;
-
-			return new SpriteMaterial( { map: texture, toneMapped: false } );
-
-		}
-
-		function updateLabels() {
-
-			posXAxisHelper.material.map.dispose();
-			posYAxisHelper.material.map.dispose();
-			posZAxisHelper.material.map.dispose();
-
-			posXAxisHelper.material.dispose();
-			posYAxisHelper.material.dispose();
-			posZAxisHelper.material.dispose();
-
-			posXAxisHelper.material = getSpriteMaterial( color1, options.labelX );
-			posYAxisHelper.material = getSpriteMaterial( color2, options.labelY );
-			posZAxisHelper.material = getSpriteMaterial( color3, options.labelZ );
-
-		}
-
-	}
-
-}
-
-export { ViewHelper };

+ 0 - 13
node_modules/three/examples/jsm/inspector/Extension.js

@@ -1,13 +0,0 @@
-import { Tab } from 'three/addons/inspector/ui/Tab.js';
-
-export class Extension extends Tab {
-
-	constructor( name, options = {} ) {
-
-		super( name, options );
-
-		this.isExtension = true;
-
-	}
-
-}

+ 0 - 542
node_modules/three/examples/jsm/inspector/Inspector.js

@@ -1,542 +0,0 @@
-
-import { RendererInspector } from './RendererInspector.js';
-import { Profiler } from './ui/Profiler.js';
-import { Performance } from './tabs/Performance.js';
-import { Memory } from './tabs/Memory.js';
-import { Console } from './tabs/Console.js';
-import { Parameters } from './tabs/Parameters.js';
-import { Settings } from './tabs/Settings.js';
-import { Viewer } from './tabs/Viewer.js';
-import { Timeline } from './tabs/Timeline.js';
-import { setText } from './ui/utils.js';
-
-import { setConsoleFunction, REVISION } from 'three/webgpu';
-
-class Inspector extends RendererInspector {
-
-	constructor() {
-
-		super();
-
-		// init profiler
-
-		const profiler = new Profiler( this );
-		profiler.addEventListener( 'resize', ( e ) => this.dispatchEvent( e ) );
-
-		const parameters = new Parameters( {
-			builtin: true,
-			icon: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M14 6m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" /><path d="M4 6l8 0" /><path d="M16 6l4 0" /><path d="M8 12m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" /><path d="M4 12l2 0" /><path d="M10 12l10 0" /><path d="M17 18m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" /><path d="M4 18l11 0" /><path d="M19 18l1 0" /></svg>'
-		} );
-		parameters.hide();
-		profiler.addTab( parameters );
-
-		const viewer = new Viewer();
-		viewer.hide();
-		profiler.addTab( viewer );
-
-		const performance = new Performance();
-		profiler.addTab( performance );
-
-		const memory = new Memory();
-		profiler.addTab( memory );
-
-		const timeline = new Timeline();
-		profiler.addTab( timeline );
-
-		const consoleTab = new Console();
-		profiler.addTab( consoleTab );
-
-		const settings = new Settings();
-		profiler.addTab( settings );
-
-		profiler.loadLayout();
-
-		if ( ! profiler.activeTabId ) {
-
-			profiler.setActiveTab( performance.id );
-
-		}
-
-		this.statsData = new Map();
-		this.profiler = profiler;
-		this.performance = performance;
-		this.memory = memory;
-		this.console = consoleTab;
-		this.parameters = parameters;
-		this.viewer = viewer;
-		this.timeline = timeline;
-		this.settings = settings;
-		this.once = {};
-		this.extensionsData = new WeakMap();
-
-		this.displayCycle = {
-			text: {
-				needsUpdate: false,
-				duration: .25,
-				time: 0
-			},
-			graph: {
-				needsUpdate: false,
-				duration: .02,
-				time: 0
-			}
-		};
-
-	}
-
-	get domElement() {
-
-		return this.profiler.domElement;
-
-	}
-
-	onExtension( name, callback ) {
-
-		const extensionAdded = ( e ) => {
-
-			if ( e.name === name ) {
-
-				callback( e.tab );
-
-				this.settings.removeEventListener( 'extensionadded', extensionAdded );
-
-			}
-
-		};
-
-		if ( this.settings.extensions[ name ] && this.settings.extensions[ name ].loaded ) {
-
-			callback( this.settings.extensions[ name ] );
-
-		} else {
-
-			this.settings.addEventListener( 'extensionadded', extensionAdded );
-
-		}
-
-		return this;
-
-	}
-
-	hide() {
-
-		this.profiler.hide();
-
-	}
-
-	show() {
-
-		this.profiler.show();
-
-	}
-
-	getSize() {
-
-		return this.profiler.getSize();
-
-	}
-
-	setActiveTab( tab ) {
-
-		this.profiler.setActiveTab( tab.id );
-
-		return this;
-
-	}
-
-	addTab( tab ) {
-
-		this.profiler.addTab( tab );
-
-		return this;
-
-	}
-
-	removeTab( tab ) {
-
-		this.profiler.removeTab( tab );
-
-		return this;
-
-	}
-
-	setActiveExtension( name, value ) {
-
-		this.settings.setActiveExtension( name, value );
-
-		return this;
-
-	}
-
-	resolveConsoleOnce( type, message ) {
-
-		const key = type + message;
-
-		if ( this.once[ key ] !== true ) {
-
-			this.resolveConsole( type, message );
-			this.once[ key ] = true;
-
-		}
-
-	}
-
-	resolveConsole( type, message, stackTrace = null ) {
-
-		switch ( type ) {
-
-			case 'log':
-
-				this.console.addMessage( 'info', message );
-
-				console.log( message );
-
-				break;
-
-			case 'warn':
-
-				this.console.addMessage( 'warn', message );
-
-				if ( stackTrace && stackTrace.isStackTrace ) {
-
-					console.warn( stackTrace.getError( message ) );
-
-				} else {
-
-					console.warn( message );
-
-				}
-
-				break;
-
-			case 'error':
-
-				this.console.addMessage( 'error', message );
-
-				if ( stackTrace && stackTrace.isStackTrace ) {
-
-					console.error( stackTrace.getError( message ) );
-
-				} else {
-
-					console.error( message );
-
-				}
-
-				break;
-
-		}
-
-	}
-
-	init() {
-
-		const renderer = this.getRenderer();
-
-		let sign = `THREE.WebGPURenderer: ${ REVISION } [ "`;
-
-		if ( renderer.backend.isWebGPUBackend ) {
-
-			sign += 'WebGPU';
-
-		} else if ( renderer.backend.isWebGLBackend ) {
-
-			sign += 'WebGL2';
-
-		}
-
-		sign += '" ]';
-
-		this.console.addMessage( 'info', sign );
-
-		//
-
-		if ( renderer.inspector.domElement.parentElement === null && renderer.domElement.parentElement !== null ) {
-
-			renderer.domElement.parentElement.appendChild( renderer.inspector.domElement );
-
-		}
-
-	}
-
-	setRenderer( renderer ) {
-
-		super.setRenderer( renderer );
-
-		if ( renderer !== null ) {
-
-			setConsoleFunction( this.resolveConsole.bind( this ) );
-
-			if ( this.isAvailable ) {
-
-				renderer.init().then( () => {
-
-					renderer.backend.trackTimestamp = true;
-
-					if ( renderer.hasFeature( 'timestamp-query' ) !== true ) {
-
-						this.console.addMessage( 'error', 'THREE.Inspector: GPU Timestamp Queries not available.' );
-
-					}
-
-				} );
-
-				this.timeline.setRenderer( renderer );
-
-			}
-
-		}
-
-		return this;
-
-	}
-
-	createParameters( name ) {
-
-		if ( this.parameters.isVisible === false ) {
-
-			this.parameters.show();
-
-		}
-
-		return this.parameters.createGroup( name );
-
-	}
-
-	getStatsData( cid ) {
-
-		let data = this.statsData.get( cid );
-
-		if ( data === undefined ) {
-
-			data = {};
-
-			this.statsData.set( cid, data );
-
-		}
-
-		return data;
-
-	}
-
-	resolveStats( stats ) {
-
-		const data = this.getStatsData( stats.cid );
-
-		if ( data.initialized !== true ) {
-
-			data.cpu = stats.cpu;
-			data.gpu = stats.gpu;
-			data.stats = [];
-
-			data.initialized = true;
-
-		}
-
-		// store stats
-
-		if ( data.stats.length > this.maxFrames ) {
-
-			data.stats.shift();
-
-		}
-
-		data.stats.push( stats );
-
-		// compute averages
-
-		data.cpu = this.getAverageDeltaTime( data, 'cpu' );
-		data.gpu = this.getAverageDeltaTime( data, 'gpu' );
-		data.total = data.cpu + data.gpu;
-
-		// children
-
-		for ( const child of stats.children ) {
-
-			this.resolveStats( child );
-
-			const childData = this.getStatsData( child.cid );
-
-			data.cpu += childData.cpu;
-			data.gpu += childData.gpu;
-			data.total += childData.total;
-
-		}
-
-	}
-
-	getNodes() {
-
-		return this.currentNodes;
-
-	}
-
-	getAverageDeltaTime( statsData, property, frames = this.fps ) {
-
-		const statsArray = statsData.stats;
-
-		let sum = 0;
-		let count = 0;
-
-		for ( let i = statsArray.length - 1; i >= 0 && count < frames; i -- ) {
-
-			const stats = statsArray[ i ];
-			const value = stats[ property ];
-
-			if ( value > 0 ) {
-
-				// ignore invalid values
-
-				sum += value;
-				count ++;
-
-			}
-
-		}
-
-		return count > 0 ? sum / count : 0;
-
-	}
-
-	updateTabs() {
-
-		// tabs
-
-		const tabs = Object.values( this.profiler.tabs );
-
-		for ( const tab of tabs ) {
-
-			let tabData = this.extensionsData.get( tab );
-
-			if ( tabData === undefined ) {
-
-				tab.init( this );
-
-				tabData = {};
-
-				this.extensionsData.set( tab, tabData );
-
-			}
-
-			tab.update( this );
-
-		}
-
-	}
-
-	resolveFrame( frame ) {
-
-		const nextFrame = this.getFrameById( frame.frameId + 1 );
-
-		if ( ! nextFrame ) return;
-
-		frame.cpu = 0;
-		frame.gpu = 0;
-		frame.total = 0;
-
-		for ( const stats of frame.children ) {
-
-			this.resolveStats( stats );
-
-			const data = this.getStatsData( stats.cid );
-
-			frame.cpu += data.cpu;
-			frame.gpu += data.gpu;
-			frame.total += data.total;
-
-		}
-
-		// improve stats using next frame
-
-		frame.deltaTime = nextFrame.startTime - frame.startTime;
-		frame.miscellaneous = frame.deltaTime - frame.total;
-
-		if ( frame.miscellaneous < 0 ) {
-
-			// Frame desync, probably due to async GPU timing.
-
-			frame.miscellaneous = 0;
-
-		}
-
-		//
-
-		this.updateCycle( this.displayCycle.text );
-		this.updateCycle( this.displayCycle.graph );
-
-		if ( this.displayCycle.text.needsUpdate ) {
-
-			setText( 'fps-counter', this.fps.toFixed() );
-
-			this.performance.updateText( this, frame );
-			this.memory.updateText( this );
-
-		}
-
-		if ( this.displayCycle.graph.needsUpdate ) {
-
-			this.performance.updateGraph( this, frame );
-			this.memory.updateGraph( this );
-
-		}
-
-		this.displayCycle.text.needsUpdate = false;
-		this.displayCycle.graph.needsUpdate = false;
-
-	}
-
-	updateCycle( cycle ) {
-
-		cycle.time += this.nodeFrame.deltaTime;
-
-		if ( cycle.time >= cycle.duration ) {
-
-			cycle.needsUpdate = true;
-			cycle.time = 0;
-
-		}
-
-	}
-
-	static getItem( id ) {
-
-		console.warn( 'Inspector.getItem is deprecated. Use getItem directly instead.' );
-		return getItem( id );
-
-	}
-
-	static setItem( id, state ) {
-
-		console.warn( 'Inspector.setItem is deprecated. Use setItem directly instead.' );
-		setItem( id, state );
-
-	}
-
-}
-
-function getItem( id ) {
-
-	const data = JSON.parse( localStorage.getItem( 'threejs-inspector' ) || '{}' );
-	return data[ id ] || {};
-
-}
-
-function setItem( id, state ) {
-
-	const data = JSON.parse( localStorage.getItem( 'threejs-inspector' ) || '{}' );
-
-	if ( state === null ) {
-
-		delete data[ id ];
-
-	} else {
-
-		data[ id ] = state;
-
-	}
-
-	localStorage.setItem( 'threejs-inspector', JSON.stringify( data ) );
-
-}
-
-export { Inspector, getItem, setItem };

+ 0 - 425
node_modules/three/examples/jsm/inspector/RendererInspector.js

@@ -1,425 +0,0 @@
-
-import { InspectorBase, TimestampQuery, warnOnce } from 'three/webgpu';
-
-class ObjectStats {
-
-	constructor( uid, name ) {
-
-		this.uid = uid;
-		this.cid = uid.match( /^(.*):f(\d+)$/ )[ 1 ]; // call id
-		this.name = name;
-		this.timestamp = 0;
-		this.cpu = 0;
-		this.gpu = 0;
-		this.fps = 0;
-
-		this.children = [];
-		this.parent = null;
-
-	}
-
-}
-
-class RenderStats extends ObjectStats {
-
-	constructor( uid, scene, camera, renderTarget ) {
-
-		let name = scene.name;
-
-		if ( name === '' ) {
-
-			if ( scene.isScene ) {
-
-				name = 'Scene';
-
-			} else if ( scene.isQuadMesh ) {
-
-				name = 'QuadMesh';
-
-			}
-
-		}
-
-		super( uid, name );
-
-		this.scene = scene;
-		this.camera = camera;
-		this.renderTarget = renderTarget;
-
-		this.isRenderStats = true;
-
-	}
-
-}
-
-class ComputeStats extends ObjectStats {
-
-	constructor( uid, computeNode ) {
-
-		super( uid, computeNode.name );
-
-		this.computeNode = computeNode;
-
-		this.isComputeStats = true;
-
-	}
-
-}
-
-export class RendererInspector extends InspectorBase {
-
-	constructor() {
-
-		super();
-
-		this.currentFrame = null;
-		this.currentRender = null;
-		this.currentNodes = null;
-		this.lastFrame = null;
-
-		this.frames = [];
-		this.framesLib = {};
-		this.maxFrames = 512;
-
-		this._lastFinishTime = 0;
-		this._resolveTimestampPromise = null;
-
-		this.isRendererInspector = true;
-
-	}
-
-	getParent() {
-
-		return this.currentRender || this.getFrame();
-
-	}
-
-	begin() {
-
-		this.currentFrame = this._createFrame();
-		this.currentRender = this.currentFrame;
-		this.currentNodes = [];
-
-	}
-
-	finish() {
-
-		const now = performance.now();
-
-		const frame = this.currentFrame;
-		frame.finishTime = now;
-		frame.deltaTime = now - ( this._lastFinishTime > 0 ? this._lastFinishTime : now );
-
-		this.addFrame( frame );
-
-		this.fps = this._getFPS();
-
-		this.lastFrame = frame;
-
-		this.currentFrame = null;
-		this.currentRender = null;
-		this.currentNodes = null;
-
-		this._lastFinishTime = now;
-
-	}
-
-	_getFPS() {
-
-		let frameSum = 0;
-		let timeSum = 0;
-
-		for ( let i = this.frames.length - 1; i >= 0; i -- ) {
-
-			const frame = this.frames[ i ];
-
-			frameSum ++;
-			timeSum += frame.deltaTime;
-
-			if ( timeSum >= 1000 ) break;
-
-		}
-
-		return ( frameSum * 1000 ) / timeSum;
-
-	}
-
-	_createFrame() {
-
-		return {
-			frameId: this.nodeFrame.frameId,
-			resolvedCompute: false,
-			resolvedRender: false,
-			deltaTime: 0,
-			startTime: performance.now(),
-			finishTime: 0,
-			miscellaneous: 0,
-			children: [],
-			renders: [],
-			computes: []
-		};
-
-	}
-
-	getFrame() {
-
-		return this.currentFrame || this.lastFrame;
-
-	}
-
-	getFrameById( frameId ) {
-
-		return this.framesLib[ frameId ] || null;
-
-	}
-
-	updateTabs() { }
-
-	resolveFrame( /*frame*/ ) { }
-
-	async resolveTimestamp() {
-
-		if ( this._resolveTimestampPromise !== null ) {
-
-			return this._resolveTimestampPromise;
-
-		}
-
-		this._resolveTimestampPromise = new Promise( ( resolve ) => {
-
-			requestAnimationFrame( async () => {
-
-				const renderer = this.getRenderer();
-
-				await renderer.resolveTimestampsAsync( TimestampQuery.COMPUTE );
-				await renderer.resolveTimestampsAsync( TimestampQuery.RENDER );
-
-				const computeFrames = renderer.backend.getTimestampFrames( TimestampQuery.COMPUTE );
-				const renderFrames = renderer.backend.getTimestampFrames( TimestampQuery.RENDER );
-
-				const frameIds = [ ...new Set( [ ...computeFrames, ...renderFrames ] ) ];
-
-				for ( const frameId of frameIds ) {
-
-					const frame = this.getFrameById( frameId );
-
-					if ( frame !== null ) {
-
-						// resolve compute timestamps
-
-						if ( frame.resolvedCompute === false ) {
-
-							if ( frame.computes.length > 0 ) {
-
-								if ( computeFrames.includes( frameId ) ) {
-
-									for ( const stats of frame.computes ) {
-
-										if ( renderer.backend.hasTimestamp( stats.uid ) ) {
-
-											stats.gpu = renderer.backend.getTimestamp( stats.uid );
-
-										} else {
-
-											stats.gpu = 0;
-											stats.gpuNotAvailable = true;
-
-										}
-
-									}
-
-									frame.resolvedCompute = true;
-
-								}
-
-							} else {
-
-								frame.resolvedCompute = true;
-
-							}
-
-						}
-
-						// resolve render timestamps
-
-						if ( frame.resolvedRender === false ) {
-
-							if ( frame.renders.length > 0 ) {
-
-								if ( renderFrames.includes( frameId ) ) {
-
-									for ( const stats of frame.renders ) {
-
-										if ( renderer.backend.hasTimestamp( stats.uid ) ) {
-
-											stats.gpu = renderer.backend.getTimestamp( stats.uid );
-
-										} else {
-
-											stats.gpu = 0;
-											stats.gpuNotAvailable = true;
-
-										}
-
-									}
-
-									frame.resolvedRender = true;
-
-								}
-
-							} else {
-
-								frame.resolvedRender = true;
-
-							}
-
-						}
-
-						if ( frame.resolvedCompute === true && frame.resolvedRender === true ) {
-
-							this.resolveFrame( frame );
-
-						}
-
-					}
-
-				}
-
-				this._resolveTimestampPromise = null;
-
-				resolve();
-
-			} );
-
-		} );
-
-		return this._resolveTimestampPromise;
-
-	}
-
-	get isAvailable() {
-
-		const renderer = this.getRenderer();
-
-		return renderer !== null;
-
-	}
-
-	addFrame( frame ) {
-
-		// Limit to max frames.
-
-		if ( this.frames.length >= this.maxFrames ) {
-
-			const removedFrame = this.frames.shift();
-			delete this.framesLib[ removedFrame.frameId ];
-
-		}
-
-		this.frames.push( frame );
-		this.framesLib[ frame.frameId ] = frame;
-
-		if ( this.isAvailable ) {
-
-			this.updateTabs();
-			this.resolveTimestamp();
-
-		}
-
-	}
-
-	inspect( node ) {
-
-		const currentNodes = this.currentNodes;
-
-		if ( currentNodes !== null ) {
-
-			currentNodes.push( node );
-
-		} else {
-
-			warnOnce( 'RendererInspector: Unable to inspect node outside of frame scope. Use "renderer.setAnimationLoop()".' );
-
-		}
-
-	}
-
-	beginCompute( uid, computeNode ) {
-
-		const frame = this.getFrame();
-
-		if ( ! frame ) return;
-
-		const currentCompute = new ComputeStats( uid, computeNode );
-		currentCompute.timestamp = performance.now();
-		currentCompute.parent = this.currentCompute || this.getParent();
-
-		frame.computes.push( currentCompute );
-
-		if ( this.currentRender !== null ) {
-
-			this.currentRender.children.push( currentCompute );
-
-		} else {
-
-			frame.children.push( currentCompute );
-
-		}
-
-		this.currentCompute = currentCompute;
-
-	}
-
-	finishCompute() {
-
-		const frame = this.getFrame();
-
-		if ( ! frame ) return;
-
-		const currentCompute = this.currentCompute;
-		currentCompute.cpu = performance.now() - currentCompute.timestamp;
-
-		this.currentCompute = currentCompute.parent.isComputeStats ? currentCompute.parent : null;
-
-	}
-
-	beginRender( uid, scene, camera, renderTarget ) {
-
-		const frame = this.getFrame();
-
-		if ( ! frame ) return;
-
-		const currentRender = new RenderStats( uid, scene, camera, renderTarget );
-		currentRender.timestamp = performance.now();
-		currentRender.parent = this.getParent();
-
-		frame.renders.push( currentRender );
-
-		if ( this.currentRender !== null ) {
-
-			this.currentRender.children.push( currentRender );
-
-		} else {
-
-			frame.children.push( currentRender );
-
-		}
-
-		this.currentRender = currentRender;
-
-	}
-
-	finishRender() {
-
-		const frame = this.getFrame();
-
-		if ( ! frame ) return;
-
-		const currentRender = this.currentRender;
-		currentRender.cpu = performance.now() - currentRender.timestamp;
-
-		this.currentRender = currentRender.parent;
-
-	}
-
-}

Некоторые файлы не были показаны из-за большого количества измененных файлов