super-three 0.160.1 → 0.162.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 (225) hide show
  1. package/LICENSE +1 -1
  2. package/build/three.cjs +867 -499
  3. package/build/three.module.js +867 -496
  4. package/build/three.module.min.js +1 -1
  5. package/examples/jsm/Addons.js +5 -1
  6. package/examples/jsm/capabilities/WebGPU.js +13 -9
  7. package/examples/jsm/controls/DragControls.js +91 -30
  8. package/examples/jsm/controls/OrbitControls.js +130 -15
  9. package/examples/jsm/controls/TransformControls.js +6 -6
  10. package/examples/jsm/curves/NURBSUtils.js +59 -4
  11. package/examples/jsm/curves/NURBSVolume.js +62 -0
  12. package/examples/jsm/exporters/GLTFExporter.js +11 -1
  13. package/examples/jsm/exporters/USDZExporter.js +8 -7
  14. package/examples/jsm/helpers/TextureHelper.js +3 -3
  15. package/examples/jsm/interactive/InteractiveGroup.js +15 -25
  16. package/examples/jsm/libs/rhino3dm/rhino3dm.js +1 -8723
  17. package/examples/jsm/libs/rhino3dm/rhino3dm.module.js +1 -8734
  18. package/examples/jsm/libs/rhino3dm/rhino3dm.wasm +0 -0
  19. package/examples/jsm/libs/tween.module.js +32 -14
  20. package/examples/jsm/loaders/3DMLoader.js +57 -64
  21. package/examples/jsm/loaders/DDSLoader.js +1 -0
  22. package/examples/jsm/loaders/KTX2Loader.js +20 -5
  23. package/examples/jsm/loaders/LUT3dlLoader.js +78 -46
  24. package/examples/jsm/loaders/LUTCubeLoader.js +81 -67
  25. package/examples/jsm/loaders/LUTImageLoader.js +3 -2
  26. package/examples/jsm/loaders/MaterialXLoader.js +115 -16
  27. package/examples/jsm/loaders/SVGLoader.js +4 -3
  28. package/examples/jsm/loaders/VOXLoader.js +9 -2
  29. package/examples/jsm/loaders/VRMLLoader.js +7 -3
  30. package/examples/jsm/materials/MeshPostProcessingMaterial.js +144 -0
  31. package/examples/jsm/misc/ProgressiveLightMap.js +1 -0
  32. package/examples/jsm/misc/Timer.js +13 -4
  33. package/examples/jsm/nodes/Nodes.js +24 -11
  34. package/examples/jsm/nodes/accessors/AccessorsUtils.js +10 -0
  35. package/examples/jsm/nodes/accessors/BufferAttributeNode.js +5 -3
  36. package/examples/jsm/nodes/accessors/CameraNode.js +9 -4
  37. package/examples/jsm/nodes/accessors/ClippingNode.js +144 -0
  38. package/examples/jsm/nodes/accessors/CubeTextureNode.js +12 -1
  39. package/examples/jsm/nodes/accessors/MaterialNode.js +2 -2
  40. package/examples/jsm/nodes/accessors/MaterialReferenceNode.js +2 -12
  41. package/examples/jsm/nodes/accessors/MorphNode.js +8 -8
  42. package/examples/jsm/nodes/accessors/ReferenceNode.js +87 -29
  43. package/examples/jsm/nodes/accessors/SkinningNode.js +31 -10
  44. package/examples/jsm/nodes/accessors/StorageBufferNode.js +45 -0
  45. package/examples/jsm/nodes/accessors/TangentNode.js +8 -2
  46. package/examples/jsm/nodes/accessors/TextureNode.js +1 -1
  47. package/examples/jsm/nodes/accessors/TextureStoreNode.js +56 -3
  48. package/examples/jsm/nodes/accessors/UniformsNode.js +140 -0
  49. package/examples/jsm/nodes/accessors/VertexColorNode.js +70 -0
  50. package/examples/jsm/nodes/code/CodeNode.js +6 -0
  51. package/examples/jsm/nodes/core/AssignNode.js +68 -12
  52. package/examples/jsm/nodes/core/AttributeNode.js +1 -1
  53. package/examples/jsm/nodes/core/Node.js +14 -4
  54. package/examples/jsm/nodes/core/NodeBuilder.js +26 -27
  55. package/examples/jsm/nodes/core/NodeFrame.js +18 -10
  56. package/examples/jsm/nodes/core/TempNode.js +1 -1
  57. package/examples/jsm/nodes/core/constants.js +1 -0
  58. package/examples/jsm/nodes/display/AfterImageNode.js +148 -0
  59. package/examples/jsm/nodes/display/AnamorphicNode.js +148 -0
  60. package/examples/jsm/nodes/display/BlendModeNode.js +30 -1
  61. package/examples/jsm/nodes/display/ColorAdjustmentNode.js +3 -0
  62. package/examples/jsm/nodes/display/GaussianBlurNode.js +33 -13
  63. package/examples/jsm/nodes/display/NormalMapNode.js +3 -5
  64. package/examples/jsm/nodes/display/PassNode.js +3 -2
  65. package/examples/jsm/nodes/display/ToneMappingNode.js +46 -3
  66. package/examples/jsm/nodes/display/ViewportDepthTextureNode.js +1 -4
  67. package/examples/jsm/nodes/display/ViewportNode.js +0 -2
  68. package/examples/jsm/nodes/display/ViewportSharedTextureNode.js +4 -4
  69. package/examples/jsm/nodes/fog/FogNode.js +2 -1
  70. package/examples/jsm/nodes/lighting/AmbientLightNode.js +1 -1
  71. package/examples/jsm/nodes/lighting/AnalyticLightNode.js +13 -5
  72. package/examples/jsm/nodes/lighting/LightingContextNode.js +1 -1
  73. package/examples/jsm/nodes/lighting/LightsNode.js +1 -1
  74. package/examples/jsm/nodes/materials/Line2NodeMaterial.js +18 -30
  75. package/examples/jsm/nodes/materials/Materials.js +1 -0
  76. package/examples/jsm/nodes/materials/MeshSSSNodeMaterial.js +84 -0
  77. package/examples/jsm/nodes/materials/NodeMaterial.js +43 -10
  78. package/examples/jsm/nodes/materials/SpriteNodeMaterial.js +1 -7
  79. package/examples/jsm/nodes/math/CondNode.js +42 -7
  80. package/examples/jsm/nodes/math/MathNode.js +32 -2
  81. package/examples/jsm/nodes/math/MathUtils.js +15 -0
  82. package/examples/jsm/nodes/math/OperatorNode.js +13 -5
  83. package/examples/jsm/nodes/math/TriNoise3D.js +71 -0
  84. package/examples/jsm/nodes/shadernode/ShaderNode.js +10 -1
  85. package/examples/jsm/nodes/utils/JoinNode.js +2 -2
  86. package/examples/jsm/nodes/utils/LoopNode.js +5 -3
  87. package/examples/jsm/nodes/utils/ReflectorNode.js +227 -0
  88. package/examples/jsm/nodes/utils/RotateNode.js +68 -0
  89. package/examples/jsm/nodes/utils/RotateUVNode.js +1 -9
  90. package/examples/jsm/nodes/utils/SplitNode.js +4 -4
  91. package/examples/jsm/nodes/utils/StorageArrayElementNode.js +91 -0
  92. package/examples/jsm/objects/GroundedSkybox.js +50 -0
  93. package/examples/jsm/objects/QuadMesh.js +8 -2
  94. package/examples/jsm/objects/Water2.js +8 -8
  95. package/examples/jsm/postprocessing/GTAOPass.js +11 -1
  96. package/examples/jsm/postprocessing/OutputPass.js +2 -0
  97. package/examples/jsm/renderers/common/Backend.js +14 -0
  98. package/examples/jsm/renderers/common/Background.js +2 -2
  99. package/examples/jsm/renderers/common/Bindings.js +1 -1
  100. package/examples/jsm/renderers/common/ClippingContext.js +165 -0
  101. package/examples/jsm/renderers/common/DataMap.js +1 -1
  102. package/examples/jsm/renderers/common/Info.js +25 -1
  103. package/examples/jsm/renderers/common/Pipelines.js +8 -8
  104. package/examples/jsm/renderers/common/PostProcessing.js +2 -2
  105. package/examples/jsm/renderers/common/ProgrammableStage.js +3 -1
  106. package/examples/jsm/renderers/common/RenderContext.js +2 -0
  107. package/examples/jsm/renderers/common/RenderContexts.js +2 -13
  108. package/examples/jsm/renderers/common/RenderObject.js +46 -1
  109. package/examples/jsm/renderers/common/RenderObjects.js +3 -1
  110. package/examples/jsm/renderers/common/Renderer.js +290 -17
  111. package/examples/jsm/renderers/common/StorageBufferAttribute.js +17 -0
  112. package/examples/jsm/renderers/common/StorageInstancedBufferAttribute.js +17 -0
  113. package/examples/jsm/renderers/common/Textures.js +28 -18
  114. package/examples/jsm/renderers/common/UniformsGroup.js +6 -4
  115. package/examples/jsm/renderers/common/nodes/NodeBuilderState.js +2 -1
  116. package/examples/jsm/renderers/common/nodes/NodeStorageBuffer.js +23 -0
  117. package/examples/jsm/renderers/common/nodes/NodeUniformBuffer.js +23 -0
  118. package/examples/jsm/renderers/common/nodes/Nodes.js +5 -2
  119. package/examples/jsm/renderers/webgl/WebGLBackend.js +653 -272
  120. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +171 -39
  121. package/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js +95 -8
  122. package/examples/jsm/renderers/webgl/utils/WebGLConstants.js +11 -0
  123. package/examples/jsm/renderers/webgl/utils/WebGLState.js +197 -0
  124. package/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +424 -11
  125. package/examples/jsm/renderers/webgl/utils/WebGLUtils.js +3 -2
  126. package/examples/jsm/renderers/webgl-legacy/nodes/GLSL1NodeBuilder.js +1 -21
  127. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodeBuilder.js +2 -2
  128. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +300 -112
  129. package/examples/jsm/renderers/webgpu/WebGPURenderer.js +7 -2
  130. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +71 -79
  131. package/examples/jsm/renderers/webgpu/utils/WebGPUAttributeUtils.js +15 -1
  132. package/examples/jsm/renderers/webgpu/utils/WebGPUPipelineUtils.js +38 -4
  133. package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +87 -14
  134. package/examples/jsm/shaders/OutputShader.js +4 -0
  135. package/examples/jsm/transpiler/AST.js +1 -1
  136. package/examples/jsm/transpiler/GLSLDecoder.js +1 -1
  137. package/examples/jsm/transpiler/ShaderToyDecoder.js +1 -1
  138. package/examples/jsm/transpiler/TSLEncoder.js +1 -1
  139. package/examples/jsm/utils/BufferGeometryUtils.js +23 -27
  140. package/examples/jsm/utils/SkeletonUtils.js +14 -3
  141. package/examples/jsm/utils/SortUtils.js +2 -0
  142. package/examples/jsm/webxr/ARButton.js +12 -2
  143. package/examples/jsm/webxr/VRButton.js +25 -7
  144. package/examples/jsm/webxr/XRButton.js +12 -3
  145. package/examples/jsm/webxr/XRControllerModelFactory.js +14 -1
  146. package/examples/jsm/webxr/XRHandMeshModel.js +3 -1
  147. package/package.json +5 -4
  148. package/src/Three.Legacy.js +20 -0
  149. package/src/Three.js +0 -1
  150. package/src/audio/Audio.js +1 -3
  151. package/src/cameras/PerspectiveCamera.js +35 -0
  152. package/src/constants.js +2 -6
  153. package/src/core/BufferAttribute.js +2 -12
  154. package/src/core/BufferGeometry.js +23 -29
  155. package/src/core/InterleavedBuffer.js +2 -1
  156. package/src/core/InterleavedBufferAttribute.js +20 -0
  157. package/src/core/Object3D.js +11 -0
  158. package/src/core/Raycaster.js +18 -4
  159. package/src/core/RenderTarget.js +44 -21
  160. package/src/extras/PMREMGenerator.js +2 -0
  161. package/src/extras/curves/EllipseCurve.js +2 -2
  162. package/src/helpers/SpotLightHelper.js +18 -1
  163. package/src/loaders/DataTextureLoader.js +0 -4
  164. package/src/loaders/MaterialLoader.js +1 -0
  165. package/src/loaders/ObjectLoader.js +2 -1
  166. package/src/materials/Material.js +2 -1
  167. package/src/materials/MeshBasicMaterial.js +3 -0
  168. package/src/materials/MeshLambertMaterial.js +3 -0
  169. package/src/materials/MeshPhongMaterial.js +3 -0
  170. package/src/materials/MeshStandardMaterial.js +3 -0
  171. package/src/materials/ShaderMaterial.js +2 -1
  172. package/src/math/Quaternion.js +13 -12
  173. package/src/math/Triangle.js +0 -30
  174. package/src/math/Vector3.js +7 -7
  175. package/src/objects/BatchedMesh.js +6 -7
  176. package/src/objects/InstancedMesh.js +53 -0
  177. package/src/objects/Mesh.js +0 -1
  178. package/src/objects/SkinnedMesh.js +0 -8
  179. package/src/renderers/WebGLCubeRenderTarget.js +1 -10
  180. package/src/renderers/WebGLRenderer.js +20 -23
  181. package/src/renderers/shaders/ShaderChunk/alphatest_fragment.glsl.js +9 -0
  182. package/src/renderers/shaders/ShaderChunk/clipping_planes_fragment.glsl.js +56 -11
  183. package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +1 -0
  184. package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +1 -1
  185. package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +2 -2
  186. package/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js +1 -1
  187. package/src/renderers/shaders/ShaderChunk/morphinstance_vertex.glsl.js +14 -0
  188. package/src/renderers/shaders/ShaderChunk/morphtarget_pars_vertex.glsl.js +11 -2
  189. package/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js +38 -7
  190. package/src/renderers/shaders/ShaderChunk.js +2 -0
  191. package/src/renderers/shaders/ShaderLib/backgroundCube.glsl.js +3 -2
  192. package/src/renderers/shaders/ShaderLib/depth.glsl.js +3 -2
  193. package/src/renderers/shaders/ShaderLib/distanceRGBA.glsl.js +3 -2
  194. package/src/renderers/shaders/ShaderLib/linedashed.glsl.js +2 -1
  195. package/src/renderers/shaders/ShaderLib/meshbasic.glsl.js +2 -2
  196. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +2 -1
  197. package/src/renderers/shaders/ShaderLib/meshmatcap.glsl.js +2 -2
  198. package/src/renderers/shaders/ShaderLib/meshnormal.glsl.js +4 -1
  199. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +2 -1
  200. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +2 -1
  201. package/src/renderers/shaders/ShaderLib/meshtoon.glsl.js +2 -1
  202. package/src/renderers/shaders/ShaderLib/points.glsl.js +2 -1
  203. package/src/renderers/shaders/ShaderLib/shadow.glsl.js +1 -0
  204. package/src/renderers/shaders/ShaderLib/sprite.glsl.js +1 -1
  205. package/src/renderers/shaders/ShaderLib.js +2 -1
  206. package/src/renderers/shaders/UniformsLib.js +1 -0
  207. package/src/renderers/webgl/WebGLAttributes.js +2 -2
  208. package/src/renderers/webgl/WebGLBackground.js +18 -0
  209. package/src/renderers/webgl/WebGLCubeMaps.js +1 -1
  210. package/src/renderers/webgl/WebGLMaterials.js +24 -1
  211. package/src/renderers/webgl/WebGLMorphtargets.js +15 -8
  212. package/src/renderers/webgl/WebGLProgram.js +42 -4
  213. package/src/renderers/webgl/WebGLPrograms.js +38 -27
  214. package/src/renderers/webgl/WebGLState.js +11 -21
  215. package/src/renderers/webgl/WebGLTextures.js +170 -66
  216. package/src/renderers/webxr/WebXRDepthSensing.js +105 -0
  217. package/src/renderers/webxr/WebXRManager.js +46 -0
  218. package/src/scenes/Scene.js +8 -0
  219. package/src/textures/Source.js +1 -0
  220. package/src/textures/Texture.js +1 -29
  221. package/build/three.js +0 -54519
  222. package/build/three.min.js +0 -7
  223. package/examples/jsm/nodes/core/ArrayUniformNode.js +0 -26
  224. package/examples/jsm/objects/GroundProjectedSkybox.js +0 -172
  225. package/src/renderers/WebGLMultipleRenderTargets.js +0 -82
