@needle-tools/three 0.162.12 → 0.169.2

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