super-three 0.161.0 → 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 (131) hide show
  1. package/build/three.cjs +490 -393
  2. package/build/three.module.js +490 -391
  3. package/build/three.module.min.js +1 -1
  4. package/examples/jsm/controls/DragControls.js +91 -30
  5. package/examples/jsm/controls/OrbitControls.js +32 -6
  6. package/examples/jsm/controls/TransformControls.js +6 -6
  7. package/examples/jsm/exporters/GLTFExporter.js +11 -1
  8. package/examples/jsm/interactive/InteractiveGroup.js +15 -25
  9. package/examples/jsm/libs/rhino3dm/rhino3dm.js +1 -8723
  10. package/examples/jsm/libs/rhino3dm/rhino3dm.module.js +1 -8734
  11. package/examples/jsm/libs/rhino3dm/rhino3dm.wasm +0 -0
  12. package/examples/jsm/libs/tween.module.js +32 -14
  13. package/examples/jsm/loaders/3DMLoader.js +13 -21
  14. package/examples/jsm/loaders/VOXLoader.js +9 -2
  15. package/examples/jsm/loaders/VRMLLoader.js +6 -2
  16. package/examples/jsm/misc/ProgressiveLightMap.js +1 -0
  17. package/examples/jsm/nodes/Nodes.js +9 -7
  18. package/examples/jsm/nodes/accessors/AccessorsUtils.js +10 -0
  19. package/examples/jsm/nodes/accessors/ClippingNode.js +144 -0
  20. package/examples/jsm/nodes/accessors/MaterialNode.js +2 -2
  21. package/examples/jsm/nodes/accessors/MaterialReferenceNode.js +2 -12
  22. package/examples/jsm/nodes/accessors/MorphNode.js +8 -8
  23. package/examples/jsm/nodes/accessors/ReferenceNode.js +87 -29
  24. package/examples/jsm/nodes/accessors/SkinningNode.js +31 -10
  25. package/examples/jsm/nodes/accessors/StorageBufferNode.js +18 -0
  26. package/examples/jsm/nodes/accessors/TangentNode.js +8 -2
  27. package/examples/jsm/nodes/accessors/TextureNode.js +1 -1
  28. package/examples/jsm/nodes/accessors/UniformsNode.js +140 -0
  29. package/examples/jsm/nodes/code/CodeNode.js +6 -0
  30. package/examples/jsm/nodes/core/AssignNode.js +68 -12
  31. package/examples/jsm/nodes/core/Node.js +14 -4
  32. package/examples/jsm/nodes/core/NodeBuilder.js +3 -9
  33. package/examples/jsm/nodes/core/NodeFrame.js +2 -2
  34. package/examples/jsm/nodes/core/TempNode.js +1 -1
  35. package/examples/jsm/nodes/display/BlendModeNode.js +30 -1
  36. package/examples/jsm/nodes/display/NormalMapNode.js +3 -5
  37. package/examples/jsm/nodes/materials/NodeMaterial.js +37 -6
  38. package/examples/jsm/nodes/math/CondNode.js +42 -7
  39. package/examples/jsm/nodes/math/MathNode.js +20 -0
  40. package/examples/jsm/nodes/utils/ArrayElementNode.js +0 -6
  41. package/examples/jsm/nodes/utils/LoopNode.js +2 -0
  42. package/examples/jsm/nodes/utils/StorageArrayElementNode.js +91 -0
  43. package/examples/jsm/postprocessing/OutputPass.js +2 -0
  44. package/examples/jsm/renderers/common/Background.js +2 -2
  45. package/examples/jsm/renderers/common/ClippingContext.js +165 -0
  46. package/examples/jsm/renderers/common/RenderContext.js +2 -0
  47. package/examples/jsm/renderers/common/RenderContexts.js +2 -13
  48. package/examples/jsm/renderers/common/RenderObject.js +44 -1
  49. package/examples/jsm/renderers/common/RenderObjects.js +3 -1
  50. package/examples/jsm/renderers/common/Renderer.js +94 -37
  51. package/examples/jsm/renderers/common/StorageBufferAttribute.js +2 -2
  52. package/examples/jsm/renderers/common/StorageInstancedBufferAttribute.js +17 -0
  53. package/examples/jsm/renderers/common/Textures.js +3 -13
  54. package/examples/jsm/renderers/common/UniformsGroup.js +6 -4
  55. package/examples/jsm/renderers/common/nodes/NodeStorageBuffer.js +23 -0
  56. package/examples/jsm/renderers/common/nodes/NodeUniformBuffer.js +23 -0
  57. package/examples/jsm/renderers/common/nodes/Nodes.js +1 -0
  58. package/examples/jsm/renderers/webgl/WebGLBackend.js +26 -6
  59. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +135 -10
  60. package/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js +7 -1
  61. package/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +47 -0
  62. package/examples/jsm/renderers/webgl/utils/WebGLUtils.js +1 -0
  63. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +13 -12
  64. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +15 -40
  65. package/examples/jsm/renderers/webgpu/utils/WebGPUAttributeUtils.js +7 -1
  66. package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +2 -2
  67. package/examples/jsm/shaders/OutputShader.js +4 -0
  68. package/examples/jsm/utils/SkeletonUtils.js +14 -3
  69. package/examples/jsm/webxr/VRButton.js +13 -5
  70. package/examples/jsm/webxr/XRButton.js +0 -1
  71. package/examples/jsm/webxr/XRControllerModelFactory.js +8 -0
  72. package/package.json +4 -3
  73. package/src/Three.Legacy.js +20 -0
  74. package/src/Three.js +0 -1
  75. package/src/constants.js +2 -5
  76. package/src/core/BufferAttribute.js +0 -11
  77. package/src/core/BufferGeometry.js +23 -29
  78. package/src/core/Object3D.js +11 -0
  79. package/src/core/Raycaster.js +18 -4
  80. package/src/core/RenderTarget.js +44 -21
  81. package/src/extras/PMREMGenerator.js +2 -0
  82. package/src/extras/curves/EllipseCurve.js +2 -2
  83. package/src/helpers/SpotLightHelper.js +18 -1
  84. package/src/loaders/DataTextureLoader.js +0 -4
  85. package/src/loaders/MaterialLoader.js +1 -0
  86. package/src/loaders/ObjectLoader.js +2 -1
  87. package/src/materials/Material.js +2 -1
  88. package/src/materials/MeshBasicMaterial.js +3 -0
  89. package/src/materials/MeshLambertMaterial.js +3 -0
  90. package/src/materials/MeshPhongMaterial.js +3 -0
  91. package/src/materials/MeshStandardMaterial.js +3 -0
  92. package/src/math/Quaternion.js +13 -12
  93. package/src/math/Vector3.js +7 -7
  94. package/src/objects/InstancedMesh.js +53 -0
  95. package/src/objects/Mesh.js +0 -1
  96. package/src/renderers/WebGLCubeRenderTarget.js +1 -10
  97. package/src/renderers/WebGLRenderer.js +15 -22
  98. package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +1 -0
  99. package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +1 -1
  100. package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +2 -2
  101. package/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js +1 -1
  102. package/src/renderers/shaders/ShaderChunk/morphinstance_vertex.glsl.js +14 -0
  103. package/src/renderers/shaders/ShaderChunk/morphtarget_pars_vertex.glsl.js +11 -2
  104. package/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js +23 -0
  105. package/src/renderers/shaders/ShaderChunk.js +2 -0
  106. package/src/renderers/shaders/ShaderLib/backgroundCube.glsl.js +3 -2
  107. package/src/renderers/shaders/ShaderLib/depth.glsl.js +2 -0
  108. package/src/renderers/shaders/ShaderLib/distanceRGBA.glsl.js +2 -0
  109. package/src/renderers/shaders/ShaderLib/linedashed.glsl.js +1 -0
  110. package/src/renderers/shaders/ShaderLib/meshbasic.glsl.js +1 -0
  111. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +1 -0
  112. package/src/renderers/shaders/ShaderLib/meshmatcap.glsl.js +1 -0
  113. package/src/renderers/shaders/ShaderLib/meshnormal.glsl.js +1 -0
  114. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +1 -0
  115. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +1 -0
  116. package/src/renderers/shaders/ShaderLib/meshtoon.glsl.js +1 -0
  117. package/src/renderers/shaders/ShaderLib/points.glsl.js +1 -0
  118. package/src/renderers/shaders/ShaderLib/shadow.glsl.js +1 -0
  119. package/src/renderers/shaders/ShaderLib.js +2 -1
  120. package/src/renderers/shaders/UniformsLib.js +1 -0
  121. package/src/renderers/webgl/WebGLBackground.js +18 -0
  122. package/src/renderers/webgl/WebGLMaterials.js +24 -1
  123. package/src/renderers/webgl/WebGLMorphtargets.js +15 -8
  124. package/src/renderers/webgl/WebGLProgram.js +12 -1
  125. package/src/renderers/webgl/WebGLPrograms.js +19 -16
  126. package/src/renderers/webgl/WebGLState.js +11 -21
  127. package/src/renderers/webgl/WebGLTextures.js +80 -50
  128. package/src/scenes/Scene.js +8 -0
  129. package/src/textures/Texture.js +1 -29
  130. package/examples/jsm/nodes/core/ArrayUniformNode.js +0 -26
  131. package/src/renderers/WebGLMultipleRenderTargets.js +0 -82
