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
@@ -1,5 +1,12 @@
1
1
  import * as THREE from 'three/webgpu';
2
- import { Fn, instanceIndex, positionGeometry, materialColor, materialOpacity, vec4 } from 'three/tsl';
2
+ import {
3
+ Fn,
4
+ instanceIndex,
5
+ positionGeometry,
6
+ materialColor,
7
+ materialOpacity,
8
+ vec4,
9
+ } from 'three/tsl';
3
10
  import { NODE_MATERIAL_CLASSES } from './morphColorMaterial';
4
11
 
5
12
  /**
@@ -26,7 +33,8 @@ import { NODE_MATERIAL_CLASSES } from './morphColorMaterial';
26
33
  function createGlyphInstancedMaterial(sourceMaterial, glyphCompute) {
27
34
  let material = sourceMaterial;
28
35
  if (!material || !material.isNodeMaterial) {
29
- const NodeMaterialClass = (sourceMaterial && NODE_MATERIAL_CLASSES[sourceMaterial.type]) || THREE.MeshPhongNodeMaterial;
36
+ const NodeMaterialClass =
37
+ (sourceMaterial && NODE_MATERIAL_CLASSES[sourceMaterial.type]) || THREE.MeshPhongNodeMaterial;
30
38
  material = new NodeMaterialClass();
31
39
  if (sourceMaterial) material.copy(sourceMaterial);
32
40
  }
@@ -35,7 +43,8 @@ function createGlyphInstancedMaterial(sourceMaterial, glyphCompute) {
35
43
 
36
44
  material.positionNode = Fn(() => {
37
45
  const idx = instanceIndex;
38
- return position.element(idx)
46
+ return position
47
+ .element(idx)
39
48
  .add(axis1.element(idx).mul(positionGeometry.x))
40
49
  .add(axis2.element(idx).mul(positionGeometry.y))
41
50
  .add(axis3.element(idx).mul(positionGeometry.z));
@@ -22,21 +22,25 @@ const REPEAT_MODE = { NONE: 0, MIRROR: 1, AXES_2D: 2, AXES_3D: 3 };
22
22
 
23
23
  const repeatModeToInt = (repeat_mode) => {
24
24
  switch (repeat_mode) {
25
- case "MIRROR": return REPEAT_MODE.MIRROR;
26
- case "AXES_2D": return REPEAT_MODE.AXES_2D;
27
- case "AXES_3D": return REPEAT_MODE.AXES_3D;
28
- default: return REPEAT_MODE.NONE;
25
+ case 'MIRROR':
26
+ return REPEAT_MODE.MIRROR;
27
+ case 'AXES_2D':
28
+ return REPEAT_MODE.AXES_2D;
29
+ case 'AXES_3D':
30
+ return REPEAT_MODE.AXES_3D;
31
+ default:
32
+ return REPEAT_MODE.NONE;
29
33
  }
30
- }
34
+ };
31
35
 
32
36
  //Order of the vec4 fields of each glyph instance in the output buffer
33
37
  const OUTPUT_FIELDS = { position: 0, axis1: 1, axis2: 2, axis3: 3, color: 4 };
34
38
 
35
39
  const multiplierForRepeatMode = (repeat_mode) => {
36
- if (repeat_mode == "AXES_2D" || repeat_mode == "MIRROR") return 2;
37
- if (repeat_mode == "AXES_3D") return 3;
40
+ if (repeat_mode == 'AXES_2D' || repeat_mode == 'MIRROR') return 2;
41
+ if (repeat_mode == 'AXES_3D') return 3;
38
42
  return 1;
39
- }
43
+ };
40
44
 
41
45
  /**
42
46
  * GPU port of Glyphset's resolve_glyph_axes() + the per-frame keyframe
@@ -137,7 +141,6 @@ function createGlyphTransformCompute({
137
141
  };
138
142
 
139
143
  const computeFn = Fn(() => {
140
-
141
144
  const outIdx = int(instanceIndex);
142
145
  const inputIdx = outIdx.div(int(multiplier));
143
146
  const copyIdx = outIdx.mod(int(multiplier));
@@ -162,18 +165,21 @@ function createGlyphTransformCompute({
162
165
  // test/glyphTransformCompute.test.js's development). Writing directly
163
166
  // to the output buffer inside each branch avoids it.
164
167
 
165
- const isNoneOrMirror = uniforms.repeatMode.equal(int(REPEAT_MODE.NONE))
168
+ const isNoneOrMirror = uniforms.repeatMode
169
+ .equal(int(REPEAT_MODE.NONE))
166
170
  .or(uniforms.repeatMode.equal(int(REPEAT_MODE.MIRROR)));
167
171
 
168
172
  If(isNoneOrMirror, () => {
169
-
170
173
  // resolve_glyph_axes(): NONE / MIRROR branch.
171
174
  const signVec = vec3(
172
175
  select(scale.x.lessThan(0), float(-1), float(1)),
173
176
  select(scale.y.lessThan(0), float(-1), float(1)),
174
177
  select(scale.z.lessThan(0), float(-1), float(1)),
175
178
  );
176
- const axisScale = signVec.mul(uniforms.baseSize).add(scale.mul(uniforms.scaleFactors)).mul(uniforms.globalScale);
179
+ const axisScale = signVec
180
+ .mul(uniforms.baseSize)
181
+ .add(scale.mul(uniforms.scaleFactors))
182
+ .mul(uniforms.globalScale);
177
183
  const baseAxis1 = axis1.mul(axisScale.x);
178
184
  const baseAxis2 = axis2.mul(axisScale.y);
179
185
  const baseAxis3 = axis3.mul(axisScale.z);
@@ -182,7 +188,9 @@ function createGlyphTransformCompute({
182
188
  .add(baseAxis2.mul(uniforms.offset.y))
183
189
  .add(baseAxis3.mul(uniforms.offset.z));
184
190
 
185
- const isMirrorCopy = uniforms.repeatMode.equal(int(REPEAT_MODE.MIRROR)).and(copyIdx.equal(int(1)));
191
+ const isMirrorCopy = uniforms.repeatMode
192
+ .equal(int(REPEAT_MODE.MIRROR))
193
+ .and(copyIdx.equal(int(1)));
186
194
 
187
195
  const a1 = select(isMirrorCopy, baseAxis1.negate(), baseAxis1).toVar();
188
196
  const a2 = select(isMirrorCopy, baseAxis2.negate(), baseAxis2).toVar();
@@ -204,44 +212,60 @@ function createGlyphTransformCompute({
204
212
  writeOutput(outIdx, OUTPUT_FIELDS.axis1, a1);
205
213
  writeOutput(outIdx, OUTPUT_FIELDS.axis2, a2);
206
214
  writeOutput(outIdx, OUTPUT_FIELDS.axis3, a3);
207
-
208
215
  }).Else(() => {
209
-
210
216
  // resolve_glyph_axes(): AXES_2D / AXES_3D branch.
211
217
  const signVec = vec3(
212
218
  select(scale.x.lessThan(0), float(-1), float(1)),
213
219
  select(scale.y.lessThan(0), float(-1), float(1)),
214
220
  select(scale.z.lessThan(0), float(-1), float(1)),
215
221
  );
216
- const axisScale = signVec.mul(uniforms.baseSize.x).add(scale.mul(uniforms.scaleFactors.x)).mul(uniforms.globalScale);
222
+ const axisScale = signVec
223
+ .mul(uniforms.baseSize.x)
224
+ .add(scale.mul(uniforms.scaleFactors.x))
225
+ .mul(uniforms.globalScale);
217
226
  const finalPoint = point
218
227
  .add(axis1.mul(axisScale.x).mul(uniforms.offset.x))
219
228
  .add(axis2.mul(axisScale.y).mul(uniforms.offset.y))
220
229
  .add(axis3.mul(axisScale.z).mul(uniforms.offset.z));
221
230
 
222
- const useScale = select(copyIdx.equal(int(0)), scale.x,
223
- select(copyIdx.equal(int(1)), scale.y, scale.z));
231
+ const useScale = select(
232
+ copyIdx.equal(int(0)),
233
+ scale.x,
234
+ select(copyIdx.equal(int(1)), scale.y, scale.z),
235
+ );
224
236
 
225
237
  const isAxes2D = uniforms.repeatMode.equal(int(REPEAT_MODE.AXES_2D));
226
238
 
227
- const useAxis1 = select(copyIdx.equal(int(0)), axis1,
228
- select(copyIdx.equal(int(1)), axis2, axis3));
229
- const useAxis2 = select(copyIdx.equal(int(0)), axis2,
230
- select(copyIdx.equal(int(1)), select(isAxes2D, axis1, axis3), axis1));
239
+ const useAxis1 = select(
240
+ copyIdx.equal(int(0)),
241
+ axis1,
242
+ select(copyIdx.equal(int(1)), axis2, axis3),
243
+ );
244
+ const useAxis2 = select(
245
+ copyIdx.equal(int(0)),
246
+ axis2,
247
+ select(copyIdx.equal(int(1)), select(isAxes2D, axis1, axis3), axis1),
248
+ );
231
249
 
232
- const finalScale1 = uniforms.baseSize.x.add(useScale.mul(uniforms.scaleFactors.x)).mul(uniforms.globalScale);
250
+ const finalScale1 = uniforms.baseSize.x
251
+ .add(useScale.mul(uniforms.scaleFactors.x))
252
+ .mul(uniforms.globalScale);
233
253
  const finalAxis1 = useAxis1.mul(finalScale1);
234
254
 
235
255
  const axis3Raw = finalAxis1.cross(useAxis2);
236
256
  const mag1 = axis3Raw.length();
237
- let scaling1 = uniforms.baseSize.z.add(useScale.mul(uniforms.scaleFactors.z)).mul(uniforms.globalScale)
257
+ let scaling1 = uniforms.baseSize.z
258
+ .add(useScale.mul(uniforms.scaleFactors.z))
259
+ .mul(uniforms.globalScale)
238
260
  .div(max(mag1, 1e-8));
239
261
  scaling1 = select(isAxes2D.and(copyIdx.greaterThan(int(0))), scaling1.mul(-1), scaling1);
240
262
  const finalAxis3 = select(mag1.greaterThan(0), axis3Raw.mul(scaling1), axis3Raw);
241
263
 
242
264
  const axis2Raw = finalAxis3.cross(finalAxis1);
243
265
  const mag2 = axis2Raw.length();
244
- const scaling2 = uniforms.baseSize.y.add(useScale.mul(uniforms.scaleFactors.y)).mul(uniforms.globalScale)
266
+ const scaling2 = uniforms.baseSize.y
267
+ .add(useScale.mul(uniforms.scaleFactors.y))
268
+ .mul(uniforms.globalScale)
245
269
  .div(max(mag2, 1e-8));
246
270
  const finalAxis2 = select(mag2.greaterThan(0), axis2Raw.mul(scaling2), axis2Raw);
247
271
 
@@ -249,15 +273,13 @@ function createGlyphTransformCompute({
249
273
  writeOutput(outIdx, OUTPUT_FIELDS.axis1, finalAxis1);
250
274
  writeOutput(outIdx, OUTPUT_FIELDS.axis2, finalAxis2);
251
275
  writeOutput(outIdx, OUTPUT_FIELDS.axis3, finalAxis3);
252
-
253
276
  });
254
277
 
255
278
  if (hasColor) {
256
279
  const color = mix(readInput(topIdx, 5), readInput(bottomIdx, 5), uniforms.proportion);
257
280
  writeOutput(outIdx, OUTPUT_FIELDS.color, color);
258
281
  }
259
-
260
- } )().compute( outputCount );
282
+ })().compute(outputCount);
261
283
 
262
284
  return {
263
285
  uniforms,
@@ -344,7 +366,7 @@ let glyphComputeSupported = true;
344
366
 
345
367
  const setGlyphComputeSupported = (flag) => {
346
368
  glyphComputeSupported = flag ? true : false;
347
- }
369
+ };
348
370
 
349
371
  const isGlyphComputeSupported = () => glyphComputeSupported;
350
372
 
@@ -16,40 +16,40 @@ import {
16
16
 
17
17
  export function createWebGPUMaterial() {
18
18
  const material = new THREE.MeshBasicNodeMaterial({
19
- side: THREE.DoubleSide
19
+ side: THREE.DoubleSide,
20
20
  });
21
21
 
22
- const dummyData = new Uint8Array(32);
22
+ const dummyData = new Uint8Array(32);
23
23
 
24
- const placeholderTexture = new THREE.Data3DTexture(dummyData, 2, 2, 2);
25
- placeholderTexture.image = {
24
+ const placeholderTexture = new THREE.Data3DTexture(dummyData, 2, 2, 2);
25
+ placeholderTexture.image = {
26
26
  data: dummyData,
27
27
  width: 2,
28
28
  height: 2,
29
29
  depth: 2,
30
- };
30
+ };
31
31
 
32
- placeholderTexture.format = THREE.RGBAFormat;
33
- placeholderTexture.type = THREE.UnsignedByteType; // Be explicit for WebGPU
34
- placeholderTexture.minFilter = THREE.LinearFilter;
35
- placeholderTexture.magFilter = THREE.LinearFilter;
36
- placeholderTexture.generateMipmaps = false; // WebGPU cannot auto-generate mipmaps for custom Data3D
37
- placeholderTexture.unpackAlignment = 1;
38
- placeholderTexture.needsUpdate = true;
32
+ placeholderTexture.format = THREE.RGBAFormat;
33
+ placeholderTexture.type = THREE.UnsignedByteType; // Be explicit for WebGPU
34
+ placeholderTexture.minFilter = THREE.LinearFilter;
35
+ placeholderTexture.magFilter = THREE.LinearFilter;
36
+ placeholderTexture.generateMipmaps = false; // WebGPU cannot auto-generate mipmaps for custom Data3D
37
+ placeholderTexture.unpackAlignment = 1;
38
+ placeholderTexture.needsUpdate = true;
39
39
 
40
40
  // Define Uniforms
41
41
  const uniforms = {
42
- brightness: uniform(0),
43
- contrast: uniform(1),
44
- depth: uniform(1),
42
+ brightness: uniform(0),
43
+ contrast: uniform(1),
44
+ depth: uniform(1),
45
45
  discardAlpha: uniform(true),
46
- direction: uniform(1),
47
- flipY: uniform(true),
48
- flipZ: uniform(false),
49
- nChannels: uniform(1),
50
- maskEnabled: uniform(false),
51
- slide: uniform(new THREE.Vector3(0, 0, 1)),
52
- time: uniform(0)
46
+ direction: uniform(1),
47
+ flipY: uniform(true),
48
+ flipZ: uniform(false),
49
+ nChannels: uniform(1),
50
+ maskEnabled: uniform(false),
51
+ slide: uniform(new THREE.Vector3(0, 0, 1)),
52
+ time: uniform(0),
53
53
  };
54
54
 
55
55
  // Share Varyings via TSL
@@ -89,7 +89,6 @@ placeholderTexture.needsUpdate = true;
89
89
  return positionLocal;
90
90
  });
91
91
 
92
-
93
92
  // Fragment Node
94
93
  const fragmentNode = Fn(() => {
95
94
  // diffuse0/diffuse1/mask are already-built texture3D sampling nodes.
@@ -117,7 +116,7 @@ placeholderTexture.needsUpdate = true;
117
116
  return vec4(sRGBTransferEOTF(contrastedColor), 1.0);
118
117
  });
119
118
 
120
- // Assign to NodeMaterial slots
119
+ // Assign to NodeMaterial slots
121
120
  // TSL handles the base vertex transformation automatically, positionNode hooks custom vertex behaviour.
122
121
  material.positionNode = vertexNode();
123
122
  material.colorNode = fragmentNode();