@@ -25,6 +25,7 @@ export * from './csm/CSMShader.js';
25
25
  export * as Curves from './curves/CurveExtras.js';
26
26
  export * from './curves/NURBSCurve.js';
27
27
  export * from './curves/NURBSSurface.js';
28
+ export * from './curves/NURBSVolume.js';
28
29
  export * as NURBSUtils from './curves/NURBSUtils.js';
29
30
 
30
31
  export * from './effects/AnaglyphEffect.js';
@@ -151,6 +152,7 @@ export * from './misc/MorphAnimMesh.js';
151
152
  export * from './misc/MorphBlendMesh.js';
152
153
  export * from './misc/ProgressiveLightMap.js';
153
154
  export * from './misc/RollerCoaster.js';
155
+ export * from './misc/Timer.js';
154
156
  export * from './misc/TubePainter.js';
155
157
  export * from './misc/Volume.js';
156
158
  export * from './misc/VolumeSlice.js';
@@ -160,7 +162,7 @@ export * from './modifiers/EdgeSplitModifier.js';
160
162
  export * from './modifiers/SimplifyModifier.js';
161
163
  export * from './modifiers/TessellateModifier.js';
162
164
 
163
- export * from './objects/GroundProjectedSkybox.js';
165
+ export * from './objects/GroundedSkybox.js';
164
166
  export * from './objects/Lensflare.js';
