@plastic-software/three 0.167.4 → 0.174.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (747) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1 -1
  3. package/build/three.cjs +36217 -23964
  4. package/build/three.core.js +48830 -0
  5. package/build/three.core.min.js +6 -0
  6. package/build/three.module.js +10175 -46744
  7. package/build/three.module.min.js +2 -3
  8. package/build/three.tsl.js +550 -0
  9. package/build/three.tsl.min.js +6 -0
  10. package/build/three.webgpu.js +44348 -50671
  11. package/build/three.webgpu.min.js +2 -3
  12. package/build/three.webgpu.nodes.js +70301 -0
  13. package/build/three.webgpu.nodes.min.js +6 -0
  14. package/examples/jsm/Addons.js +3 -15
  15. package/examples/jsm/animation/AnimationClipCreator.js +1 -1
  16. package/examples/jsm/animation/CCDIKSolver.js +61 -11
  17. package/examples/jsm/capabilities/WebGL.js +27 -21
  18. package/examples/jsm/capabilities/WebGPU.js +1 -10
  19. package/examples/jsm/controls/ArcballControls.js +262 -231
  20. package/examples/jsm/controls/DragControls.js +1 -1
  21. package/examples/jsm/controls/FirstPersonControls.js +175 -163
  22. package/examples/jsm/controls/FlyControls.js +194 -188
  23. package/examples/jsm/controls/OrbitControls.js +801 -777
  24. package/examples/jsm/controls/PointerLockControls.js +26 -20
  25. package/examples/jsm/controls/TrackballControls.js +469 -448
  26. package/examples/jsm/controls/TransformControls.js +119 -68
  27. package/examples/jsm/csm/CSM.js +2 -2
  28. package/examples/jsm/csm/CSMFrustum.js +7 -4
  29. package/examples/jsm/csm/CSMHelper.js +2 -0
  30. package/examples/jsm/csm/CSMShadowNode.js +442 -0
  31. package/examples/jsm/curves/NURBSCurve.js +33 -2
  32. package/examples/jsm/curves/NURBSUtils.js +3 -0
  33. package/examples/jsm/effects/AnaglyphEffect.js +6 -13
  34. package/examples/jsm/effects/OutlineEffect.js +1 -1
  35. package/examples/jsm/effects/ParallaxBarrierEffect.js +17 -11
  36. package/examples/jsm/effects/StereoEffect.js +6 -1
  37. package/examples/jsm/exporters/DRACOExporter.js +4 -2
  38. package/examples/jsm/exporters/EXRExporter.js +19 -11
  39. package/examples/jsm/exporters/GLTFExporter.js +181 -109
  40. package/examples/jsm/exporters/KTX2Exporter.js +54 -23
  41. package/examples/jsm/exporters/OBJExporter.js +5 -1
  42. package/examples/jsm/exporters/PLYExporter.js +11 -9
  43. package/examples/jsm/exporters/USDZExporter.js +50 -11
  44. package/examples/jsm/geometries/DecalGeometry.js +73 -21
  45. package/examples/jsm/geometries/TextGeometry.js +1 -12
  46. package/examples/jsm/helpers/LightProbeHelper.js +43 -44
  47. package/examples/jsm/helpers/LightProbeHelperGPU.js +65 -0
  48. package/examples/jsm/helpers/TextureHelperGPU.js +185 -0
  49. package/examples/jsm/helpers/VertexNormalsHelper.js +2 -0
  50. package/examples/jsm/interactive/HTMLMesh.js +1 -0
  51. package/examples/jsm/interactive/InteractiveGroup.js +108 -51
  52. package/examples/jsm/interactive/SelectionHelper.js +3 -1
  53. package/examples/jsm/libs/basis/basis_transcoder.js +8 -10
  54. package/examples/jsm/libs/basis/basis_transcoder.wasm +0 -0
  55. package/examples/jsm/libs/demuxer_mp4.js +109 -0
  56. package/examples/jsm/libs/ktx-parse.module.js +1 -1
  57. package/examples/jsm/lighting/TiledLighting.js +18 -0
  58. package/examples/jsm/lights/LightProbeGenerator.js +26 -12
  59. package/examples/jsm/lights/RectAreaLightTexturesLib.js +1 -1
  60. package/examples/jsm/lines/LineGeometry.js +25 -0
  61. package/examples/jsm/lines/LineMaterial.js +0 -1
  62. package/examples/jsm/lines/LineSegmentsGeometry.js +2 -0
  63. package/examples/jsm/lines/webgpu/Line2.js +2 -1
  64. package/examples/jsm/lines/webgpu/LineSegments2.js +16 -21
  65. package/examples/jsm/lines/webgpu/Wireframe.js +57 -0
  66. package/examples/jsm/loaders/3DMLoader.js +1 -0
  67. package/examples/jsm/loaders/3MFLoader.js +104 -2
  68. package/examples/jsm/loaders/BVHLoader.js +1 -1
  69. package/examples/jsm/loaders/ColladaLoader.js +15 -12
  70. package/examples/jsm/loaders/DDSLoader.js +42 -0
  71. package/examples/jsm/loaders/DRACOLoader.js +3 -1
  72. package/examples/jsm/loaders/FBXLoader.js +71 -22
  73. package/examples/jsm/loaders/GCodeLoader.js +4 -2
  74. package/examples/jsm/loaders/GLTFLoader.js +29 -14
  75. package/examples/jsm/loaders/KTX2Loader.js +160 -58
  76. package/examples/jsm/loaders/KTXLoader.js +4 -4
  77. package/examples/jsm/loaders/LDrawLoader.js +22 -136
  78. package/examples/jsm/loaders/LottieLoader.js +2 -1
  79. package/examples/jsm/loaders/MTLLoader.js +27 -7
  80. package/examples/jsm/loaders/MaterialXLoader.js +40 -14
  81. package/examples/jsm/loaders/NRRDLoader.js +1 -1
  82. package/examples/jsm/loaders/OBJLoader.js +5 -3
  83. package/examples/jsm/loaders/PCDLoader.js +14 -13
  84. package/examples/jsm/loaders/PDBLoader.js +3 -2
  85. package/examples/jsm/loaders/PLYLoader.js +15 -12
  86. package/examples/jsm/loaders/PVRLoader.js +1 -1
  87. package/examples/jsm/loaders/STLLoader.js +3 -2
  88. package/examples/jsm/loaders/SVGLoader.js +2 -2
  89. package/examples/jsm/loaders/TDSLoader.js +17 -18
  90. package/examples/jsm/loaders/VRMLLoader.js +17 -17
  91. package/examples/jsm/loaders/VTKLoader.js +4 -3
  92. package/examples/jsm/loaders/XYZLoader.js +3 -2
  93. package/examples/jsm/loaders/lwo/IFFParser.js +4 -4
  94. package/examples/jsm/materials/LDrawConditionalLineMaterial.js +143 -0
  95. package/examples/jsm/materials/LDrawConditionalLineNodeMaterial.js +114 -0
  96. package/examples/jsm/materials/MeshGouraudMaterial.js +2 -0
  97. package/examples/jsm/math/ColorSpaces.js +76 -0
  98. package/examples/jsm/math/ConvexHull.js +1 -1
  99. package/examples/jsm/math/OBB.js +17 -0
  100. package/examples/jsm/misc/GPUComputationRenderer.js +6 -7
  101. package/examples/jsm/misc/ProgressiveLightMap.js +54 -41
  102. package/examples/jsm/misc/ProgressiveLightMapGPU.js +294 -0
  103. package/examples/jsm/misc/Timer.js +27 -12
  104. package/examples/jsm/misc/Volume.js +28 -18
  105. package/examples/jsm/misc/VolumeSlice.js +19 -16
  106. package/examples/jsm/modifiers/CurveModifier.js +10 -8
  107. package/examples/jsm/modifiers/CurveModifierGPU.js +235 -0
  108. package/examples/jsm/modifiers/SimplifyModifier.js +2 -2
  109. package/examples/jsm/objects/GroundedSkybox.js +4 -4
  110. package/examples/jsm/objects/LensflareMesh.js +324 -0
  111. package/examples/jsm/objects/Reflector.js +5 -2
  112. package/examples/jsm/objects/Sky.js +2 -2
  113. package/examples/jsm/objects/SkyMesh.js +14 -14
  114. package/examples/jsm/objects/Water2.js +1 -1
  115. package/examples/jsm/objects/Water2Mesh.js +11 -9
  116. package/examples/jsm/objects/WaterMesh.js +38 -33
  117. package/examples/jsm/physics/JoltPhysics.js +8 -8
  118. package/examples/jsm/physics/RapierPhysics.js +5 -5
  119. package/examples/jsm/postprocessing/AfterimagePass.js +14 -3
  120. package/examples/jsm/postprocessing/BloomPass.js +2 -2
  121. package/examples/jsm/postprocessing/EffectComposer.js +1 -2
  122. package/examples/jsm/postprocessing/OutlinePass.js +37 -51
  123. package/examples/jsm/postprocessing/OutputPass.js +2 -0
  124. package/examples/jsm/postprocessing/SAOPass.js +1 -2
  125. package/examples/jsm/postprocessing/SMAAPass.js +1 -3
  126. package/examples/jsm/postprocessing/SSAARenderPass.js +3 -1
  127. package/examples/jsm/postprocessing/SSAOPass.js +2 -4
  128. package/examples/jsm/postprocessing/SSRPass.js +8 -4
  129. package/examples/jsm/postprocessing/UnrealBloomPass.js +2 -2
  130. package/examples/jsm/renderers/CSS2DRenderer.js +6 -3
  131. package/examples/jsm/renderers/CSS3DRenderer.js +7 -4
  132. package/examples/jsm/renderers/SVGRenderer.js +6 -4
  133. package/examples/jsm/shaders/BokehShader2.js +1 -1
  134. package/examples/jsm/shaders/FXAAShader.js +225 -224
  135. package/examples/jsm/shaders/GodRaysShader.js +3 -3
  136. package/examples/jsm/shaders/OutputShader.js +6 -2
  137. package/examples/jsm/shaders/SobelOperatorShader.js +1 -1
  138. package/examples/jsm/transpiler/AST.js +12 -2
  139. package/examples/jsm/transpiler/GLSLDecoder.js +77 -31
  140. package/examples/jsm/transpiler/ShaderToyDecoder.js +3 -3
  141. package/examples/jsm/transpiler/TSLEncoder.js +96 -21
  142. package/examples/jsm/tsl/display/AfterImageNode.js +243 -0
  143. package/examples/jsm/tsl/display/AnaglyphPassNode.js +106 -0
  144. package/examples/jsm/tsl/display/AnamorphicNode.js +257 -0
  145. package/{src/nodes/display/BleachBypassNode.js → examples/jsm/tsl/display/BleachBypass.js} +11 -6
  146. package/{src/nodes → examples/jsm/tsl}/display/BloomNode.js +252 -67
  147. package/examples/jsm/tsl/display/DenoiseNode.js +332 -0
  148. package/{src/nodes → examples/jsm/tsl}/display/DepthOfFieldNode.js +92 -14
  149. package/examples/jsm/tsl/display/DotScreenNode.js +103 -0
  150. package/examples/jsm/tsl/display/FXAANode.js +364 -0
  151. package/examples/jsm/tsl/display/FilmNode.js +100 -0
  152. package/examples/jsm/tsl/display/GTAONode.js +521 -0
  153. package/examples/jsm/tsl/display/GaussianBlurNode.js +393 -0
  154. package/examples/jsm/tsl/display/LensflareNode.js +278 -0
  155. package/examples/jsm/tsl/display/Lut3DNode.js +108 -0
  156. package/examples/jsm/tsl/display/MotionBlur.js +33 -0
  157. package/examples/jsm/tsl/display/OutlineNode.js +750 -0
  158. package/examples/jsm/tsl/display/ParallaxBarrierPassNode.js +88 -0
  159. package/{src/nodes → examples/jsm/tsl}/display/PixelationPassNode.js +160 -28
  160. package/examples/jsm/tsl/display/RGBShiftNode.js +95 -0
  161. package/examples/jsm/tsl/display/SMAANode.js +767 -0
  162. package/examples/jsm/tsl/display/SSAAPassNode.js +357 -0
  163. package/examples/jsm/tsl/display/SSRNode.js +538 -0
  164. package/examples/jsm/tsl/display/Sepia.js +24 -0
  165. package/{src/nodes → examples/jsm/tsl}/display/SobelOperatorNode.js +66 -20
  166. package/examples/jsm/tsl/display/StereoCompositePassNode.js +184 -0
  167. package/examples/jsm/tsl/display/StereoPassNode.js +119 -0
  168. package/examples/jsm/tsl/display/TRAAPassNode.js +451 -0
  169. package/examples/jsm/tsl/display/TransitionNode.js +140 -0
  170. package/examples/jsm/tsl/display/hashBlur.js +34 -0
  171. package/examples/jsm/tsl/lighting/TiledLightsNode.js +395 -0
  172. package/examples/jsm/tsl/math/Bayer.js +18 -0
  173. package/examples/jsm/tsl/utils/Raymarching.js +65 -0
  174. package/examples/jsm/utils/BufferGeometryUtils.js +2 -2
  175. package/examples/jsm/utils/CameraUtils.js +4 -1
  176. package/examples/jsm/utils/GeometryCompressionUtils.js +38 -123
  177. package/examples/jsm/utils/GeometryUtils.js +22 -19
  178. package/examples/jsm/utils/SceneOptimizer.js +410 -0
  179. package/examples/jsm/utils/SceneUtils.js +2 -2
  180. package/examples/jsm/utils/ShadowMapViewer.js +3 -8
  181. package/examples/jsm/utils/ShadowMapViewerGPU.js +201 -0
  182. package/examples/jsm/utils/SkeletonUtils.js +84 -66
  183. package/examples/jsm/utils/UVsDebug.js +1 -1
  184. package/examples/jsm/utils/{TextureUtils.js → WebGLTextureUtils.js} +1 -0
  185. package/examples/jsm/utils/WebGPUTextureUtils.js +64 -0
  186. package/examples/jsm/webxr/OculusHandPointerModel.js +21 -21
  187. package/examples/jsm/webxr/Text2D.js +6 -6
  188. package/examples/jsm/webxr/XRControllerModelFactory.js +7 -2
  189. package/examples/jsm/webxr/XREstimatedLight.js +1 -1
  190. package/package.json +14 -9
  191. package/src/Three.Core.js +182 -0
  192. package/src/Three.Legacy.js +0 -21
  193. package/src/Three.TSL.js +543 -0
  194. package/src/Three.WebGPU.Nodes.js +23 -0
  195. package/src/Three.WebGPU.js +13 -184
  196. package/src/Three.js +1 -176
  197. package/src/animation/AnimationClip.js +2 -2
  198. package/src/animation/AnimationObjectGroup.js +2 -2
  199. package/src/animation/AnimationUtils.js +1 -1
  200. package/src/animation/PropertyBinding.js +2 -2
  201. package/src/audio/Audio.js +379 -2
  202. package/src/audio/AudioAnalyser.js +58 -1
  203. package/src/audio/AudioContext.js +15 -0
  204. package/src/audio/AudioListener.js +76 -0
  205. package/src/audio/PositionalAudio.js +107 -0
  206. package/src/cameras/ArrayCamera.js +29 -0
  207. package/src/cameras/Camera.js +47 -0
  208. package/src/cameras/CubeCamera.js +66 -0
  209. package/src/cameras/OrthographicCamera.js +109 -0
  210. package/src/cameras/PerspectiveCamera.js +173 -34
  211. package/src/cameras/StereoCamera.js +48 -2
  212. package/src/constants.js +6 -6
  213. package/src/core/BufferAttribute.js +4 -9
  214. package/src/core/BufferGeometry.js +48 -8
  215. package/src/core/Clock.js +1 -1
  216. package/src/core/EventDispatcher.js +52 -8
  217. package/src/core/InterleavedBuffer.js +4 -13
  218. package/src/core/Object3D.js +573 -3
  219. package/src/core/RenderTarget.js +22 -4
  220. package/src/core/RenderTarget3D.js +22 -0
  221. package/src/core/RenderTargetArray.js +22 -0
  222. package/src/extras/Controls.js +104 -0
  223. package/src/extras/DataUtils.js +48 -8
  224. package/src/extras/Earcut.js +18 -7
  225. package/src/extras/ImageUtils.js +18 -11
  226. package/src/extras/PMREMGenerator.js +40 -9
  227. package/src/extras/ShapeUtils.js +24 -2
  228. package/src/extras/TextureUtils.js +96 -10
  229. package/src/extras/core/Curve.js +153 -53
  230. package/src/extras/core/CurvePath.js +63 -22
  231. package/src/extras/core/Interpolations.js +29 -3
  232. package/src/extras/core/Path.js +134 -1
  233. package/src/extras/core/Shape.js +66 -3
  234. package/src/extras/core/ShapePath.js +76 -0
  235. package/src/extras/curves/ArcCurve.js +22 -0
  236. package/src/extras/curves/CatmullRomCurve3.js +89 -18
  237. package/src/extras/curves/CubicBezierCurve.js +67 -0
  238. package/src/extras/curves/CubicBezierCurve3.js +50 -0
  239. package/src/extras/curves/EllipseCurve.js +102 -0
  240. package/src/extras/curves/LineCurve.js +36 -0
  241. package/src/extras/curves/LineCurve3.js +36 -0
  242. package/src/extras/curves/QuadraticBezierCurve.js +59 -0
  243. package/src/extras/curves/QuadraticBezierCurve3.js +43 -0
  244. package/src/extras/curves/SplineCurve.js +48 -0
  245. package/src/geometries/BoxGeometry.js +38 -0
  246. package/src/geometries/CapsuleGeometry.js +34 -0
  247. package/src/geometries/CircleGeometry.js +40 -0
  248. package/src/geometries/ConeGeometry.js +38 -0
  249. package/src/geometries/CylinderGeometry.js +50 -4
  250. package/src/geometries/DodecahedronGeometry.js +32 -0
  251. package/src/geometries/EdgesGeometry.js +30 -2
  252. package/src/geometries/ExtrudeGeometry.js +52 -0
  253. package/src/geometries/IcosahedronGeometry.js +32 -0
  254. package/src/geometries/LatheGeometry.js +43 -3
  255. package/src/geometries/OctahedronGeometry.js +32 -0
  256. package/src/geometries/PlaneGeometry.js +34 -0
  257. package/src/geometries/PolyhedronGeometry.js +29 -0
  258. package/src/geometries/RingGeometry.js +36 -0
  259. package/src/geometries/ShapeGeometry.js +37 -0
  260. package/src/geometries/SphereGeometry.js +37 -0
  261. package/src/geometries/TetrahedronGeometry.js +32 -0
  262. package/src/geometries/TorusGeometry.js +35 -0
  263. package/src/geometries/TorusKnotGeometry.js +38 -0
  264. package/src/geometries/TubeGeometry.js +49 -0
  265. package/src/geometries/WireframeGeometry.js +32 -0
  266. package/src/helpers/ArrowHelper.js +60 -3
  267. package/src/helpers/AxesHelper.js +28 -0
  268. package/src/helpers/Box3Helper.js +28 -0
  269. package/src/helpers/BoxHelper.js +43 -7
  270. package/src/helpers/CameraHelper.js +61 -18
  271. package/src/helpers/DirectionalLightHelper.js +52 -0
  272. package/src/helpers/GridHelper.js +26 -0
  273. package/src/helpers/HemisphereLightHelper.js +39 -0
  274. package/src/helpers/PlaneHelper.js +33 -0
  275. package/src/helpers/PointLightHelper.js +43 -0
  276. package/src/helpers/PolarGridHelper.js +30 -0
  277. package/src/helpers/SkeletonHelper.js +39 -2
  278. package/src/helpers/SpotLightHelper.js +40 -0
  279. package/src/lights/AmbientLight.js +25 -0
  280. package/src/lights/DirectionalLight.js +57 -0
  281. package/src/lights/DirectionalLightShadow.js +15 -0
  282. package/src/lights/HemisphereLight.js +32 -0
  283. package/src/lights/Light.js +36 -0
  284. package/src/lights/LightProbe.js +43 -0
  285. package/src/lights/LightShadow.js +159 -0
  286. package/src/lights/PointLight.js +59 -0
  287. package/src/lights/PointLightShadow.js +21 -0
  288. package/src/lights/RectAreaLight.js +59 -0
  289. package/src/lights/SpotLight.js +102 -0
  290. package/src/lights/SpotLightShadow.js +24 -2
  291. package/src/lights/webgpu/IESSpotLight.js +21 -0
  292. package/src/loaders/Loader.js +132 -0
  293. package/src/loaders/MaterialLoader.js +7 -1
  294. package/src/loaders/nodes/NodeLoader.js +189 -0
  295. package/src/loaders/nodes/NodeMaterialLoader.js +108 -0
  296. package/src/loaders/nodes/NodeObjectLoader.js +151 -0
  297. package/src/materials/LineDashedMaterial.js +0 -1
  298. package/src/materials/Material.js +469 -7
  299. package/src/materials/MeshPhongMaterial.js +1 -1
  300. package/src/materials/MeshPhysicalMaterial.js +2 -2
  301. package/src/materials/MeshStandardMaterial.js +2 -2
  302. package/src/{nodes/materials → materials/nodes}/Line2NodeMaterial.js +192 -82
  303. package/src/materials/nodes/LineBasicNodeMaterial.js +46 -0
  304. package/src/materials/nodes/LineDashedNodeMaterial.js +132 -0
  305. package/src/materials/nodes/MeshBasicNodeMaterial.js +133 -0
  306. package/src/materials/nodes/MeshLambertNodeMaterial.js +82 -0
  307. package/src/materials/nodes/MeshMatcapNodeMaterial.js +77 -0
  308. package/src/materials/nodes/MeshNormalNodeMaterial.js +67 -0
  309. package/src/materials/nodes/MeshPhongNodeMaterial.js +141 -0
  310. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +517 -0
  311. package/src/materials/nodes/MeshSSSNodeMaterial.js +175 -0
  312. package/src/materials/nodes/MeshStandardNodeMaterial.js +186 -0
  313. package/src/materials/nodes/MeshToonNodeMaterial.js +66 -0
  314. package/src/materials/nodes/NodeMaterial.js +1180 -0
  315. package/src/{nodes/materials/Materials.js → materials/nodes/NodeMaterials.js} +3 -2
  316. package/src/materials/nodes/PointsNodeMaterial.js +153 -0
  317. package/src/materials/nodes/ShadowNodeMaterial.js +67 -0
  318. package/src/materials/nodes/SpriteNodeMaterial.js +198 -0
  319. package/src/materials/nodes/VolumeNodeMaterial.js +72 -0
  320. package/src/materials/nodes/manager/NodeMaterialObserver.js +509 -0
  321. package/src/math/Box2.js +177 -0
  322. package/src/math/Box3.js +243 -0
  323. package/src/math/Color.js +343 -0
  324. package/src/math/ColorManagement.js +143 -102
  325. package/src/math/Cylindrical.js +65 -6
  326. package/src/math/Euler.js +137 -4
  327. package/src/math/Frustum.js +83 -0
  328. package/src/math/Interpolant.js +87 -8
  329. package/src/math/Line3.js +96 -2
  330. package/src/math/MathUtils.js +182 -19
  331. package/src/math/Matrix2.js +70 -0
  332. package/src/math/Matrix3.js +229 -4
  333. package/src/math/Matrix4.js +368 -3
  334. package/src/math/Plane.js +164 -2
  335. package/src/math/Quaternion.js +265 -9
  336. package/src/math/Ray.js +160 -0
  337. package/src/math/Sphere.js +147 -0
  338. package/src/math/Spherical.js +73 -11
  339. package/src/math/SphericalHarmonics3.js +112 -14
  340. package/src/math/Triangle.js +230 -2
  341. package/src/math/Vector2.js +396 -10
  342. package/src/math/Vector3.js +550 -13
  343. package/src/math/Vector4.js +415 -9
  344. package/src/math/interpolants/CubicInterpolant.js +10 -1
  345. package/src/math/interpolants/DiscreteInterpolant.js +10 -2
  346. package/src/math/interpolants/LinearInterpolant.js +13 -0
  347. package/src/math/interpolants/QuaternionLinearInterpolant.js +10 -1
  348. package/src/nodes/Nodes.js +84 -166
  349. package/src/nodes/TSL.js +167 -0
  350. package/src/nodes/accessors/AccessorsUtils.js +39 -10
  351. package/src/nodes/accessors/Arrays.js +68 -0
  352. package/src/nodes/accessors/BatchNode.js +93 -26
  353. package/src/nodes/accessors/Bitangent.js +54 -0
  354. package/src/nodes/accessors/BufferAttributeNode.js +189 -11
  355. package/src/nodes/accessors/BufferNode.js +70 -5
  356. package/src/nodes/accessors/BuiltinNode.js +63 -0
  357. package/src/nodes/accessors/Camera.js +129 -0
  358. package/src/nodes/accessors/ClippingNode.js +152 -43
  359. package/src/nodes/accessors/CubeTextureNode.js +76 -13
  360. package/src/nodes/accessors/InstanceNode.js +118 -35
  361. package/src/nodes/accessors/InstancedMeshNode.js +50 -0
  362. package/src/nodes/accessors/Lights.js +129 -0
  363. package/src/nodes/accessors/MaterialNode.js +394 -58
  364. package/src/nodes/accessors/MaterialProperties.js +57 -1
  365. package/src/nodes/accessors/MaterialReferenceNode.js +60 -18
  366. package/src/nodes/accessors/ModelNode.js +159 -12
  367. package/src/nodes/accessors/ModelViewProjectionNode.js +10 -36
  368. package/src/nodes/accessors/MorphNode.js +60 -13
  369. package/src/nodes/accessors/Normal.js +156 -0
  370. package/src/nodes/accessors/Object3DNode.js +154 -35
  371. package/src/nodes/accessors/PointUVNode.js +35 -6
  372. package/src/nodes/accessors/Position.js +64 -0
  373. package/src/nodes/accessors/ReferenceBaseNode.js +357 -0
  374. package/src/nodes/accessors/ReferenceNode.js +243 -6
  375. package/src/nodes/accessors/ReflectVector.js +36 -0
  376. package/src/nodes/accessors/RendererReferenceNode.js +57 -7
  377. package/src/nodes/accessors/SceneNode.js +98 -6
  378. package/src/nodes/accessors/SkinningNode.js +214 -21
  379. package/src/nodes/accessors/StorageBufferNode.js +288 -28
  380. package/src/nodes/accessors/StorageTextureNode.js +139 -12
  381. package/src/nodes/accessors/Tangent.js +62 -0
  382. package/src/nodes/accessors/Texture3DNode.js +98 -12
  383. package/src/nodes/accessors/{TextureBicubicNode.js → TextureBicubic.js} +14 -34
  384. package/src/nodes/accessors/TextureNode.js +347 -34
  385. package/src/nodes/accessors/TextureSizeNode.js +51 -9
  386. package/src/nodes/accessors/UV.js +11 -0
  387. package/src/nodes/accessors/UniformArrayNode.js +241 -32
  388. package/src/nodes/accessors/UserDataNode.js +55 -7
  389. package/src/nodes/accessors/VelocityNode.js +223 -0
  390. package/src/nodes/accessors/VertexColorNode.js +45 -6
  391. package/src/nodes/code/CodeNode.js +108 -8
  392. package/src/nodes/code/ExpressionNode.js +38 -7
  393. package/src/nodes/code/FunctionCallNode.js +62 -11
  394. package/src/nodes/code/FunctionNode.js +54 -24
  395. package/src/nodes/code/ScriptableNode.js +241 -17
  396. package/src/nodes/code/ScriptableValueNode.js +93 -8
  397. package/src/nodes/core/ArrayNode.js +142 -0
  398. package/src/nodes/core/AssignNode.js +60 -12
  399. package/src/nodes/core/AttributeNode.js +55 -22
  400. package/src/nodes/core/BypassNode.js +59 -11
  401. package/src/nodes/core/CacheNode.js +64 -10
  402. package/src/nodes/core/ConstNode.js +38 -3
  403. package/src/nodes/core/ContextNode.js +87 -12
  404. package/src/nodes/core/IndexNode.js +102 -10
  405. package/src/nodes/core/InputNode.js +55 -3
  406. package/src/nodes/core/LightingModel.js +65 -5
  407. package/src/nodes/core/MRTNode.js +81 -7
  408. package/src/nodes/core/Node.js +368 -50
  409. package/src/nodes/core/NodeAttribute.js +38 -0
  410. package/src/nodes/core/NodeBuilder.js +1317 -83
  411. package/src/nodes/core/NodeCache.js +41 -2
  412. package/src/nodes/core/NodeCode.js +31 -0
  413. package/src/nodes/core/NodeFrame.js +123 -2
  414. package/src/nodes/core/NodeFunction.js +46 -0
  415. package/src/nodes/core/NodeFunctionInput.js +44 -0
  416. package/src/nodes/core/NodeParser.js +11 -0
  417. package/src/nodes/core/NodeUniform.js +52 -0
  418. package/src/nodes/core/NodeUtils.js +226 -6
  419. package/src/nodes/core/NodeVar.js +47 -1
  420. package/src/nodes/core/NodeVarying.js +28 -0
  421. package/src/nodes/core/OutputStructNode.js +61 -17
  422. package/src/nodes/core/ParameterNode.js +34 -4
  423. package/src/nodes/core/PropertyNode.js +296 -32
  424. package/src/nodes/core/StackNode.js +108 -8
  425. package/src/nodes/core/StructNode.js +120 -0
  426. package/src/nodes/core/StructType.js +13 -0
  427. package/src/nodes/core/StructTypeNode.js +116 -9
  428. package/src/nodes/core/TempNode.js +37 -7
  429. package/src/nodes/core/UniformGroupNode.js +98 -17
  430. package/src/nodes/core/UniformNode.js +72 -4
  431. package/src/nodes/core/VarNode.js +170 -13
  432. package/src/nodes/core/VaryingNode.js +109 -8
  433. package/src/nodes/core/constants.js +40 -0
  434. package/src/nodes/display/BlendModes.js +193 -0
  435. package/src/nodes/display/BumpMapNode.js +47 -10
  436. package/src/nodes/display/ColorAdjustment.js +141 -0
  437. package/src/nodes/display/ColorSpaceFunctions.js +54 -0
  438. package/src/nodes/display/ColorSpaceNode.js +147 -68
  439. package/src/nodes/display/FrontFacingNode.js +39 -6
  440. package/src/nodes/display/NormalMapNode.js +55 -13
  441. package/src/nodes/display/PassNode.js +420 -19
  442. package/src/nodes/display/PosterizeNode.js +40 -7
  443. package/src/nodes/display/RenderOutputNode.js +81 -13
  444. package/src/nodes/display/ScreenNode.js +286 -0
  445. package/src/nodes/display/ToneMappingFunctions.js +242 -0
  446. package/src/nodes/display/ToneMappingNode.js +68 -175
  447. package/src/nodes/display/ToonOutlinePassNode.js +183 -0
  448. package/src/nodes/display/ViewportDepthNode.js +210 -36
  449. package/src/nodes/display/ViewportDepthTextureNode.js +32 -9
  450. package/src/nodes/display/ViewportSharedTextureNode.js +32 -9
  451. package/src/nodes/display/ViewportTextureNode.js +68 -11
  452. package/src/nodes/fog/Fog.js +113 -0
  453. package/src/nodes/functions/BSDF/BRDF_GGX.js +4 -4
  454. package/src/nodes/functions/BSDF/BRDF_Lambert.js +2 -2
  455. package/src/nodes/functions/BSDF/BRDF_Sheen.js +6 -6
  456. package/src/nodes/functions/BSDF/DFGApprox.js +2 -2
  457. package/src/nodes/functions/BSDF/D_GGX.js +2 -2
  458. package/src/nodes/functions/BSDF/D_GGX_Anisotropic.js +3 -3
  459. package/src/nodes/functions/BSDF/EnvironmentBRDF.js +2 -2
  460. package/src/nodes/functions/BSDF/F_Schlick.js +2 -2
  461. package/src/nodes/functions/BSDF/LTC.js +50 -6
  462. package/src/nodes/functions/BSDF/Schlick_to_F0.js +2 -2
  463. package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.js +2 -2
  464. package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +2 -2
  465. package/src/nodes/functions/BasicLightingModel.js +27 -6
  466. package/src/nodes/functions/PhongLightingModel.js +38 -8
  467. package/src/nodes/functions/PhysicalLightingModel.js +215 -51
  468. package/src/nodes/functions/ShadowMaskModel.js +24 -1
  469. package/src/nodes/functions/ToonLightingModel.js +24 -5
  470. package/src/nodes/functions/VolumetricLightingModel.js +183 -0
  471. package/src/nodes/functions/material/getAlphaHashThreshold.js +68 -0
  472. package/src/nodes/functions/material/getGeometryRoughness.js +10 -4
  473. package/src/nodes/functions/material/getParallaxCorrectNormal.js +37 -0
  474. package/src/nodes/functions/material/getRoughness.js +2 -2
  475. package/src/nodes/functions/material/getShIrradianceAt.js +28 -0
  476. package/src/nodes/geometry/RangeNode.js +62 -7
  477. package/src/nodes/gpgpu/AtomicFunctionNode.js +280 -0
  478. package/src/nodes/gpgpu/BarrierNode.js +89 -0
  479. package/src/nodes/gpgpu/ComputeBuiltinNode.js +227 -0
  480. package/src/nodes/gpgpu/ComputeNode.js +124 -9
  481. package/src/nodes/gpgpu/WorkgroupInfoNode.js +208 -0
  482. package/src/nodes/lighting/AONode.js +24 -3
  483. package/src/nodes/lighting/AmbientLightNode.js +16 -8
  484. package/src/nodes/lighting/AnalyticLightNode.js +151 -231
  485. package/src/nodes/lighting/BasicEnvironmentNode.js +25 -3
  486. package/src/nodes/lighting/BasicLightMapNode.js +25 -5
  487. package/src/nodes/lighting/DirectionalLightNode.js +19 -20
  488. package/src/nodes/lighting/EnvironmentNode.js +34 -17
  489. package/src/nodes/lighting/HemisphereLightNode.js +42 -11
  490. package/src/nodes/lighting/IESSpotLightNode.js +18 -9
  491. package/src/nodes/lighting/IrradianceNode.js +23 -3
  492. package/src/nodes/lighting/LightProbeNode.js +29 -36
  493. package/src/nodes/lighting/LightUtils.js +12 -4
  494. package/src/nodes/lighting/LightingContextNode.js +70 -21
  495. package/src/nodes/lighting/LightingNode.js +22 -9
  496. package/src/nodes/lighting/LightsNode.js +309 -86
  497. package/src/nodes/lighting/PointLightNode.js +66 -32
  498. package/src/nodes/lighting/PointShadowNode.js +306 -0
  499. package/src/nodes/lighting/RectAreaLightNode.js +61 -25
  500. package/src/nodes/lighting/ShadowBaseNode.js +92 -0
  501. package/src/nodes/lighting/ShadowNode.js +812 -0
  502. package/src/nodes/lighting/SpotLightNode.js +73 -31
  503. package/src/nodes/materialx/MaterialXNodes.js +2 -2
  504. package/src/nodes/materialx/lib/mx_hsv.js +27 -22
  505. package/src/nodes/materialx/lib/mx_noise.js +70 -70
  506. package/src/nodes/materialx/lib/mx_transform_color.js +2 -2
  507. package/src/nodes/math/ConditionalNode.js +230 -0
  508. package/src/nodes/math/Hash.js +21 -0
  509. package/src/nodes/math/MathNode.js +812 -131
  510. package/src/nodes/math/MathUtils.js +47 -8
  511. package/src/nodes/math/OperatorNode.js +410 -66
  512. package/src/nodes/math/TriNoise3D.js +32 -32
  513. package/src/nodes/parsers/GLSLNodeFunction.js +16 -0
  514. package/src/nodes/parsers/GLSLNodeParser.js +11 -0
  515. package/src/nodes/pmrem/PMREMNode.js +188 -28
  516. package/src/nodes/pmrem/PMREMUtils.js +24 -24
  517. package/src/nodes/procedural/Checker.js +22 -0
  518. package/src/nodes/shapes/Shapes.js +32 -0
  519. package/src/nodes/tsl/TSLBase.js +31 -0
  520. package/src/nodes/{shadernode/ShaderNode.js → tsl/TSLCore.js} +114 -98
  521. package/src/nodes/utils/ArrayElementNode.js +45 -5
  522. package/src/nodes/utils/ConvertNode.js +39 -4
  523. package/src/nodes/utils/CubeMapNode.js +88 -8
  524. package/src/nodes/utils/Discard.js +24 -0
  525. package/src/nodes/utils/EquirectUVNode.js +39 -7
  526. package/src/nodes/utils/FlipNode.js +106 -0
  527. package/src/nodes/utils/FunctionOverloadingNode.js +61 -6
  528. package/src/nodes/utils/JoinNode.js +31 -3
  529. package/src/nodes/utils/LoopNode.js +95 -9
  530. package/src/nodes/utils/MatcapUVNode.js +27 -8
  531. package/src/nodes/utils/MaxMipLevelNode.js +57 -6
  532. package/src/nodes/utils/MemberNode.js +68 -0
  533. package/src/nodes/utils/Oscillators.js +41 -0
  534. package/src/nodes/utils/Packing.js +21 -0
  535. package/src/nodes/utils/PostProcessingUtils.js +95 -0
  536. package/src/nodes/utils/RTTNode.js +141 -9
  537. package/src/nodes/utils/ReflectorNode.js +295 -21
  538. package/src/nodes/utils/RemapNode.js +93 -10
  539. package/src/nodes/utils/RotateNode.js +48 -13
  540. package/src/nodes/utils/SetNode.js +50 -4
  541. package/src/nodes/utils/SplitNode.js +62 -6
  542. package/src/nodes/utils/SpriteSheetUVNode.js +56 -7
  543. package/src/nodes/utils/SpriteUtils.js +21 -5
  544. package/src/nodes/utils/StorageArrayElementNode.js +64 -12
  545. package/src/nodes/utils/Timer.js +73 -0
  546. package/src/nodes/utils/TriplanarTexturesNode.js +96 -10
  547. package/src/nodes/utils/UVUtils.js +27 -9
  548. package/src/nodes/utils/ViewportUtils.js +16 -4
  549. package/src/objects/BatchedMesh.js +808 -281
  550. package/src/objects/Bone.js +24 -0
  551. package/src/objects/ClippingGroup.js +68 -0
  552. package/src/objects/Group.js +24 -0
  553. package/src/objects/InstancedMesh.js +120 -2
  554. package/src/objects/LOD.js +120 -5
  555. package/src/objects/Line.js +89 -6
  556. package/src/objects/LineLoop.js +20 -0
  557. package/src/objects/LineSegments.js +18 -0
  558. package/src/objects/Mesh.js +82 -23
  559. package/src/objects/Points.js +62 -0
  560. package/src/objects/Skeleton.js +107 -2
  561. package/src/objects/SkinnedMesh.js +99 -5
  562. package/src/objects/Sprite.js +54 -0
  563. package/src/renderers/WebGLRenderer.js +274 -157
  564. package/src/renderers/common/Animation.js +109 -12
  565. package/src/renderers/common/Attributes.js +40 -0
  566. package/src/renderers/common/Backend.js +504 -44
  567. package/src/renderers/common/Background.js +67 -9
  568. package/src/renderers/common/BindGroup.js +45 -1
  569. package/src/renderers/common/Binding.js +35 -0
  570. package/src/renderers/common/Bindings.js +136 -19
  571. package/src/renderers/common/Buffer.js +49 -0
  572. package/src/renderers/common/BufferUtils.js +25 -0
  573. package/src/renderers/common/BundleGroup.js +83 -0
  574. package/src/renderers/common/ChainMap.js +45 -6
  575. package/src/renderers/common/ClippingContext.js +175 -80
  576. package/src/renderers/common/Color4.js +40 -0
  577. package/src/renderers/common/ComputePipeline.js +24 -0
  578. package/src/renderers/common/Constants.js +2 -1
  579. package/src/renderers/common/CubeRenderTarget.js +22 -3
  580. package/src/renderers/common/DataMap.js +37 -1
  581. package/src/renderers/common/Geometries.js +111 -14
  582. package/src/renderers/common/IndirectStorageBufferAttribute.js +38 -0
  583. package/src/renderers/common/Info.js +78 -35
  584. package/src/renderers/common/Lighting.js +73 -0
  585. package/src/renderers/common/Pipeline.js +22 -0
  586. package/src/renderers/common/Pipelines.js +148 -5
  587. package/src/renderers/common/PostProcessing.js +112 -11
  588. package/src/renderers/common/ProgrammableStage.js +60 -2
  589. package/src/renderers/common/QuadMesh.js +56 -5
  590. package/src/renderers/common/RenderBundle.js +14 -8
  591. package/src/renderers/common/RenderBundles.js +39 -10
  592. package/src/renderers/common/RenderContext.js +205 -7
  593. package/src/renderers/common/RenderContexts.js +59 -6
  594. package/src/renderers/common/RenderList.js +230 -21
  595. package/src/renderers/common/RenderLists.js +45 -6
  596. package/src/renderers/common/RenderObject.js +552 -41
  597. package/src/renderers/common/RenderObjects.js +118 -9
  598. package/src/renderers/common/RenderPipeline.js +24 -0
  599. package/src/renderers/common/Renderer.js +1537 -239
  600. package/src/renderers/common/RendererUtils.js +191 -0
  601. package/src/renderers/common/SampledTexture.js +132 -3
  602. package/src/renderers/common/Sampler.js +30 -0
  603. package/src/renderers/common/StorageBuffer.js +24 -0
  604. package/src/renderers/common/StorageBufferAttribute.js +31 -2
  605. package/src/renderers/common/StorageInstancedBufferAttribute.js +31 -2
  606. package/src/renderers/common/StorageTexture.js +38 -0
  607. package/src/renderers/common/Textures.js +142 -32
  608. package/src/renderers/common/TimestampQueryPool.js +98 -0
  609. package/src/renderers/common/Uniform.js +225 -3
  610. package/src/renderers/common/UniformBuffer.js +19 -0
  611. package/src/renderers/common/UniformsGroup.js +157 -6
  612. package/src/renderers/common/XRManager.js +1185 -0
  613. package/src/renderers/common/XRRenderTarget.js +74 -0
  614. package/src/renderers/common/extras/PMREMGenerator.js +211 -53
  615. package/src/renderers/common/nodes/NodeBuilderState.js +100 -6
  616. package/src/renderers/common/nodes/NodeLibrary.js +194 -0
  617. package/src/renderers/common/nodes/NodeSampledTexture.js +92 -4
  618. package/src/renderers/common/nodes/NodeSampler.js +28 -0
  619. package/src/renderers/common/nodes/NodeStorageBuffer.js +37 -3
  620. package/src/renderers/common/nodes/NodeUniform.js +285 -2
  621. package/src/renderers/common/nodes/NodeUniformBuffer.js +29 -0
  622. package/src/renderers/common/nodes/NodeUniformsGroup.js +31 -18
  623. package/src/renderers/common/nodes/Nodes.js +390 -70
  624. package/src/renderers/shaders/ShaderChunk/colorspace_pars_fragment.glsl.js +4 -24
  625. package/src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl.js +8 -0
  626. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +2 -2
  627. package/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js +2 -2
  628. package/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js +2 -2
  629. package/src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js +7 -7
  630. package/src/renderers/shaders/ShaderLib/sprite.glsl.js +2 -4
  631. package/src/renderers/webgl/WebGLAttributes.js +45 -14
  632. package/src/renderers/webgl/WebGLBackground.js +24 -1
  633. package/src/renderers/webgl/WebGLBufferRenderer.js +2 -6
  634. package/src/renderers/webgl/WebGLCapabilities.js +2 -0
  635. package/src/renderers/webgl/WebGLGeometries.js +0 -28
  636. package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +2 -6
  637. package/src/renderers/webgl/WebGLProgram.js +27 -29
  638. package/src/renderers/webgl/WebGLPrograms.js +24 -16
  639. package/src/renderers/webgl/WebGLState.js +68 -11
  640. package/src/renderers/webgl/WebGLTextures.js +49 -10
  641. package/src/renderers/webgl-fallback/WebGLBackend.js +1055 -238
  642. package/src/renderers/webgl-fallback/WebGLBufferRenderer.js +5 -10
  643. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +425 -48
  644. package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +64 -1
  645. package/src/renderers/webgl-fallback/utils/WebGLCapabilities.js +28 -0
  646. package/src/renderers/webgl-fallback/utils/WebGLExtensions.js +45 -0
  647. package/src/renderers/webgl-fallback/utils/WebGLState.js +419 -14
  648. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +281 -59
  649. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +367 -0
  650. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +43 -0
  651. package/src/renderers/webgpu/WebGPUBackend.js +816 -236
  652. package/src/renderers/webgpu/WebGPURenderer.Nodes.js +78 -0
  653. package/src/renderers/webgpu/WebGPURenderer.js +45 -6
  654. package/src/renderers/webgpu/nodes/BasicNodeLibrary.js +63 -0
  655. package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +97 -0
  656. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +954 -147
  657. package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +29 -4
  658. package/src/renderers/webgpu/nodes/WGSLNodeParser.js +11 -0
  659. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +147 -31
  660. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +213 -31
  661. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +146 -28
  662. package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +161 -7
  663. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +333 -50
  664. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +287 -0
  665. package/src/renderers/webgpu/utils/WebGPUUtils.js +131 -3
  666. package/src/renderers/webxr/WebXRDepthSensing.js +1 -1
  667. package/src/renderers/webxr/WebXRManager.js +54 -32
  668. package/src/scenes/Fog.js +60 -0
  669. package/src/scenes/FogExp2.js +51 -0
  670. package/src/scenes/Scene.js +87 -0
  671. package/src/textures/Data3DTexture.js +2 -2
  672. package/src/textures/DepthTexture.js +2 -0
  673. package/src/textures/Source.js +2 -2
  674. package/src/textures/Texture.js +368 -5
  675. package/src/textures/VideoFrameTexture.js +35 -0
  676. package/src/utils.js +33 -1
  677. package/examples/jsm/animation/MMDAnimationHelper.js +0 -1207
  678. package/examples/jsm/animation/MMDPhysics.js +0 -1406
  679. package/examples/jsm/cameras/CinematicCamera.js +0 -208
  680. package/examples/jsm/controls/Controls.js +0 -32
  681. package/examples/jsm/exporters/MMDExporter.js +0 -217
  682. package/examples/jsm/geometries/InstancedPointsGeometry.js +0 -174
  683. package/examples/jsm/geometries/SDFGeometryGenerator.js +0 -144
  684. package/examples/jsm/libs/mmdparser.module.js +0 -11530
  685. package/examples/jsm/loaders/LogLuvLoader.js +0 -606
  686. package/examples/jsm/loaders/MMDLoader.js +0 -2295
  687. package/examples/jsm/loaders/TiltLoader.js +0 -520
  688. package/examples/jsm/objects/InstancedPoints.js +0 -21
  689. package/examples/jsm/shaders/MMDToonShader.js +0 -134
  690. package/examples/jsm/utils/GPUStatsPanel.js +0 -95
  691. package/examples/jsm/utils/PackedPhongMaterial.js +0 -178
  692. package/src/nodes/accessors/BitangentNode.js +0 -13
  693. package/src/nodes/accessors/CameraNode.js +0 -19
  694. package/src/nodes/accessors/InstancedPointsMaterialNode.js +0 -21
  695. package/src/nodes/accessors/NormalNode.js +0 -14
  696. package/src/nodes/accessors/PositionNode.js +0 -10
  697. package/src/nodes/accessors/ReflectVectorNode.js +0 -10
  698. package/src/nodes/accessors/TangentNode.js +0 -23
  699. package/src/nodes/accessors/UVNode.js +0 -3
  700. package/src/nodes/core/NodeKeywords.js +0 -80
  701. package/src/nodes/core/UniformGroup.js +0 -13
  702. package/src/nodes/display/AfterImageNode.js +0 -152
  703. package/src/nodes/display/AnamorphicNode.js +0 -145
  704. package/src/nodes/display/BlendModeNode.js +0 -128
  705. package/src/nodes/display/ColorAdjustmentNode.js +0 -104
  706. package/src/nodes/display/DenoiseNode.js +0 -198
  707. package/src/nodes/display/DotScreenNode.js +0 -75
  708. package/src/nodes/display/FXAANode.js +0 -327
  709. package/src/nodes/display/FilmNode.js +0 -52
  710. package/src/nodes/display/GTAONode.js +0 -324
  711. package/src/nodes/display/GaussianBlurNode.js +0 -207
  712. package/src/nodes/display/Lut3DNode.js +0 -53
  713. package/src/nodes/display/RGBShiftNode.js +0 -49
  714. package/src/nodes/display/SepiaNode.js +0 -18
  715. package/src/nodes/display/TransitionNode.js +0 -76
  716. package/src/nodes/display/ViewportNode.js +0 -137
  717. package/src/nodes/fog/FogExp2Node.js +0 -34
  718. package/src/nodes/fog/FogNode.js +0 -48
  719. package/src/nodes/fog/FogRangeNode.js +0 -35
  720. package/src/nodes/lighting/LightNode.js +0 -57
  721. package/src/nodes/loaders/NodeLoader.js +0 -110
  722. package/src/nodes/loaders/NodeMaterialLoader.js +0 -60
  723. package/src/nodes/loaders/NodeObjectLoader.js +0 -71
  724. package/src/nodes/materials/InstancedPointsNodeMaterial.js +0 -162
  725. package/src/nodes/materials/LineBasicNodeMaterial.js +0 -28
  726. package/src/nodes/materials/LineDashedNodeMaterial.js +0 -55
  727. package/src/nodes/materials/MeshBasicNodeMaterial.js +0 -73
  728. package/src/nodes/materials/MeshLambertNodeMaterial.js +0 -43
  729. package/src/nodes/materials/MeshMatcapNodeMaterial.js +0 -53
  730. package/src/nodes/materials/MeshNormalNodeMaterial.js +0 -40
  731. package/src/nodes/materials/MeshPhongNodeMaterial.js +0 -74
  732. package/src/nodes/materials/MeshPhysicalNodeMaterial.js +0 -244
  733. package/src/nodes/materials/MeshSSSNodeMaterial.js +0 -84
  734. package/src/nodes/materials/MeshStandardNodeMaterial.js +0 -104
  735. package/src/nodes/materials/MeshToonNodeMaterial.js +0 -34
  736. package/src/nodes/materials/NodeMaterial.js +0 -680
  737. package/src/nodes/materials/PointsNodeMaterial.js +0 -39
  738. package/src/nodes/materials/ShadowNodeMaterial.js +0 -34
  739. package/src/nodes/materials/SpriteNodeMaterial.js +0 -90
  740. package/src/nodes/materials/VolumeNodeMaterial.js +0 -106
  741. package/src/nodes/math/CondNode.js +0 -139
  742. package/src/nodes/math/HashNode.js +0 -34
  743. package/src/nodes/procedural/CheckerNode.js +0 -42
  744. package/src/nodes/utils/DiscardNode.js +0 -28
  745. package/src/nodes/utils/OscNode.js +0 -81
  746. package/src/nodes/utils/PackingNode.js +0 -55
  747. package/src/nodes/utils/TimerNode.js +0 -94