@@ -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,12 +380,13 @@ class OrbitControls extends EventDispatcher {
374
380
 
375
381
  } else if ( scope.object.isOrthographicCamera ) {
376
382
 
377
- zoomChanged = scale !== 1;
383
+ const prevZoom = scope.object.zoom;
384
+ scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / scale ) );
378
385
 
379
- if ( zoomChanged ) {
386
+ if ( prevZoom !== scope.object.zoom ) {
380
387
 
381
- scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / scale ) );
382
388
  scope.object.updateProjectionMatrix();
389
+ zoomChanged = true;
383
390
 
384
391
  }
385
392
 
@@ -395,7 +402,7 @@ class OrbitControls extends EventDispatcher {
395
402
  if ( zoomChanged ||
396
403
  lastPosition.distanceToSquared( scope.object.position ) > EPS ||
397
404
  8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ||
398
- lastTargetPosition.distanceToSquared( scope.target ) > 0 ) {
405
+ lastTargetPosition.distanceToSquared( scope.target ) > EPS ) {
399
406
 
400
407
  scope.dispatchEvent( _changeEvent );
401
408
 
@@ -424,6 +431,9 @@ class OrbitControls extends EventDispatcher {
424
431
  scope.domElement.removeEventListener( 'pointermove', onPointerMove );
425
432
  scope.domElement.removeEventListener( 'pointerup', onPointerUp );
426
433
 
434
+ const document = scope.domElement.getRootNode(); // offscreen canvas compatibility
435
+
436
+ document.removeEventListener( 'keydown', interceptControlDown, { capture: true } );
427
437
 
428
438
  if ( scope._domElementKeyEvents !== null ) {
429
439
 
@@ -1013,6 +1023,10 @@ class OrbitControls extends EventDispatcher {
1013
1023
 
1014
1024
  //
1015
1025
 
1026
+ if ( isTrackingPointer( event ) ) return;
1027
+
1028
+ //
1029
+
1016
1030
  addPointer( event );
1017
1031
 
1018
1032
  if ( event.pointerType === 'touch' ) {
@@ -1460,6 +1474,18 @@ class OrbitControls extends EventDispatcher {
1460
1474
 
1461
1475
  }
1462
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
+
1463
1489
  function trackPointer( event ) {
1464
1490
 
1465
1491
  let position = pointerPositions[ event.pointerId ];
@@ -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
 
@@ -1288,7 +1288,17 @@ class GLTFWriter {
1288
1288
 
1289
1289
  } else {
1290
1290
 
1291
- ctx.drawImage( image, 0, 0, canvas.width, canvas.height );
1291
+ if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||
1292
+ ( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||
1293
+ ( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) {
1294
+
1295
+ ctx.drawImage( image, 0, 0, canvas.width, canvas.height );
1296
+
1297
+ } else {
1298
+
1299
+ throw new Error( 'THREE.GLTFExporter: Invalid image type. Use HTMLImageElement, HTMLCanvasElement or ImageBitmap.' );
1300
+
1301
+ }
1292
1302
 
1293
1303
  }
1294
1304
 
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  Group,
3
- Matrix4,
4
3
  Raycaster,
5
4
  Vector2
6
5
  } from 'three';
@@ -8,18 +7,14 @@ import {
8
7
  const _pointer = new Vector2();
9
8
  const _event = { type: '', data: _pointer };
10
9
 
11
- class InteractiveGroup extends Group {
10
+ const _raycaster = new Raycaster();
12
11
 
13
- constructor( renderer, camera ) {
12
+ class InteractiveGroup extends Group {
14
13
 
15
- super();
14
+ listenToPointerEvents( renderer, camera ) {
16
15
 
17
16
  const scope = this;
18
-
19
17
  const raycaster = new Raycaster();
20
- const tempMatrix = new Matrix4();
21
-
22
- // Pointer Events
23
18
 
24
19
  const element = renderer.domElement;
25
20
 
@@ -60,7 +55,12 @@ class InteractiveGroup extends Group {
60
55
  element.addEventListener( 'mousemove', onPointerEvent );
61
56
  element.addEventListener( 'click', onPointerEvent );
62
57
 
63
- // WebXR Controller Events
58
+ }
59
+
60
+ listenToXRControllerEvents( controller ) {
61
+
62
+ const scope = this;
63
+
64
64
  // TODO: Dispatch pointerevents too
65
65
 
66
66
  const events = {
@@ -74,12 +74,9 @@ class InteractiveGroup extends Group {
74
74
 
75
75
  const controller = event.target;
76
76
 
77
- tempMatrix.identity().extractRotation( controller.matrixWorld );
78
-
79
- raycaster.ray.origin.setFromMatrixPosition( controller.matrixWorld );
80
- raycaster.ray.direction.set( 0, 0, - 1 ).applyMatrix4( tempMatrix );
77
+ _raycaster.setFromXRController( controller );
81
78
 
82
- const intersections = raycaster.intersectObjects( scope.children, false );
79
+ const intersections = _raycaster.intersectObjects( scope.children, false );
83
80
 
84
81
  if ( intersections.length > 0 ) {
85
82
 
@@ -97,17 +94,10 @@ class InteractiveGroup extends Group {
97
94
 
98
95
  }
99
96
 
100
- const controller1 = renderer.xr.getController( 0 );
101
- controller1.addEventListener( 'move', onXRControllerEvent );
102
- controller1.addEventListener( 'select', onXRControllerEvent );
103
- controller1.addEventListener( 'selectstart', onXRControllerEvent );
104
- controller1.addEventListener( 'selectend', onXRControllerEvent );
105
-
106
- const controller2 = renderer.xr.getController( 1 );
107
- controller2.addEventListener( 'move', onXRControllerEvent );
108
- controller2.addEventListener( 'select', onXRControllerEvent );
109
- controller2.addEventListener( 'selectstart', onXRControllerEvent );
110
- controller2.addEventListener( 'selectend', onXRControllerEvent );
97
+ controller.addEventListener( 'move', onXRControllerEvent );
98
+ controller.addEventListener( 'select', onXRControllerEvent );
99
+ controller.addEventListener( 'selectstart', onXRControllerEvent );
100
+ controller.addEventListener( 'selectend', onXRControllerEvent );
111
101
 
112
102
  }
113
103