165
167
  export * from './objects/MarchingCubes.js';
166
168
  export * from './objects/Reflector.js';
@@ -183,6 +185,7 @@ export * from './postprocessing/DotScreenPass.js';
183
185
  export * from './postprocessing/EffectComposer.js';
184
186
  export * from './postprocessing/FilmPass.js';
185
187
  export * from './postprocessing/GlitchPass.js';
188
+ export * from './postprocessing/GTAOPass.js';
186
189
  export * from './postprocessing/HalftonePass.js';
187
190
  export * from './postprocessing/LUTPass.js';
188
191
  export * from './postprocessing/MaskPass.js';
@@ -230,6 +233,7 @@ export * from './shaders/FocusShader.js';
230
233
  export * from './shaders/FreiChenShader.js';
231
234
  export * from './shaders/GammaCorrectionShader.js';
232
235
  export * from './shaders/GodRaysShader.js';
236
+ export * from './shaders/GTAOShader.js';
233
237
  export * from './shaders/HalftoneShader.js';
234
238
  export * from './shaders/HorizontalBlurShader.js';
235
239
  export * from './shaders/HorizontalTiltShiftShader.js';
@@ -1,20 +1,17 @@
1
- if ( window.GPUShaderStage === undefined ) {
1
+ if ( self.GPUShaderStage === undefined ) {
2
2
 
3
- window.GPUShaderStage = { VERTEX: 1, FRAGMENT: 2, COMPUTE: 4 };
3
+ self.GPUShaderStage = { VERTEX: 1, FRAGMENT: 2, COMPUTE: 4 };
4
4
 
5
5
  }
6
6
 
7
- let isAvailable = false;
7
+ // statics
8
8
 
9
- if ( navigator.gpu !== undefined ) {
9
+ let isAvailable = navigator.gpu !== undefined;
10
10
 
11
- const adapter = await navigator.gpu.requestAdapter();
12
11
 
13
- if ( adapter !== null ) {
12
+ if ( typeof window !== 'undefined' && isAvailable ) {
14
13
 
15
- isAvailable = true;
16
-
17
- }
14
+ isAvailable = await navigator.gpu.requestAdapter();
18
15
 
19
16
  }
20
17
 
@@ -22,6 +19,12 @@ class WebGPU {
22
19
 
23
20
  static isAvailable() {
24
21
 
22
+ return Boolean( isAvailable );
23
+
24
+ }
25
+
26
+ static getStaticAdapter() {
27
+
25
28
  return isAvailable;
26
29
 
27
30
  }
@@ -50,4 +53,5 @@ class WebGPU {
50
53
 
51
54
  }
52
55
 
56
+
53
57
  export default WebGPU;
@@ -12,10 +12,15 @@ const _raycaster = new Raycaster();
12
12
 
13
13
  const _pointer = new Vector2();
14
14
  const _offset = new Vector3();
15
+ const _diff = new Vector2();
16
+ const _previousPointer = new Vector2();
15
17
  const _intersection = new Vector3();
16
18
  const _worldPosition = new Vector3();
17
19
  const _inverseMatrix = new Matrix4();
18
20
 
21
+ const _up = new Vector3();
22
+ const _right = new Vector3();
23
+
19
24
  class DragControls extends EventDispatcher {
20
25
 
21
26
  constructor( _objects, _camera, _domElement ) {
@@ -28,6 +33,10 @@ class DragControls extends EventDispatcher {
28
33
 
29
34
  const _intersections = [];
30
35
 
36
+ this.mode = 'translate';
37
+
38
+ this.rotateSpeed = 1;
39
+
31
40
  //
32
41
 
33
42
  const scope = this;
@@ -64,6 +73,12 @@ class DragControls extends EventDispatcher {
64
73
 
65
74
  }
66
75
 
76
+ function setObjects( objects ) {
77
+
78
+ _objects = objects;
79
+
80
+ }
81
+
67
82
  function getRaycaster() {
68
83
 
69
84
  return _raycaster;
@@ -80,59 +95,71 @@ class DragControls extends EventDispatcher {
80
95
 
81
96
  if ( _selected ) {
82
97
 
83
- if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
98
+ if ( scope.mode === 'translate' ) {
84
99
 
85
- _selected.position.copy( _intersection.sub( _offset ).applyMatrix4( _inverseMatrix ) );
100
+ if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
101
+
102
+ _selected.position.copy( _intersection.sub( _offset ).applyMatrix4( _inverseMatrix ) );
103
+
104
+ }
105
+
106
+ } else if ( scope.mode === 'rotate' ) {
107
+
108
+ _diff.subVectors( _pointer, _previousPointer ).multiplyScalar( scope.rotateSpeed );
109
+ _selected.rotateOnWorldAxis( _up, _diff.x );
110
+ _selected.rotateOnWorldAxis( _right.normalize(), - _diff.y );
86
111
 
87
112
  }
88
113
 
89
114
  scope.dispatchEvent( { type: 'drag', object: _selected } );
90
115
 
91
- return;
116
+ _previousPointer.copy( _pointer );
92
117
 
93
- }
118
+ } else {
94
119
 
95
- // hover support
120
+ // hover support
96
121
 
97
- if ( event.pointerType === 'mouse' || event.pointerType === 'pen' ) {
122
+ if ( event.pointerType === 'mouse' || event.pointerType === 'pen' ) {
98
123
 
99
- _intersections.length = 0;
124
+ _intersections.length = 0;
100
125
 
101
- _raycaster.setFromCamera( _pointer, _camera );
102
- _raycaster.intersectObjects( _objects, scope.recursive, _intersections );
126
+ _raycaster.setFromCamera( _pointer, _camera );
127
+ _raycaster.intersectObjects( _objects, scope.recursive, _intersections );
103
128
 
104
- if ( _intersections.length > 0 ) {
129
+ if ( _intersections.length > 0 ) {
105
130
 
106
- const object = _intersections[ 0 ].object;
131
+ const object = _intersections[ 0 ].object;
107
132
 
108
- _plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( object.matrixWorld ) );
133
+ _plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( object.matrixWorld ) );
109
134
 
110
- if ( _hovered !== object && _hovered !== null ) {
135
+ if ( _hovered !== object && _hovered !== null ) {
111
136
 
112
- scope.dispatchEvent( { type: 'hoveroff', object: _hovered } );
137
+ scope.dispatchEvent( { type: 'hoveroff', object: _hovered } );
113
138
 
114
- _domElement.style.cursor = 'auto';
115
- _hovered = null;
139
+ _domElement.style.cursor = 'auto';
140
+ _hovered = null;
116
141
 
117
- }
142
+ }
118
143
 
119
- if ( _hovered !== object ) {
144
+ if ( _hovered !== object ) {
120
145
 
121
- scope.dispatchEvent( { type: 'hoveron', object: object } );
146
+ scope.dispatchEvent( { type: 'hoveron', object: object } );
122
147
 
123
- _domElement.style.cursor = 'pointer';
124
- _hovered = object;
148
+ _domElement.style.cursor = 'pointer';
149
+ _hovered = object;
125
150
 
126
- }
151
+ }
127
152
 
128
- } else {
153
+ } else {
129
154
 
130
- if ( _hovered !== null ) {
155
+ if ( _hovered !== null ) {
131
156
 
132
- scope.dispatchEvent( { type: 'hoveroff', object: _hovered } );
157
+ scope.dispatchEvent( { type: 'hoveroff', object: _hovered } );
133
158
 
134
- _domElement.style.cursor = 'auto';
135
- _hovered = null;
159
+ _domElement.style.cursor = 'auto';
160
+ _hovered = null;
161
+
162
+ }
136
163
 
137
164
  }
138
165
 
@@ -140,6 +167,8 @@ class DragControls extends EventDispatcher {
140
167
 
141
168
  }
142
169
 
170
+ _previousPointer.copy( _pointer );
171
+
143
172
  }
144
173
 
145
174
  function onPointerDown( event ) {
@@ -155,14 +184,34 @@ class DragControls extends EventDispatcher {
155
184
 
156
185
  if ( _intersections.length > 0 ) {
157
186
 
158
- _selected = ( scope.transformGroup === true ) ? _objects[ 0 ] : _intersections[ 0 ].object;
187
+ if ( scope.transformGroup === true ) {
188
+
189
+ // look for the outermost group in the object's upper hierarchy
190
+
191
+ _selected = findGroup( _intersections[ 0 ].object );
192
+
193
+ } else {
194
+
195
+ _selected = _intersections[ 0 ].object;
196
+
197
+ }
159
198
 
160
199
  _plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
161
200
 
162
201
  if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
163
202
 
164
- _inverseMatrix.copy( _selected.parent.matrixWorld ).invert();
165
- _offset.copy( _intersection ).sub( _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
203
+ if ( scope.mode === 'translate' ) {
204
+
205
+ _inverseMatrix.copy( _selected.parent.matrixWorld ).invert();
206
+ _offset.copy( _intersection ).sub( _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
207
+
208
+ } else if ( scope.mode === 'rotate' ) {
209
+
210
+ // the controls only support Y+ up
211
+ _up.set( 0, 1, 0 ).applyQuaternion( _camera.quaternion ).normalize();
212
+ _right.set( 1, 0, 0 ).applyQuaternion( _camera.quaternion ).normalize();
213
+
214
+ }
166
215
 
167
216
  }
168
217
 
@@ -172,6 +221,7 @@ class DragControls extends EventDispatcher {
172
221
 
173
222
  }
174
223
 
224
+ _previousPointer.copy( _pointer );
175
225
 
176
226
  }
177
227
 
@@ -200,6 +250,16 @@ class DragControls extends EventDispatcher {
200
250
 
201
251
  }
202
252
 
253
+ function findGroup( obj, group = null ) {
254
+
255
+ if ( obj.isGroup ) group = obj;
256
+
257
+ if ( obj.parent === null ) return group;
258
+
259
+ return findGroup( obj.parent, group );
260
+
261
+ }
262
+
203
263
  activate();
204
264
 
205
265
  // API
@@ -213,6 +273,7 @@ class DragControls extends EventDispatcher {
213
273
  this.dispose = dispose;
214
274
  this.getObjects = getObjects;
215
275
  this.getRaycaster = getRaycaster;
276
+ this.setObjects = setObjects;
216
277
 
217
278
  }
218
279
 
@@ -261,6 +261,7 @@ class OrbitControls extends EventDispatcher {
261
261
  scope.target.clampLength( scope.minTargetRadius, scope.maxTargetRadius );
262
262
  scope.target.add( scope.cursor );
263
263
 
264
+ let zoomChanged = false;
264
265
  // adjust the camera position based on zoom only if we're not zooming to the cursor or if it's an ortho camera
265
266
  // we adjust zoom later in these cases
266
267
  if ( scope.zoomToCursor && performCursorZoom || scope.object.isOrthographicCamera ) {
@@ -269,7 +270,9 @@ class OrbitControls extends EventDispatcher {
269
270
 
270
271
  } else {
271
272
 
273
+ const prevRadius = spherical.radius;
272
274
  spherical.radius = clampDistance( spherical.radius * scale );
275
+ zoomChanged = prevRadius != spherical.radius;
273
276
 
274
277
  }
275
278
 
@@ -298,7 +301,6 @@ class OrbitControls extends EventDispatcher {
298
301
  }
299
302
 
300
303
  // adjust camera position
301
- let zoomChanged = false;
302
304
  if ( scope.zoomToCursor && performCursorZoom ) {
303
305
 
304
306
  let newRadius = null;
@@ -313,15 +315,19 @@ class OrbitControls extends EventDispatcher {
313
315
  scope.object.position.addScaledVector( dollyDirection, radiusDelta );
314
316
  scope.object.updateMatrixWorld();
315
317
 
318
+ zoomChanged = !! radiusDelta;
319
+
316
320
  } else if ( scope.object.isOrthographicCamera ) {
317
321
 
318
322
  // adjust the ortho camera position based on zoom changes
319
323
  const mouseBefore = new Vector3( mouse.x, mouse.y, 0 );
320
324
  mouseBefore.unproject( scope.object );
321
325
 
326
+ const prevZoom = scope.object.zoom;
322
327
  scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / scale ) );
323
328
  scope.object.updateProjectionMatrix();
324
- zoomChanged = true;
329
+
330
+ zoomChanged = prevZoom !== scope.object.zoom;
325
331
 
326
332
  const mouseAfter = new Vector3( mouse.x, mouse.y, 0 );
327
333
  mouseAfter.unproject( scope.object );
@@ -374,9 +380,15 @@ class OrbitControls extends EventDispatcher {
374
380
 
375
381
  } else if ( scope.object.isOrthographicCamera ) {
376
382
 
383
+ const prevZoom = scope.object.zoom;
377
384
  scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / scale ) );
378
- scope.object.updateProjectionMatrix();
379
- zoomChanged = true;
385
+
386
+ if ( prevZoom !== scope.object.zoom ) {
387
+
388
+ scope.object.updateProjectionMatrix();
389
+ zoomChanged = true;
390
+
391
+ }
380
392
 
381
393
  }
382
394
 
@@ -390,7 +402,7 @@ class OrbitControls extends EventDispatcher {
390
402
  if ( zoomChanged ||
391
403
  lastPosition.distanceToSquared( scope.object.position ) > EPS ||
392
404
  8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ||
393
- lastTargetPosition.distanceToSquared( scope.target ) > 0 ) {
405
+ lastTargetPosition.distanceToSquared( scope.target ) > EPS ) {
394
406
 
395
407
  scope.dispatchEvent( _changeEvent );
396
408
 
@@ -419,6 +431,9 @@ class OrbitControls extends EventDispatcher {
419
431
  scope.domElement.removeEventListener( 'pointermove', onPointerMove );
420
432
  scope.domElement.removeEventListener( 'pointerup', onPointerUp );
421
433
 
434
+ const document = scope.domElement.getRootNode(); // offscreen canvas compatibility
435
+
436
+ document.removeEventListener( 'keydown', interceptControlDown, { capture: true } );
422
437
 
423
438
  if ( scope._domElementKeyEvents !== null ) {
424
439
 
@@ -478,6 +493,8 @@ class OrbitControls extends EventDispatcher {
478
493
  const pointers = [];
479
494
  const pointerPositions = {};
480
495
 
496
+ let controlActive = false;
497
+
481
498
  function getAutoRotationAngle( deltaTime ) {
482
499
 
483
500
  if ( deltaTime !== null ) {
@@ -494,8 +511,8 @@ class OrbitControls extends EventDispatcher {
494
511
 
495
512
  function getZoomScale( delta ) {
496
513
 
497
- const normalized_delta = Math.abs( delta ) / ( 100 * ( window.devicePixelRatio | 0 ) );
498
- return Math.pow( 0.95, scope.zoomSpeed * normalized_delta );
514
+ const normalizedDelta = Math.abs( delta * 0.01 );
515
+ return Math.pow( 0.95, scope.zoomSpeed * normalizedDelta );
499
516
 
500
517
  }
501
518
 
@@ -1006,6 +1023,10 @@ class OrbitControls extends EventDispatcher {
1006
1023
 
1007
1024
  //
1008
1025
 
1026
+ if ( isTrackingPointer( event ) ) return;
1027
+
1028
+ //
1029
+
1009
1030
  addPointer( event );
1010
1031
 
1011
1032
  if ( event.pointerType === 'touch' ) {
@@ -1040,18 +1061,32 @@ class OrbitControls extends EventDispatcher {
1040
1061
 
1041
1062
  removePointer( event );
1042
1063
 
1043
- if ( pointers.length === 0 ) {
1064
+ switch ( pointers.length ) {
1044
1065
 
1045
- scope.domElement.releasePointerCapture( event.pointerId );
1066
+ case 0:
1046
1067
 
1047
- scope.domElement.removeEventListener( 'pointermove', onPointerMove );
1048
- scope.domElement.removeEventListener( 'pointerup', onPointerUp );
1068
+ scope.domElement.releasePointerCapture( event.pointerId );
1049
1069
 
1050
- }
1070
+ scope.domElement.removeEventListener( 'pointermove', onPointerMove );
1071
+ scope.domElement.removeEventListener( 'pointerup', onPointerUp );
1051
1072
 
1052
- scope.dispatchEvent( _endEvent );
1073
+ scope.dispatchEvent( _endEvent );
1053
1074
 
1054
- state = STATE.NONE;
1075
+ state = STATE.NONE;
1076
+
1077
+ break;
1078
+
1079
+ case 1:
1080
+
1081
+ const pointerId = pointers[ 0 ];
1082
+ const position = pointerPositions[ pointerId ];
1083
+
1084
+ // minimal placeholder event - allows state correction on pointer-up
1085
+ onTouchStart( { pointerId: pointerId, pageX: position.x, pageY: position.y } );
1086
+
1087
+ break;
1088
+
1089
+ }
1055
1090
 
1056
1091
  }
1057
1092
 
@@ -1192,12 +1227,76 @@ class OrbitControls extends EventDispatcher {
1192
1227
 
1193
1228
  scope.dispatchEvent( _startEvent );
1194
1229
 
1195
- handleMouseWheel( event );
1230
+ handleMouseWheel( customWheelEvent( event ) );
1196
1231
 
1197
1232
  scope.dispatchEvent( _endEvent );
1198
1233
 
1199
1234
  }
1200
1235
 
1236
+ function customWheelEvent( event ) {
1237
+
1238
+ const mode = event.deltaMode;
1239
+
1240
+ // minimal wheel event altered to meet delta-zoom demand
1241
+ const newEvent = {
1242
+ clientX: event.clientX,
1243
+ clientY: event.clientY,
1244
+ deltaY: event.deltaY,
1245
+ };
1246
+
1247
+ switch ( mode ) {
1248
+
1249
+ case 1: // LINE_MODE
1250
+ newEvent.deltaY *= 16;
1251
+ break;
1252
+
1253
+ case 2: // PAGE_MODE
1254
+ newEvent.deltaY *= 100;
1255
+ break;
1256
+
1257
+ }
1258
+
1259
+ // detect if event was triggered by pinching
1260
+ if ( event.ctrlKey && ! controlActive ) {
1261
+
1262
+ newEvent.deltaY *= 10;
1263
+
1264
+ }
1265
+
1266
+ return newEvent;
1267
+
1268
+ }
1269
+
1270
+ function interceptControlDown( event ) {
1271
+
1272
+ if ( event.key === 'Control' ) {
1273
+
1274
+ controlActive = true;
1275
+
1276
+
1277
+ const document = scope.domElement.getRootNode(); // offscreen canvas compatibility
1278
+
1279
+ document.addEventListener( 'keyup', interceptControlUp, { passive: true, capture: true } );
1280
+
1281
+ }
1282
+
1283
+ }
1284
+
1285
+ function interceptControlUp( event ) {
1286
+
1287
+ if ( event.key === 'Control' ) {
1288
+
1289
+ controlActive = false;
1290
+
1291
+
1292
+ const document = scope.domElement.getRootNode(); // offscreen canvas compatibility
1293
+
1294
+ document.removeEventListener( 'keyup', interceptControlUp, { passive: true, capture: true } );
1295
+
1296
+ }
1297
+
1298
+ }
1299
+
1201
1300
  function onKeyDown( event ) {
1202
1301
 
1203
1302
  if ( scope.enabled === false || scope.enablePan === false ) return;
@@ -1375,6 +1474,18 @@ class OrbitControls extends EventDispatcher {
1375
1474
 
1376
1475
  }
1377
1476
 
1477
+ function isTrackingPointer( event ) {
1478
+
1479
+ for ( let i = 0; i < pointers.length; i ++ ) {
1480
+
1481
+ if ( pointers[ i ] == event.pointerId ) return true;
1482
+
1483
+ }
1484
+
1485
+ return false;
1486
+
1487
+ }
1488
+
1378
1489
  function trackPointer( event ) {
1379
1490
 
1380
1491
  let position = pointerPositions[ event.pointerId ];
@@ -1406,6 +1517,10 @@ class OrbitControls extends EventDispatcher {
1406
1517
  scope.domElement.addEventListener( 'pointercancel', onPointerUp );
1407
1518
  scope.domElement.addEventListener( 'wheel', onMouseWheel, { passive: false } );
1408
1519
 
1520
+ const document = scope.domElement.getRootNode(); // offscreen canvas compatibility
1521
+
1522
+ document.addEventListener( 'keydown', interceptControlDown, { passive: true, capture: true } );
1523
+
1409
1524
  // force an update at start
1410
1525
 
1411
1526
  this.update();
@@ -223,7 +223,7 @@ class TransformControls extends Object3D {
223
223
 
224
224
  if ( this.object === undefined || this.dragging === true ) return;
225
225
 
226
- _raycaster.setFromCamera( pointer, this.camera );
226
+ if ( pointer !== null ) _raycaster.setFromCamera( pointer, this.camera );
227
227
 
228
228
  const intersect = intersectObjectWithRay( this._gizmo.picker[ this.mode ], _raycaster );
229
229
 
@@ -241,11 +241,11 @@ class TransformControls extends Object3D {
241
241
 
242
242
  pointerDown( pointer ) {
243
243
 
244
- if ( this.object === undefined || this.dragging === true || pointer.button !== 0 ) return;
244
+ if ( this.object === undefined || this.dragging === true || ( pointer != null && pointer.button !== 0 ) ) return;
245
245
 
246
246
  if ( this.axis !== null ) {
247
247
 
248
- _raycaster.setFromCamera( pointer, this.camera );
248
+ if ( pointer !== null ) _raycaster.setFromCamera( pointer, this.camera );
249
249
 
250
250
  const planeIntersect = intersectObjectWithRay( this._plane, _raycaster, true );
251
251
 
@@ -289,9 +289,9 @@ class TransformControls extends Object3D {
289
289
 
290
290
  }
291
291
 
292
- if ( object === undefined || axis === null || this.dragging === false || pointer.button !== - 1 ) return;
292
+ if ( object === undefined || axis === null || this.dragging === false || ( pointer !== null && pointer.button !== - 1 ) ) return;
293
293
 
294
- _raycaster.setFromCamera( pointer, this.camera );
294
+ if ( pointer !== null ) _raycaster.setFromCamera( pointer, this.camera );
295
295
 
296
296
  const planeIntersect = intersectObjectWithRay( this._plane, _raycaster, true );
297
297
 
@@ -539,7 +539,7 @@ class TransformControls extends Object3D {
539
539
 
540
540
  pointerUp( pointer ) {
541
541
 
542
- if ( pointer.button !== 0 ) return;
542
+ if ( pointer !== null && pointer.button !== 0 ) return;
543
543
 
544
544
  if ( this.dragging && ( this.axis !== null ) ) {
545
545
 
@@ -429,10 +429,10 @@ function calcNURBSDerivatives( p, U, P, u, nd ) {
429
429
  /*
430
430
  Calculate rational B-Spline surface point. See The NURBS Book, page 134, algorithm A4.3.
431
431
 
432
- p1, p2 : degrees of B-Spline surface
433
- U1, U2 : knot vectors
434
- P : control points (x, y, z, w)
435
- u, v : parametric values
432
+ p, q : degrees of B-Spline surface
433
+ U, V : knot vectors
434
+ P : control points (x, y, z, w)
435
+ u, v : parametric values
436
436
 
437
437
  returns point for given (u, v)
438
438
  */
@@ -472,6 +472,60 @@ function calcSurfacePoint( p, q, U, V, P, u, v, target ) {
472
472
 
473
473
  }
474
474
 
475
+ /*
476
+ Calculate rational B-Spline volume point. See The NURBS Book, page 134, algorithm A4.3.
477
+
478
+ p, q, r : degrees of B-Splinevolume
479
+ U, V, W : knot vectors
480
+ P : control points (x, y, z, w)
481
+ u, v, w : parametric values
482
+
483
+ returns point for given (u, v, w)
484
+ */
485
+ function calcVolumePoint( p, q, r, U, V, W, P, u, v, w, target ) {
486
+
487
+ const uspan = findSpan( p, u, U );
488
+ const vspan = findSpan( q, v, V );
489
+ const wspan = findSpan( r, w, W );
490
+ const Nu = calcBasisFunctions( uspan, u, p, U );
491
+ const Nv = calcBasisFunctions( vspan, v, q, V );
492
+ const Nw = calcBasisFunctions( wspan, w, r, W );
493
+ const temp = [];
494
+
495
+ for ( let m = 0; m <= r; ++ m ) {
496
+
497
+ temp[ m ] = [];
498
+
499
+ for ( let l = 0; l <= q; ++ l ) {
500
+
501
+ temp[ m ][ l ] = new Vector4( 0, 0, 0, 0 );
502
+ for ( let k = 0; k <= p; ++ k ) {
503
+
504
+ const point = P[ uspan - p + k ][ vspan - q + l ][ wspan - r + m ].clone();
505
+ const w = point.w;
506
+ point.x *= w;
507
+ point.y *= w;
508
+ point.z *= w;
509
+ temp[ m ][ l ].add( point.multiplyScalar( Nu[ k ] ) );
510
+
511
+ }
512
+
513
+ }
514
+
515
+ }
516
+ const Sw = new Vector4( 0, 0, 0, 0 );
517
+ for ( let m = 0; m <= r; ++ m ) {
518
+ for ( let l = 0; l <= q; ++ l ) {
519
+
520
+ Sw.add( temp[ m ][ l ].multiplyScalar( Nw[ m ] ).multiplyScalar( Nv[ l ] ) );
521
+
522
+ }
523
+ }
524
+
525
+ Sw.divideScalar( Sw.w );
526
+ target.set( Sw.x, Sw.y, Sw.z );
527
+
528
+ }
475
529
 
476
530
 
477
531
  export {
@@ -484,4 +538,5 @@ export {
484
538
  calcRationalCurveDerivatives,
485
539
  calcNURBSDerivatives,
486
540
  calcSurfacePoint,
541
+ calcVolumePoint,
487
542
  };