@@ -1,5 +1,5 @@
1
1
  import {
2
- EventDispatcher,
2
+ Controls,
3
3
  MOUSE,
4
4
  Quaternion,
5
5
  Spherical,
@@ -23,17 +23,30 @@ const _startEvent = { type: 'start' };
23
23
  const _endEvent = { type: 'end' };
24
24
  const _ray = new Ray();
25
25
  const _plane = new Plane();
26
- const TILT_LIMIT = Math.cos( 70 * MathUtils.DEG2RAD );
26
+ const _TILT_LIMIT = Math.cos( 70 * MathUtils.DEG2RAD );
27
27
 
28
- class OrbitControls extends EventDispatcher {
28
+ const _v = new Vector3();
29
+ const _twoPI = 2 * Math.PI;
29
30
 
30
- constructor( object, domElement ) {
31
+ const _STATE = {
32
+ NONE: - 1,
33
+ ROTATE: 0,
34
+ DOLLY: 1,
35
+ PAN: 2,
36
+ TOUCH_ROTATE: 3,
37
+ TOUCH_PAN: 4,
38
+ TOUCH_DOLLY_PAN: 5,
39
+ TOUCH_DOLLY_ROTATE: 6
40
+ };
41
+ const _EPS = 0.000001;
31
42
 
32
- super();
43
+ class OrbitControls extends Controls {
33
44
 
34
- this.object = object;
35
- this.domElement = domElement;
36
- this.domElement.style.touchAction = 'none'; // disable touch scroll
45
+ constructor( object, domElement = null ) {
46
+
47
+ super( object, domElement );
48
+
49
+ this.state = _STATE.NONE;
37
50
 
38
51
  // Set to false to disable this control
39
52
  this.enabled = true;
@@ -79,6 +92,7 @@ class OrbitControls extends EventDispatcher {
79
92
  // Set to false to disable rotating
80
93
  this.enableRotate = true;
81
94
  this.rotateSpeed = 1.0;
95
+ this.keyRotateSpeed = 1.0;
82
96
 
83
97
  // Set to false to disable panning
84
98
  this.enablePan = true;
@@ -109,1421 +123,1431 @@ class OrbitControls extends EventDispatcher {
109
123
  // the target DOM element for key events
110
124
  this._domElementKeyEvents = null;
111
125
 
112
- //
113
- // public methods
114
- //
126
+ // internals
115
127
 
116
- this.getPolarAngle = function () {
128
+ this._lastPosition = new Vector3();
129
+ this._lastQuaternion = new Quaternion();
130
+ this._lastTargetPosition = new Vector3();
117
131
 
118
- return spherical.phi;
132
+ // so camera.up is the orbit axis
133
+ this._quat = new Quaternion().setFromUnitVectors( object.up, new Vector3( 0, 1, 0 ) );
134
+ this._quatInverse = this._quat.clone().invert();
119
135
 
120
- };
136
+ // current position in spherical coordinates
137
+ this._spherical = new Spherical();
138
+ this._sphericalDelta = new Spherical();
121
139
 
122
- this.getAzimuthalAngle = function () {
140
+ this._scale = 1;
141
+ this._panOffset = new Vector3();
123
142
 
124
- return spherical.theta;
143
+ this._rotateStart = new Vector2();
144
+ this._rotateEnd = new Vector2();
145
+ this._rotateDelta = new Vector2();
125
146
 
126
- };
147
+ this._panStart = new Vector2();
148
+ this._panEnd = new Vector2();
149
+ this._panDelta = new Vector2();
127
150
 
128
- this.getDistance = function () {
151
+ this._dollyStart = new Vector2();
152
+ this._dollyEnd = new Vector2();
153
+ this._dollyDelta = new Vector2();
129
154
 
130
- return this.object.position.distanceTo( this.target );
155
+ this._dollyDirection = new Vector3();
156
+ this._mouse = new Vector2();
157
+ this._performCursorZoom = false;
131
158
 
132
- };
159
+ this._pointers = [];
160
+ this._pointerPositions = {};
133
161
 
134
- this.listenToKeyEvents = function ( domElement ) {
162
+ this._controlActive = false;
135
163
 
136
- domElement.addEventListener( 'keydown', onKeyDown );
137
- this._domElementKeyEvents = domElement;
164
+ // event listeners
138
165
 
139
- };
166
+ this._onPointerMove = onPointerMove.bind( this );
167
+ this._onPointerDown = onPointerDown.bind( this );
168
+ this._onPointerUp = onPointerUp.bind( this );
169
+ this._onContextMenu = onContextMenu.bind( this );
170
+ this._onMouseWheel = onMouseWheel.bind( this );
171
+ this._onKeyDown = onKeyDown.bind( this );
140
172
 
141
- this.stopListenToKeyEvents = function () {
173
+ this._onTouchStart = onTouchStart.bind( this );
174
+ this._onTouchMove = onTouchMove.bind( this );
142
175
 
143
- this._domElementKeyEvents.removeEventListener( 'keydown', onKeyDown );
144
- this._domElementKeyEvents = null;
176
+ this._onMouseDown = onMouseDown.bind( this );
177
+ this._onMouseMove = onMouseMove.bind( this );
145
178
 
146
- };
179
+ this._interceptControlDown = interceptControlDown.bind( this );
180
+ this._interceptControlUp = interceptControlUp.bind( this );
147
181
 
148
- this.saveState = function () {
182
+ //
149
183
 
150
- scope.target0.copy( scope.target );
151
- scope.position0.copy( scope.object.position );
152
- scope.zoom0 = scope.object.zoom;
184
+ if ( this.domElement !== null ) {
153
185
 
154
- };
186
+ this.connect();
155
187
 
156
- this.reset = function () {
188
+ }
157
189
 
158
- scope.target.copy( scope.target0 );
159
- scope.object.position.copy( scope.position0 );
160
- scope.object.zoom = scope.zoom0;
190
+ this.update();
161
191
 
162
- scope.object.updateProjectionMatrix();
163
- scope.dispatchEvent( _changeEvent );
192
+ }
164
193
 
165
- scope.update();
194
+ connect() {
166
195
 
167
- state = STATE.NONE;
196
+ this.domElement.addEventListener( 'pointerdown', this._onPointerDown );
197
+ this.domElement.addEventListener( 'pointercancel', this._onPointerUp );
168
198
 
169
- };
199
+ this.domElement.addEventListener( 'contextmenu', this._onContextMenu );
200
+ this.domElement.addEventListener( 'wheel', this._onMouseWheel, { passive: false } );
170
201
 
171
- // this method is exposed, but perhaps it would be better if we can make it private...
172
- this.update = function () {
202
+ const document = this.domElement.getRootNode(); // offscreen canvas compatibility
203
+ document.addEventListener( 'keydown', this._interceptControlDown, { passive: true, capture: true } );
173
204
 
174
- const offset = new Vector3();
205
+ this.domElement.style.touchAction = 'none'; // disable touch scroll
175
206
 
176
- // so camera.up is the orbit axis
177
- const quat = new Quaternion().setFromUnitVectors( object.up, new Vector3( 0, 1, 0 ) );
178
- const quatInverse = quat.clone().invert();
207
+ }
179
208
 
180
- const lastPosition = new Vector3();
181
- const lastQuaternion = new Quaternion();
182
- const lastTargetPosition = new Vector3();
209
+ disconnect() {
183
210
 
184
- const twoPI = 2 * Math.PI;
211
+ this.domElement.removeEventListener( 'pointerdown', this._onPointerDown );
212
+ this.domElement.removeEventListener( 'pointermove', this._onPointerMove );
213
+ this.domElement.removeEventListener( 'pointerup', this._onPointerUp );
214
+ this.domElement.removeEventListener( 'pointercancel', this._onPointerUp );
185
215
 
186
- return function update( deltaTime = null ) {
216
+ this.domElement.removeEventListener( 'wheel', this._onMouseWheel );
217
+ this.domElement.removeEventListener( 'contextmenu', this._onContextMenu );
187
218
 
188
- const position = scope.object.position;
219
+ this.stopListenToKeyEvents();
189
220
 
190
- offset.copy( position ).sub( scope.target );
221
+ const document = this.domElement.getRootNode(); // offscreen canvas compatibility
222
+ document.removeEventListener( 'keydown', this._interceptControlDown, { capture: true } );
191
223
 
192
- // rotate offset to "y-axis-is-up" space
193
- offset.applyQuaternion( quat );
224
+ this.domElement.style.touchAction = 'auto';
194
225
 
195
- // angle from z-axis around y-axis
196
- spherical.setFromVector3( offset );
226
+ }
197
227
 
198
- if ( scope.autoRotate && state === STATE.NONE ) {
228
+ dispose() {
199
229
 
200
- rotateLeft( getAutoRotationAngle( deltaTime ) );
230
+ this.disconnect();
201
231
 
202
- }
232
+ }
203
233
 
204
- if ( scope.enableDamping ) {
234
+ getPolarAngle() {
205
235
 
206
- spherical.theta += sphericalDelta.theta * scope.dampingFactor;
207
- spherical.phi += sphericalDelta.phi * scope.dampingFactor;
236
+ return this._spherical.phi;
208
237
 
209
- } else {
238
+ }
210
239
 
211
- spherical.theta += sphericalDelta.theta;
212
- spherical.phi += sphericalDelta.phi;
240
+ getAzimuthalAngle() {
213
241
 
214
- }
242
+ return this._spherical.theta;
215
243
 
216
- // restrict theta to be between desired limits
244
+ }
217
245
 
218
- let min = scope.minAzimuthAngle;
219
- let max = scope.maxAzimuthAngle;
246
+ getDistance() {
220
247
 
221
- if ( isFinite( min ) && isFinite( max ) ) {
248
+ return this.object.position.distanceTo( this.target );
222
249
 
223
- if ( min < - Math.PI ) min += twoPI; else if ( min > Math.PI ) min -= twoPI;
250
+ }
224
251
 
225
- if ( max < - Math.PI ) max += twoPI; else if ( max > Math.PI ) max -= twoPI;
252
+ listenToKeyEvents( domElement ) {
226
253
 
227
- if ( min <= max ) {
254
+ domElement.addEventListener( 'keydown', this._onKeyDown );
255
+ this._domElementKeyEvents = domElement;
228
256
 
229
- spherical.theta = Math.max( min, Math.min( max, spherical.theta ) );
257
+ }
230
258
 
231
- } else {
259
+ stopListenToKeyEvents() {
232
260
 
233
- spherical.theta = ( spherical.theta > ( min + max ) / 2 ) ?
234
- Math.max( min, spherical.theta ) :
235
- Math.min( max, spherical.theta );
261
+ if ( this._domElementKeyEvents !== null ) {
236
262
 
237
- }
263
+ this._domElementKeyEvents.removeEventListener( 'keydown', this._onKeyDown );
264
+ this._domElementKeyEvents = null;
238
265
 
239
- }
266
+ }
240
267
 
241
- // restrict phi to be between desired limits
242
- spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );
268
+ }
243
269
 
244
- spherical.makeSafe();
270
+ saveState() {
245
271
 
272
+ this.target0.copy( this.target );
273
+ this.position0.copy( this.object.position );
274
+ this.zoom0 = this.object.zoom;
246
275
 
247
- // move target to panned location
276
+ }
248
277
 
249
- if ( scope.enableDamping === true ) {
278
+ reset() {
250
279
 
251
- scope.target.addScaledVector( panOffset, scope.dampingFactor );
280
+ this.target.copy( this.target0 );
281
+ this.object.position.copy( this.position0 );
282
+ this.object.zoom = this.zoom0;
252
283
 
253
- } else {
284
+ this.object.updateProjectionMatrix();
285
+ this.dispatchEvent( _changeEvent );
254
286
 
255
- scope.target.add( panOffset );
287
+ this.update();
256
288
 
257
- }
289
+ this.state = _STATE.NONE;
258
290
 
259
- // Limit the target distance from the cursor to create a sphere around the center of interest
260
- scope.target.sub( scope.cursor );
261
- scope.target.clampLength( scope.minTargetRadius, scope.maxTargetRadius );
262
- scope.target.add( scope.cursor );
291
+ }
263
292
 
264
- let zoomChanged = false;
265
- // adjust the camera position based on zoom only if we're not zooming to the cursor or if it's an ortho camera
266
- // we adjust zoom later in these cases
267
- if ( scope.zoomToCursor && performCursorZoom || scope.object.isOrthographicCamera ) {
293
+ update( deltaTime = null ) {
268
294
 
269
- spherical.radius = clampDistance( spherical.radius );
295
+ const position = this.object.position;
270
296
 
271
- } else {
297
+ _v.copy( position ).sub( this.target );
272
298
 
273
- const prevRadius = spherical.radius;
274
- spherical.radius = clampDistance( spherical.radius * scale );
275
- zoomChanged = prevRadius != spherical.radius;
299
+ // rotate offset to "y-axis-is-up" space
300
+ _v.applyQuaternion( this._quat );
276
301
 
277
- }
302
+ // angle from z-axis around y-axis
303
+ this._spherical.setFromVector3( _v );
278
304
 
279
- offset.setFromSpherical( spherical );
305
+ if ( this.autoRotate && this.state === _STATE.NONE ) {
280
306
 
281
- // rotate offset back to "camera-up-vector-is-up" space
282
- offset.applyQuaternion( quatInverse );
307
+ this._rotateLeft( this._getAutoRotationAngle( deltaTime ) );
283
308
 
284
- position.copy( scope.target ).add( offset );
309
+ }
285
310
 
286
- scope.object.lookAt( scope.target );
311
+ if ( this.enableDamping ) {
287
312
 
288
- if ( scope.enableDamping === true ) {
313
+ this._spherical.theta += this._sphericalDelta.theta * this.dampingFactor;
314
+ this._spherical.phi += this._sphericalDelta.phi * this.dampingFactor;
289
315
 
290
- sphericalDelta.theta *= ( 1 - scope.dampingFactor );
291
- sphericalDelta.phi *= ( 1 - scope.dampingFactor );
316
+ } else {
292
317
 
293
- panOffset.multiplyScalar( 1 - scope.dampingFactor );
318
+ this._spherical.theta += this._sphericalDelta.theta;
319
+ this._spherical.phi += this._sphericalDelta.phi;
294
320
 
295
- } else {
321
+ }
296
322
 
297
- sphericalDelta.set( 0, 0, 0 );
323
+ // restrict theta to be between desired limits
298
324
 
299
- panOffset.set( 0, 0, 0 );
325
+ let min = this.minAzimuthAngle;
326
+ let max = this.maxAzimuthAngle;
300
327
 
301
- }
328
+ if ( isFinite( min ) && isFinite( max ) ) {
302
329
 
303
- // adjust camera position
304
- if ( scope.zoomToCursor && performCursorZoom ) {
330
+ if ( min < - Math.PI ) min += _twoPI; else if ( min > Math.PI ) min -= _twoPI;
305
331
 
306
- let newRadius = null;
307
- if ( scope.object.isPerspectiveCamera ) {
332
+ if ( max < - Math.PI ) max += _twoPI; else if ( max > Math.PI ) max -= _twoPI;
308
333
 
309
- // move the camera down the pointer ray
310
- // this method avoids floating point error
311
- const prevRadius = offset.length();
312
- newRadius = clampDistance( prevRadius * scale );
334
+ if ( min <= max ) {
313
335
 
314
- const radiusDelta = prevRadius - newRadius;
315
- scope.object.position.addScaledVector( dollyDirection, radiusDelta );
316
- scope.object.updateMatrixWorld();
336
+ this._spherical.theta = Math.max( min, Math.min( max, this._spherical.theta ) );
317
337
 
318
- zoomChanged = !! radiusDelta;
338
+ } else {
319
339
 
320
- } else if ( scope.object.isOrthographicCamera ) {
340
+ this._spherical.theta = ( this._spherical.theta > ( min + max ) / 2 ) ?
341
+ Math.max( min, this._spherical.theta ) :
342
+ Math.min( max, this._spherical.theta );
321
343
 
322
- // adjust the ortho camera position based on zoom changes
323
- const mouseBefore = new Vector3( mouse.x, mouse.y, 0 );
324
- mouseBefore.unproject( scope.object );
344
+ }
325
345
 
326
- const prevZoom = scope.object.zoom;
327
- scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / scale ) );
328
- scope.object.updateProjectionMatrix();
346
+ }
329
347
 
330
- zoomChanged = prevZoom !== scope.object.zoom;
348
+ // restrict phi to be between desired limits
349
+ this._spherical.phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, this._spherical.phi ) );
331
350
 
332
- const mouseAfter = new Vector3( mouse.x, mouse.y, 0 );
333
- mouseAfter.unproject( scope.object );
351
+ this._spherical.makeSafe();
334
352
 
335
- scope.object.position.sub( mouseAfter ).add( mouseBefore );
336
- scope.object.updateMatrixWorld();
337
353
 
338
- newRadius = offset.length();
354
+ // move target to panned location
339
355
 
340
- } else {
356
+ if ( this.enableDamping === true ) {
341
357
 
342
- console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled.' );
343
- scope.zoomToCursor = false;
358
+ this.target.addScaledVector( this._panOffset, this.dampingFactor );
344
359
 
345
- }
360
+ } else {
346
361
 
347
- // handle the placement of the target
348
- if ( newRadius !== null ) {
362
+ this.target.add( this._panOffset );
349
363
 
350
- if ( this.screenSpacePanning ) {
364
+ }
351
365
 
352
- // position the orbit target in front of the new camera position
353
- scope.target.set( 0, 0, - 1 )
354
- .transformDirection( scope.object.matrix )
355
- .multiplyScalar( newRadius )
356
- .add( scope.object.position );
366
+ // Limit the target distance from the cursor to create a sphere around the center of interest
367
+ this.target.sub( this.cursor );
368
+ this.target.clampLength( this.minTargetRadius, this.maxTargetRadius );
369
+ this.target.add( this.cursor );
357
370
 
358
- } else {
371
+ let zoomChanged = false;
372
+ // adjust the camera position based on zoom only if we're not zooming to the cursor or if it's an ortho camera
373
+ // we adjust zoom later in these cases
374
+ if ( this.zoomToCursor && this._performCursorZoom || this.object.isOrthographicCamera ) {
359
375
 
360
- // get the ray and translation plane to compute target
361
- _ray.origin.copy( scope.object.position );
362
- _ray.direction.set( 0, 0, - 1 ).transformDirection( scope.object.matrix );
376
+ this._spherical.radius = this._clampDistance( this._spherical.radius );
363
377
 
364
- // if the camera is 20 degrees above the horizon then don't adjust the focus target to avoid
365
- // extremely large values
366
- if ( Math.abs( scope.object.up.dot( _ray.direction ) ) < TILT_LIMIT ) {
378
+ } else {
367
379
 
368
- object.lookAt( scope.target );
380
+ const prevRadius = this._spherical.radius;
381
+ this._spherical.radius = this._clampDistance( this._spherical.radius * this._scale );
382
+ zoomChanged = prevRadius != this._spherical.radius;
369
383
 
370
- } else {
384
+ }
371
385
 
372
- _plane.setFromNormalAndCoplanarPoint( scope.object.up, scope.target );
373
- _ray.intersectPlane( _plane, scope.target );
386
+ _v.setFromSpherical( this._spherical );
374
387
 
375
- }
388
+ // rotate offset back to "camera-up-vector-is-up" space
389
+ _v.applyQuaternion( this._quatInverse );
376
390
 
377
- }
391
+ position.copy( this.target ).add( _v );
378
392
 
379
- }
393
+ this.object.lookAt( this.target );
380
394
 
381
- } else if ( scope.object.isOrthographicCamera ) {
395
+ if ( this.enableDamping === true ) {
382
396
 
383
- const prevZoom = scope.object.zoom;
384
- scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / scale ) );
397
+ this._sphericalDelta.theta *= ( 1 - this.dampingFactor );
398
+ this._sphericalDelta.phi *= ( 1 - this.dampingFactor );
385
399
 
386
- if ( prevZoom !== scope.object.zoom ) {
400
+ this._panOffset.multiplyScalar( 1 - this.dampingFactor );
387
401
 
388
- scope.object.updateProjectionMatrix();
389
- zoomChanged = true;
402
+ } else {
390
403
 
391
- }
404
+ this._sphericalDelta.set( 0, 0, 0 );
392
405
 
393
- }
406
+ this._panOffset.set( 0, 0, 0 );
394
407
 
395
- scale = 1;
396
- performCursorZoom = false;
408
+ }
397
409
 
398
- // update condition is:
399
- // min(camera displacement, camera rotation in radians)^2 > EPS
400
- // using small-angle approximation cos(x/2) = 1 - x^2 / 8
410
+ // adjust camera position
411
+ if ( this.zoomToCursor && this._performCursorZoom ) {
401
412
 
402
- if ( zoomChanged ||
403
- lastPosition.distanceToSquared( scope.object.position ) > EPS ||
404
- 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ||
405
- lastTargetPosition.distanceToSquared( scope.target ) > EPS ) {
413
+ let newRadius = null;
414
+ if ( this.object.isPerspectiveCamera ) {
406
415
 
407
- scope.dispatchEvent( _changeEvent );
416
+ // move the camera down the pointer ray
417
+ // this method avoids floating point error
418
+ const prevRadius = _v.length();
419
+ newRadius = this._clampDistance( prevRadius * this._scale );
408
420
 
409
- lastPosition.copy( scope.object.position );
410
- lastQuaternion.copy( scope.object.quaternion );
411
- lastTargetPosition.copy( scope.target );
421
+ const radiusDelta = prevRadius - newRadius;
422
+ this.object.position.addScaledVector( this._dollyDirection, radiusDelta );
423
+ this.object.updateMatrixWorld();
412
424
 
413
- return true;
425
+ zoomChanged = !! radiusDelta;
414
426
 
415
- }
427
+ } else if ( this.object.isOrthographicCamera ) {
416
428
 
417
- return false;
429
+ // adjust the ortho camera position based on zoom changes
430
+ const mouseBefore = new Vector3( this._mouse.x, this._mouse.y, 0 );
431
+ mouseBefore.unproject( this.object );
418
432
 
419
- };
433
+ const prevZoom = this.object.zoom;
434
+ this.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom / this._scale ) );
435
+ this.object.updateProjectionMatrix();
420
436
 
421
- }();
437
+ zoomChanged = prevZoom !== this.object.zoom;
422
438
 
