zincjs 3.0.0 → 3.0.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 (60) hide show
  1. package/README.md +27 -22
  2. package/build/zinc.js +2 -2
  3. package/build/zinc.js.map +1 -1
  4. package/package.json +4 -1
  5. package/src/controls.js +1332 -1241
  6. package/src/geometryCSG.js +111 -115
  7. package/src/glyphsetCSG.js +51 -55
  8. package/src/loaders/GLTFToZincJSLoader.js +31 -33
  9. package/src/loaders/JSONLoader.js +339 -449
  10. package/src/loaders/OBJLoader.js +654 -851
  11. package/src/loaders/STLLoader.js +271 -329
  12. package/src/loaders/niftiReader.js +90 -59
  13. package/src/loaders/primitivesLoader.js +55 -52
  14. package/src/minimap.js +63 -43
  15. package/src/primitives/geometry.js +40 -44
  16. package/src/primitives/glyph.js +16 -19
  17. package/src/primitives/glyphset.js +229 -185
  18. package/src/primitives/label.js +29 -31
  19. package/src/primitives/lines.js +20 -20
  20. package/src/primitives/lines2.js +33 -39
  21. package/src/primitives/lod.js +43 -43
  22. package/src/primitives/marker.js +31 -32
  23. package/src/primitives/markerCluster.js +32 -35
  24. package/src/primitives/pointset.js +86 -83
  25. package/src/primitives/texturePrimitive.js +9 -10
  26. package/src/primitives/textureSlides.js +84 -97
  27. package/src/primitives/textureVolume.js +46 -49
  28. package/src/primitives/tubeLines.js +108 -108
  29. package/src/primitives/zincObject.js +176 -184
  30. package/src/region.js +145 -155
  31. package/src/renderRequests.js +3 -3
  32. package/src/renderer.js +635 -620
  33. package/src/scene.js +479 -419
  34. package/src/sceneExporter.js +22 -17
  35. package/src/sceneLoader.js +542 -296
  36. package/src/shaders/rgbVolumeRender.js +11 -18
  37. package/src/shaders/textureArray.js +5 -12
  38. package/src/shaders/textureSlide.js +10 -17
  39. package/src/shaders/volumeRender.js +11 -18
  40. package/src/shaders/volumeRender_old.js +11 -18
  41. package/src/shaders/volumeTexture.js +7 -14
  42. package/src/textSprite.js +23 -19
  43. package/src/texture/texture.js +14 -15
  44. package/src/texture/textureArray.js +14 -16
  45. package/src/three/InstancedPoints.js +2 -9
  46. package/src/three/Loader.js +334 -315
  47. package/src/three/line/Line.js +165 -215
  48. package/src/three/line/LineSegments.js +40 -55
  49. package/src/three/line/LineSegments2.js +322 -366
  50. package/src/three/line/LineSegmentsGeometry.js +239 -280
  51. package/src/three-js-csg.js +260 -252
  52. package/src/tsl/glyphRenderMaterial.js +12 -3
  53. package/src/tsl/glyphTransform.js +51 -29
  54. package/src/tsl/textureSlides.js +23 -24
  55. package/src/utilities.js +309 -371
  56. package/src/videoHandler.js +76 -83
  57. package/src/workers/geometryCSG.worker.js +33 -36
  58. package/src/workers/geometryCSGInternal.js +39 -44
  59. package/src/zinc.js +4 -7
  60. package/vite.config.js +7 -7
@@ -17,12 +17,11 @@ const DEFAULT_CAPACITY = 500;
17
17
  */
18
18
  const createPointQuadGeometry = (capacity) => {
19
19
  const geometry = new THREE.PlaneGeometry(1, 1);
20
- const instancePosition = new THREE.InstancedBufferAttribute(
21
- new Float32Array(capacity * 3), 3);
20
+ const instancePosition = new THREE.InstancedBufferAttribute(new Float32Array(capacity * 3), 3);
22
21
  instancePosition.setUsage(THREE.DynamicDrawUsage);
23
22
  geometry.setAttribute('instancePosition', instancePosition);
24
23
  return geometry;
25
- }
24
+ };
26
25
 
