zincjs 2.4.0 → 2.4.1-beta.1

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 (55) hide show
  1. package/build/zinc.js +3 -486
  2. package/build/zinc.js.map +1 -1
  3. package/package.json +6 -7
  4. package/src/controls.js +1 -1
  5. package/src/geometryCSG.js +1 -1
  6. package/src/glyphsetCSG.js +1 -1
  7. package/src/loaders/GLTFToZincJSLoader.js +1 -1
  8. package/src/loaders/JSONLoader.js +216 -371
  9. package/src/loaders/OBJLoader.js +1 -1
  10. package/src/loaders/STLLoader.js +1 -1
  11. package/src/loaders/niftiReader.js +6 -4
  12. package/src/loaders/primitivesLoader.js +7 -9
  13. package/src/minimap.js +1 -1
  14. package/src/primitives/geometry.js +11 -29
  15. package/src/primitives/glyph.js +1 -1
  16. package/src/primitives/glyphset.js +2 -4
  17. package/src/primitives/label.js +1 -1
  18. package/src/primitives/lines.js +12 -5
  19. package/src/primitives/lines2.js +4 -8
  20. package/src/primitives/lod.js +9 -3
  21. package/src/primitives/marker.js +1 -1
  22. package/src/primitives/markerCluster.js +1 -1
  23. package/src/primitives/pointset.js +368 -52
  24. package/src/primitives/textureSlides.js +59 -16
  25. package/src/primitives/textureVolume.js +1 -1
  26. package/src/primitives/tubeLines.js +20 -3
  27. package/src/primitives/zincObject.js +13 -1
  28. package/src/region.js +1 -1
  29. package/src/renderer.js +36 -17
  30. package/src/scene.js +20 -8
  31. package/src/sceneLoader.js +1 -1
  32. package/src/shaders/rgbVolumeRender.js +1 -1
  33. package/src/shaders/textureSlide.js +1 -1
  34. package/src/texture/texture.js +1 -1
  35. package/src/texture/textureArray.js +9 -2
  36. package/src/three/GLTFExporter.js +55 -2
  37. package/src/three/InstancedPoints.js +73 -0
  38. package/src/three/Loader.js +1 -1
  39. package/src/three/line/Line.js +1 -1
  40. package/src/three/line/LineSegments.js +1 -1
  41. package/src/three/line/LineSegments2.js +24 -39
  42. package/src/three/line/LineSegmentsGeometry.js +1 -1
  43. package/src/tls/morphColorMaterial.js +65 -0
  44. package/src/tls/pointsMaterial.js +79 -0
  45. package/src/tls/textureSlides.js +126 -0
  46. package/src/utilities.js +47 -70
  47. package/src/videoHandler.js +1 -2
  48. package/src/workers/geometryCSG.worker.js +1 -1
  49. package/src/workers/geometryCSGInternal.js +1 -1
  50. package/src/zinc.js +1 -1
  51. package/vite.config.js +3 -1
  52. package/src/primitives/augmentShader.js +0 -45
  53. package/src/three/Geometry.js +0 -2176
  54. package/src/three/Points.js +0 -224
  55. package/src/three/line/LineMaterial.js +0 -726
@@ -1,4 +1,4 @@
1
- import * as THREE from 'three';
1
+ import * as THREE from 'three/webgpu';
2
2
  import { mergeGeometries } from '../utilities';
3
3
  import { ZincObject } from './zincObject';
4
4
 