423
- this.dispose = function () {
439
+ const mouseAfter = new Vector3( this._mouse.x, this._mouse.y, 0 );
440
+ mouseAfter.unproject( this.object );
424
441
 
425
- scope.domElement.removeEventListener( 'contextmenu', onContextMenu );
442
+ this.object.position.sub( mouseAfter ).add( mouseBefore );
443
+ this.object.updateMatrixWorld();
426
444
 
427
- scope.domElement.removeEventListener( 'pointerdown', onPointerDown );
428
- scope.domElement.removeEventListener( 'pointercancel', onPointerUp );
429
- scope.domElement.removeEventListener( 'wheel', onMouseWheel );
445
+ newRadius = _v.length();
430
446
 
431
- scope.domElement.removeEventListener( 'pointermove', onPointerMove );
432
- scope.domElement.removeEventListener( 'pointerup', onPointerUp );
447
+ } else {
433
448
 
434
- const document = scope.domElement.getRootNode(); // offscreen canvas compatibility
449
+ console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled.' );
450
+ this.zoomToCursor = false;
435
451
 
436
- document.removeEventListener( 'keydown', interceptControlDown, { capture: true } );
452
+ }
437
453
 
438
- if ( scope._domElementKeyEvents !== null ) {
454
+ // handle the placement of the target
455
+ if ( newRadius !== null ) {
439
456
 
440
- scope._domElementKeyEvents.removeEventListener( 'keydown', onKeyDown );
441
- scope._domElementKeyEvents = null;
457
+ if ( this.screenSpacePanning ) {
442
458
 
443
- }
459
+ // position the orbit target in front of the new camera position
460
+ this.target.set( 0, 0, - 1 )
461
+ .transformDirection( this.object.matrix )
462
+ .multiplyScalar( newRadius )
463
+ .add( this.object.position );
444
464
 
445
- //scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?
465
+ } else {
446
466
 
447
- };
467
+ // get the ray and translation plane to compute target
468
+ _ray.origin.copy( this.object.position );
469
+ _ray.direction.set( 0, 0, - 1 ).transformDirection( this.object.matrix );
448
470
 
449
- //
450
- // internals
451
- //
471
+ // if the camera is 20 degrees above the horizon then don't adjust the focus target to avoid
472
+ // extremely large values
473
+ if ( Math.abs( this.object.up.dot( _ray.direction ) ) < _TILT_LIMIT ) {
452
474
 
453
- const scope = this;
454
-
455
- const STATE = {
456
- NONE: - 1,
457
- ROTATE: 0,
458
- DOLLY: 1,
459
- PAN: 2,
460
- TOUCH_ROTATE: 3,
461
- TOUCH_PAN: 4,
462
- TOUCH_DOLLY_PAN: 5,
463
- TOUCH_DOLLY_ROTATE: 6
464
- };
475
+ this.object.lookAt( this.target );
465
476
 
466
- let state = STATE.NONE;
477
+ } else {
467
478
 
468
- const EPS = 0.000001;
479
+ _plane.setFromNormalAndCoplanarPoint( this.object.up, this.target );
480
+ _ray.intersectPlane( _plane, this.target );
469
481
 
470
- // current position in spherical coordinates
471
- const spherical = new Spherical();
472
- const sphericalDelta = new Spherical();
482
+ }
473
483
 
474
- let scale = 1;
475
- const panOffset = new Vector3();
484
+ }
476
485
 