27
26
  /**
28
27
  * Extract the per time step, flat [x0, y0, z0, x1, y1, z1, ...] position
@@ -46,7 +45,7 @@ const extractPositionFrames = (geometry, localTimeEnabled) => {
46
45
  });
47
46
  }
48
47
  return [Float32Array.from(positionAttribute.array)];
49
- }
48
+ };
50
49
 
51
50
  /**
52
51
  * Extract the per time step, flat [r0, g0, b0, r1, g1, b1, ...] colour
@@ -60,7 +59,7 @@ const extractColorFrames = (geometry, localMorphColour) => {
60
59
  return morphColors.map((attribute) => Float32Array.from(attribute.array));
61
60
  }
62
61
  return undefined;
63
- }
62
+ };
64
63
 
65
64
  /**
66
65
  * Extract the plain, non-morph per-vertex 'color' attribute (if any) so a
@@ -70,7 +69,7 @@ const extractColorFrames = (geometry, localMorphColour) => {
70
69
  const extractStaticColorFrame = (geometry) => {
71
70
  const colorAttribute = geometry.getAttribute('color');
72
71
  return colorAttribute ? Float32Array.from(colorAttribute.array) : undefined;
73
- }
72
+ };
74
73
 
75
74
  /**
76
75
  * Provides an object which stores points and provides method which controls its position.
@@ -116,7 +115,7 @@ const Pointset = function () {
116
115
  let topFrame = 0;
117
116
  let proportion = 1;
118
117
  if (totalSteps > 1) {
119
- const currentTime = this.inbuildTime / this.duration * (totalSteps - 1);
118
+ const currentTime = (this.inbuildTime / this.duration) * (totalSteps - 1);
120
119
  bottomFrame = Math.floor(currentTime);
121
120
  topFrame = Math.ceil(currentTime);
122
121
  proportion = 1 - (currentTime - bottomFrame);
@@ -147,7 +146,7 @@ const Pointset = function () {
147
146
  }
148
147
  mesh.instanceColor.needsUpdate = true;
149
148
  }
150
- }
149
+ };
151
150
 
152
151
  /**
153
152
  * Create the pointset using geometry and material.
@@ -198,7 +197,11 @@ const Pointset = function () {
198
197
  const initialColorFrame = colorFrames ? colorFrames[0] : extractStaticColorFrame(geometry);
199
198
  if (initialColorFrame) {
200
199
  for (let i = 0; i < numberOfPoints; i++) {
201
- _tempColor.setRGB(initialColorFrame[i * 3], initialColorFrame[i * 3 + 1], initialColorFrame[i * 3 + 2]);
200
+ _tempColor.setRGB(
201
+ initialColorFrame[i * 3],
202
+ initialColorFrame[i * 3 + 1],
203
+ initialColorFrame[i * 3 + 2],
204
+ );
202
205
  mesh.setColorAt(i, _tempColor);
203
206
  }
204
207
  }
@@ -206,20 +209,19 @@ const Pointset = function () {
206
209
  this.setMorph(mesh);
207
210
  geometry.dispose();
208
211
  this.boundingBoxUpdateRequired = true;
209
- }
212
+ };
210
213
 
211
214
  /**
212
215
  * Adapt a plain THREE.Points object (e.g. one parsed from a GLTF file)
213
216
  * into this Pointset's instanced mesh representation.
214
217
  */
215
218
  this.setMesh = (mesh, localTimeEnabled, localMorphColour) => {
216
- this.createMesh(mesh.geometry, mesh.material,
217
- { localTimeEnabled, localMorphColour });
219
+ this.createMesh(mesh.geometry, mesh.material, { localTimeEnabled, localMorphColour });
218
220
  const newMesh = this.getMorph();
219
221
  if (newMesh) {
220
222
  newMesh.name = mesh.name;
221
223
  }
222
- }
224
+ };
223
225
 
224
226
  const addLabel = (index, coord, labelText, colourHex) => {
225
227
  if (labelText) {
@@ -239,7 +241,7 @@ const Pointset = function () {
239
241
  this.group.add(sprite);
240
242
  labelSets[index] = label;
241
243
  }
242
- }
244
+ };
243
245
 
