super-three 0.167.0 → 0.168.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (311) hide show
  1. package/build/three.cjs +165 -44
  2. package/build/three.module.js +165 -45
  3. package/build/three.module.min.js +1 -1
  4. package/build/three.webgpu.js +23600 -21931
  5. package/build/three.webgpu.min.js +1 -1
  6. package/examples/jsm/Addons.js +3 -1
  7. package/examples/jsm/animation/AnimationClipCreator.js +1 -1
  8. package/examples/jsm/capabilities/WebGL.js +27 -21
  9. package/examples/jsm/controls/ArcballControls.js +174 -158
  10. package/examples/jsm/controls/DragControls.js +260 -132
  11. package/examples/jsm/controls/FirstPersonControls.js +175 -163
  12. package/examples/jsm/controls/FlyControls.js +194 -188
  13. package/examples/jsm/controls/OrbitControls.js +777 -786
  14. package/examples/jsm/controls/PointerLockControls.js +24 -15
  15. package/examples/jsm/controls/TrackballControls.js +453 -452
  16. package/examples/jsm/effects/AnaglyphEffect.js +6 -13
  17. package/examples/jsm/effects/ParallaxBarrierEffect.js +17 -11
  18. package/examples/jsm/effects/StereoEffect.js +6 -1
  19. package/examples/jsm/environments/RoomEnvironment.js +1 -1
  20. package/examples/jsm/exporters/GLTFExporter.js +6 -1
  21. package/examples/jsm/exporters/USDZExporter.js +29 -8
  22. package/examples/jsm/helpers/LightProbeHelper.js +42 -43
  23. package/examples/jsm/loaders/KTX2Loader.js +19 -7
  24. package/examples/jsm/loaders/MaterialXLoader.js +11 -4
  25. package/examples/jsm/loaders/PCDLoader.js +9 -9
  26. package/examples/jsm/objects/SkyMesh.js +188 -0
  27. package/examples/jsm/objects/Water2Mesh.js +159 -0
  28. package/examples/jsm/objects/WaterMesh.js +102 -0
  29. package/examples/jsm/physics/RapierPhysics.js +20 -0
  30. package/examples/jsm/postprocessing/OutlinePass.js +31 -46
  31. package/examples/jsm/postprocessing/SSAARenderPass.js +3 -1
  32. package/examples/jsm/shaders/BleachBypassShader.js +1 -2
  33. package/examples/jsm/shaders/OutputShader.js +1 -1
  34. package/examples/jsm/transpiler/TSLEncoder.js +8 -8
  35. package/examples/jsm/utils/TextureUtils.js +1 -1
  36. package/package.json +2 -1
  37. package/src/Three.WebGPU.js +6 -0
  38. package/src/Three.js +1 -0
  39. package/src/constants.js +1 -1
  40. package/src/extras/Controls.js +32 -0
  41. package/src/loaders/ObjectLoader.js +3 -3
  42. package/src/{nodes/loaders → loaders/nodes}/NodeLoader.js +4 -4
  43. package/src/{nodes/loaders → loaders/nodes}/NodeMaterialLoader.js +1 -2
  44. package/src/materials/Material.js +4 -7
  45. package/src/{nodes/materials → materials/nodes}/InstancedPointsNodeMaterial.js +33 -24
  46. package/src/{nodes/materials → materials/nodes}/Line2NodeMaterial.js +34 -37
  47. package/src/{nodes/materials → materials/nodes}/LineBasicNodeMaterial.js +3 -4
  48. package/src/{nodes/materials → materials/nodes}/LineDashedNodeMaterial.js +7 -9
  49. package/src/{nodes/materials → materials/nodes}/MeshBasicNodeMaterial.js +11 -11
  50. package/src/{nodes/materials → materials/nodes}/MeshLambertNodeMaterial.js +5 -5
  51. package/src/{nodes/materials → materials/nodes}/MeshMatcapNodeMaterial.js +8 -8
  52. package/src/materials/nodes/MeshNormalNodeMaterial.js +40 -0
  53. package/src/{nodes/materials → materials/nodes}/MeshPhongNodeMaterial.js +9 -8
  54. package/src/{nodes/materials → materials/nodes}/MeshPhysicalNodeMaterial.js +18 -17
  55. package/src/{nodes/materials → materials/nodes}/MeshSSSNodeMaterial.js +6 -6
  56. package/src/{nodes/materials → materials/nodes}/MeshStandardNodeMaterial.js +17 -11
  57. package/src/{nodes/materials → materials/nodes}/MeshToonNodeMaterial.js +4 -4
  58. package/src/{nodes/materials → materials/nodes}/NodeMaterial.js +67 -86
  59. package/src/{nodes/materials/Materials.js → materials/nodes/NodeMaterials.js} +1 -1
  60. package/src/{nodes/materials → materials/nodes}/PointsNodeMaterial.js +3 -4
  61. package/src/{nodes/materials → materials/nodes}/ShadowNodeMaterial.js +4 -4
  62. package/src/{nodes/materials → materials/nodes}/SpriteNodeMaterial.js +11 -11
  63. package/src/{nodes/materials → materials/nodes}/VolumeNodeMaterial.js +14 -16
  64. package/src/nodes/Nodes.js +103 -159
  65. package/src/nodes/TSL.js +176 -0
  66. package/src/nodes/accessors/AccessorsUtils.js +8 -8
  67. package/src/nodes/accessors/BatchNode.js +48 -20
  68. package/src/nodes/accessors/{BitangentNode.js → Bitangent.js} +9 -9
  69. package/src/nodes/accessors/BufferAttributeNode.js +5 -5
  70. package/src/nodes/accessors/BufferNode.js +4 -4
  71. package/src/nodes/accessors/{CameraNode.js → Camera.js} +10 -10
  72. package/src/nodes/accessors/ClippingNode.js +16 -14
  73. package/src/nodes/accessors/CubeTextureNode.js +5 -7
  74. package/src/nodes/accessors/InstanceNode.js +17 -13
  75. package/src/nodes/accessors/InstancedPointsMaterialNode.js +4 -4
  76. package/src/nodes/accessors/MaterialNode.js +52 -55
  77. package/src/nodes/accessors/MaterialProperties.js +3 -0
  78. package/src/nodes/accessors/MaterialReferenceNode.js +6 -4
  79. package/src/nodes/accessors/ModelNode.js +11 -11
  80. package/src/nodes/accessors/ModelViewProjectionNode.js +6 -7
  81. package/src/nodes/accessors/MorphNode.js +12 -12
  82. package/src/nodes/accessors/Normal.js +62 -0
  83. package/src/nodes/accessors/Object3DNode.js +10 -10
  84. package/src/nodes/accessors/PointUVNode.js +4 -4
  85. package/src/nodes/accessors/Position.js +10 -0
  86. package/src/nodes/accessors/ReferenceBaseNode.js +143 -0
  87. package/src/nodes/accessors/ReferenceNode.js +13 -7
  88. package/src/nodes/accessors/ReflectVector.js +10 -0
  89. package/src/nodes/accessors/RendererReferenceNode.js +6 -6
  90. package/src/nodes/accessors/SceneNode.js +5 -6
  91. package/src/nodes/accessors/SkinningNode.js +84 -21
  92. package/src/nodes/accessors/StorageBufferNode.js +4 -5
  93. package/src/nodes/accessors/StorageTextureNode.js +5 -5
  94. package/src/nodes/accessors/Tangent.js +22 -0
  95. package/src/nodes/accessors/Texture3DNode.js +11 -11
  96. package/src/nodes/accessors/{TextureBicubicNode.js → TextureBicubic.js} +3 -32
  97. package/src/nodes/accessors/TextureNode.js +16 -21
  98. package/src/nodes/accessors/TextureSizeNode.js +4 -6
  99. package/src/nodes/accessors/{UniformsNode.js → UniformArrayNode.js} +17 -8
  100. package/src/nodes/accessors/UserDataNode.js +4 -4
  101. package/src/nodes/accessors/VelocityNode.js +83 -0
  102. package/src/nodes/accessors/VertexColorNode.js +4 -4
  103. package/src/nodes/code/CodeNode.js +5 -5
  104. package/src/nodes/code/ExpressionNode.js +4 -4
  105. package/src/nodes/code/FunctionCallNode.js +5 -5
  106. package/src/nodes/code/FunctionNode.js +5 -23
  107. package/src/nodes/code/ScriptableNode.js +4 -6
  108. package/src/nodes/code/ScriptableValueNode.js +4 -6
  109. package/src/nodes/core/AssignNode.js +5 -5
  110. package/src/nodes/core/AttributeNode.js +7 -20
  111. package/src/nodes/core/BypassNode.js +5 -5
  112. package/src/nodes/core/CacheNode.js +5 -5
  113. package/src/nodes/core/ConstNode.js +2 -2
  114. package/src/nodes/core/ContextNode.js +17 -11
  115. package/src/nodes/core/IndexNode.js +12 -7
  116. package/src/nodes/core/InputNode.js +2 -2
  117. package/src/nodes/core/MRTNode.js +12 -6
  118. package/src/nodes/core/Node.js +39 -19
  119. package/src/nodes/core/NodeBuilder.js +46 -33
  120. package/src/nodes/core/NodeUtils.js +1 -0
  121. package/src/nodes/core/OutputStructNode.js +4 -4
  122. package/src/nodes/core/ParameterNode.js +4 -4
  123. package/src/nodes/core/PropertyNode.js +32 -32
  124. package/src/nodes/core/StackNode.js +26 -10
  125. package/src/nodes/core/StructTypeNode.js +2 -2
  126. package/src/nodes/core/TempNode.js +2 -2
  127. package/src/nodes/core/UniformGroupNode.js +8 -9
  128. package/src/nodes/core/UniformNode.js +4 -4
  129. package/src/nodes/core/VarNode.js +6 -6
  130. package/src/nodes/core/VaryingNode.js +5 -5
  131. package/src/nodes/display/AfterImageNode.js +9 -9
  132. package/src/nodes/display/AnaglyphPassNode.js +61 -0
  133. package/src/nodes/display/AnamorphicNode.js +11 -11
  134. package/src/nodes/display/BleachBypass.js +26 -0
  135. package/src/nodes/display/BlendMode.js +54 -0
  136. package/src/nodes/display/BloomNode.js +21 -19
  137. package/src/nodes/display/BumpMapNode.js +7 -12
  138. package/src/nodes/display/ColorAdjustment.js +46 -0
  139. package/src/nodes/display/ColorSpaceFunctions.js +38 -0
  140. package/src/nodes/display/ColorSpaceNode.js +40 -63
  141. package/src/nodes/display/DenoiseNode.js +20 -17
  142. package/src/nodes/display/DepthOfFieldNode.js +8 -6
  143. package/src/nodes/display/DotScreenNode.js +10 -22
  144. package/src/nodes/display/FXAANode.js +17 -15
  145. package/src/nodes/display/FilmNode.js +7 -6
  146. package/src/nodes/display/FrontFacingNode.js +5 -5
  147. package/src/nodes/display/GTAONode.js +19 -15
  148. package/src/nodes/display/GaussianBlurNode.js +11 -8
  149. package/src/nodes/display/Lut3DNode.js +6 -5
  150. package/src/nodes/display/MotionBlur.js +25 -0
  151. package/src/nodes/display/NormalMapNode.js +8 -10
  152. package/src/nodes/display/ParallaxBarrierPassNode.js +55 -0
  153. package/src/nodes/display/PassNode.js +84 -8
  154. package/src/nodes/display/PixelationPassNode.js +12 -7
  155. package/src/nodes/display/PosterizeNode.js +4 -6
  156. package/src/nodes/display/RGBShiftNode.js +8 -7
  157. package/src/nodes/display/RenderOutputNode.js +9 -9
  158. package/src/nodes/display/SSAAPassNode.js +284 -0
  159. package/src/nodes/display/Sepia.js +17 -0
  160. package/src/nodes/display/SobelOperatorNode.js +9 -7
  161. package/src/nodes/display/StereoCompositePassNode.js +107 -0
  162. package/src/nodes/display/StereoPassNode.js +80 -0
  163. package/src/nodes/display/ToneMappingFunctions.js +190 -0
  164. package/src/nodes/display/ToneMappingNode.js +12 -173
  165. package/src/nodes/display/TransitionNode.js +9 -8
  166. package/src/nodes/display/ViewportDepthNode.js +30 -29
  167. package/src/nodes/display/ViewportDepthTextureNode.js +6 -8
  168. package/src/nodes/display/ViewportNode.js +26 -25
  169. package/src/nodes/display/ViewportSharedTextureNode.js +6 -8
  170. package/src/nodes/display/ViewportTextureNode.js +7 -10
  171. package/src/nodes/fog/FogExp2Node.js +4 -6
  172. package/src/nodes/fog/FogNode.js +5 -7
  173. package/src/nodes/fog/FogRangeNode.js +4 -6
  174. package/src/nodes/functions/BSDF/BRDF_GGX.js +4 -4
  175. package/src/nodes/functions/BSDF/BRDF_Lambert.js +2 -2
  176. package/src/nodes/functions/BSDF/BRDF_Sheen.js +6 -6
  177. package/src/nodes/functions/BSDF/DFGApprox.js +2 -2
  178. package/src/nodes/functions/BSDF/D_GGX.js +2 -2
  179. package/src/nodes/functions/BSDF/D_GGX_Anisotropic.js +3 -3
  180. package/src/nodes/functions/BSDF/EnvironmentBRDF.js +2 -2
  181. package/src/nodes/functions/BSDF/F_Schlick.js +2 -2
  182. package/src/nodes/functions/BSDF/LTC.js +6 -6
  183. package/src/nodes/functions/BSDF/Schlick_to_F0.js +2 -2
  184. package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.js +2 -2
  185. package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +2 -2
  186. package/src/nodes/functions/BasicLightingModel.js +1 -1
  187. package/src/nodes/functions/PhongLightingModel.js +5 -5
  188. package/src/nodes/functions/PhysicalLightingModel.js +32 -31
  189. package/src/nodes/functions/ShadowMaskModel.js +1 -1
  190. package/src/nodes/functions/ToonLightingModel.js +3 -3
  191. package/src/nodes/functions/material/getGeometryRoughness.js +4 -4
  192. package/src/nodes/functions/material/getRoughness.js +2 -2
  193. package/src/nodes/geometry/RangeNode.js +4 -4
  194. package/src/nodes/gpgpu/ComputeNode.js +5 -5
  195. package/src/nodes/lighting/AONode.js +2 -2
  196. package/src/nodes/lighting/AmbientLightNode.js +2 -7
  197. package/src/nodes/lighting/AnalyticLightNode.js +34 -13
  198. package/src/nodes/lighting/BasicEnvironmentNode.js +4 -3
  199. package/src/nodes/lighting/BasicLightMapNode.js +3 -3
  200. package/src/nodes/lighting/DirectionalLightNode.js +2 -7
  201. package/src/nodes/lighting/EnvironmentNode.js +20 -19
  202. package/src/nodes/lighting/HemisphereLightNode.js +3 -7
  203. package/src/nodes/lighting/IESSpotLightNode.js +3 -8
  204. package/src/nodes/lighting/IrradianceNode.js +2 -2
  205. package/src/nodes/lighting/LightNode.js +5 -5
  206. package/src/nodes/lighting/LightProbeNode.js +76 -0
  207. package/src/nodes/lighting/LightUtils.js +3 -3
  208. package/src/nodes/lighting/LightingContextNode.js +15 -17
  209. package/src/nodes/lighting/LightingNode.js +2 -2
  210. package/src/nodes/lighting/LightsNode.js +94 -76
  211. package/src/nodes/lighting/PointLightNode.js +3 -8
  212. package/src/nodes/lighting/RectAreaLightNode.js +2 -6
  213. package/src/nodes/lighting/SpotLightNode.js +3 -8
  214. package/src/nodes/materialx/MaterialXNodes.js +2 -2
  215. package/src/nodes/materialx/lib/mx_hsv.js +36 -31
  216. package/src/nodes/materialx/lib/mx_noise.js +96 -96
  217. package/src/nodes/materialx/lib/mx_transform_color.js +2 -2
  218. package/src/nodes/math/{CondNode.js → ConditionalNode.js} +18 -7
  219. package/src/nodes/math/Hash.js +13 -0
  220. package/src/nodes/math/MathNode.js +124 -124
  221. package/src/nodes/math/MathUtils.js +0 -7
  222. package/src/nodes/math/OperatorNode.js +94 -52
  223. package/src/nodes/math/TriNoise3D.js +19 -29
  224. package/src/nodes/pmrem/PMREMNode.js +58 -15
  225. package/src/nodes/pmrem/PMREMUtils.js +46 -46
  226. package/src/nodes/procedural/Checker.js +14 -0
  227. package/src/nodes/tsl/TSLBase.js +30 -0
  228. package/src/nodes/{shadernode/ShaderNode.js → tsl/TSLCore.js} +105 -97
  229. package/src/nodes/utils/ArrayElementNode.js +2 -2
  230. package/src/nodes/utils/ConvertNode.js +2 -2
  231. package/src/nodes/utils/CubeMapNode.js +157 -0
  232. package/src/nodes/utils/Discard.js +8 -0
  233. package/src/nodes/utils/EquirectUVNode.js +5 -5
  234. package/src/nodes/utils/FlipNode.js +65 -0
  235. package/src/nodes/utils/FunctionOverloadingNode.js +5 -5
  236. package/src/nodes/utils/JoinNode.js +2 -2
  237. package/src/nodes/utils/LoopNode.js +12 -6
  238. package/src/nodes/utils/MatcapUVNode.js +6 -6
  239. package/src/nodes/utils/MaxMipLevelNode.js +4 -4
  240. package/src/nodes/utils/OscNode.js +7 -7
  241. package/src/nodes/utils/Packing.js +4 -0
  242. package/src/nodes/utils/RTTNode.js +8 -8
  243. package/src/nodes/utils/ReflectorNode.js +8 -3
  244. package/src/nodes/utils/RemapNode.js +7 -7
  245. package/src/nodes/utils/RotateNode.js +4 -12
  246. package/src/nodes/utils/SetNode.js +2 -2
  247. package/src/nodes/utils/SplitNode.js +2 -2
  248. package/src/nodes/utils/SpriteSheetUVNode.js +5 -5
  249. package/src/nodes/utils/SpriteUtils.js +47 -0
  250. package/src/nodes/utils/StorageArrayElementNode.js +4 -6
  251. package/src/nodes/utils/TimerNode.js +5 -5
  252. package/src/nodes/utils/TriplanarTexturesNode.js +7 -9
  253. package/src/nodes/utils/UVUtils.js +19 -0
  254. package/src/nodes/utils/ViewportUtils.js +14 -0
  255. package/src/objects/BatchedMesh.js +2 -3
  256. package/src/renderers/WebGLRenderer.js +24 -0
  257. package/src/renderers/common/Backend.js +2 -2
  258. package/src/renderers/common/Background.js +3 -1
  259. package/src/renderers/common/BindGroup.js +3 -1
  260. package/src/renderers/common/Bindings.js +13 -15
  261. package/src/renderers/common/ClippingContext.js +14 -5
  262. package/src/renderers/common/CubeRenderTarget.js +9 -3
  263. package/src/renderers/common/PostProcessing.js +4 -1
  264. package/src/renderers/common/QuadMesh.js +2 -0
  265. package/src/renderers/common/RenderContext.js +24 -0
  266. package/src/renderers/common/RenderList.js +1 -1
  267. package/src/renderers/common/RenderObject.js +2 -2
  268. package/src/renderers/common/Renderer.js +75 -49
  269. package/src/renderers/common/SampledTexture.js +12 -3
  270. package/src/renderers/common/StandardRenderer.js +18 -0
  271. package/src/renderers/common/Textures.js +8 -12
  272. package/src/renderers/common/extras/PMREMGenerator.js +12 -13
  273. package/src/renderers/common/nodes/NodeBuilderState.js +1 -1
  274. package/src/renderers/common/nodes/NodeLibrary.js +118 -0
  275. package/src/renderers/common/nodes/NodeSampledTexture.js +2 -2
  276. package/src/renderers/common/nodes/Nodes.js +36 -9
  277. package/src/renderers/common/nodes/StandardNodeLibrary.js +105 -0
  278. package/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js +2 -2
  279. package/src/renderers/webgl/WebGLProgram.js +1 -1
  280. package/src/renderers/webgl/WebGLProperties.js +7 -0
  281. package/src/renderers/webgl/WebGLTextures.js +61 -4
  282. package/src/renderers/webgl-fallback/WebGLBackend.js +88 -68
  283. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +57 -9
  284. package/src/renderers/webgl-fallback/utils/WebGLState.js +21 -0
  285. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +28 -21
  286. package/src/renderers/webgpu/WebGPUBackend.js +86 -68
  287. package/src/renderers/webgpu/WebGPURenderer.js +8 -8
  288. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +99 -63
  289. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +45 -21
  290. package/src/renderers/webgpu/utils/WebGPUConstants.js +2 -1
  291. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +6 -15
  292. package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +62 -5
  293. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +36 -21
  294. package/src/renderers/webgpu/utils/WebGPUUtils.js +18 -1
  295. package/src/renderers/webxr/WebXRManager.js +32 -25
  296. package/examples/jsm/loaders/LogLuvLoader.js +0 -606
  297. package/src/nodes/accessors/NormalNode.js +0 -14
  298. package/src/nodes/accessors/PositionNode.js +0 -10
  299. package/src/nodes/accessors/ReflectVectorNode.js +0 -10
  300. package/src/nodes/accessors/TangentNode.js +0 -23
  301. package/src/nodes/core/NodeKeywords.js +0 -80
  302. package/src/nodes/display/BlendModeNode.js +0 -128
  303. package/src/nodes/display/ColorAdjustmentNode.js +0 -104
  304. package/src/nodes/materials/MeshNormalNodeMaterial.js +0 -40
  305. package/src/nodes/math/HashNode.js +0 -34
  306. package/src/nodes/procedural/CheckerNode.js +0 -42
  307. package/src/nodes/utils/DiscardNode.js +0 -28
  308. package/src/nodes/utils/PackingNode.js +0 -55
  309. package/src/nodes/utils/RotateUVNode.js +0 -35
  310. /package/src/{nodes/loaders → loaders/nodes}/NodeObjectLoader.js +0 -0
  311. /package/src/nodes/accessors/{UVNode.js → UV.js} +0 -0