477
- const rotateStart = new Vector2();
478
- const rotateEnd = new Vector2();
479
- const rotateDelta = new Vector2();
486
+ }
480
487
 
481
- const panStart = new Vector2();
482
- const panEnd = new Vector2();
483
- const panDelta = new Vector2();
488
+ } else if ( this.object.isOrthographicCamera ) {
484
489
 
485
- const dollyStart = new Vector2();
486
- const dollyEnd = new Vector2();
487
- const dollyDelta = new Vector2();
490
+ const prevZoom = this.object.zoom;
491
+ this.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom / this._scale ) );
488
492
 
489
- const dollyDirection = new Vector3();
490
- const mouse = new Vector2();
491
- let performCursorZoom = false;
493
+ if ( prevZoom !== this.object.zoom ) {
492
494
 
493
- const pointers = [];
494
- const pointerPositions = {};
495
+ this.object.updateProjectionMatrix();
496
+ zoomChanged = true;
495
497
 
496
- let controlActive = false;
498
+ }
497
499
 
498
- function getAutoRotationAngle( deltaTime ) {
500
+ }
499
501
 
500
- if ( deltaTime !== null ) {
502
+ this._scale = 1;
503
+ this._performCursorZoom = false;
501
504
 
502
- return ( 2 * Math.PI / 60 * scope.autoRotateSpeed ) * deltaTime;
505
+ // update condition is:
506
+ // min(camera displacement, camera rotation in radians)^2 > EPS
507
+ // using small-angle approximation cos(x/2) = 1 - x^2 / 8
503
508
 
504
- } else {
509
+ if ( zoomChanged ||
510
+ this._lastPosition.distanceToSquared( this.object.position ) > _EPS ||
511
+ 8 * ( 1 - this._lastQuaternion.dot( this.object.quaternion ) ) > _EPS ||
512
+ this._lastTargetPosition.distanceToSquared( this.target ) > _EPS ) {
505
513
 
506
- return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
514
+ this.dispatchEvent( _changeEvent );
507
515
 
508
- }
516
+ this._lastPosition.copy( this.object.position );
517
+ this._lastQuaternion.copy( this.object.quaternion );
518
+ this._lastTargetPosition.copy( this.target );
509
519
 
510
- }
520
+ return true;
511
521
 