244
246
  const removeLabel = (index) => {
245
247
  const label = labelSets[index];
@@ -249,7 +251,7 @@ const Pointset = function () {
249
251
  label.dispose();
250
252
  labelSets.splice(index, 1);
251
253
  }
252
- }
254
+ };
253
255
 
254
256
  /**
255
257
  * Add points to existing mesh if it exists, otherwise
@@ -278,7 +280,7 @@ const Pointset = function () {
278
280
  this.setMorph(mesh);
279
281
  }
280
282
  const instancePosition = mesh.geometry.getAttribute('instancePosition');
281
- coords.forEach(coord => {
283
+ coords.forEach((coord) => {
282
284
  if (this.drawRange < DEFAULT_CAPACITY) {
283
285
  instancePosition.setXYZ(this.drawRange, coord[0], coord[1], coord[2]);
284
286
  this.drawRange++;
@@ -289,10 +291,12 @@ const Pointset = function () {
289
291
 
290
292
  let end = current + coords.length;
291
293
  let index = 0;
292
- if ((Array.isArray(labels) && labels.length === coords.length) ||
293
- (typeof labels === "string")) {
294
+ if (
295
+ (Array.isArray(labels) && labels.length === coords.length) ||
296
+ typeof labels === 'string'
297
+ ) {
294
298
  for (current; current + index < end;) {
295
- const labelText = typeof labels === "string" ? labels : labels[index];
299
+ const labelText = typeof labels === 'string' ? labels : labels[index];
296
300
  addLabel(current + index, coords[index], labelText, this._lod._material.color);
297
301
  index++;
298
302
  }
@@ -300,14 +304,14 @@ const Pointset = function () {
300
304
  this.boundingBoxUpdateRequired = true;
301
305
  if (this.region) this.region.pickableUpdateRequired = true;
302
306
  }
303
- }
307
+ };
304
308
 
305
- /**
309
+ /**
306
310
  * Set the colour of the pointset and its label using the hex value
307
311
  *
308
312
  * @param {Number} hex - hex value of color to be set
309
313
  */
310
- this.setColourHex = function(hex) {
314
+ this.setColourHex = function (hex) {
311
315
  this.requestRender();
312
316
  this._lod._material.color.setHex(hex);
313
317
  if (this._lod._secondaryMaterial) {
@@ -318,7 +322,7 @@ const Pointset = function () {
318
322
  labelSets[i].setColour(this._lod._material.color);
319
323
  }
320
324
  }
321
- }
325
+ };
322
326
 
323
327
  /**
324
328
  * Set the colour of the pointset and its label
@@ -333,7 +337,7 @@ const Pointset = function () {
333
337
  labelSets[i].setColour(this._lod._material.color);
334
338
  }
335
339
  }
336
- }
340
+ };
337
341
 
338
342
  /**
339
343
  * Turn size attenuation on/off based on the flag.
@@ -349,7 +353,7 @@ const Pointset = function () {
349
353
  labelSets[i].setDepthTest(flag);
350
354
  }
351
355
  }
352
- }
356
+ };
353
357
 
354
358
  /**
355
359
  * Turn size attenuation on/off based on the flag.
@@ -364,7 +368,7 @@ const Pointset = function () {
364
368
  labelSets[i].setFontWeight(fontWeightIn);
365
369
  }
366
370
  }
367
- }
371
+ };
368
372
 
369
373
  /**
370
374
  * Set the size of the label
@@ -380,35 +384,35 @@ const Pointset = function () {
380
384
  labelSets[i].setSize(labelSize);
381
385
  }
382
386
  }
383
- }
387
+ };
384
388
 
385
389
  /**
386
390
  * Set visibility of Labels
387
391
  *
388
392
  * @param {boolean} flag - default value is true
389
393
  */