@@ -1,5 +1,5 @@
1
1
  import {
2
- EventDispatcher,
2
+ Controls,
3
3
  MathUtils,
4
4
  MOUSE,
5
5
  Quaternion,
@@ -11,18 +11,25 @@ const _changeEvent = { type: 'change' };
11
11
  const _startEvent = { type: 'start' };
12
12
  const _endEvent = { type: 'end' };
13
13
 
14
- class TrackballControls extends EventDispatcher {
14
+ const _EPS = 0.000001;
15
+ const _STATE = { NONE: - 1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 };
15
16
 
16
- constructor( object, domElement ) {
17
+ const _v2 = new Vector2();
18
+ const _mouseChange = new Vector2();
19
+ const _objectUp = new Vector3();
20
+ const _pan = new Vector3();
21
+ const _axis = new Vector3();
22
+ const _quaternion = new Quaternion();
23
+ const _eyeDirection = new Vector3();
24
+ const _objectUpDirection = new Vector3();
25
+ const _objectSidewaysDirection = new Vector3();
26
+ const _moveDirection = new Vector3();
17
27
 
18
- super();
28
+ class TrackballControls extends Controls {
19
29
 
20
- const scope = this;
21
- const STATE = { NONE: - 1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 };
30
+ constructor( object, domElement = null ) {
22
31
 
23
- this.object = object;
24
- this.domElement = domElement;
25
- this.domElement.style.touchAction = 'none'; // disable touch scroll
32
+ super( object, domElement );
26
33
 
27
34
  // API
28
35
 
@@ -50,779 +57,773 @@ class TrackballControls extends EventDispatcher {
50
57
  this.keys = [ 'KeyA' /*A*/, 'KeyS' /*S*/, 'KeyD' /*D*/ ];
51
58
 
52
59
  this.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.PAN };
53
-
54
- // internals
60
+ this.state = _STATE.NONE;
61
+ this.keyState = _STATE.NONE;
55
62
 
56
63
  this.target = new Vector3();
57
64
 
58
- const EPS = 0.000001;
59
-
60
- const lastPosition = new Vector3();
61
- let lastZoom = 1;
62
-
63
- let _state = STATE.NONE,
64
- _keyState = STATE.NONE,
65
-
66
- _touchZoomDistanceStart = 0,
67
- _touchZoomDistanceEnd = 0,
65
+ // internals
68
66
 
69
- _lastAngle = 0;
67
+ this._lastPosition = new Vector3();
68
+ this._lastZoom = 1;
69
+ this._touchZoomDistanceStart = 0;
70
+ this._touchZoomDistanceEnd = 0;
71
+ this._lastAngle = 0;
70
72
 
71
- const _eye = new Vector3(),
73
+ this._eye = new Vector3();
72
74
 
73
- _movePrev = new Vector2(),
74
- _moveCurr = new Vector2(),
75
+ this._movePrev = new Vector2();
76
+ this._moveCurr = new Vector2();
75
77
 
76
- _lastAxis = new Vector3(),
78
+ this._lastAxis = new Vector3();
77
79
 
78
- _zoomStart = new Vector2(),
79
- _zoomEnd = new Vector2(),
80
+ this._zoomStart = new Vector2();
81
+ this._zoomEnd = new Vector2();
80
82
 
81
- _panStart = new Vector2(),
82
- _panEnd = new Vector2(),
83
+ this._panStart = new Vector2();
84
+ this._panEnd = new Vector2();
83
85
 
84
- _pointers = [],
85
- _pointerPositions = {};
86
+ this._pointers = [];
87
+ this._pointerPositions = {};
86
88
 
87
- // for reset
89
+ // event listeners
88
90
 
89
- this.target0 = this.target.clone();
90
- this.position0 = this.object.position.clone();
91
- this.up0 = this.object.up.clone();
92
- this.zoom0 = this.object.zoom;
91
+ this._onPointerMove = onPointerMove.bind( this );
92
+ this._onPointerDown = onPointerDown.bind( this );
93
+ this._onPointerUp = onPointerUp.bind( this );
94
+ this._onPointerCancel = onPointerCancel.bind( this );
95
+ this._onContextMenu = onContextMenu.bind( this );
96
+ this._onMouseWheel = onMouseWheel.bind( this );
97
+ this._onKeyDown = onKeyDown.bind( this );
98
+ this._onKeyUp = onKeyUp.bind( this );
93
99
 
94
- // methods
100
+ this._onTouchStart = onTouchStart.bind( this );
101
+ this._onTouchMove = onTouchMove.bind( this );
102
+ this._onTouchEnd = onTouchEnd.bind( this );
95
103
 
96
- this.handleResize = function () {
104
+ this._onMouseDown = onMouseDown.bind( this );
105
+ this._onMouseMove = onMouseMove.bind( this );
106
+ this._onMouseUp = onMouseUp.bind( this );
97
107
 
98
- const box = scope.domElement.getBoundingClientRect();
99
- // adjustments come from similar code in the jquery offset() function
100
- const d = scope.domElement.ownerDocument.documentElement;
101
- scope.screen.left = box.left + window.pageXOffset - d.clientLeft;
102
- scope.screen.top = box.top + window.pageYOffset - d.clientTop;
103
- scope.screen.width = box.width;
104
- scope.screen.height = box.height;
108
+ // for reset
105
109
 
106
- };
110
+ this._target0 = this.target.clone();
111
+ this._position0 = this.object.position.clone();
112
+ this._up0 = this.object.up.clone();
113
+ this._zoom0 = this.object.zoom;
107
114
 
108
- const getMouseOnScreen = ( function () {
115
+ if ( domElement !== null ) {
109
116
 
110
- const vector = new Vector2();
117
+ this.connect();
111
118
 
112
- return function getMouseOnScreen( pageX, pageY ) {
119
+ this.handleResize();
113
120
 
114
- vector.set(
115
- ( pageX - scope.screen.left ) / scope.screen.width,
116
- ( pageY - scope.screen.top ) / scope.screen.height
117
- );
121
+ }
118
122
 
119
- return vector;
123
+ // force an update at start
124
+ this.update();
120
125
 
121
- };
126
+ }
122
127
 
123
- }() );
128
+ connect() {
124
129
 
125
- const getMouseOnCircle = ( function () {
130
+ window.addEventListener( 'keydown', this._onKeyDown );
131
+ window.addEventListener( 'keyup', this._onKeyUp );
126
132
 
127
- const vector = new Vector2();
133
+ this.domElement.addEventListener( 'pointerdown', this._onPointerDown );
134
+ this.domElement.addEventListener( 'pointercancel', this._onPointerCancel );
135
+ this.domElement.addEventListener( 'wheel', this._onMouseWheel, { passive: false } );
136
+ this.domElement.addEventListener( 'contextmenu', this._onContextMenu );
128
137
 
129
- return function getMouseOnCircle( pageX, pageY ) {
138
+ this.domElement.style.touchAction = 'none'; // disable touch scroll
130
139
 
131
- vector.set(
132
- ( ( pageX - scope.screen.width * 0.5 - scope.screen.left ) / ( scope.screen.width * 0.5 ) ),
133
- ( ( scope.screen.height + 2 * ( scope.screen.top - pageY ) ) / scope.screen.width ) // screen.width intentional
134
- );
140
+ }
135
141
 
136
- return vector;
142
+ disconnect() {
137
143
 
138
- };
144
+ window.removeEventListener( 'keydown', this._onKeyDown );
145
+ window.removeEventListener( 'keyup', this._onKeyUp );
139
146
 
140
- }() );
147
+ this.domElement.removeEventListener( 'pointerdown', this._onPointerDown );
148
+ this.domElement.removeEventListener( 'pointermove', this._onPointerMove );
149
+ this.domElement.removeEventListener( 'pointerup', this._onPointerUp );
150
+ this.domElement.removeEventListener( 'pointercancel', this._onPointerCancel );
151
+ this.domElement.removeEventListener( 'wheel', this._onMouseWheel );
152
+ this.domElement.removeEventListener( 'contextmenu', this._onContextMenu );
141
153
 
142
- this.rotateCamera = ( function () {
154
+ this.domElement.style.touchAction = 'auto'; // disable touch scroll
143
155
 
144
- const axis = new Vector3(),
145
- quaternion = new Quaternion(),
146
- eyeDirection = new Vector3(),
147
- objectUpDirection = new Vector3(),
148
- objectSidewaysDirection = new Vector3(),
149
- moveDirection = new Vector3();
156
+ }
150
157
 
151
- return function rotateCamera() {
158
+ dispose() {
152
159
 
153
- moveDirection.set( _moveCurr.x - _movePrev.x, _moveCurr.y - _movePrev.y, 0 );
154
- let angle = moveDirection.length();
160
+ this.disconnect();
155
161
 
156
- if ( angle ) {
162
+ }
157
163
 
158
- _eye.copy( scope.object.position ).sub( scope.target );
164
+ handleResize() {
159
165
 
160
- eyeDirection.copy( _eye ).normalize();
161
- objectUpDirection.copy( scope.object.up ).normalize();
162
- objectSidewaysDirection.crossVectors( objectUpDirection, eyeDirection ).normalize();
166
+ const box = this.domElement.getBoundingClientRect();
167
+ // adjustments come from similar code in the jquery offset() function
168
+ const d = this.domElement.ownerDocument.documentElement;
163
169
 
164
- objectUpDirection.setLength( _moveCurr.y - _movePrev.y );
165
- objectSidewaysDirection.setLength( _moveCurr.x - _movePrev.x );
170
+ this.screen.left = box.left + window.pageXOffset - d.clientLeft;
171
+ this.screen.top = box.top + window.pageYOffset - d.clientTop;
172
+ this.screen.width = box.width;
173
+ this.screen.height = box.height;
166
174
 
167
- moveDirection.copy( objectUpDirection.add( objectSidewaysDirection ) );
175
+ }
168
176
 
169
- axis.crossVectors( moveDirection, _eye ).normalize();
177
+ update() {
170
178
 
171
- angle *= scope.rotateSpeed;
172
- quaternion.setFromAxisAngle( axis, angle );
179
+ this._eye.subVectors( this.object.position, this.target );
173
180
 
174
- _eye.applyQuaternion( quaternion );
175
- scope.object.up.applyQuaternion( quaternion );
181
+ if ( ! this.noRotate ) {
176
182
 
177
- _lastAxis.copy( axis );
178
- _lastAngle = angle;
183
+ this._rotateCamera();
179
184
 
180
- } else if ( ! scope.staticMoving && _lastAngle ) {
185
+ }
181
186
 
182
- _lastAngle *= Math.sqrt( 1.0 - scope.dynamicDampingFactor );
183
- _eye.copy( scope.object.position ).sub( scope.target );
184
- quaternion.setFromAxisAngle( _lastAxis, _lastAngle );
185
- _eye.applyQuaternion( quaternion );
186
- scope.object.up.applyQuaternion( quaternion );
187
+ if ( ! this.noZoom ) {
187
188
 
188
- }
189
+ this._zoomCamera();
189
190
 
190
- _movePrev.copy( _moveCurr );
191
+ }
191
192
 
192
- };
193
+ if ( ! this.noPan ) {
193
194
 
194
- }() );
195
+ this._panCamera();
195
196
 
197
+ }
196
198
 
197
- this.zoomCamera = function () {
199
+ this.object.position.addVectors( this.target, this._eye );
198
200
 
199
- let factor;
201
+ if ( this.object.isPerspectiveCamera ) {
200
202
 
201
- if ( _state === STATE.TOUCH_ZOOM_PAN ) {
203
+ this._checkDistances();
202
204
 
203
- factor = _touchZoomDistanceStart / _touchZoomDistanceEnd;
204
- _touchZoomDistanceStart = _touchZoomDistanceEnd;
205
+ this.object.lookAt( this.target );
205
206
 
206
- if ( scope.object.isPerspectiveCamera ) {
207
+ if ( this._lastPosition.distanceToSquared( this.object.position ) > _EPS ) {
207
208
 
208
- _eye.multiplyScalar( factor );
209
+ this.dispatchEvent( _changeEvent );
209
210
 
210
- } else if ( scope.object.isOrthographicCamera ) {
211
+ this._lastPosition.copy( this.object.position );
211
212
 
212
- scope.object.zoom = MathUtils.clamp( scope.object.zoom / factor, scope.minZoom, scope.maxZoom );
213
+ }
213
214
 
214
- if ( lastZoom !== scope.object.zoom ) {
215
+ } else if ( this.object.isOrthographicCamera ) {
215
216
 
216
- scope.object.updateProjectionMatrix();
217
+ this.object.lookAt( this.target );
217
218
 
218
- }
219
+ if ( this._lastPosition.distanceToSquared( this.object.position ) > _EPS || this._lastZoom !== this.object.zoom ) {
219
220
 
220
- } else {
221
+ this.dispatchEvent( _changeEvent );
221
222
 
222
- console.warn( 'THREE.TrackballControls: Unsupported camera type' );
223
+ this._lastPosition.copy( this.object.position );
224
+ this._lastZoom = this.object.zoom;
223
225
 
224
- }
226
+ }
225
227
 
226
- } else {
228
+ } else {
227
229
 
228
- factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * scope.zoomSpeed;
230
+ console.warn( 'THREE.TrackballControls: Unsupported camera type.' );
229
231
 
230
- if ( factor !== 1.0 && factor > 0.0 ) {
232
+ }
231
233
 
232
- if ( scope.object.isPerspectiveCamera ) {
234
+ }
233
235
 
234
- _eye.multiplyScalar( factor );
236
+ reset() {
235
237
 
236
- } else if ( scope.object.isOrthographicCamera ) {
238
+ this.state = _STATE.NONE;
239
+ this.keyState = _STATE.NONE;
237
240
 
238
- scope.object.zoom = MathUtils.clamp( scope.object.zoom / factor, scope.minZoom, scope.maxZoom );
241
+ this.target.copy( this._target0 );
242
+ this.object.position.copy( this._position0 );
243
+ this.object.up.copy( this._up0 );
244
+ this.object.zoom = this._zoom0;
239
245
 
240
- if ( lastZoom !== scope.object.zoom ) {
246
+ this.object.updateProjectionMatrix();
241
247
 
242
- scope.object.updateProjectionMatrix();
248
+ this._eye.subVectors( this.object.position, this.target );
243
249
 
244
- }
250
+ this.object.lookAt( this.target );
245
251
 
246
- } else {
252
+ this.dispatchEvent( _changeEvent );
247
253
 
248
- console.warn( 'THREE.TrackballControls: Unsupported camera type' );
254
+ this._lastPosition.copy( this.object.position );
255
+ this._lastZoom = this.object.zoom;
249
256
 
250
- }
257
+ }
251
258
 
252
- }
259
+ _panCamera() {
253
260
 
254
- if ( scope.staticMoving ) {
261
+ _mouseChange.copy( this._panEnd ).sub( this._panStart );
255
262
 
256
- _zoomStart.copy( _zoomEnd );
263
+ if ( _mouseChange.lengthSq() ) {
257
264
 
258
- } else {
265
+ if ( this.object.isOrthographicCamera ) {
259
266
 
260
- _zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor;
267
+ const scale_x = ( this.object.right - this.object.left ) / this.object.zoom / this.domElement.clientWidth;
268
+ const scale_y = ( this.object.top - this.object.bottom ) / this.object.zoom / this.domElement.clientWidth;
261
269
 
262
- }
270
+ _mouseChange.x *= scale_x;
271
+ _mouseChange.y *= scale_y;
263
272
 
264
273
  }
265
274
 
266
- };
267
-
268
- this.panCamera = ( function () {
269
-
270
- const mouseChange = new Vector2(),
271
- objectUp = new Vector3(),
272
- pan = new Vector3();
275
+ _mouseChange.multiplyScalar( this._eye.length() * this.panSpeed );
273
276
 
274
- return function panCamera() {
277
+ _pan.copy( this._eye ).cross( this.object.up ).setLength( _mouseChange.x );
278
+ _pan.add( _objectUp.copy( this.object.up ).setLength( _mouseChange.y ) );
275
279
 
276
- mouseChange.copy( _panEnd ).sub( _panStart );
280
+ this.object.position.add( _pan );
281
+ this.target.add( _pan );
277
282
 
278
- if ( mouseChange.lengthSq() ) {
283
+ if ( this.staticMoving ) {
279
284
 
280
- if ( scope.object.isOrthographicCamera ) {
285
+ this._panStart.copy( this._panEnd );
281
286
 
282
- const scale_x = ( scope.object.right - scope.object.left ) / scope.object.zoom / scope.domElement.clientWidth;
283
- const scale_y = ( scope.object.top - scope.object.bottom ) / scope.object.zoom / scope.domElement.clientWidth;
287
+ } else {
284
288
 
285
- mouseChange.x *= scale_x;
286
- mouseChange.y *= scale_y;
289
+ this._panStart.add( _mouseChange.subVectors( this._panEnd, this._panStart ).multiplyScalar( this.dynamicDampingFactor ) );
287
290
 
288
- }
291
+ }
289
292
 
290
- mouseChange.multiplyScalar( _eye.length() * scope.panSpeed );
293
+ }
291
294
 
292
- pan.copy( _eye ).cross( scope.object.up ).setLength( mouseChange.x );
293
- pan.add( objectUp.copy( scope.object.up ).setLength( mouseChange.y ) );
295
+ }
294
296
 
295
- scope.object.position.add( pan );
296
- scope.target.add( pan );
297
+ _rotateCamera() {
297
298
 
298
- if ( scope.staticMoving ) {
299
+ _moveDirection.set( this._moveCurr.x - this._movePrev.x, this._moveCurr.y - this._movePrev.y, 0 );
300
+ let angle = _moveDirection.length();
299
301
 
300
- _panStart.copy( _panEnd );
302
+ if ( angle ) {
301
303
 
302
- } else {
304
+ this._eye.copy( this.object.position ).sub( this.target );
303
305
 
304
- _panStart.add( mouseChange.subVectors( _panEnd, _panStart ).multiplyScalar( scope.dynamicDampingFactor ) );
306
+ _eyeDirection.copy( this._eye ).normalize();
307
+ _objectUpDirection.copy( this.object.up ).normalize();
308
+ _objectSidewaysDirection.crossVectors( _objectUpDirection, _eyeDirection ).normalize();
305
309
 
306
- }
310
+ _objectUpDirection.setLength( this._moveCurr.y - this._movePrev.y );
311
+ _objectSidewaysDirection.setLength( this._moveCurr.x - this._movePrev.x );
307
312
 
308
- }
313
+ _moveDirection.copy( _objectUpDirection.add( _objectSidewaysDirection ) );
309
314
 
310
- };
315
+ _axis.crossVectors( _moveDirection, this._eye ).normalize();
311
316
 
312
- }() );
317
+ angle *= this.rotateSpeed;
318
+ _quaternion.setFromAxisAngle( _axis, angle );
313
319
 
314
- this.checkDistances = function () {
320
+ this._eye.applyQuaternion( _quaternion );
321
+ this.object.up.applyQuaternion( _quaternion );
315
322
 
316
- if ( ! scope.noZoom || ! scope.noPan ) {
323
+ this._lastAxis.copy( _axis );
324
+ this._lastAngle = angle;
317
325
 
318
- if ( _eye.lengthSq() > scope.maxDistance * scope.maxDistance ) {
326
+ } else if ( ! this.staticMoving && this._lastAngle ) {
319
327
 
320
- scope.object.position.addVectors( scope.target, _eye.setLength( scope.maxDistance ) );
321
- _zoomStart.copy( _zoomEnd );
328
+ this._lastAngle *= Math.sqrt( 1.0 - this.dynamicDampingFactor );
329
+ this._eye.copy( this.object.position ).sub( this.target );
330
+ _quaternion.setFromAxisAngle( this._lastAxis, this._lastAngle );
331
+ this._eye.applyQuaternion( _quaternion );
332
+ this.object.up.applyQuaternion( _quaternion );
322
333
 
323
- }
334
+ }
324
335
 
325
- if ( _eye.lengthSq() < scope.minDistance * scope.minDistance ) {
336
+ this._movePrev.copy( this._moveCurr );
326
337
 
327
- scope.object.position.addVectors( scope.target, _eye.setLength( scope.minDistance ) );
328
- _zoomStart.copy( _zoomEnd );
338
+ }
329
339
 
330
- }
340
+ _zoomCamera() {
331
341
 
332
- }
342
+ let factor;
333
343
 
334
- };
344
+ if ( this.state === _STATE.TOUCH_ZOOM_PAN ) {
335
345
 
336
- this.update = function () {
346
+ factor = this._touchZoomDistanceStart / this._touchZoomDistanceEnd;
347
+ this._touchZoomDistanceStart = this._touchZoomDistanceEnd;
337
348
 
338
- _eye.subVectors( scope.object.position, scope.target );
349
+ if ( this.object.isPerspectiveCamera ) {
339
350
 
340
- if ( ! scope.noRotate ) {
351
+ this._eye.multiplyScalar( factor );
341
352
 
342
- scope.rotateCamera();
353
+ } else if ( this.object.isOrthographicCamera ) {
343
354
 
344
- }
355
+ this.object.zoom = MathUtils.clamp( this.object.zoom / factor, this.minZoom, this.maxZoom );
345
356
 
346
- if ( ! scope.noZoom ) {
357
+ if ( this._lastZoom !== this.object.zoom ) {
347
358
 
348
- scope.zoomCamera();
359
+ this.object.updateProjectionMatrix();
349
360
 
350
- }
361
+ }
351
362
 
352
- if ( ! scope.noPan ) {
363
+ } else {
353
364
 
354
- scope.panCamera();
365
+ console.warn( 'THREE.TrackballControls: Unsupported camera type' );
355
366
 
356
367
  }
357
368
 
358
- scope.object.position.addVectors( scope.target, _eye );
369
+ } else {
359
370
 
360
- if ( scope.object.isPerspectiveCamera ) {
371
+ factor = 1.0 + ( this._zoomEnd.y - this._zoomStart.y ) * this.zoomSpeed;
361
372
 
362
- scope.checkDistances();
373
+ if ( factor !== 1.0 && factor > 0.0 ) {
363
374
 
364
- scope.object.lookAt( scope.target );
375
+ if ( this.object.isPerspectiveCamera ) {
365
376
 
366
- if ( lastPosition.distanceToSquared( scope.object.position ) > EPS ) {
377
+ this._eye.multiplyScalar( factor );
367
378
 
368
- scope.dispatchEvent( _changeEvent );
379
+ } else if ( this.object.isOrthographicCamera ) {
369
380
 
370
- lastPosition.copy( scope.object.position );
381
+ this.object.zoom = MathUtils.clamp( this.object.zoom / factor, this.minZoom, this.maxZoom );
371
382
 
372
- }
373
-
374
- } else if ( scope.object.isOrthographicCamera ) {
383
+ if ( this._lastZoom !== this.object.zoom ) {
375
384
 
376
- scope.object.lookAt( scope.target );
385
+ this.object.updateProjectionMatrix();
377
386
 
378
- if ( lastPosition.distanceToSquared( scope.object.position ) > EPS || lastZoom !== scope.object.zoom ) {
387
+ }
379
388
 
380
- scope.dispatchEvent( _changeEvent );
389
+ } else {
381
390
 
382
- lastPosition.copy( scope.object.position );
383
- lastZoom = scope.object.zoom;
391
+ console.warn( 'THREE.TrackballControls: Unsupported camera type' );
384
392
 
385
393
  }
386
394
 
387
- } else {
388
-
389
- console.warn( 'THREE.TrackballControls: Unsupported camera type' );
390
-
391
395
  }
392
396
 
393
- };
397
+ if ( this.staticMoving ) {
394
398
 
395
- this.reset = function () {
399
+ this._zoomStart.copy( this._zoomEnd );
396
400
 
397
- _state = STATE.NONE;
398
- _keyState = STATE.NONE;
401
+ } else {
399
402
 
400
- scope.target.copy( scope.target0 );
401
- scope.object.position.copy( scope.position0 );
402
- scope.object.up.copy( scope.up0 );
403
- scope.object.zoom = scope.zoom0;
403
+ this._zoomStart.y += ( this._zoomEnd.y - this._zoomStart.y ) * this.dynamicDampingFactor;
404
404
 
405
- scope.object.updateProjectionMatrix();
405
+ }
406
406
 
407
- _eye.subVectors( scope.object.position, scope.target );
407
+ }
408
408
 
409
- scope.object.lookAt( scope.target );
409
+ }
410
410
 
411
- scope.dispatchEvent( _changeEvent );
411
+ _getMouseOnScreen( pageX, pageY ) {
412
412
 
413
- lastPosition.copy( scope.object.position );
414
- lastZoom = scope.object.zoom;
413
+ _v2.set(
414
+ ( pageX - this.screen.left ) / this.screen.width,
415
+ ( pageY - this.screen.top ) / this.screen.height
416
+ );
415
417
 
416
- };
418
+ return _v2;
417
419
 
418
- // listeners
420
+ }
419
421
 
420
- function onPointerDown( event ) {
422
+ _getMouseOnCircle( pageX, pageY ) {
421
423
 
422
- if ( scope.enabled === false ) return;
424
+ _v2.set(
425
+ ( ( pageX - this.screen.width * 0.5 - this.screen.left ) / ( this.screen.width * 0.5 ) ),
426
+ ( ( this.screen.height + 2 * ( this.screen.top - pageY ) ) / this.screen.width ) // screen.width intentional
427
+ );
423
428
 
424
- if ( _pointers.length === 0 ) {
429
+ return _v2;
425
430
 
426
- scope.domElement.setPointerCapture( event.pointerId );
431
+ }
427
432
 
428
- scope.domElement.addEventListener( 'pointermove', onPointerMove );
429
- scope.domElement.addEventListener( 'pointerup', onPointerUp );
433
+ _addPointer( event ) {
430
434
 
431
- }
435
+ this._pointers.push( event );
432
436
 
433
- //
437
+ }
434
438
 
435
- addPointer( event );
439
+ _removePointer( event ) {
436
440
 
437
- if ( event.pointerType === 'touch' ) {
441
+ delete this._pointerPositions[ event.pointerId ];
438
442
 
439
- onTouchStart( event );
443
+ for ( let i = 0; i < this._pointers.length; i ++ ) {
440
444
 
441
- } else {
445
+ if ( this._pointers[ i ].pointerId == event.pointerId ) {
442
446
 
443
- onMouseDown( event );
447
+ this._pointers.splice( i, 1 );
448
+ return;
444
449
 
445
450
  }
446
451
 
447
452
  }
448
453
 
449
- function onPointerMove( event ) {
450
-
451
- if ( scope.enabled === false ) return;
454
+ }
452
455
 
453
- if ( event.pointerType === 'touch' ) {
456
+ _trackPointer( event ) {
454
457
 
455
- onTouchMove( event );
458
+ let position = this._pointerPositions[ event.pointerId ];
456
459
 
457
- } else {
460
+ if ( position === undefined ) {
458
461
 
459
- onMouseMove( event );
460
-
461
- }
462
+ position = new Vector2();
463
+ this._pointerPositions[ event.pointerId ] = position;
462
464
 
463
465
  }
464
466
 
465
- function onPointerUp( event ) {
467
+ position.set( event.pageX, event.pageY );
468
+
469
+ }
466
470
 
467
- if ( scope.enabled === false ) return;
471
+ _getSecondPointerPosition( event ) {
468
472
 
469
- if ( event.pointerType === 'touch' ) {
473
+ const pointer = ( event.pointerId === this._pointers[ 0 ].pointerId ) ? this._pointers[ 1 ] : this._pointers[ 0 ];
470
474
 
471
- onTouchEnd( event );
475
+ return this._pointerPositions[ pointer.pointerId ];
472
476
 
473
- } else {
477
+ }
474
478
 
475
- onMouseUp();
479
+ _checkDistances() {
476
480
 
477
- }
481
+ if ( ! this.noZoom || ! this.noPan ) {
478
482
 
479
- //
483
+ if ( this._eye.lengthSq() > this.maxDistance * this.maxDistance ) {
480
484
 
481
- removePointer( event );
485
+ this.object.position.addVectors( this.target, this._eye.setLength( this.maxDistance ) );
486
+ this._zoomStart.copy( this._zoomEnd );
482
487
 
483
- if ( _pointers.length === 0 ) {
488
+ }
484
489
 
485
- scope.domElement.releasePointerCapture( event.pointerId );
490
+ if ( this._eye.lengthSq() < this.minDistance * this.minDistance ) {
486
491
 
487
- scope.domElement.removeEventListener( 'pointermove', onPointerMove );
488
- scope.domElement.removeEventListener( 'pointerup', onPointerUp );
492
+ this.object.position.addVectors( this.target, this._eye.setLength( this.minDistance ) );
493
+ this._zoomStart.copy( this._zoomEnd );
489
494
 
490
495
  }
491
496
 
492
-
493
497
  }
494
498
 
495
- function onPointerCancel( event ) {
499
+ }
496
500
 
497
- removePointer( event );
501
+ }
498
502
 
499
- }
503
+ function onPointerDown( event ) {
500
504
 
501
- function keydown( event ) {
505
+ if ( this.enabled === false ) return;
502
506
 
503
- if ( scope.enabled === false ) return;
507
+ if ( this._pointers.length === 0 ) {
504
508
 
505
- window.removeEventListener( 'keydown', keydown );
509
+ this.domElement.setPointerCapture( event.pointerId );
506
510
 
507
- if ( _keyState !== STATE.NONE ) {
511
+ this.domElement.addEventListener( 'pointermove', this._onPointerMove );
512
+ this.domElement.addEventListener( 'pointerup', this._onPointerUp );
508
513
 
509
- return;
514
+ }
510
515
 
511
- } else if ( event.code === scope.keys[ STATE.ROTATE ] && ! scope.noRotate ) {
516
+ //
512
517
 
513
- _keyState = STATE.ROTATE;
518
+ this._addPointer( event );
514
519
 
515
- } else if ( event.code === scope.keys[ STATE.ZOOM ] && ! scope.noZoom ) {
520
+ if ( event.pointerType === 'touch' ) {
516
521
 
517
- _keyState = STATE.ZOOM;
522
+ this._onTouchStart( event );
518
523
 
519
- } else if ( event.code === scope.keys[ STATE.PAN ] && ! scope.noPan ) {
524
+ } else {
520
525
 
521
- _keyState = STATE.PAN;
526
+ this._onMouseDown( event );
522
527
 
523
- }
528
+ }
524
529
 
525
- }
530
+ }
526
531
 
527
- function keyup() {
532
+ function onPointerMove( event ) {
528
533
 
529
- if ( scope.enabled === false ) return;
534
+ if ( this.enabled === false ) return;
530
535
 
531
- _keyState = STATE.NONE;
536
+ if ( event.pointerType === 'touch' ) {
532
537
 
533
- window.addEventListener( 'keydown', keydown );
538
+ this._onTouchMove( event );
534
539
 
535
- }
540
+ } else {
536
541
 
537
- function onMouseDown( event ) {
542
+ this._onMouseMove( event );
538
543
 
539
- if ( _state === STATE.NONE ) {
544
+ }
540
545
 
541
- switch ( event.button ) {
546
+ }
542
547
 
543
- case scope.mouseButtons.LEFT:
544
- _state = STATE.ROTATE;
545
- break;
548
+ function onPointerUp( event ) {
546
549
 
547
- case scope.mouseButtons.MIDDLE:
548
- _state = STATE.ZOOM;
549
- break;
550
+ if ( this.enabled === false ) return;
550
551
 
551
- case scope.mouseButtons.RIGHT:
552
- _state = STATE.PAN;
553
- break;
552
+ if ( event.pointerType === 'touch' ) {
554
553
 
555
- }
554
+ this._onTouchEnd( event );
556
555
 
557
- }
556
+ } else {
558
557
 
559
- const state = ( _keyState !== STATE.NONE ) ? _keyState : _state;
558
+ this._onMouseUp();
560
559
 
561
- if ( state === STATE.ROTATE && ! scope.noRotate ) {
560
+ }
562
561
 
563
- _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
564
- _movePrev.copy( _moveCurr );
562
+ //
565
563
 
566
- } else if ( state === STATE.ZOOM && ! scope.noZoom ) {
564
+ this._removePointer( event );
567
565
 
568
- _zoomStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
569
- _zoomEnd.copy( _zoomStart );
566
+ if ( this._pointers.length === 0 ) {
570
567
 
571
- } else if ( state === STATE.PAN && ! scope.noPan ) {
568
+ this.domElement.releasePointerCapture( event.pointerId );
572
569
 
573
- _panStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
574
- _panEnd.copy( _panStart );
570
+ this.domElement.removeEventListener( 'pointermove', this._onPointerMove );
571
+ this.domElement.removeEventListener( 'pointerup', this._onPointerUp );
575
572
 
576
- }
573
+ }
577
574
 
578
- scope.dispatchEvent( _startEvent );
575
+ }
579
576
 
580
- }
577
+ function onPointerCancel( event ) {
581
578
 
582
- function onMouseMove( event ) {
579
+ this._removePointer( event );
583
580
 
584
- const state = ( _keyState !== STATE.NONE ) ? _keyState : _state;
581
+ }
585
582
 
586
- if ( state === STATE.ROTATE && ! scope.noRotate ) {
583
+ function onKeyUp() {
587
584
 
588
- _movePrev.copy( _moveCurr );
589
- _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
585
+ if ( this.enabled === false ) return;
590
586
 
591
- } else if ( state === STATE.ZOOM && ! scope.noZoom ) {
587
+ this.keyState = _STATE.NONE;
592
588
 
593
- _zoomEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) );
589
+ window.addEventListener( 'keydown', this._onKeyDown );
594
590
 
595
- } else if ( state === STATE.PAN && ! scope.noPan ) {
591
+ }
596
592
 
597
- _panEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) );
593
+ function onKeyDown( event ) {
598
594
 
599
- }
595
+ if ( this.enabled === false ) return;
600
596
 
601
- }
597
+ window.removeEventListener( 'keydown', this._onKeyDown );
602
598
 
603
- function onMouseUp() {
599
+ if ( this.keyState !== _STATE.NONE ) {
604
600
 
605
- _state = STATE.NONE;
601
+ return;
606
602
 
607
- scope.dispatchEvent( _endEvent );
603
+ } else if ( event.code === this.keys[ _STATE.ROTATE ] && ! this.noRotate ) {
608
604
 
609
- }
605
+ this.keyState = _STATE.ROTATE;
610
606
 
611
- function onMouseWheel( event ) {
607
+ } else if ( event.code === this.keys[ _STATE.ZOOM ] && ! this.noZoom ) {
612
608
 
613
- if ( scope.enabled === false ) return;
609
+ this.keyState = _STATE.ZOOM;
614
610
 
615
- if ( scope.noZoom === true ) return;
611
+ } else if ( event.code === this.keys[ _STATE.PAN ] && ! this.noPan ) {
616
612
 
617
- event.preventDefault();
613
+ this.keyState = _STATE.PAN;
618
614
 
619
- switch ( event.deltaMode ) {
615
+ }
620
616
 
621
- case 2:
622
- // Zoom in pages
623
- _zoomStart.y -= event.deltaY * 0.025;
624
- break;
617
+ }
625
618
 
626
- case 1:
627
- // Zoom in lines
628
- _zoomStart.y -= event.deltaY * 0.01;
629
- break;
619
+ function onMouseDown( event ) {
630
620
 
631
- default:
632
- // undefined, 0, assume pixels
633
- _zoomStart.y -= event.deltaY * 0.00025;
634
- break;
621
+ if ( this.state === _STATE.NONE ) {
635
622
 
636
- }
623
+ switch ( event.button ) {
637
624
 
638
- scope.dispatchEvent( _startEvent );
639
- scope.dispatchEvent( _endEvent );
625
+ case this.mouseButtons.LEFT:
626
+ this.state = _STATE.ROTATE;
627
+ break;
640
628
 
641
- }
629
+ case this.mouseButtons.MIDDLE:
630
+ this.state = _STATE.ZOOM;
631
+ break;
642
632
 
643
- function onTouchStart( event ) {
633
+ case this.mouseButtons.RIGHT:
634
+ this.state = _STATE.PAN;
635
+ break;
644
636
 
645
- trackPointer( event );
637
+ }
646
638
 
647
- switch ( _pointers.length ) {
639
+ }
648
640
 
649
- case 1:
650
- _state = STATE.TOUCH_ROTATE;
651
- _moveCurr.copy( getMouseOnCircle( _pointers[ 0 ].pageX, _pointers[ 0 ].pageY ) );
652
- _movePrev.copy( _moveCurr );
653
- break;
641
+ const state = ( this.keyState !== _STATE.NONE ) ? this.keyState : this.state;
654
642
 
655
- default: // 2 or more
656
- _state = STATE.TOUCH_ZOOM_PAN;
657
- const dx = _pointers[ 0 ].pageX - _pointers[ 1 ].pageX;
658
- const dy = _pointers[ 0 ].pageY - _pointers[ 1 ].pageY;
659
- _touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy );
643
+ if ( state === _STATE.ROTATE && ! this.noRotate ) {
660
644
 
661
- const x = ( _pointers[ 0 ].pageX + _pointers[ 1 ].pageX ) / 2;
662
- const y = ( _pointers[ 0 ].pageY + _pointers[ 1 ].pageY ) / 2;
663
- _panStart.copy( getMouseOnScreen( x, y ) );
664
- _panEnd.copy( _panStart );
665
- break;
645
+ this._moveCurr.copy( this._getMouseOnCircle( event.pageX, event.pageY ) );
646
+ this._movePrev.copy( this._moveCurr );
666
647
 
667
- }
648
+ } else if ( state === _STATE.ZOOM && ! this.noZoom ) {
668
649
 
669
- scope.dispatchEvent( _startEvent );
650
+ this._zoomStart.copy( this._getMouseOnScreen( event.pageX, event.pageY ) );
651
+ this._zoomEnd.copy( this._zoomStart );
670
652
 
671
- }
653
+ } else if ( state === _STATE.PAN && ! this.noPan ) {
672
654
 
673
- function onTouchMove( event ) {
655
+ this._panStart.copy( this._getMouseOnScreen( event.pageX, event.pageY ) );
656
+ this._panEnd.copy( this._panStart );
674
657
 
675
- trackPointer( event );
658
+ }
676
659
 
677
- switch ( _pointers.length ) {
660
+ this.dispatchEvent( _startEvent );
678
661
 
679
- case 1:
680
- _movePrev.copy( _moveCurr );
681
- _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
682
- break;
662
+ }
683
663
 
684
- default: // 2 or more
664
+ function onMouseMove( event ) {
685
665
 
686
- const position = getSecondPointerPosition( event );
666
+ const state = ( this.keyState !== _STATE.NONE ) ? this.keyState : this.state;
687
667
 
688
- const dx = event.pageX - position.x;
689
- const dy = event.pageY - position.y;
690
- _touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy );
668
+ if ( state === _STATE.ROTATE && ! this.noRotate ) {
691
669
 
692
- const x = ( event.pageX + position.x ) / 2;
693
- const y = ( event.pageY + position.y ) / 2;
694
- _panEnd.copy( getMouseOnScreen( x, y ) );
695
- break;
670
+ this._movePrev.copy( this._moveCurr );
671
+ this._moveCurr.copy( this._getMouseOnCircle( event.pageX, event.pageY ) );
696
672
 
697
- }
673
+ } else if ( state === _STATE.ZOOM && ! this.noZoom ) {
698
674
 
699
- }
675
+ this._zoomEnd.copy( this._getMouseOnScreen( event.pageX, event.pageY ) );
700
676
 
701
- function onTouchEnd( event ) {
677
+ } else if ( state === _STATE.PAN && ! this.noPan ) {
702
678
 
703
- switch ( _pointers.length ) {
679
+ this._panEnd.copy( this._getMouseOnScreen( event.pageX, event.pageY ) );
704
680
 
705
- case 0:
706
- _state = STATE.NONE;
707
- break;
681
+ }
708
682
 
709
- case 1:
710
- _state = STATE.TOUCH_ROTATE;
711
- _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
712
- _movePrev.copy( _moveCurr );
713
- break;
683
+ }
714
684
 
715
- case 2:
716
- _state = STATE.TOUCH_ZOOM_PAN;
685
+ function onMouseUp() {
717
686
 
718
- for ( let i = 0; i < _pointers.length; i ++ ) {
687
+ this.state = _STATE.NONE;
719
688
 
720
- if ( _pointers[ i ].pointerId !== event.pointerId ) {
689
+ this.dispatchEvent( _endEvent );
721
690
 
722
- const position = _pointerPositions[ _pointers[ i ].pointerId ];
723
- _moveCurr.copy( getMouseOnCircle( position.x, position.y ) );
724
- _movePrev.copy( _moveCurr );
725
- break;
691
+ }
726
692
 
727
- }
693
+ function onMouseWheel( event ) {
728
694
 
729
- }
695
+ if ( this.enabled === false ) return;
730
696
 
731
- break;
697
+ if ( this.noZoom === true ) return;
732
698
 
733
- }
699
+ event.preventDefault();
734
700
 
735
- scope.dispatchEvent( _endEvent );
701
+ switch ( event.deltaMode ) {
736
702
 
737
- }
703
+ case 2:
704
+ // Zoom in pages
705
+ this._zoomStart.y -= event.deltaY * 0.025;
706
+ break;
738
707
 
739
- function contextmenu( event ) {
708
+ case 1:
709
+ // Zoom in lines
710
+ this._zoomStart.y -= event.deltaY * 0.01;
711
+ break;
740
712
 
741
- if ( scope.enabled === false ) return;
713
+ default:
714
+ // undefined, 0, assume pixels
715
+ this._zoomStart.y -= event.deltaY * 0.00025;
716
+ break;
742
717
 
743
- event.preventDefault();
718
+ }
744
719
 
745
- }
720
+ this.dispatchEvent( _startEvent );
721
+ this.dispatchEvent( _endEvent );
746
722
 
747
- function addPointer( event ) {
723
+ }
748
724
 
749
- _pointers.push( event );
725
+ function onContextMenu( event ) {
750
726
 
751
- }
727
+ if ( this.enabled === false ) return;
752
728
 
753
- function removePointer( event ) {
729
+ event.preventDefault();
754
730
 
755
- delete _pointerPositions[ event.pointerId ];
731
+ }
756
732
 
757
- for ( let i = 0; i < _pointers.length; i ++ ) {
733
+ function onTouchStart( event ) {
758
734
 
759
- if ( _pointers[ i ].pointerId == event.pointerId ) {
735
+ this._trackPointer( event );
760
736
 
761
- _pointers.splice( i, 1 );
762
- return;
737
+ switch ( this._pointers.length ) {
763
738
 
764
- }
739
+ case 1:
740
+ this.state = _STATE.TOUCH_ROTATE;
741
+ this._moveCurr.copy( this._getMouseOnCircle( this._pointers[ 0 ].pageX, this._pointers[ 0 ].pageY ) );
742
+ this._movePrev.copy( this._moveCurr );
743
+ break;
765
744
 
766
- }
745
+ default: // 2 or more
746
+ this.state = _STATE.TOUCH_ZOOM_PAN;
747
+ const dx = this._pointers[ 0 ].pageX - this._pointers[ 1 ].pageX;
748
+ const dy = this._pointers[ 0 ].pageY - this._pointers[ 1 ].pageY;
749
+ this._touchZoomDistanceEnd = this._touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy );
767
750
 
768
- }
751
+ const x = ( this._pointers[ 0 ].pageX + this._pointers[ 1 ].pageX ) / 2;
752
+ const y = ( this._pointers[ 0 ].pageY + this._pointers[ 1 ].pageY ) / 2;
753
+ this._panStart.copy( this._getMouseOnScreen( x, y ) );
754
+ this._panEnd.copy( this._panStart );
755
+ break;
769
756
 
770
- function trackPointer( event ) {
757
+ }
771
758
 
772
- let position = _pointerPositions[ event.pointerId ];
759
+ this.dispatchEvent( _startEvent );
773
760
 
774
- if ( position === undefined ) {
761
+ }
775
762
 
776
- position = new Vector2();
777
- _pointerPositions[ event.pointerId ] = position;
763
+ function onTouchMove( event ) {
778
764
 
779
- }
765
+ this._trackPointer( event );
780
766
 
781
- position.set( event.pageX, event.pageY );
767
+ switch ( this._pointers.length ) {
782
768
 
783
- }
769
+ case 1:
770
+ this._movePrev.copy( this._moveCurr );
771
+ this._moveCurr.copy( this._getMouseOnCircle( event.pageX, event.pageY ) );
772
+ break;
784
773
 
785
- function getSecondPointerPosition( event ) {
774
+ default: // 2 or more
786
775
 
787
- const pointer = ( event.pointerId === _pointers[ 0 ].pointerId ) ? _pointers[ 1 ] : _pointers[ 0 ];
776
+ const position = this._getSecondPointerPosition( event );
788
777
 
789
- return _pointerPositions[ pointer.pointerId ];
778
+ const dx = event.pageX - position.x;
779
+ const dy = event.pageY - position.y;
780
+ this._touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy );
790
781
 
791
- }
782
+ const x = ( event.pageX + position.x ) / 2;
783
+ const y = ( event.pageY + position.y ) / 2;
784
+ this._panEnd.copy( this._getMouseOnScreen( x, y ) );
785
+ break;
792
786
 
793
- this.dispose = function () {
787
+ }
794
788
 
795
- scope.domElement.removeEventListener( 'contextmenu', contextmenu );
789
+ }
796
790
 
797
- scope.domElement.removeEventListener( 'pointerdown', onPointerDown );
798
- scope.domElement.removeEventListener( 'pointercancel', onPointerCancel );
799
- scope.domElement.removeEventListener( 'wheel', onMouseWheel );
791
+ function onTouchEnd( event ) {
800
792
 
801
- scope.domElement.removeEventListener( 'pointermove', onPointerMove );
802
- scope.domElement.removeEventListener( 'pointerup', onPointerUp );
793
+ switch ( this._pointers.length ) {
803
794
 
804
- window.removeEventListener( 'keydown', keydown );
805
- window.removeEventListener( 'keyup', keyup );
795
+ case 0:
796
+ this.state = _STATE.NONE;
797
+ break;
806
798
 
807
- };
799
+ case 1:
800
+ this.state = _STATE.TOUCH_ROTATE;
801
+ this._moveCurr.copy( this._getMouseOnCircle( event.pageX, event.pageY ) );
802
+ this._movePrev.copy( this._moveCurr );
803
+ break;
808
804
 
809
- this.domElement.addEventListener( 'contextmenu', contextmenu );
805
+ case 2:
806
+ this.state = _STATE.TOUCH_ZOOM_PAN;
810
807
 
811
- this.domElement.addEventListener( 'pointerdown', onPointerDown );
812
- this.domElement.addEventListener( 'pointercancel', onPointerCancel );
813
- this.domElement.addEventListener( 'wheel', onMouseWheel, { passive: false } );
808
+ for ( let i = 0; i < this._pointers.length; i ++ ) {
814
809
 
810
+ if ( this._pointers[ i ].pointerId !== event.pointerId ) {
811
+
812
+ const position = this._pointerPositions[ this._pointers[ i ].pointerId ];
813
+ this._moveCurr.copy( this._getMouseOnCircle( position.x, position.y ) );
814
+ this._movePrev.copy( this._moveCurr );
815
+ break;
815
816
 
816
- window.addEventListener( 'keydown', keydown );
817
- window.addEventListener( 'keyup', keyup );
817
+ }
818
818
 
819
- this.handleResize();
819
+ }
820
820
 
821
- // force an update at start
822
- this.update();
821
+ break;
823
822
 
824
823
  }
825
824
 
825
+ this.dispatchEvent( _endEvent );
826
+
826
827
  }
827
828
 
828
829
  export { TrackballControls };