512
- function getZoomScale( delta ) {
522
+ }
513
523
 
514
- const normalizedDelta = Math.abs( delta * 0.01 );
515
- return Math.pow( 0.95, scope.zoomSpeed * normalizedDelta );
524
+ return false;
516
525
 
517
- }
526
+ }
518
527
 
519
- function rotateLeft( angle ) {
528
+ _getAutoRotationAngle( deltaTime ) {
520
529
 
521
- sphericalDelta.theta -= angle;
530
+ if ( deltaTime !== null ) {
522
531
 
523
- }
532
+ return ( _twoPI / 60 * this.autoRotateSpeed ) * deltaTime;
524
533
 
525
- function rotateUp( angle ) {
534
+ } else {
526
535
 
527
- sphericalDelta.phi -= angle;
536
+ return _twoPI / 60 / 60 * this.autoRotateSpeed;
528
537
 
529
538
  }
530
539
 
531
- const panLeft = function () {
540
+ }
532
541
 
533
- const v = new Vector3();
542
+ _getZoomScale( delta ) {
534
543
 
535
- return function panLeft( distance, objectMatrix ) {
544
+ const normalizedDelta = Math.abs( delta * 0.01 );
545
+ return Math.pow( 0.95, this.zoomSpeed * normalizedDelta );
536
546
 
537
- v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix
538
- v.multiplyScalar( - distance );
547
+ }
539
548
 
540
- panOffset.add( v );
549
+ _rotateLeft( angle ) {
541
550
 
542
- };
551
+ this._sphericalDelta.theta -= angle;
543
552
 
544
- }();
553
+ }
545
554
 
546
- const panUp = function () {
555
+ _rotateUp( angle ) {
547
556
 
548
- const v = new Vector3();
557
+ this._sphericalDelta.phi -= angle;
549
558
 
550
- return function panUp( distance, objectMatrix ) {
559
+ }
551
560
 
552
- if ( scope.screenSpacePanning === true ) {
561
+ _panLeft( distance, objectMatrix ) {
553
562
 
554
- v.setFromMatrixColumn( objectMatrix, 1 );
563
+ _v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix
564
+ _v.multiplyScalar( - distance );
555
565
 
556
- } else {
566
+ this._panOffset.add( _v );
557
567
 
558
- v.setFromMatrixColumn( objectMatrix, 0 );
559
- v.crossVectors( scope.object.up, v );
568
+ }
560
569
 
561
- }
570
+ _panUp( distance, objectMatrix ) {
562
571
 
563
- v.multiplyScalar( distance );
572
+ if ( this.screenSpacePanning === true ) {
564
573
 
565
- panOffset.add( v );
574
+ _v.setFromMatrixColumn( objectMatrix, 1 );
566
575
 
567
- };
576
+ } else {
568
577
 
569
- }();
578
+ _v.setFromMatrixColumn( objectMatrix, 0 );
579
+ _v.crossVectors( this.object.up, _v );
570
580
 
571
- // deltaX and deltaY are in pixels; right and down are positive
572
- const pan = function () {
581
+ }
573
582
 
574
- const offset = new Vector3();
583
+ _v.multiplyScalar( distance );
575
584
 
576
- return function pan( deltaX, deltaY ) {
585
+ this._panOffset.add( _v );
577
586
 
578
- const element = scope.domElement;
587
+ }
579
588
 
580
- if ( scope.object.isPerspectiveCamera ) {
589
+ // deltaX and deltaY are in pixels; right and down are positive
590
+ _pan( deltaX, deltaY ) {
581
591
 
582
- // perspective
583
- const position = scope.object.position;
584
- offset.copy( position ).sub( scope.target );
585
- let targetDistance = offset.length();
592
+ const element = this.domElement;
586
593
 
587
- // half of the fov is center to top of screen
588
- targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );
594
+ if ( this.object.isPerspectiveCamera ) {
589
595
 
590
- // we use only clientHeight here so aspect ratio does not distort speed
591
- panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );
592
- panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );
596
+ // perspective
597
+ const position = this.object.position;
598
+ _v.copy( position ).sub( this.target );
599
+ let targetDistance = _v.length();
593
600
 
594
- } else if ( scope.object.isOrthographicCamera ) {
601
+ // half of the fov is center to top of screen
602
+ targetDistance *= Math.tan( ( this.object.fov / 2 ) * Math.PI / 180.0 );
595
603
 
596
- // orthographic
597
- panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );
598
- panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );
604
+ // we use only clientHeight here so aspect ratio does not distort speed
605
+ this._panLeft( 2 * deltaX * targetDistance / element.clientHeight, this.object.matrix );
606
+ this._panUp( 2 * deltaY * targetDistance / element.clientHeight, this.object.matrix );
599
607
 
600
- } else {
608
+ } else if ( this.object.isOrthographicCamera ) {
601
609
 
602
- // camera neither orthographic nor perspective
603
- console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );
604
- scope.enablePan = false;
610
+ // orthographic
611
+ this._panLeft( deltaX * ( this.object.right - this.object.left ) / this.object.zoom / element.clientWidth, this.object.matrix );
612
+ this._panUp( deltaY * ( this.object.top - this.object.bottom ) / this.object.zoom / element.clientHeight, this.object.matrix );
605
613
 