390
- this.displayLabels = (flag) => {
391
- this.requestRender();
392
- labelVisibility = flag;
393
- for (let i = 0; i < labelSets.length; i++) {
394
- if (labelSets[i]) {
395
- labelSets[i].setVisibility(labelVisibility);
396
- }
394
+ this.displayLabels = (flag) => {
395
+ this.requestRender();
396
+ labelVisibility = flag;
397
+ for (let i = 0; i < labelSets.length; i++) {
398
+ if (labelSets[i]) {
399
+ labelSets[i].setVisibility(labelVisibility);
397
400
  }
398
401
  }
402
+ };
399
403
  /**
400
404
  * Set the size of the points in pixels.
401
405
  *
402
406
  * @param {Number} size - size to be set.
403
407
  */
404
- this.setSize = size => {
408
+ this.setSize = (size) => {
405
409
  this.requestRender();
406
410
  if (this.morph && this.morph.material) {
407
411
  this.morph.material.size = size;
408
412
  this.morph.material.userData.uniforms.pointSize.value = size;
409
413
  this.morph.pointSize = size;
410
414
  }
411
- }
415
+ };
412
416
 
413
417
  /**
414
418
  * Turn size attenuation on/off based on the flag.
@@ -416,18 +420,18 @@ const Pointset = function () {
416
420
  * @param {Boolean} flag - Determin either size attenuation
417
421
  * should be on or off.
418
422
  */
419
- this.setSizeAttenuation = flag => {
423
+ this.setSizeAttenuation = (flag) => {
420
424
  this.requestRender();
421
425
  if (this.morph && this.morph.material) {
422
426
  this.morph.material.sizeAttenuation = flag;
423
427
  this.morph.material.userData.uniforms.sizeAttenuation.value = flag ? 1 : 0;
424
428
  }
425
- }
429
+ };
426
430
 
427
431
  /**
428
432
  * Get vertices at index
429
433
  */
430
- this.getVerticesByIndex = function(index) {
434
+ this.getVerticesByIndex = function (index) {
431
435
  const mesh = this.getMorph();
432
436
  if (mesh && index >= 0 && this.drawRange > index) {
433
437
  return [
@@ -437,12 +441,12 @@ const Pointset = function () {
437
441
  ];
438
442
  }
439
443
  return undefined;
440
- }
444
+ };
441
445
 
442
446
  /**
443
447
  * Edit Vertice in index.
444
448
  */
445
- this.editVertices = function(coords, i) {
449
+ this.editVertices = function (coords, i) {
446
450
  this.requestRender();
447
451
  if (coords && coords.length) {
448
452
  const mesh = this.getMorph();
@@ -452,7 +456,7 @@ const Pointset = function () {
452
456
  } else {
453
457
  const instancePosition = mesh.geometry.getAttribute('instancePosition');
454
458
  let index = i;
455
- coords.forEach(coord => {
459
+ coords.forEach((coord) => {
456
460
  const label = labelSets[index];
457
461
  if (label) {
458
462
  label.setPosition(coord[0], coord[1], coord[2]);
@@ -471,53 +475,53 @@ const Pointset = function () {
471
475
  this.boundingBoxUpdateRequired = true;
472
476
  }
473
477
  }
474
- }
478
+ };
475
479
 
476
- /**
480
+ /**
477
481
  * Delete a vertex in index.
478
482
  */
479
- this.deleteVertices = function(index) {
480
- this.requestRender();
481
- const mesh = this.getMorph();
482
- if (!mesh || 0 > index || index >= this.drawRange) {
483
- return this.drawRange;
484
- }
485
- const instancePosition = mesh.geometry.getAttribute('instancePosition');
486
- const end = this.drawRange - 1;
487
- instancePosition.array.copyWithin(index * 3, (index + 1) * 3, this.drawRange * 3);
488
- if (mesh.pointPositions !== instancePosition.array)
489
- mesh.pointPositions.copyWithin(index * 3, (index + 1) * 3, this.drawRange * 3);
490
- if (mesh.instanceColor) {
491
- mesh.instanceColor.array.copyWithin(index * 3, (index + 1) * 3, this.drawRange * 3);
492
- mesh.instanceColor.needsUpdate = true;
493
- }
494
- instancePosition.needsUpdate = true;
495
- this.drawRange = end;
496
- mesh.count = this.drawRange;
497
- removeLabel(index);
498
- this.boundingBoxUpdateRequired = true;
483
+ this.deleteVertices = function (index) {
484
+ this.requestRender();
485
+ const mesh = this.getMorph();
486
+ if (!mesh || 0 > index || index >= this.drawRange) {
499
487
  return this.drawRange;
500
488
  }
489
+ const instancePosition = mesh.geometry.getAttribute('instancePosition');
490
+ const end = this.drawRange - 1;
491
+ instancePosition.array.copyWithin(index * 3, (index + 1) * 3, this.drawRange * 3);
492
+ if (mesh.pointPositions !== instancePosition.array)
493
+ mesh.pointPositions.copyWithin(index * 3, (index + 1) * 3, this.drawRange * 3);
494
+ if (mesh.instanceColor) {
495
+ mesh.instanceColor.array.copyWithin(index * 3, (index + 1) * 3, this.drawRange * 3);
496
+ mesh.instanceColor.needsUpdate = true;
497
+ }
498
+ instancePosition.needsUpdate = true;
499
+ this.drawRange = end;
500
+ mesh.count = this.drawRange;
501
+ removeLabel(index);
502
+ this.boundingBoxUpdateRequired = true;
503
+ return this.drawRange;
504
+ };
501
505
 
502
506
  /**
503
507
  * Set the name for this ZincObject.
504
508
  *
505
509
  * @param {String} groupNameIn - Name to be set.
506
510
  */
507
- this.setName = function(groupNameIn) {
511
+ this.setName = function (groupNameIn) {
508
512
  const oldName = this.groupName;
509
513
  Pointset.prototype.setName.call(this, groupNameIn);
510
- labelSets.forEach(label => {
514
+ labelSets.forEach((label) => {
511
515
  if (label.getString() === oldName) {
512
516
  label?.setText(groupNameIn);
513
517
  }
514
- })
515
- }
518
+ });
519
+ };
516
520
 
517
521
  /**
518
522
  * Get the index of the closest vertex to centroid.
519
523
  */
520
- this.getClosestVertexIndex = function() {
524
+ this.getClosestVertexIndex = function () {
521
525
  let closestIndex = -1;
522
526
  const mesh = this.getMorph();
523
527
  if (mesh && this.drawRange > 0) {
@@ -534,12 +538,12 @@ const Pointset = function () {
534
538
  }
535
539
  }
536
540
  return closestIndex;
537
- }
541
+ };
538
542
 
539
543
  /**
540
544
  * Get the closest vertex to centroid.
541
545
  */
542
- this.getClosestVertex = function(applyMatrixWorld) {
546
+ this.getClosestVertex = function (applyMatrixWorld) {
543
547
  const mesh = this.getMorph();
544
548
  if (this.closestVertexIndex === -1) {
545
549
  this.closestVertexIndex = this.getClosestVertexIndex();
@@ -552,14 +556,14 @@ const Pointset = function () {
552
556
  this.getBoundingBox();
553
557
  position.copy(this.center);
554
558
  return position;
555
- }
559
+ };
556
560
 
557
561
  /**
558
562
  * Get the bounding box for the whole set of points.
559
563
  *
560
564
  * @return {THREE.Box3}
561
565
  */
562
- this.getBoundingBox = function() {
566
+ this.getBoundingBox = function () {
563
567
  const mesh = this.getMorph();
564
568
  if (this.visible && mesh && mesh.visible && this.drawRange > 0) {
565
569
  if (this.boundingBoxUpdateRequired) {
@@ -573,7 +577,7 @@ const Pointset = function () {
573
577
  return this.cachedBoundingBox;
574
578
  }
575
579
  return undefined;
576
- }
580
+ };
577
581
 
578
582
  /**
579
583
  * Check if the pointset is time varying.
@@ -582,14 +586,14 @@ const Pointset = function () {
582
586
  */
583
587
  this.isTimeVarying = () => {
584
588
  return morphVertices || morphColours;
585
- }
589
+ };
586
590
 
587
591
  /**
588
592
  * Set the local time of this pointset.
589
593
  *
590
594
  * @param {Number} time - Can be any value between 0 to duration.
591
595
  */
592
- this.setMorphTime = time => {
596
+ this.setMorphTime = (time) => {
593
597
  this.requestRender();
594
598
  if (time > this.duration) {
595
599
  this.inbuildTime = this.duration;
@@ -601,12 +605,12 @@ const Pointset = function () {
601
605
  if (morphVertices || morphColours) {
602
606
  updateMorphPointset();
603
607
  }
604
- }
608
+ };
605
609
 
606
610
  /**
607
- * Update the geometry and colours depending on the internal time and
608
- * refresh the marker/LOD state for the render.
609
- */
611
+ * Update the geometry and colours depending on the internal time and
612
+ * refresh the marker/LOD state for the render.
613
+ */
610
614
  this.render = (delta, playAnimation, cameraControls, options) => {
611
615
  if (this.morph && cameraControls) {
612
616
  this.morph.sizePerPixel = cameraControls.pixelHeight;
@@ -623,9 +627,8 @@ const Pointset = function () {
623
627
  updateMorphPointset();
624
628
  }
625
629
  this.updateMarker(playAnimation, options);
626
- }
627
-
628
- }
630
+ };
631
+ };
629
632
 
630
633
  Pointset.prototype = Object.create(ZincObject.prototype);
631
634
  export { Pointset, createPointQuadGeometry };
@@ -1,4 +1,3 @@
1
-
2
1
  import { TextureArray } from '../texture/textureArray';
3
2
  import { ZincObject } from './zincObject';
4
3
  /**
@@ -31,7 +30,7 @@ const TexturePrimitive = function (textureIn) {
31
30
  if (textureData.images && textureData.images.source) {
32
31
  const texture = new TextureArray();
33
32
  const imgArray = [];
34
- textureData.images.source.forEach(img => {
33
+ textureData.images.source.forEach((img) => {
35
34
  imgArray.push(img);
36
35
  });
37
36
  const _this = this;
@@ -42,7 +41,7 @@ const TexturePrimitive = function (textureIn) {
42
41
  });
43
42
  }
44
43
  }
45
- }
44
+ };
46
45
 
47
46
  this.addTextureArray = (tArray) => {
48
47
  if (this.textureList.length === 0 && this.texture) {
@@ -51,7 +50,7 @@ const TexturePrimitive = function (textureIn) {
51
50
  if (tArray && tArray.isTextureArray) {
52
51
  this.textureList.push(tArray);
53
52
  }
54
- }
53
+ };
55
54
 
56
55
  /**
57
56
  * Initialise a texture based on the provided textureData, this should be used
@@ -62,11 +61,11 @@ const TexturePrimitive = function (textureIn) {
62
61
  * is loaded.
63
62
  */
64
63
  this.initialise = (textureData, finishCallback) => {
65
- if (finishCallback != undefined && (typeof finishCallback == 'function')) {
64
+ if (finishCallback != undefined && typeof finishCallback == 'function') {
66
65
  finishCallback(this);
67
66
  }
68
- }
69
- }
67
+ };
68
+ };
70
69
 
71
70
  TexturePrimitive.prototype = Object.create(ZincObject.prototype);
72
71
  TexturePrimitive.prototype.constructor = TexturePrimitive;
@@ -74,12 +73,12 @@ TexturePrimitive.prototype.constructor = TexturePrimitive;
74
73
  /**
75
74
  * Free the textures and the other allocated memory.
76
75
  */
77
- TexturePrimitive.prototype.dispose = function() {
76
+ TexturePrimitive.prototype.dispose = function () {
78
77
  const textures = new Set(this.textureList);
79
78
  if (this.texture) textures.add(this.texture);
80
- textures.forEach(texture => texture.dispose());
79
+ textures.forEach((texture) => texture.dispose());
81
80
  this.texture = undefined;
82
81
  this.textureList = [];
83
82
  ZincObject.prototype.dispose.call(this);
84
- }
83
+ };
85
84
  export { TexturePrimitive };