@@ -31,7 +31,7 @@ const TubeLines = function () {
31
31
  this.createLineSegment = (geometryIn, materialIn, options) => {
32
32
  if (geometryIn && materialIn) {
33
33
  dataIn = { geometryIn, materialIn, options };
34
- const geometry = getTubeLinesGeometry(geometryIn.vertices);
34
+ const geometry = getTubeLinesGeometry(extractVertices(geometryIn));
35
35
  const material = new THREE.MeshStandardMaterial({ color: materialIn.color });
36
36
  const mesh = new THREE.Mesh(geometry, material);
37
37
  this.setMesh(mesh, options.localTimeEnabled, options.localMorphColour);
@@ -86,10 +86,27 @@ const TubeLines = function () {
86
86
  mesh.geometry.dispose();
87
87
 
88
88
  geometryConfig = Object.assign(geometryConfig, { radius, radialSegments });
89
- mesh.geometry = getTubeLinesGeometry(geometryIn.vertices);
89
+ mesh.geometry = getTubeLinesGeometry(extractVertices(geometryIn));
90
90
  }
91
91
  }
92
92
 
93
+ /**
94
+ * Read the position attribute of a BufferGeometry into an array of
95
+ * THREE.Vector3, since TubeGeometry/CatmullRomCurve3/LineCurve3 need
96
+ * actual Vector3 instances to work with, not a flat typed array.
97
+ *
98
+ * @param {THREE.BufferGeometry} geometry
99
+ * @returns {Array}
100
+ */
101
+ const extractVertices = (geometry) => {
102
+ const position = geometry.getAttribute('position');
103
+ const vertices = [];
104
+ for (let i = 0; i < position.count; i++) {
105
+ vertices.push(new THREE.Vector3().fromBufferAttribute(position, i));
106
+ }
107
+ return vertices;
108
+ }
109
+
93
110
  /**
94
111
  * Get merged geometry from list of geometry vertices
95
112
  *
@@ -1,4 +1,4 @@
1
- import * as THREE from 'three';
1
+ import * as THREE from 'three/webgpu';
2
2
  import {
3
3
  createBufferGeometry,
4
4
  getBoundingBox,
@@ -183,6 +183,10 @@ ZincObject.prototype.setMesh = function(mesh, localTimeEnabled, localMorphColour
183
183
  this.clipAction.loop = THREE.LoopRepeat;
184
184
  this.clipAction.clampWhenFinished = true;
185
185
  this.clipAction.play();
186
+ //Evaluate the clip immediately so morphTargetInfluences reflects
187
+ //time 0 right away, rather than staying at its all-zero default
188
+ //until the first mixer.update() from playback/setMorphTime.
189
+ this.mixer.update(0);
186
190
  }
187
191
  }
188
192
  }
@@ -200,6 +204,14 @@ ZincObject.prototype.setMesh = function(mesh, localTimeEnabled, localMorphColour
200
204
  geometry.setAttribute('morphTarget1', geometry.getAttribute( 'position' ) );
201
205
  }
202
206
  }
207
+ if (this.morphColour) {
208
+ //Make sure morphColor0/morphColor1 exist before this mesh is ever
209
+ //rendered. WebGPU builds its pipeline against whatever attributes the
210
+ //geometry has at first render, and adding these two afterwards doesn't
211
+ //get picked up by an already-built pipeline - the object would render
212
+ //black forever after, since the colour shader can no longer see them.
213
+ this.initiateMorphColor();
214
+ }
203
215
  this.boundingBoxUpdateRequired = true;
204
216
  }
205
217
 
package/src/region.js CHANGED
@@ -1,4 +1,4 @@
1
- import * as THREE from 'three';
1
+ import * as THREE from 'three/webgpu';
2
2
  import { Pointset } from './primitives/pointset';
3
3
  import { Lines2 } from './primitives/lines2';
4
4
  import { Geometry } from './primitives/geometry';
package/src/renderer.js CHANGED
@@ -1,5 +1,4 @@
1
- import * as THREE from 'three';
2
- //import { WebGPURenderer } from 'three/webgpu';
1
+ import * as THREE from 'three/webgpu';
3
2
  import { ResizeSensor } from 'css-element-queries';
4
3
  import { Scene } from './scene';
5
4
  /**
@@ -24,7 +23,7 @@ const Renderer = function (containerIn) {
24
23
  let currentScene = undefined;
25
24
 
26
25
  //myGezincGeometriestains a tuple of the threejs mesh, timeEnabled, morphColour flag, unique id and morph
27
- const clock = new THREE.Clock(false);
26
+ const clock = new THREE.Timer();
28
27
  this.playAnimation = true;
29
28
  /* default animation update rate, rate is 1000 and duration
30
29
  is default to 6000, 6s to finish a full animation */
@@ -77,8 +76,9 @@ const Renderer = function (containerIn) {
77
76
  */
78
77
  this.onWindowResize = () => {
79
78
  currentScene.onWindowResize();
80
- const width = this.getDrawingWidth();
81
- const height = this.getDrawingHeight();
79
+ //Give it a miniumum size of 1 x 1
80
+ const width = this.getDrawingWidth() || 1;
81
+ const height = this.getDrawingHeight() || 1;
82
82
  if (renderer != undefined) {
83
83
  let localRect = undefined;
84
84
  if (container) {
@@ -109,7 +109,7 @@ const Renderer = function (containerIn) {
109
109
  /**
110
110
  * Initialise the renderer and its visualisations.
111
111
  */
112
- this.initialiseVisualisation = parameters => {
112
+ this.initialiseVisualisation = async (parameters) => {
113
113
  if (!isInitialised) {
114
114
  parameters = parameters || {};
115
115
  if (parameters['antialias'] === undefined) {
@@ -131,11 +131,26 @@ const Renderer = function (containerIn) {
131
131
  container = undefined;
132
132
  canvas = parameters["canvas"];
133
133
  }
134
- //parameters["forceWebGL"] = true;
135
- //renderer = new WebGPURenderer(parameters);
136
- //await renderer.init();
134
+ //WebGPURenderer otherwise requests a device with the default
135
+ //maxTextureArrayLayers (256 on many adapters), which is too low for
136
+ //some currnetly sypported scaffold. We will request the highest possible
137
+ //on the device
138
+ if (parameters.device === undefined && parameters.requiredLimits === undefined &&
139
+ typeof navigator !== 'undefined' && navigator.gpu) {
140
+ try {
141
+ const adapter = await navigator.gpu.requestAdapter({ powerPreference: parameters.powerPreference });
142
+ if (adapter) {
143
+ parameters.requiredLimits = { maxTextureArrayLayers: adapter.limits.maxTextureArrayLayers };
144
+ }
145
+ } catch (err) {
146
+ //Fall through and let WebGPURenderer's own adapter/device request
147
+ //use its defaults.
148
+ }
149
+ }
150
+ renderer = new THREE.WebGPURenderer(parameters);
151
+ await renderer.init();
137
152
 
138
- renderer = new THREE.WebGLRenderer(parameters);
153
+ //renderer = new THREE.WebGLRenderer(parameters);
139
154
  if (container !== undefined) {
140
155
  container.appendChild( renderer.domElement );
141
156
  }
@@ -208,10 +223,10 @@ const Renderer = function (containerIn) {
208
223
  * @return {Zinc.Scene}
209
224
  */
210
225
  this.getSceneByName = name => {
211
- return sceneMap[name];
212
- }
226
+ return sceneMap[name];
227
+ }
213
228
 
214
- /**
229
+ /*
215
230
  * Create a new scene with the provided name if scene with the same name exists,
216
231
  * return undefined.
217
232
  *
@@ -244,6 +259,10 @@ const Renderer = function (containerIn) {
244
259
  logoSprite.position.set(calculatedWidth, calculatedHeight, 1 );
245
260
  }
246
261
  }
262
+ return sceneMap[name];
263
+ }
264
+
265
+ /**
247
266
  };
248
267
 
249
268
  const updateOrthoCamera = () => {
@@ -341,7 +360,6 @@ const Renderer = function (containerIn) {
341
360
  */
342
361
  this.stopAnimate = () => {
343
362
  if (isRendering) {
344
- clock.stop();
345
363
  isRendering = false;
346
364
  }
347
365
  }
@@ -351,7 +369,7 @@ const Renderer = function (containerIn) {
351
369
  */
352
370
  this.animate = () => {
353
371
  if (!isRendering) {
354
- clock.start();
372
+ clock.reset();
355
373
  isRendering = true;
356
374
  runAnimation();
357
375
  }
@@ -549,6 +567,7 @@ const Renderer = function (containerIn) {
549
567
  sensor = new ResizeSensor(canvas, this.onWindowResize);
550
568
  }
551
569
  }
570
+ clock.update();
552
571
  const delta = clock.getDelta();
553
572
  currentScene.renderGeometries(playRate, delta, this.playAnimation);
554
573
  for(let i = 0; i < additionalActiveScenes.length; i++) {
@@ -573,11 +592,11 @@ const Renderer = function (containerIn) {
573
592
  }
574
593
 
575
594
  this.forceContextLoss = () => {
576
- renderer.forceContextLoss();
595
+ // renderer.forceContextLoss();
577
596
  }
578
597
 
579
598
  this.forceContextRestore= () => {
580
- renderer.forceContextRestore();
599
+ // renderer.forceContextRestore();
581
600
  }
582
601
 
583
602
  /**
package/src/scene.js CHANGED
@@ -1,13 +1,15 @@
1
- import * as THREE from 'three';
1
+ import * as THREE from 'three/webgpu';
2
2
  import { CameraControls, StereoEffect } from './controls';
3
3
  import { LineSegments } from './three/line/LineSegments';
4
4
  import { MarkerCluster } from './primitives/markerCluster';
5
5
  import { Minimap } from './minimap';
6
6
  import { Region } from './region';
7
- import { Points } from './three/Points';
7
+ import { InstancedPoints } from './three/InstancedPoints';
8
8
  import { SceneExporter } from './sceneExporter';
9
9
  import { SceneLoader } from './sceneLoader';
10
10
  import { Viewport } from './controls';
11
+ import { createPointQuadGeometry } from './primitives/pointset';
12
+ import { createInstancedPointsMaterial } from './tls/pointsMaterial';
11
13
  import {
12
14
  createBufferGeometry,
13
15
  createNewSpriteText,
@@ -1233,12 +1235,22 @@ const Scene = function (containerIn, rendererIn) {
1233
1235
  * with clearTemporaryPrimitives method.
1234
1236
  */
1235
1237
  this.addTemporaryPoints = (coords, colour) => {
1236
- const geometry = createBufferGeometry(coords.length, coords);
1237
- let material = new THREE.PointsMaterial({ alphaTest: 0.5, size: 15,
1238
- color: colour, sizeAttenuation: false });
1239
- const texture = getCircularTexture();
1240
- material.map = texture;
1241
- let point = new Points(geometry, material);
1238
+ const geometry = createPointQuadGeometry(coords.length);
1239
+ const material = createInstancedPointsMaterial(getCircularTexture());
1240
+ material.color.set(colour);
1241
+ material.size = 15;
1242
+ material.userData.uniforms.pointSize.value = 15;
1243
+ material.alphaTest = 0.5;
1244
+ const point = new InstancedPoints(geometry, material, coords.length);
1245
+ point.pointPositions = new Float32Array(coords.length * 3);
1246
+ const instancePosition = geometry.getAttribute('instancePosition');
1247
+ coords.forEach((coord, index) => {
1248
+ instancePosition.setXYZ(index, coord[0], coord[1], coord[2]);
1249
+ point.pointPositions[index * 3] = coord[0];
1250
+ point.pointPositions[index * 3 + 1] = coord[1];
1251
+ point.pointPositions[index * 3 + 2] = coord[2];
1252
+ });
1253
+ instancePosition.needsUpdate = true;
1242
1254
  tempGroup.add(point);
1243
1255
  return point;
1244
1256
  }
@@ -1,4 +1,4 @@
1
- import * as THREE from 'three';
1
+ import * as THREE from 'three/webgpu';
2
2
  import { GLTFToZincJSLoader } from './loaders/GLTFToZincJSLoader';
3
3
  import { OBJLoader } from './loaders/OBJLoader';
4
4
  import { PrimitivesLoader } from './loaders/primitivesLoader';
@@ -1,4 +1,4 @@
1
- import * as THREE from 'three';
1
+ import * as THREE from 'three/webgpu';
2
2
  const glslVersion = null;
3
3
 
4
4
  const fs =
@@ -1,4 +1,4 @@
1
- import * as THREE from 'three';
1
+ import * as THREE from 'three/webgpu';
2
2
  const glslVersion = THREE.GLSL3;
3
3
 
4
4
  const fs =
@@ -1,4 +1,4 @@
1
- import * as THREE from 'three';
1
+ import * as THREE from 'three/webgpu';
2
2
 
3
3
  /**
4
4
  * Base texture object for importing images and turning them into
@@ -1,4 +1,4 @@
1
- import * as THREE from 'three';
1
+ import * as THREE from 'three/webgpu';
2
2
  import { Texture } from './texture';
3
3
 
4
4
  /**
@@ -12,8 +12,15 @@ import { Texture } from './texture';
12
12
  const TextureArray = function () {
13
13
  Texture.call(this);
14
14
  this.isTextureArray = true;
15
+ this.imageData = undefined;
15
16
 
16
17
 
18
+ this.setDataTexture = (dataTexture) => {
19
+ this.impl = dataTexture;
20
+ console.log("setDataTexture", dataTexture);
21
+ this.imageData = dataTexture.image.data;
22
+ }
23
+
17
24
  /**
18
25
  * Read images from an array containg src locations.
19
26
  *
@@ -48,7 +55,7 @@ const TextureArray = function () {
48
55
  length += data.length;
49
56
  });
50
57
 
51
- this.impl = new THREE.DataArrayTexture(fullArray, w, h, d);
58
+ this.impl = new THREE.Data3DTexture(fullArray, w, h, d);
52
59
  this.size = {
53
60
  width: w,
54
61
  height: h,
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  BufferAttribute,
3
+ BufferGeometry,
3
4
  ClampToEdgeWrapping,
4
5
  DoubleSide,
5
6
  InterpolateDiscrete,
@@ -19,7 +20,7 @@ import {
19
20
  RepeatWrapping,
20
21
  Scene,
21
22
  Vector3
22
- } from 'three';
23
+ } from 'three/webgpu';
23
24
 
24
25
 
25
26
  class GLTFExporter {
@@ -1291,6 +1292,48 @@ class GLTFWriter {
1291
1292
 
1292
1293
  }
1293
1294
 
1295
+ /**
1296
+ * A Pointset's {@link InstancedPoints} draws every point as an instance of a
1297
+ * small camera facing quad - its `geometry` only carries that quad, the
1298
+ * actual point positions/colours live in `pointPositions`/`instanceColor`.
1299
+ * Temporarily substitute a plain points geometry built from that data (and
1300
+ * flag the object as `isPoints`) so the regular POINTS export path below
1301
+ * produces a correct round trip, then return a function that restores the
1302
+ * object to its original state.
1303
+ *
1304
+ * @param {InstancedPoints} object Object to substitute the geometry of
1305
+ * @return {Function} Restores `object` to its pre-substitution state
1306
+ */
1307
+ substituteInstancedPointsGeometry( object ) {
1308
+
1309
+ const count = object.count;
1310
+ const geometry = new BufferGeometry();
1311
+ geometry.setAttribute( 'position',
1312
+ new BufferAttribute( object.pointPositions.slice( 0, count * 3 ), 3 ) );
1313
+
1314
+ if ( object.instanceColor ) {
1315
+
1316
+ geometry.setAttribute( 'color',
1317
+ new BufferAttribute( object.instanceColor.array.slice( 0, count * 3 ), 3 ) );
1318
+
1319
+ }
1320
+
1321
+ const originalGeometry = object.geometry;
1322
+ const originalIsPoints = object.isPoints;
1323
+
1324
+ object.geometry = geometry;
1325
+ object.isPoints = true;
1326
+
1327
+ return function () {
1328
+
1329
+ object.geometry = originalGeometry;
1330
+ object.isPoints = originalIsPoints;
1331
+ geometry.dispose();
1332
+
1333
+ };
1334
+
1335
+ }
1336
+
1294
1337
  /**
1295
1338
  * Process mesh
1296
1339
  * @param {THREE.Mesh} mesh Mesh to process
@@ -1887,10 +1930,20 @@ class GLTFWriter {
1887
1930
 
1888
1931
  this.serializeUserData( object, nodeDef );
1889
1932
 
1890
- if ( object.isMesh || object.isLine || object.isPoints ) {
1933
+ if ( object.isMesh || object.isLine || object.isPoints || object.isInstancedPoints ) {
1934
+
1935
+ let restoreInstancedPoints;
1936
+
1937
+ if ( object.isInstancedPoints ) {
1938
+
1939
+ restoreInstancedPoints = this.substituteInstancedPointsGeometry( object );
1940
+
1941
+ }
1891
1942
 
1892
1943
  const meshIndex = this.processMesh( object );
1893
1944
 
1945
+ if ( restoreInstancedPoints ) restoreInstancedPoints();
1946
+
1894
1947
  if ( meshIndex !== null ) nodeDef.mesh = meshIndex;
1895
1948
 
1896
1949
  } else if ( object.isCamera ) {
@@ -0,0 +1,73 @@
1
+ import {
2
+ InstancedMesh,
3
+ Matrix4,
4
+ Ray,
5
+ Vector3,
6
+ } from 'three/webgpu';
7
+
8
+ const _inverseMatrix = /*@__PURE__*/ new Matrix4();
9
+ const _ray = /*@__PURE__*/ new Ray();
10
+ const _position = /*@__PURE__*/ new Vector3();
11
+
12
+ /**
13
+ * An {@link THREE.InstancedMesh} used to draw a {@link Pointset}. Every
14
+ * instance is a small quad billboarded towards the camera on the GPU (see
15
+ * {@link createInstancedPointsMaterial}), so the usual matrix/geometry based
16
+ * raycasting and bounding logic performed by `THREE.InstancedMesh` does not
17
+ * apply - the true, already time-blended location of every point is instead
18
+ * kept in `pointPositions` (local space) and used here directly, mirroring
19
+ * the distance-to-point approach the legacy `THREE.Points` override used.
20
+ */
21
+ class InstancedPoints extends InstancedMesh {
22
+
23
+ constructor(geometry, material, count) {
24
+ super(geometry, material, count);
25
+ this.type = 'InstancedPoints';
26
+ this.isInstancedPoints = true;
27
+ this.frustumCulled = false;
28
+ this.pointSize = 10;
29
+ this.sizePerPixel = 1;
30
+ //Flat [x0, y0, z0, x1, y1, z1, ...] array of the current, already
31
+ //time-blended local positions of every active point.
32
+ this.pointPositions = new Float32Array(0);
33
+ }
34
+
35
+ raycast(raycaster, intersects) {
36
+ const matrixWorld = this.matrixWorld;
37
+ const threshold = raycaster.params.Points ? raycaster.params.Points.threshold : 1;
38
+ const count = this.count;
39
+ const positions = this.pointPositions;
40
+
41
+ if (!count || !positions || positions.length < count * 3) return;
42
+
43
+ _inverseMatrix.copy(matrixWorld).invert();
44
+ _ray.copy(raycaster.ray).applyMatrix4(_inverseMatrix);
45
+
46
+ const averageScale = (this.scale.x + this.scale.y + this.scale.z) / 3;
47
+ const localThreshold = threshold / averageScale * this.pointSize * this.sizePerPixel;
48
+ const localThresholdSq = localThreshold * localThreshold;
49
+
50
+ for (let i = 0; i < count; i++) {
51
+ _position.fromArray(positions, i * 3);
52
+ const rayPointDistanceSq = _ray.distanceSqToPoint(_position);
53
+ if (rayPointDistanceSq < localThresholdSq) {
54
+ const intersectPoint = new Vector3();
55
+ _ray.closestPointToPoint(_position, intersectPoint);
56
+ intersectPoint.applyMatrix4(matrixWorld);
57
+ const distance = raycaster.ray.origin.distanceTo(intersectPoint);
58
+ if (distance < raycaster.near || distance > raycaster.far) continue;
59
+ intersects.push({
60
+ distance: distance,
61
+ distanceToRay: Math.sqrt(rayPointDistanceSq),
62
+ point: intersectPoint,
63
+ index: i,
64
+ face: null,
65
+ object: this,
66
+ });
67
+ }
68
+ }
69
+ }
70
+
71
+ }
72
+
73
+ export { InstancedPoints };
@@ -18,7 +18,7 @@ import {
18
18
  MaterialLoader,
19
19
  TextureLoader,
20
20
  Color
21
- } from 'three';
21
+ } from 'three/webgpu';
22
22
 
23
23
  /**
24
24
  * @author alteredq / http://alteredqualia.com/
@@ -7,7 +7,7 @@ import {
7
7
  Ray,
8
8
  Sphere,
9
9
  Vector3
10
- } from 'three';
10
+ } from 'three/webgpu';
11
11
 
12
12
 
13
13
  const _start = /*@__PURE__*/ new Vector3();
@@ -2,7 +2,7 @@ import { Line } from './Line.js';
2
2
  import {
3
3
  Float32BufferAttribute,
4
4
  Vector3
5
- } from 'three';
5
+ } from 'three/webgpu';
6
6
 
7
7
  const _start = /*@__PURE__*/ new Vector3();
8
8
  const _end = /*@__PURE__*/ new Vector3();
@@ -8,12 +8,11 @@ import {
8
8
  Mesh,
9
9
  Sphere,
10
10
  Vector3,
11
- Vector4
12
- } from 'three';
11
+ Vector4,
12
+ Line2NodeMaterial,
13
+ Vector2
14
+ } from 'three/webgpu';
13
15
  import { LineSegmentsGeometry } from './LineSegmentsGeometry.js';
14
- import { LineMaterial } from './LineMaterial.js';
15
-
16
- const _viewport = new Vector4();
17
16
 
18
17
  const _start = new Vector3();
19
18
  const _end = new Vector3();
@@ -30,6 +29,7 @@ const _closestPoint = new Vector3();
30
29
  const _box = new Box3();
31
30
  const _sphere = new Sphere();
32
31
  const _clipToWorldVector = new Vector4();
32
+ const _viewport = new Vector4();
33
33
 
34
34
  let _ray, _lineWidth;
35
35
 
@@ -94,10 +94,10 @@ function raycastWorldUnits( lineSegments, intersects ) {
94
94
  function raycastScreenSpace( lineSegments, camera, intersects ) {
95
95
 
96
96
  const projectionMatrix = camera.projectionMatrix;
97
- const material = lineSegments.material;
98
- const resolution = material.resolution;
99
97
  const matrixWorld = lineSegments.matrixWorld;
100
98
 
99
+ const resolution = lineSegments._resolution;
100
+
101
101
  const geometry = lineSegments.geometry;
102
102
  const instanceStart = geometry.attributes.instanceStart;
103
103
  const instanceEnd = geometry.attributes.instanceEnd;
@@ -231,22 +231,11 @@ function raycastScreenSpace( lineSegments, camera, intersects ) {
231
231
  * to be in world units. {@link Line2} extends this object, forming a polyline instead of individual
232
232
  * segments.
233
233
  *
234
- * This module can only be used with {@link WebGLRenderer}. When using {@link WebGPURenderer},
235
- * import the class from `lines/webgpu/LineSegments2.js`.
236
- *
237
- * ```js
238
- * const geometry = new LineSegmentsGeometry();
239
- * geometry.setPositions( positions );
240
- * geometry.setColors( colors );
241
- *
242
- * const material = new LineMaterial( { linewidth: 5, vertexColors: true } };
243
- *
244
- * const lineSegments = new LineSegments2( geometry, material );
245
- * scene.add( lineSegments );
246
- * ```
234
+ * This module can only be used with {@link WebGPURenderer}. When using {@link WebGLRenderer},
235
+ * import the class from `lines/LineSegments2.js`.
247
236
  *
248
237
  * @augments Mesh
249
- * @three_import import { LineSegments2 } from 'three/addons/lines/LineSegments2.js';
238
+ * @three_import import { LineSegments2 } from 'three/addons/lines/webgpu/LineSegments2.js';
250
239
  */
251
240
  class LineSegments2 extends Mesh {
252
241
 
@@ -254,9 +243,9 @@ class LineSegments2 extends Mesh {
254
243
  * Constructs a new wide line.
255
244
  *
256
245
  * @param {LineSegmentsGeometry} [geometry] - The line geometry.
257
- * @param {LineMaterial} [material] - The line material.
246
+ * @param {Line2NodeMaterial} [material] - The line material.
258
247
  */
259
- constructor( geometry = new LineSegmentsGeometry(), material = new LineMaterial( { color: Math.random() * 0xffffff } ) ) {
248
+ constructor( geometry = new LineSegmentsGeometry(), material = new Line2NodeMaterial( { color: Math.random() * 0xffffff } ) ) {
260
249
 
261
250
  super( geometry, material );
262
251
 
@@ -271,6 +260,8 @@ class LineSegments2 extends Mesh {
271
260
 
272
261
  this.type = 'LineSegments2';
273
262
 
263
+ this._resolution = new Vector2();
264
+
274
265
  }
275
266
 
276
267
  /**
@@ -309,6 +300,13 @@ class LineSegments2 extends Mesh {
309
300
 
310
301
  }
311
302
 
303
+ onBeforeRender( renderer ) {
304
+
305
+ renderer.getViewport( _viewport );
306
+ this._resolution.set( _viewport.z, _viewport.w );
307
+
308
+ }
309
+
312
310
  /**
313
311
  * Computes intersection points between a casted ray and this instance.
314
312
  *
@@ -328,7 +326,7 @@ class LineSegments2 extends Mesh {
328
326
 
329
327
  // early out if no resolution has been set (line was not rendered yet)
330
328
 
331
- if ( worldUnits === false && ( this.material.resolution.x === 0 || this.material.resolution.y === 0 ) ) {
329
+ if ( worldUnits === false && ( this._resolution.x === 0 || this._resolution.y === 0 ) ) {
332
330
 
333
331
  return;
334
332
 
@@ -362,7 +360,7 @@ class LineSegments2 extends Mesh {
362
360
  } else {
363
361
 
364
362
  const distanceToSphere = Math.max( camera.near, _sphere.distanceToPoint( _ray.origin ) );
365
- sphereMargin = getWorldSpaceHalfWidth( camera, distanceToSphere, material.resolution );
363
+ sphereMargin = getWorldSpaceHalfWidth( camera, distanceToSphere, this._resolution );
366
364
 
367
365
  }
368
366
 
@@ -392,7 +390,7 @@ class LineSegments2 extends Mesh {
392
390
  } else {
393
391
 
394
392
  const distanceToBox = Math.max( camera.near, _box.distanceToPoint( _ray.origin ) );
395
- boxMargin = getWorldSpaceHalfWidth( camera, distanceToBox, material.resolution );
393
+ boxMargin = getWorldSpaceHalfWidth( camera, distanceToBox, this._resolution );
396
394
 
397
395
  }
398
396
 
@@ -416,19 +414,6 @@ class LineSegments2 extends Mesh {
416
414
 
417
415
  }
418
416
 
419
- onBeforeRender( renderer ) {
420
-
421
- const uniforms = this.material.uniforms;
422
-
423
- if ( uniforms && uniforms.resolution ) {
424
-
425
- renderer.getViewport( _viewport );
426
- this.material.uniforms.resolution.value.set( _viewport.z, _viewport.w );
427
-
428
- }
429
-
430
- }
431
-
432
417
  }
433
418
 
434
419
  export { LineSegments2 };
@@ -7,7 +7,7 @@ import {
7
7
  Sphere,
8
8
  Vector3,
9
9
  WireframeGeometry
10
- } from 'three';
10
+ } from 'three/webgpu';
11
11
 
12
12
  const _box = new Box3();
13
13
  const _vector = new Vector3();