606
- }
614
+ } else {
607
615
 
608
- };
616
+ // camera neither orthographic nor perspective
617
+ console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );
618
+ this.enablePan = false;
609
619
 
610
- }();
620
+ }
611
621
 
612
- function dollyOut( dollyScale ) {
622
+ }
613
623
 
614
- if ( scope.object.isPerspectiveCamera || scope.object.isOrthographicCamera ) {
624
+ _dollyOut( dollyScale ) {
615
625
 
616
- scale /= dollyScale;
626
+ if ( this.object.isPerspectiveCamera || this.object.isOrthographicCamera ) {
617
627
 
618
- } else {
628
+ this._scale /= dollyScale;
619
629
 
620
- console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
621
- scope.enableZoom = false;
630
+ } else {
622
631
 
623
- }
632
+ console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
633
+ this.enableZoom = false;
624
634
 
625
635
  }
626
636
 
627
- function dollyIn( dollyScale ) {
637
+ }
628
638
 
629
- if ( scope.object.isPerspectiveCamera || scope.object.isOrthographicCamera ) {
639
+ _dollyIn( dollyScale ) {
630
640
 
631
- scale *= dollyScale;
641
+ if ( this.object.isPerspectiveCamera || this.object.isOrthographicCamera ) {
632
642
 
633
- } else {
643
+ this._scale *= dollyScale;
634
644
 
635
- console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
636
- scope.enableZoom = false;
645
+ } else {
637
646
 
638
- }
647
+ console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
648
+ this.enableZoom = false;
639
649
 
640
650
  }
641
651
 
642
- function updateZoomParameters( x, y ) {
643
-
644
- if ( ! scope.zoomToCursor ) {
645
-
646
- return;
652
+ }
647
653
 
648
- }
654
+ _updateZoomParameters( x, y ) {
649
655
 
650
- performCursorZoom = true;
656
+ if ( ! this.zoomToCursor ) {
651
657
 
652
- const rect = scope.domElement.getBoundingClientRect();
653
- const dx = x - rect.left;
654
- const dy = y - rect.top;
655
- const w = rect.width;
656
- const h = rect.height;
658
+ return;
657
659
 
658
- mouse.x = ( dx / w ) * 2 - 1;
659
- mouse.y = - ( dy / h ) * 2 + 1;
660
+ }
660
661
 
661
- dollyDirection.set( mouse.x, mouse.y, 1 ).unproject( scope.object ).sub( scope.object.position ).normalize();
662
+ this._performCursorZoom = true;
662
663
 
663
- }
664
+ const rect = this.domElement.getBoundingClientRect();
665
+ const dx = x - rect.left;
666
+ const dy = y - rect.top;
667
+ const w = rect.width;
668
+ const h = rect.height;
664
669
 
665
- function clampDistance( dist ) {
670
+ this._mouse.x = ( dx / w ) * 2 - 1;
671
+ this._mouse.y = - ( dy / h ) * 2 + 1;
666
672
 
667
- return Math.max( scope.minDistance, Math.min( scope.maxDistance, dist ) );
673
+ this._dollyDirection.set( this._mouse.x, this._mouse.y, 1 ).unproject( this.object ).sub( this.object.position ).normalize();
668
674
 
669
- }
675
+ }
670
676
 
671
- //
672
- // event callbacks - update the object state
673
- //
677
+ _clampDistance( dist ) {
674
678
 
675
- function handleMouseDownRotate( event ) {
679
+ return Math.max( this.minDistance, Math.min( this.maxDistance, dist ) );
676
680
 
677
- rotateStart.set( event.clientX, event.clientY );
681
+ }
678
682
 
679
- }
683
+ //
684
+ // event callbacks - update the object state
685
+ //
680
686
 
681
- function handleMouseDownDolly( event ) {
687
+ _handleMouseDownRotate( event ) {
682
688
 
683
- updateZoomParameters( event.clientX, event.clientX );
684
- dollyStart.set( event.clientX, event.clientY );
689
+ this._rotateStart.set( event.clientX, event.clientY );
685
690
 
686
- }
691
+ }
687
692
 
688
- function handleMouseDownPan( event ) {
693
+ _handleMouseDownDolly( event ) {
689
694
 
690
- panStart.set( event.clientX, event.clientY );
695
+ this._updateZoomParameters( event.clientX, event.clientX );
696
+ this._dollyStart.set( event.clientX, event.clientY );
691
697
 
692
- }
698
+ }
693
699
 
694
- function handleMouseMoveRotate( event ) {
700
+ _handleMouseDownPan( event ) {
695
701
 
696
- rotateEnd.set( event.clientX, event.clientY );
702
+ this._panStart.set( event.clientX, event.clientY );
697
703
 
698
- rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );
704
+ }
699
705
 
700
- const element = scope.domElement;
706
+ _handleMouseMoveRotate( event ) {
701
707
 
702
- rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height
708
+ this._rotateEnd.set( event.clientX, event.clientY );
703
709
 
704
- rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight );
710
+ this._rotateDelta.subVectors( this._rotateEnd, this._rotateStart ).multiplyScalar( this.rotateSpeed );
705
711
 
706
- rotateStart.copy( rotateEnd );
712
+ const element = this.domElement;
707
713
 
708
- scope.update();
714
+ this._rotateLeft( _twoPI * this._rotateDelta.x / element.clientHeight ); // yes, height
709
715
 
710
- }
716
+ this._rotateUp( _twoPI * this._rotateDelta.y / element.clientHeight );
711
717
 
712
- function handleMouseMoveDolly( event ) {
718
+ this._rotateStart.copy( this._rotateEnd );
713
719
 
714
- dollyEnd.set( event.clientX, event.clientY );
720
+ this.update();
715
721
 
716
- dollyDelta.subVectors( dollyEnd, dollyStart );
722
+ }
717
723
 
718
- if ( dollyDelta.y > 0 ) {
724
+ _handleMouseMoveDolly( event ) {
719
725
 
720
- dollyOut( getZoomScale( dollyDelta.y ) );
726
+ this._dollyEnd.set( event.clientX, event.clientY );
721
727
 
722
- } else if ( dollyDelta.y < 0 ) {
728
+ this._dollyDelta.subVectors( this._dollyEnd, this._dollyStart );
723
729
 
724
- dollyIn( getZoomScale( dollyDelta.y ) );
730
+ if ( this._dollyDelta.y > 0 ) {
725
731
 
726
- }
732
+ this._dollyOut( this._getZoomScale( this._dollyDelta.y ) );
727
733
 
728
- dollyStart.copy( dollyEnd );
734
+ } else if ( this._dollyDelta.y < 0 ) {
729
735
 
730
- scope.update();
736
+ this._dollyIn( this._getZoomScale( this._dollyDelta.y ) );
731
737
 
732
738
  }
733
739
 
734
- function handleMouseMovePan( event ) {
740
+ this._dollyStart.copy( this._dollyEnd );
735
741
 
736
- panEnd.set( event.clientX, event.clientY );
742
+ this.update();
737
743
 
738
- panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );
744
+ }
739
745
 
740
- pan( panDelta.x, panDelta.y );
746
+ _handleMouseMovePan( event ) {
741
747
 
742
- panStart.copy( panEnd );
748
+ this._panEnd.set( event.clientX, event.clientY );
743
749
 
744
- scope.update();
750
+ this._panDelta.subVectors( this._panEnd, this._panStart ).multiplyScalar( this.panSpeed );
745
751
 
746
- }
752
+ this._pan( this._panDelta.x, this._panDelta.y );
747
753
 
748
- function handleMouseWheel( event ) {
754
+ this._panStart.copy( this._panEnd );
749
755
 
750
- updateZoomParameters( event.clientX, event.clientY );
756
+ this.update();
751
757
 
752
- if ( event.deltaY < 0 ) {
758
+ }
753
759
 
754
- dollyIn( getZoomScale( event.deltaY ) );
760
+ _handleMouseWheel( event ) {
755
761
 
756
- } else if ( event.deltaY > 0 ) {
762
+ this._updateZoomParameters( event.clientX, event.clientY );
757
763
 
758
- dollyOut( getZoomScale( event.deltaY ) );
764
+ if ( event.deltaY < 0 ) {
759
765
 
760
- }
766
+ this._dollyIn( this._getZoomScale( event.deltaY ) );
767
+
768
+ } else if ( event.deltaY > 0 ) {
761
769
 
762
- scope.update();
770
+ this._dollyOut( this._getZoomScale( event.deltaY ) );
763
771
 
764
772
  }
765
773
 
766
- function handleKeyDown( event ) {
774
+ this.update();
767
775
 
768
- let needsUpdate = false;
776
+ }
769
777
 
770
- switch ( event.code ) {
778
+ _handleKeyDown( event ) {
771
779
 
772
- case scope.keys.UP:
780
+ let needsUpdate = false;
773
781
 
774
- if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
782
+ switch ( event.code ) {
775
783
 
776
- rotateUp( 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight );
784
+ case this.keys.UP:
777
785
 
778
- } else {
786
+ if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
787
+
788
+ if ( this.enableRotate ) {
779
789
 
780
- pan( 0, scope.keyPanSpeed );
790
+ this._rotateUp( _twoPI * this.keyRotateSpeed / this.domElement.clientHeight );
781
791
 
782
792
  }
783
793
 
784
- needsUpdate = true;
785
- break;
794
+ } else {
786
795
 
787
- case scope.keys.BOTTOM:
796
+ if ( this.enablePan ) {
788
797
 
789
- if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
798
+ this._pan( 0, this.keyPanSpeed );
790
799
 
791
- rotateUp( - 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight );
800
+ }
792
801
 
793
- } else {
802
+ }
794
803
 
795
- pan( 0, - scope.keyPanSpeed );
804
+ needsUpdate = true;
805
+ break;
796
806
 
797
- }
807
+ case this.keys.BOTTOM:
798
808
 
799
- needsUpdate = true;
800
- break;
809
+ if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
801
810
 
802
- case scope.keys.LEFT:
811
+ if ( this.enableRotate ) {
803
812
 
804
- if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
813
+ this._rotateUp( - _twoPI * this.keyRotateSpeed / this.domElement.clientHeight );
805
814
 
806
- rotateLeft( 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight );
815
+ }
807
816
 
808
- } else {
817
+ } else {
809
818
 
810
- pan( scope.keyPanSpeed, 0 );
819
+ if ( this.enablePan ) {
820
+
821
+ this._pan( 0, - this.keyPanSpeed );
811
822
 
812
823
  }
813
824
 
814
- needsUpdate = true;
815
- break;
825
+ }
816
826
 
817
- case scope.keys.RIGHT:
827
+ needsUpdate = true;
828
+ break;
818
829
 
819
- if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
830
+ case this.keys.LEFT:
820
831
 
821
- rotateLeft( - 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight );
832
+ if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
822
833
 
823
- } else {
834
+ if ( this.enableRotate ) {
824
835
 
825
- pan( - scope.keyPanSpeed, 0 );
836
+ this._rotateLeft( _twoPI * this.keyRotateSpeed / this.domElement.clientHeight );
826
837
 
827
838
  }
828
839
 
829
- needsUpdate = true;
830
- break;
840
+ } else {
831
841
 
832
- }
842
+ if ( this.enablePan ) {
833
843
 
834
- if ( needsUpdate ) {
844
+ this._pan( this.keyPanSpeed, 0 );
835
845
 
836
- // prevent the browser from scrolling on cursor keys
837
- event.preventDefault();
846
+ }
838
847
 
839
- scope.update();
848
+ }
840
849
 
841
- }
850
+ needsUpdate = true;
851
+ break;
842
852
 
853
+ case this.keys.RIGHT:
843
854
 
844
- }
855
+ if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
845
856
 
846
- function handleTouchStartRotate( event ) {
857
+ if ( this.enableRotate ) {
847
858
 
848
- if ( pointers.length === 1 ) {
859
+ this._rotateLeft( - _twoPI * this.keyRotateSpeed / this.domElement.clientHeight );
849
860
 
850
- rotateStart.set( event.pageX, event.pageY );
861
+ }
851
862
 
852
- } else {
863
+ } else {
853
864
 
854
- const position = getSecondPointerPosition( event );
865
+ if ( this.enablePan ) {
855
866
 
856
- const x = 0.5 * ( event.pageX + position.x );
857
- const y = 0.5 * ( event.pageY + position.y );
867
+ this._pan( - this.keyPanSpeed, 0 );
858
868
 
859
- rotateStart.set( x, y );
869
+ }
860
870
 
861
- }
871
+ }
862
872
 
863
- }
873
+ needsUpdate = true;
874
+ break;
864
875
 
865
- function handleTouchStartPan( event ) {
876
+ }
866
877
 
867
- if ( pointers.length === 1 ) {
878
+ if ( needsUpdate ) {
868
879
 
869
- panStart.set( event.pageX, event.pageY );
880
+ // prevent the browser from scrolling on cursor keys
881
+ event.preventDefault();
870
882
 
871
- } else {
883
+ this.update();
872
884
 
873
- const position = getSecondPointerPosition( event );
885
+ }
874
886
 
875
- const x = 0.5 * ( event.pageX + position.x );
876
- const y = 0.5 * ( event.pageY + position.y );
877
887
 
878
- panStart.set( x, y );
888
+ }
879
889
 
880
- }
890
+ _handleTouchStartRotate( event ) {
881
891
 
882
- }
892
+ if ( this._pointers.length === 1 ) {
883
893
 
884
- function handleTouchStartDolly( event ) {
894
+ this._rotateStart.set( event.pageX, event.pageY );
885
895
 
886
- const position = getSecondPointerPosition( event );
896
+ } else {
887
897
 
888
- const dx = event.pageX - position.x;
889
- const dy = event.pageY - position.y;
898
+ const position = this._getSecondPointerPosition( event );
890
899
 
891
- const distance = Math.sqrt( dx * dx + dy * dy );
900
+ const x = 0.5 * ( event.pageX + position.x );
901
+ const y = 0.5 * ( event.pageY + position.y );
892
902
 
893
- dollyStart.set( 0, distance );
903
+ this._rotateStart.set( x, y );
894
904
 
895
905
  }
896
906
 
897
- function handleTouchStartDollyPan( event ) {
907
+ }
908
+
909
+ _handleTouchStartPan( event ) {
898
910
 
899
- if ( scope.enableZoom ) handleTouchStartDolly( event );
911
+ if ( this._pointers.length === 1 ) {
900
912
 
901
- if ( scope.enablePan ) handleTouchStartPan( event );
913
+ this._panStart.set( event.pageX, event.pageY );
902
914
 
903
- }
915
+ } else {
904
916
 
905
- function handleTouchStartDollyRotate( event ) {
917
+ const position = this._getSecondPointerPosition( event );
906
918
 
907
- if ( scope.enableZoom ) handleTouchStartDolly( event );
919
+ const x = 0.5 * ( event.pageX + position.x );
920
+ const y = 0.5 * ( event.pageY + position.y );
908
921
 
909
- if ( scope.enableRotate ) handleTouchStartRotate( event );
922
+ this._panStart.set( x, y );
910
923
 
911
924
  }
912
925
 
913
- function handleTouchMoveRotate( event ) {
926
+ }
914
927
 
915
- if ( pointers.length == 1 ) {
928
+ _handleTouchStartDolly( event ) {
916
929
 
917
- rotateEnd.set( event.pageX, event.pageY );
930
+ const position = this._getSecondPointerPosition( event );
918
931
 
919
- } else {
932
+ const dx = event.pageX - position.x;
933
+ const dy = event.pageY - position.y;
920
934
 
921
- const position = getSecondPointerPosition( event );
935
+ const distance = Math.sqrt( dx * dx + dy * dy );
922
936
 
923
- const x = 0.5 * ( event.pageX + position.x );
924
- const y = 0.5 * ( event.pageY + position.y );
937
+ this._dollyStart.set( 0, distance );
925
938
 
926
- rotateEnd.set( x, y );
939
+ }
927
940
 
928
- }
941
+ _handleTouchStartDollyPan( event ) {
929
942
 
930
- rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );
943
+ if ( this.enableZoom ) this._handleTouchStartDolly( event );
931
944
 
932
- const element = scope.domElement;
945
+ if ( this.enablePan ) this._handleTouchStartPan( event );
933
946
 
934
- rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height
947
+ }
935
948
 
936
- rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight );
949
+ _handleTouchStartDollyRotate( event ) {
937
950
 
938
- rotateStart.copy( rotateEnd );
951
+ if ( this.enableZoom ) this._handleTouchStartDolly( event );
939
952
 
940
- }
953
+ if ( this.enableRotate ) this._handleTouchStartRotate( event );
941
954
 
942
- function handleTouchMovePan( event ) {
955
+ }
943
956
 
944
- if ( pointers.length === 1 ) {
957
+ _handleTouchMoveRotate( event ) {
945
958
 
946
- panEnd.set( event.pageX, event.pageY );
959
+ if ( this._pointers.length == 1 ) {
947
960
 
948
- } else {
961
+ this._rotateEnd.set( event.pageX, event.pageY );
949
962
 
950
- const position = getSecondPointerPosition( event );
963
+ } else {
951
964
 
952
- const x = 0.5 * ( event.pageX + position.x );
953
- const y = 0.5 * ( event.pageY + position.y );
965
+ const position = this._getSecondPointerPosition( event );
954
966
 
955
- panEnd.set( x, y );
967
+ const x = 0.5 * ( event.pageX + position.x );
968
+ const y = 0.5 * ( event.pageY + position.y );
956
969
 
957
- }
970
+ this._rotateEnd.set( x, y );
958
971
 
959
- panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );
972
+ }
960
973
 
961
- pan( panDelta.x, panDelta.y );
974
+ this._rotateDelta.subVectors( this._rotateEnd, this._rotateStart ).multiplyScalar( this.rotateSpeed );
962
975
 
963
- panStart.copy( panEnd );
976
+ const element = this.domElement;
964
977
 
965
- }
978
+ this._rotateLeft( _twoPI * this._rotateDelta.x / element.clientHeight ); // yes, height
966
979
 
967
- function handleTouchMoveDolly( event ) {
980
+ this._rotateUp( _twoPI * this._rotateDelta.y / element.clientHeight );
968
981
 
969
- const position = getSecondPointerPosition( event );
982
+ this._rotateStart.copy( this._rotateEnd );
970
983
 
971
- const dx = event.pageX - position.x;
972
- const dy = event.pageY - position.y;
984
+ }
973
985
 
974
- const distance = Math.sqrt( dx * dx + dy * dy );
986
+ _handleTouchMovePan( event ) {
975
987
 
976
- dollyEnd.set( 0, distance );
988
+ if ( this._pointers.length === 1 ) {
977
989
 
978
- dollyDelta.set( 0, Math.pow( dollyEnd.y / dollyStart.y, scope.zoomSpeed ) );
990
+ this._panEnd.set( event.pageX, event.pageY );
979
991
 
980
- dollyOut( dollyDelta.y );
992
+ } else {
981
993
 
982
- dollyStart.copy( dollyEnd );
994
+ const position = this._getSecondPointerPosition( event );
983
995
 
984
- const centerX = ( event.pageX + position.x ) * 0.5;
985
- const centerY = ( event.pageY + position.y ) * 0.5;
996
+ const x = 0.5 * ( event.pageX + position.x );
997
+ const y = 0.5 * ( event.pageY + position.y );
986
998
 
987
- updateZoomParameters( centerX, centerY );
999
+ this._panEnd.set( x, y );
988
1000
 
989
1001
  }
990
1002
 
991
- function handleTouchMoveDollyPan( event ) {
1003
+ this._panDelta.subVectors( this._panEnd, this._panStart ).multiplyScalar( this.panSpeed );
992
1004
 
993
- if ( scope.enableZoom ) handleTouchMoveDolly( event );
1005
+ this._pan( this._panDelta.x, this._panDelta.y );
994
1006
 
995
- if ( scope.enablePan ) handleTouchMovePan( event );
1007
+ this._panStart.copy( this._panEnd );
996
1008
 
997
- }
1009
+ }
998
1010
 
999
- function handleTouchMoveDollyRotate( event ) {
1011
+ _handleTouchMoveDolly( event ) {
1000
1012
 
1001
- if ( scope.enableZoom ) handleTouchMoveDolly( event );
1013
+ const position = this._getSecondPointerPosition( event );
1002
1014
 
1003
- if ( scope.enableRotate ) handleTouchMoveRotate( event );
1015
+ const dx = event.pageX - position.x;
1016
+ const dy = event.pageY - position.y;
1004
1017
 
1005
- }
1018
+ const distance = Math.sqrt( dx * dx + dy * dy );
1006
1019
 
1007
- //
1008
- // event handlers - FSM: listen for events and reset state
1009
- //
1020
+ this._dollyEnd.set( 0, distance );
1010
1021
 
1011
- function onPointerDown( event ) {
1022
+ this._dollyDelta.set( 0, Math.pow( this._dollyEnd.y / this._dollyStart.y, this.zoomSpeed ) );
1012
1023
 
1013
- if ( scope.enabled === false ) return;
1024
+ this._dollyOut( this._dollyDelta.y );
1014
1025
 
1015
- if ( pointers.length === 0 ) {
1026
+ this._dollyStart.copy( this._dollyEnd );
1016
1027
 
1017
- scope.domElement.setPointerCapture( event.pointerId );
1028
+ const centerX = ( event.pageX + position.x ) * 0.5;
1029
+ const centerY = ( event.pageY + position.y ) * 0.5;
1018
1030
 
1019
- scope.domElement.addEventListener( 'pointermove', onPointerMove );
1020
- scope.domElement.addEventListener( 'pointerup', onPointerUp );
1031
+ this._updateZoomParameters( centerX, centerY );
1021
1032
 
1022
- }
1033
+ }
1034
+
1035
+ _handleTouchMoveDollyPan( event ) {
1023
1036
 
1024
- //
1037
+ if ( this.enableZoom ) this._handleTouchMoveDolly( event );
1025
1038
 
1026
- if ( isTrackingPointer( event ) ) return;
1039
+ if ( this.enablePan ) this._handleTouchMovePan( event );
1027
1040
 
1028
- //
1041
+ }
1029
1042
 
1030
- addPointer( event );
1043
+ _handleTouchMoveDollyRotate( event ) {
1031
1044
 
1032
- if ( event.pointerType === 'touch' ) {
1045
+ if ( this.enableZoom ) this._handleTouchMoveDolly( event );
1033
1046
 
1034
- onTouchStart( event );
1047
+ if ( this.enableRotate ) this._handleTouchMoveRotate( event );
1035
1048
 
1036
- } else {
1049
+ }
1037
1050
 
1038
- onMouseDown( event );
1051
+ // pointers
1039
1052
 
1040
- }
1053
+ _addPointer( event ) {
1041
1054
 
1042
- }
1055
+ this._pointers.push( event.pointerId );
1043
1056
 
1044
- function onPointerMove( event ) {
1057
+ }
1045
1058
 
1046
- if ( scope.enabled === false ) return;
1059
+ _removePointer( event ) {
1047
1060
 
1048
- if ( event.pointerType === 'touch' ) {
1061
+ delete this._pointerPositions[ event.pointerId ];
1049
1062
 
1050
- onTouchMove( event );
1063
+ for ( let i = 0; i < this._pointers.length; i ++ ) {
1051
1064
 
1052
- } else {
1065
+ if ( this._pointers[ i ] == event.pointerId ) {
1053
1066
 
1054
- onMouseMove( event );
1067
+ this._pointers.splice( i, 1 );
1068
+ return;
1055
1069
 
1056
1070
  }
1057
1071
 
1058
1072
  }
1059
1073
 
1060
- function onPointerUp( event ) {
1074
+ }
1061
1075
 
1062
- removePointer( event );
1076
+ _isTrackingPointer( event ) {
1063
1077
 
1064
- switch ( pointers.length ) {
1078
+ for ( let i = 0; i < this._pointers.length; i ++ ) {
1065
1079
 
1066
- case 0:
1080
+ if ( this._pointers[ i ] == event.pointerId ) return true;
1067
1081
 
1068
- scope.domElement.releasePointerCapture( event.pointerId );
1082
+ }
1069
1083
 
1070
- scope.domElement.removeEventListener( 'pointermove', onPointerMove );
1071
- scope.domElement.removeEventListener( 'pointerup', onPointerUp );
1084
+ return false;
1072
1085
 
1073
- scope.dispatchEvent( _endEvent );
1086
+ }
1074
1087
 
1075
- state = STATE.NONE;
1088
+ _trackPointer( event ) {
1076
1089
 
1077
- break;
1090
+ let position = this._pointerPositions[ event.pointerId ];
1078
1091
 
1079
- case 1:
1092
+ if ( position === undefined ) {
1080
1093
 
1081
- const pointerId = pointers[ 0 ];
1082
- const position = pointerPositions[ pointerId ];
1094
+ position = new Vector2();
1095
+ this._pointerPositions[ event.pointerId ] = position;
1083
1096
 
1084
- // minimal placeholder event - allows state correction on pointer-up
1085
- onTouchStart( { pointerId: pointerId, pageX: position.x, pageY: position.y } );
1097
+ }
1086
1098
 
1087
- break;
1099
+ position.set( event.pageX, event.pageY );
1088
1100
 
1089
- }
1101
+ }
1090
1102
 
1091
- }
1103
+ _getSecondPointerPosition( event ) {
1092
1104
 
1093
- function onMouseDown( event ) {
1105
+ const pointerId = ( event.pointerId === this._pointers[ 0 ] ) ? this._pointers[ 1 ] : this._pointers[ 0 ];
1094
1106
 
1095
- let mouseAction;
1107
+ return this._pointerPositions[ pointerId ];
1096
1108
 
1097
- switch ( event.button ) {
1109
+ }
1098
1110
 
1099
- case 0:
1111
+ //
1100
1112
 
1101
- mouseAction = scope.mouseButtons.LEFT;
1102
- break;
1113
+ _customWheelEvent( event ) {
1103
1114
 
1104
- case 1:
1115
+ const mode = event.deltaMode;
1105
1116
 
1106
- mouseAction = scope.mouseButtons.MIDDLE;
1107
- break;
1117
+ // minimal wheel event altered to meet delta-zoom demand
1118
+ const newEvent = {
1119
+ clientX: event.clientX,
1120
+ clientY: event.clientY,
1121
+ deltaY: event.deltaY,
1122
+ };
1108
1123
 
1109
- case 2:
1124
+ switch ( mode ) {
1110
1125
 
1111
- mouseAction = scope.mouseButtons.RIGHT;
1112
- break;
1126
+ case 1: // LINE_MODE
1127
+ newEvent.deltaY *= 16;
1128
+ break;
1113
1129
 
1114
- default:
1130
+ case 2: // PAGE_MODE
1131
+ newEvent.deltaY *= 100;
1132
+ break;
1115
1133
 
1116
- mouseAction = - 1;
1134
+ }
1117
1135
 
1118
- }
1136
+ // detect if event was triggered by pinching
1137
+ if ( event.ctrlKey && ! this._controlActive ) {
1119
1138
 
1120
- switch ( mouseAction ) {
1139
+ newEvent.deltaY *= 10;
1121
1140
 
1122
- case MOUSE.DOLLY:
1141
+ }
1123
1142
 
1124
- if ( scope.enableZoom === false ) return;
1143
+ return newEvent;
1125
1144
 
1126
- handleMouseDownDolly( event );
1145
+ }
1127
1146
 
1128
- state = STATE.DOLLY;
1147
+ }
1129
1148
 
1130
- break;
1149
+ function onPointerDown( event ) {
1131
1150
 
1132
- case MOUSE.ROTATE:
1151
+ if ( this.enabled === false ) return;
1133
1152
 
1134
- if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
1153
+ if ( this._pointers.length === 0 ) {
1135
1154
 
1136
- if ( scope.enablePan === false ) return;
1155
+ this.domElement.setPointerCapture( event.pointerId );
1137
1156
 
1138
- handleMouseDownPan( event );
1157
+ this.domElement.addEventListener( 'pointermove', this._onPointerMove );
1158
+ this.domElement.addEventListener( 'pointerup', this._onPointerUp );
1139
1159
 
1140
- state = STATE.PAN;
1160
+ }
1141
1161
 
1142
- } else {
1162
+ //
1143
1163
 
1144
- if ( scope.enableRotate === false ) return;
1164
+ if ( this._isTrackingPointer( event ) ) return;
1145
1165
 
1146
- handleMouseDownRotate( event );
1166
+ //
1147
1167
 
1148
- state = STATE.ROTATE;
1168
+ this._addPointer( event );
1149
1169
 
1150
- }
1170
+ if ( event.pointerType === 'touch' ) {
1151
1171
 
1152
- break;
1172
+ this._onTouchStart( event );
1153
1173
 
1154
- case MOUSE.PAN:
1174
+ } else {
1155
1175
 
1156
- if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
1176
+ this._onMouseDown( event );
1157
1177
 
1158
- if ( scope.enableRotate === false ) return;
1178
+ }
1159
1179
 
1160
- handleMouseDownRotate( event );
1180
+ }
1161
1181
 
1162
- state = STATE.ROTATE;
1182
+ function onPointerMove( event ) {
1163
1183
 
1164
- } else {
1184
+ if ( this.enabled === false ) return;
1165
1185
 
1166
- if ( scope.enablePan === false ) return;
1186
+ if ( event.pointerType === 'touch' ) {
1167
1187
 
1168
- handleMouseDownPan( event );
1188
+ this._onTouchMove( event );
1169
1189
 
1170
- state = STATE.PAN;
1190
+ } else {
1171
1191
 
1172
- }
1192
+ this._onMouseMove( event );
1173
1193
 
1174
- break;
1194
+ }
1175
1195
 
1176
- default:
1196
+ }
1177
1197
 
1178
- state = STATE.NONE;
1198
+ function onPointerUp( event ) {
1179
1199
 
1180
- }
1200
+ this._removePointer( event );
1181
1201
 
1182
- if ( state !== STATE.NONE ) {
1202
+ switch ( this._pointers.length ) {
1183
1203
 
1184
- scope.dispatchEvent( _startEvent );
1204
+ case 0:
1185
1205
 
1186
- }
1206
+ this.domElement.releasePointerCapture( event.pointerId );
1187
1207
 
1188
- }
1208
+ this.domElement.removeEventListener( 'pointermove', this._onPointerMove );
1209
+ this.domElement.removeEventListener( 'pointerup', this._onPointerUp );
1189
1210
 
1190
- function onMouseMove( event ) {
1211
+ this.dispatchEvent( _endEvent );
1191
1212
 
1192
- switch ( state ) {
1213
+ this.state = _STATE.NONE;
1193
1214
 
1194
- case STATE.ROTATE:
1215
+ break;
1195
1216
 
1196
- if ( scope.enableRotate === false ) return;
1217
+ case 1:
1197
1218
 
1198
- handleMouseMoveRotate( event );
1219
+ const pointerId = this._pointers[ 0 ];
1220
+ const position = this._pointerPositions[ pointerId ];
1199
1221
 
1200
- break;
1222
+ // minimal placeholder event - allows state correction on pointer-up
1223
+ this._onTouchStart( { pointerId: pointerId, pageX: position.x, pageY: position.y } );
1201
1224
 
1202
- case STATE.DOLLY:
1225
+ break;
1203
1226
 
1204
- if ( scope.enableZoom === false ) return;
1227
+ }
1205
1228
 
1206
- handleMouseMoveDolly( event );
1229
+ }
1207
1230
 
1208
- break;
1231
+ function onMouseDown( event ) {
1209
1232
 
1210
- case STATE.PAN:
1233
+ let mouseAction;
1211
1234
 
1212
- if ( scope.enablePan === false ) return;
1235
+ switch ( event.button ) {
1213
1236
 
1214
- handleMouseMovePan( event );
1237
+ case 0:
1215
1238
 
1216
- break;
1239
+ mouseAction = this.mouseButtons.LEFT;
1240
+ break;
1217
1241
 
1218
- }
1242
+ case 1:
1219
1243
 
1220
- }
1244
+ mouseAction = this.mouseButtons.MIDDLE;
1245
+ break;
1221
1246
 
1222
- function onMouseWheel( event ) {
1247
+ case 2:
1223
1248
 
1224
- if ( scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE ) return;
1249
+ mouseAction = this.mouseButtons.RIGHT;
1250
+ break;
1225
1251
 
1226
- event.preventDefault();
1252
+ default:
1227
1253
 
1228
- scope.dispatchEvent( _startEvent );
1254
+ mouseAction = - 1;
1229
1255
 
1230
- handleMouseWheel( customWheelEvent( event ) );
1256
+ }
1231
1257
 
1232
- scope.dispatchEvent( _endEvent );
1258
+ switch ( mouseAction ) {
1233
1259
 
1234
- }
1260
+ case MOUSE.DOLLY:
1235
1261
 
1236
- function customWheelEvent( event ) {
1262
+ if ( this.enableZoom === false ) return;
1237
1263
 
1238
- const mode = event.deltaMode;
1264
+ this._handleMouseDownDolly( event );
1239
1265
 
1240
- // minimal wheel event altered to meet delta-zoom demand
1241
- const newEvent = {
1242
- clientX: event.clientX,
1243
- clientY: event.clientY,
1244
- deltaY: event.deltaY,
1245
- };
1266
+ this.state = _STATE.DOLLY;
1246
1267
 
1247
- switch ( mode ) {
1268
+ break;
1248
1269
 
1249
- case 1: // LINE_MODE
1250
- newEvent.deltaY *= 16;
1251
- break;
1270
+ case MOUSE.ROTATE:
1252
1271
 
1253
- case 2: // PAGE_MODE
1254
- newEvent.deltaY *= 100;
1255
- break;
1272
+ if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
1256
1273
 
1257
- }
1274
+ if ( this.enablePan === false ) return;
1258
1275
 
1259
- // detect if event was triggered by pinching
1260
- if ( event.ctrlKey && ! controlActive ) {
1276
+ this._handleMouseDownPan( event );
1261
1277
 
1262
- newEvent.deltaY *= 10;
1278
+ this.state = _STATE.PAN;
1263
1279
 
1264
- }
1280
+ } else {
1265
1281
 
1266
- return newEvent;
1282
+ if ( this.enableRotate === false ) return;
1267
1283
 
1268
- }
1284
+ this._handleMouseDownRotate( event );
1269
1285
 
1270
- function interceptControlDown( event ) {
1286
+ this.state = _STATE.ROTATE;
1271
1287
 
1272
- if ( event.key === 'Control' ) {
1288
+ }
1273
1289
 
1274
- controlActive = true;
1290
+ break;
1275
1291
 
1292
+ case MOUSE.PAN:
1276
1293
 
1277
- const document = scope.domElement.getRootNode(); // offscreen canvas compatibility
1294
+ if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
1278
1295
 
1279
- document.addEventListener( 'keyup', interceptControlUp, { passive: true, capture: true } );
1296
+ if ( this.enableRotate === false ) return;
1280
1297
 
1281
- }
1298
+ this._handleMouseDownRotate( event );
1282
1299
 
1283
- }
1300
+ this.state = _STATE.ROTATE;
1284
1301
 
1285
- function interceptControlUp( event ) {
1302
+ } else {
1286
1303
 
1287
- if ( event.key === 'Control' ) {
1304
+ if ( this.enablePan === false ) return;
1288
1305
 
1289
- controlActive = false;
1306
+ this._handleMouseDownPan( event );
1290
1307
 
1308
+ this.state = _STATE.PAN;
1291
1309
 
1292
- const document = scope.domElement.getRootNode(); // offscreen canvas compatibility
1310
+ }
1293
1311
 
1294
- document.removeEventListener( 'keyup', interceptControlUp, { passive: true, capture: true } );
1312
+ break;
1295
1313
 
1296
- }
1314
+ default:
1297
1315
 
1298
- }
1316
+ this.state = _STATE.NONE;
1299
1317
 
1300
- function onKeyDown( event ) {
1318
+ }
1301
1319
 
1302
- if ( scope.enabled === false || scope.enablePan === false ) return;
1320
+ if ( this.state !== _STATE.NONE ) {
1303
1321
 
1304
- handleKeyDown( event );
1322
+ this.dispatchEvent( _startEvent );
1305
1323
 
1306
- }
1324
+ }
1307
1325
 
1308
- function onTouchStart( event ) {
1326
+ }
1309
1327
 
1310
- trackPointer( event );
1328
+ function onMouseMove( event ) {
1311
1329
 
1312
- switch ( pointers.length ) {
1330
+ switch ( this.state ) {
1313
1331
 
1314
- case 1:
1332
+ case _STATE.ROTATE:
1315
1333
 
1316
- switch ( scope.touches.ONE ) {
1334
+ if ( this.enableRotate === false ) return;
1317
1335
 
1318
- case TOUCH.ROTATE:
1336
+ this._handleMouseMoveRotate( event );
1319
1337
 
1320
- if ( scope.enableRotate === false ) return;
1338
+ break;
1321
1339
 
1322
- handleTouchStartRotate( event );
1340
+ case _STATE.DOLLY:
1323
1341
 
1324
- state = STATE.TOUCH_ROTATE;
1342
+ if ( this.enableZoom === false ) return;
1325
1343
 
1326
- break;
1344
+ this._handleMouseMoveDolly( event );
1327
1345
 
1328
- case TOUCH.PAN:
1346
+ break;
1329
1347
 
1330
- if ( scope.enablePan === false ) return;
1348
+ case _STATE.PAN:
1331
1349
 
1332
- handleTouchStartPan( event );
1350
+ if ( this.enablePan === false ) return;
1333
1351
 
1334
- state = STATE.TOUCH_PAN;
1352
+ this._handleMouseMovePan( event );
1335
1353
 
1336
- break;
1354
+ break;
1337
1355
 
1338
- default:
1356
+ }
1339
1357
 
1340
- state = STATE.NONE;
1358
+ }
1341
1359
 
1342
- }
1360
+ function onMouseWheel( event ) {
1343
1361
 
1344
- break;
1362
+ if ( this.enabled === false || this.enableZoom === false || this.state !== _STATE.NONE ) return;
1345
1363
 
1346
- case 2:
1364
+ event.preventDefault();
1347
1365
 
1348
- switch ( scope.touches.TWO ) {
1366
+ this.dispatchEvent( _startEvent );
1349
1367
 
1350
- case TOUCH.DOLLY_PAN:
1368
+ this._handleMouseWheel( this._customWheelEvent( event ) );
1351
1369
 
1352
- if ( scope.enableZoom === false && scope.enablePan === false ) return;
1370
+ this.dispatchEvent( _endEvent );
1353
1371
 
1354
- handleTouchStartDollyPan( event );
1372
+ }
1355
1373
 
1356
- state = STATE.TOUCH_DOLLY_PAN;
1374
+ function onKeyDown( event ) {
1357
1375
 
1358
- break;
1376
+ if ( this.enabled === false ) return;
1359
1377
 
1360
- case TOUCH.DOLLY_ROTATE:
1378
+ this._handleKeyDown( event );
1361
1379
 
1362
- if ( scope.enableZoom === false && scope.enableRotate === false ) return;
1380
+ }
1363
1381
 
1364
- handleTouchStartDollyRotate( event );
1382
+ function onTouchStart( event ) {
1365
1383
 
1366
- state = STATE.TOUCH_DOLLY_ROTATE;
1384
+ this._trackPointer( event );
1367
1385
 
1368
- break;
1386
+ switch ( this._pointers.length ) {
1369
1387
 
1370
- default:
1388
+ case 1:
1371
1389
 
1372
- state = STATE.NONE;
1390
+ switch ( this.touches.ONE ) {
1373
1391
 
1374
- }
1392
+ case TOUCH.ROTATE:
1393
+
1394
+ if ( this.enableRotate === false ) return;
1395
+
1396
+ this._handleTouchStartRotate( event );
1397
+
1398
+ this.state = _STATE.TOUCH_ROTATE;
1375
1399
 
1376
1400
  break;
1377
1401
 
1378
- default:
1402
+ case TOUCH.PAN:
1379
1403
 
1380
- state = STATE.NONE;
1404
+ if ( this.enablePan === false ) return;
1381
1405
 
1382
- }
1406
+ this._handleTouchStartPan( event );
1383
1407
 
1384
- if ( state !== STATE.NONE ) {
1408
+ this.state = _STATE.TOUCH_PAN;
1385
1409
 
1386
- scope.dispatchEvent( _startEvent );
1410
+ break;
1387
1411
 
1388
- }
1412
+ default:
1389
1413
 
1390
- }
1414
+ this.state = _STATE.NONE;
1391
1415
 
1392
- function onTouchMove( event ) {
1416
+ }
1393
1417
 
1394
- trackPointer( event );
1418
+ break;
1395
1419
 
1396
- switch ( state ) {
1420
+ case 2:
1397
1421
 
1398
- case STATE.TOUCH_ROTATE:
1422
+ switch ( this.touches.TWO ) {
1399
1423
 
1400
- if ( scope.enableRotate === false ) return;
1424
+ case TOUCH.DOLLY_PAN:
1401
1425
 
1402
- handleTouchMoveRotate( event );
1426
+ if ( this.enableZoom === false && this.enablePan === false ) return;
1403
1427
 
1404
- scope.update();
1428
+ this._handleTouchStartDollyPan( event );
1429
+
1430
+ this.state = _STATE.TOUCH_DOLLY_PAN;
1405
1431
 
1406
1432
  break;
1407
1433
 
1408
- case STATE.TOUCH_PAN:
1434
+ case TOUCH.DOLLY_ROTATE:
1409
1435
 
1410
- if ( scope.enablePan === false ) return;
1436
+ if ( this.enableZoom === false && this.enableRotate === false ) return;
1411
1437
 
1412
- handleTouchMovePan( event );
1438
+ this._handleTouchStartDollyRotate( event );
1413
1439
 
1414
- scope.update();
1440
+ this.state = _STATE.TOUCH_DOLLY_ROTATE;
1415
1441
 
1416
1442
  break;
1417
1443
 
1418
- case STATE.TOUCH_DOLLY_PAN:
1444
+ default:
1419
1445
 
1420
- if ( scope.enableZoom === false && scope.enablePan === false ) return;
1446
+ this.state = _STATE.NONE;
1421
1447
 
1422
- handleTouchMoveDollyPan( event );
1448
+ }
1423
1449
 
1424
- scope.update();
1450
+ break;
1425
1451
 
1426
- break;
1452
+ default:
1427
1453
 
1428
- case STATE.TOUCH_DOLLY_ROTATE:
1454
+ this.state = _STATE.NONE;
1429
1455
 
1430
- if ( scope.enableZoom === false && scope.enableRotate === false ) return;
1456
+ }
1431
1457
 
1432
- handleTouchMoveDollyRotate( event );
1458
+ if ( this.state !== _STATE.NONE ) {
1433
1459
 
1434
- scope.update();
1460
+ this.dispatchEvent( _startEvent );
1435
1461
 
1436
- break;
1462
+ }
1437
1463
 
1438
- default:
1464
+ }
1439
1465
 
1440
- state = STATE.NONE;
1466
+ function onTouchMove( event ) {
1441
1467
 
1442
- }
1468
+ this._trackPointer( event );
1443
1469
 
1444
- }
1470
+ switch ( this.state ) {
1445
1471
 
1446
- function onContextMenu( event ) {
1472
+ case _STATE.TOUCH_ROTATE:
1447
1473
 
1448
- if ( scope.enabled === false ) return;
1474
+ if ( this.enableRotate === false ) return;
1449
1475
 
1450
- event.preventDefault();
1476
+ this._handleTouchMoveRotate( event );
1451
1477
 
1452
- }
1478
+ this.update();
1453
1479
 
1454
- function addPointer( event ) {
1480
+ break;
1455
1481
 
1456
- pointers.push( event.pointerId );
1482
+ case _STATE.TOUCH_PAN:
1457
1483
 
1458
- }
1484
+ if ( this.enablePan === false ) return;
1459
1485
 
1460
- function removePointer( event ) {
1486
+ this._handleTouchMovePan( event );
1461
1487
 
1462
- delete pointerPositions[ event.pointerId ];
1488
+ this.update();
1463
1489
 
1464
- for ( let i = 0; i < pointers.length; i ++ ) {
1490
+ break;
1465
1491
 
1466
- if ( pointers[ i ] == event.pointerId ) {
1492
+ case _STATE.TOUCH_DOLLY_PAN:
1467
1493
 
1468
- pointers.splice( i, 1 );
1469
- return;
1494
+ if ( this.enableZoom === false && this.enablePan === false ) return;
1470
1495
 
1471
- }
1496
+ this._handleTouchMoveDollyPan( event );
1472
1497
 
1473
- }
1498
+ this.update();
1474
1499
 
1475
- }
1500
+ break;
1476
1501
 
1477
- function isTrackingPointer( event ) {
1502
+ case _STATE.TOUCH_DOLLY_ROTATE:
1478
1503
 
1479
- for ( let i = 0; i < pointers.length; i ++ ) {
1504
+ if ( this.enableZoom === false && this.enableRotate === false ) return;
1480
1505
 
1481
- if ( pointers[ i ] == event.pointerId ) return true;
1506
+ this._handleTouchMoveDollyRotate( event );
1482
1507
 
1483
- }
1508
+ this.update();
1484
1509
 
1485
- return false;
1510
+ break;
1486
1511
 
1487
- }
1512
+ default:
1488
1513
 
1489
- function trackPointer( event ) {
1514
+ this.state = _STATE.NONE;
1490
1515
 
1491
- let position = pointerPositions[ event.pointerId ];
1516
+ }
1492
1517
 
1493
- if ( position === undefined ) {
1518
+ }
1494
1519
 
1495
- position = new Vector2();
1496
- pointerPositions[ event.pointerId ] = position;
1520
+ function onContextMenu( event ) {
1497
1521
 
1498
- }
1522
+ if ( this.enabled === false ) return;
1499
1523
 
1500
- position.set( event.pageX, event.pageY );
1524
+ event.preventDefault();
1501
1525
 
1502
- }
1526
+ }
1503
1527
 
1504
- function getSecondPointerPosition( event ) {
1528
+ function interceptControlDown( event ) {
1505
1529
 
1506
- const pointerId = ( event.pointerId === pointers[ 0 ] ) ? pointers[ 1 ] : pointers[ 0 ];
1530
+ if ( event.key === 'Control' ) {
1507
1531
 
1508
- return pointerPositions[ pointerId ];
1532
+ this._controlActive = true;
1509
1533
 
1510
- }
1534
+ const document = this.domElement.getRootNode(); // offscreen canvas compatibility
1511
1535
 
1512
- //
1536
+ document.addEventListener( 'keyup', this._interceptControlUp, { passive: true, capture: true } );
1513
1537
 
1514
- scope.domElement.addEventListener( 'contextmenu', onContextMenu );
1538
+ }
1539
+
1540
+ }
1515
1541
 
1516
- scope.domElement.addEventListener( 'pointerdown', onPointerDown );
1517
- scope.domElement.addEventListener( 'pointercancel', onPointerUp );
1518
- scope.domElement.addEventListener( 'wheel', onMouseWheel, { passive: false } );
1542
+ function interceptControlUp( event ) {
1519
1543
 
1520
- const document = scope.domElement.getRootNode(); // offscreen canvas compatibility
1544
+ if ( event.key === 'Control' ) {
1521
1545
 
1522
- document.addEventListener( 'keydown', interceptControlDown, { passive: true, capture: true } );
1546
+ this._controlActive = false;
1523
1547
 
1524
- // force an update at start
1548
+ const document = this.domElement.getRootNode(); // offscreen canvas compatibility
1525
1549
 
1526
- this.update();
1550
+ document.removeEventListener( 'keyup', this._interceptControlUp, { passive: true, capture: true } );
1527
1551
 
1528
1552
  }
1529
1553