zincjs 2.4.1-beta.7 → 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 +6 -2
  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
package/src/utilities.js CHANGED
@@ -6,20 +6,20 @@ import { createTextSprite } from './textSprite';
6
6
  function createNewURL(target, reference) {
7
7
  const getNewURL = (target, reference) => {
8
8
  try {
9
- let newURL = (new URL(target, reference)).href;
9
+ let newURL = new URL(target, reference).href;
10
10
  //Make sure the target url does not contain parameters
11
- if (target && target.split("?").length < 2) {
12
- const paramsStrings = reference.split("?");
11
+ if (target && target.split('?').length < 2) {
12
+ const paramsStrings = reference.split('?');
13
13
  //There are parameters, add them to the target
14
14
  if (paramsStrings.length === 2) {
15
- newURL = newURL + "?" + paramsStrings[1];
15
+ newURL = newURL + '?' + paramsStrings[1];
16
16
  }
17
17
  }
18
18
  return newURL;
19
19
  } catch {
20
- console.error(`There is an issue creating the url link with: ${target}.` );
20
+ console.error(`There is an issue creating the url link with: ${target}.`);
21
21
  }
22
- }
22
+ };
23
23
  if (!Array.isArray(target)) {
24
24
  return getNewURL(target, reference);
25
25
  } else {
@@ -62,8 +62,7 @@ function updateWorldMatrixFromAncestors(object) {
62
62
  function getBoundingBox(mesh, cachedBox, b1, v1, v2) {
63
63
  let influences = mesh.morphTargetInfluences;
64
64
  let attributes = undefined;
65
- if (mesh.geometry)
66
- attributes = mesh.geometry.morphAttributes;
65
+ if (mesh.geometry) attributes = mesh.geometry.morphAttributes;
67
66
  let found = false;
68
67
  if (influences && attributes && attributes.position) {
69
68
  v1.set(0.0, 0.0, 0.0);
@@ -81,82 +80,78 @@ function getBoundingBox(mesh, cachedBox, b1, v1, v2) {
81
80
  }
82
81
  }
83
82
  if (!found) {
84
- cachedBox.setFromBufferAttribute(
85
- mesh.geometry.attributes.position);
83
+ cachedBox.setFromBufferAttribute(mesh.geometry.attributes.position);
86
84
  }
87
85
  cachedBox.applyMatrix4(updateWorldMatrixFromAncestors(mesh));
88
86
  }
89
87
 
90
-
91
88
  //Convenient function
92
89
  function loadExternalFile(url, data, callback, errorCallback) {
93
- // Set up an asynchronous request
90
+ // Set up an asynchronous request
94
91
  fetch(url)
95
- .then((response) => {
96
- if (!response.ok) {
97
- throw new Error(`HTTP error! status: ${response.status}`);
98
- }
99
- return response.text();
100
- })
101
- .then((responseText) => {
102
- callback(responseText, data);
103
- })
104
- .catch((error) => {
105
- console.error(`Fetch string payload retrieval failed for: ${requestURL}`, error);
106
- errorCallback(url);
107
- });
92
+ .then((response) => {
93
+ if (!response.ok) {
94
+ throw new Error(`HTTP error! status: ${response.status}`);
95
+ }
96
+ return response.text();
97
+ })
98
+ .then((responseText) => {
99
+ callback(responseText, data);
100
+ })
101
+ .catch((error) => {
102
+ console.error(`Fetch string payload retrieval failed for: ${requestURL}`, error);
103
+ errorCallback(url);
104
+ });
108
105
  }
109
106
 
110
107
  function loadExternalFiles(urls, callback, errorCallback) {
111
- const numUrls = urls.length;
112
- let numComplete = 0;
113
- const result = [];
114
-
115
- // Callback for a single file
116
- function partialCallback(text, urlIndex) {
117
- result[urlIndex] = text;
118
- numComplete++;
119
-
120
- // When all files have downloaded
121
- if (numComplete == numUrls) {
122
- callback(result);
123
- }
124
- }
108
+ const numUrls = urls.length;
109
+ let numComplete = 0;
110
+ const result = [];
125
111
 
126
- for (let i = 0; i < numUrls; i++) {
127
- loadExternalFile(urls[i], i, partialCallback, errorCallback);
112
+ // Callback for a single file
113
+ function partialCallback(text, urlIndex) {
114
+ result[urlIndex] = text;
115
+ numComplete++;
116
+
117
+ // When all files have downloaded
118
+ if (numComplete == numUrls) {
119
+ callback(result);
128
120
  }
129
- }
121
+ }
130
122
 
123
+ for (let i = 0; i < numUrls; i++) {
124
+ loadExternalFile(urls[i], i, partialCallback, errorCallback);
125
+ }
126
+ }
131
127
 
132
128
  //Get the colours at index
133
129
  const getColorsRGB = (colors, index) => {
134
- const index_in_colors = Math.floor(index/3);
135
- const remainder = index%3;
136
- let hex_value = 0;
137
- if (remainder == 0)
138
- {
139
- hex_value = colors[index_in_colors].r;
140
- }
141
- else if (remainder == 1)
142
- {
143
- hex_value = colors[index_in_colors].g;
144
- }
145
- else if (remainder == 2)
146
- {
147
- hex_value = colors[index_in_colors].b;
148
- }
149
- const mycolor = new THREE.Color(hex_value);
150
- return [mycolor.r, mycolor.g, mycolor.b];
151
- }
130
+ const index_in_colors = Math.floor(index / 3);
131
+ const remainder = index % 3;
132
+ let hex_value = 0;
133
+ if (remainder == 0) {
134
+ hex_value = colors[index_in_colors].r;
135
+ } else if (remainder == 1) {
136
+ hex_value = colors[index_in_colors].g;
137
+ } else if (remainder == 2) {
138
+ hex_value = colors[index_in_colors].b;
139
+ }
140
+ const mycolor = new THREE.Color(hex_value);
141
+ return [mycolor.r, mycolor.g, mycolor.b];
142
+ };
152
143
 
153
144
  //morphColor0/morphColor1 attribute -> morph colour target last copied into it
154
145
  const morphColorSources = new WeakMap();
155
146
 
156
- const updateMorphColorAttribute = function(targetGeometry, morph) {
157
- if (morph && targetGeometry && targetGeometry.morphAttributes &&
158
- targetGeometry.morphAttributes[ "color" ]) {
159
- const morphColors = targetGeometry.morphAttributes[ "color" ];
147
+ const updateMorphColorAttribute = function (targetGeometry, morph) {
148
+ if (
149
+ morph &&
150
+ targetGeometry &&
151
+ targetGeometry.morphAttributes &&
152
+ targetGeometry.morphAttributes['color']
153
+ ) {
154
+ const morphColors = targetGeometry.morphAttributes['color'];
160
155
  const influences = morph.morphTargetInfluences;
161
156
  const length = influences.length;
162
157
  //Find the first two morph targets with non-zero influence
@@ -199,9 +194,13 @@ const updateMorphColorAttribute = function(targetGeometry, morph) {
199
194
  let attribute1 = targetGeometry.getAttribute('morphColor1');
200
195
  if (!attribute0 || !attribute1) {
201
196
  attribute0 = new THREE.Float32BufferAttribute(
202
- new Float32Array(morphColors[0].array.length), morphColors[0].itemSize);
197
+ new Float32Array(morphColors[0].array.length),
198
+ morphColors[0].itemSize,
199
+ );
203
200
  attribute1 = new THREE.Float32BufferAttribute(
204
- new Float32Array(morphColors[0].array.length), morphColors[0].itemSize);
201
+ new Float32Array(morphColors[0].array.length),
202
+ morphColors[0].itemSize,
203
+ );
205
204
  attribute0.setUsage(THREE.DynamicDrawUsage);
206
205
  attribute1.setUsage(THREE.DynamicDrawUsage);
207
206
  targetGeometry.setAttribute('morphColor0', attribute0);
@@ -221,24 +220,25 @@ const updateMorphColorAttribute = function(targetGeometry, morph) {
221
220
  attribute1.needsUpdate = true;
222
221
  morphColorSources.set(attribute1, source1);
223
222
  }
224
- const morphColorMix = morph.material && morph.material.userData &&
225
- morph.material.userData.uniforms && morph.material.userData.uniforms.morphColorMix;
223
+ const morphColorMix =
224
+ morph.material &&
225
+ morph.material.userData &&
226
+ morph.material.userData.uniforms &&
227
+ morph.material.userData.uniforms.morphColorMix;
226
228
  if (morphColorMix) {
227
229
  morphColorMix.value = mix;
228
230
  }
229
231
  }
230
- }
231
-
232
+ };
232
233
 
233
234
  const toBufferGeometry = (geometryIn) => {
234
235
  const geometry = geometryIn.clone();
235
236
  geometry.colorsNeedUpdate = true;
236
237
  geometry.computeBoundingBox();
237
238
  geometry.computeBoundingSphere();
238
- if (geometryIn._video)
239
- geometry._video = geometryIn._video;
239
+ if (geometryIn._video) geometry._video = geometryIn._video;
240
240
  return geometry;
241
- }
241
+ };
242
242
 
243
243
  /**
244
244
  * Merges a set of attributes into a single instance. All attributes must have compatible properties and types.
@@ -247,93 +247,77 @@ const toBufferGeometry = (geometryIn) => {
247
247
  * @param {Array<BufferAttribute>} attributes - The attributes to merge.
248
248
  * @return {?BufferAttribute} The merged attribute. Returns `null` if the merge does not succeed.
249
249
  */
250
- function mergeAttributes( attributes ) {
251
-
250
+ function mergeAttributes(attributes) {
252
251
  let TypedArray;
253
252
  let itemSize;
254
253
  let normalized;
255
- let gpuType = - 1;
254
+ let gpuType = -1;
256
255
  let arrayLength = 0;
257
256
 
258
- for ( let i = 0; i < attributes.length; ++ i ) {
259
-
260
- const attribute = attributes[ i ];
257
+ for (let i = 0; i < attributes.length; ++i) {
258
+ const attribute = attributes[i];
261
259
 
262
- if ( TypedArray === undefined ) TypedArray = attribute.array.constructor;
263
- if ( TypedArray !== attribute.array.constructor ) {
264
-
265
- console.error( 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.array must be of consistent array types across matching attributes.' );
260
+ if (TypedArray === undefined) TypedArray = attribute.array.constructor;
261
+ if (TypedArray !== attribute.array.constructor) {
262
+ console.error(
263
+ 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.array must be of consistent array types across matching attributes.',
264
+ );
266
265
  return null;
267
-
268
266
  }
269
267
 
270
- if ( itemSize === undefined ) itemSize = attribute.itemSize;
271
- if ( itemSize !== attribute.itemSize ) {
272
-
273
- console.error( 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.itemSize must be consistent across matching attributes.' );
268
+ if (itemSize === undefined) itemSize = attribute.itemSize;
269
+ if (itemSize !== attribute.itemSize) {
270
+ console.error(
271
+ 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.itemSize must be consistent across matching attributes.',
272
+ );
274
273
  return null;
275
-
276
274
  }
277
275
 
278
- if ( normalized === undefined ) normalized = attribute.normalized;
279
- if ( normalized !== attribute.normalized ) {
280
-
281
- console.error( 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.normalized must be consistent across matching attributes.' );
276
+ if (normalized === undefined) normalized = attribute.normalized;
277
+ if (normalized !== attribute.normalized) {
278
+ console.error(
279
+ 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.normalized must be consistent across matching attributes.',
280
+ );
282
281
  return null;
283
-
284
282
  }
285
283
 
286
- if ( gpuType === - 1 ) gpuType = attribute.gpuType;
287
- if ( gpuType !== attribute.gpuType ) {
288
-
289
- console.error( 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.gpuType must be consistent across matching attributes.' );
284
+ if (gpuType === -1) gpuType = attribute.gpuType;
285
+ if (gpuType !== attribute.gpuType) {
286
+ console.error(
287
+ 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.gpuType must be consistent across matching attributes.',
288
+ );
290
289
  return null;
291
-
292
290
  }
293
291
 
294
292
  arrayLength += attribute.count * itemSize;
295
-
296
293
  }
297
294
 
298
- const array = new TypedArray( arrayLength );
299
- const result = new THREE.BufferAttribute( array, itemSize, normalized );
295
+ const array = new TypedArray(arrayLength);
296
+ const result = new THREE.BufferAttribute(array, itemSize, normalized);
300
297
  let offset = 0;
301
298
 
302
- for ( let i = 0; i < attributes.length; ++ i ) {
303
-
304
- const attribute = attributes[ i ];
305
- if ( attribute.isInterleavedBufferAttribute ) {
306
-
299
+ for (let i = 0; i < attributes.length; ++i) {
300
+ const attribute = attributes[i];
301
+ if (attribute.isInterleavedBufferAttribute) {
307
302
  const tupleOffset = offset / itemSize;
308
- for ( let j = 0, l = attribute.count; j < l; j ++ ) {
309
-
310
- for ( let c = 0; c < itemSize; c ++ ) {
311
-
312
- const value = attribute.getComponent( j, c );
313
- result.setComponent( j + tupleOffset, c, value );
314
-
303
+ for (let j = 0, l = attribute.count; j < l; j++) {
304
+ for (let c = 0; c < itemSize; c++) {
305
+ const value = attribute.getComponent(j, c);
306
+ result.setComponent(j + tupleOffset, c, value);
315
307
  }
316
-
317
308
  }
318
-
319
309
  } else {
320
-
321
- array.set( attribute.array, offset );
322
-
310
+ array.set(attribute.array, offset);
323
311
  }
324
312
 
325
313
  offset += attribute.count * itemSize;
326
-
327
314
  }
328
315
 
329
- if ( gpuType !== undefined ) {
330
-
316
+ if (gpuType !== undefined) {
331
317
  result.gpuType = gpuType;
332
-
333
318
  }
334
319
 
335
320
  return result;
336
-
337
321
  }
338
322
 
339
323
  /**
@@ -343,378 +327,331 @@ function mergeAttributes( attributes ) {
343
327
  * @param {boolean} [useGroups=false] - Whether to use groups or not.
344
328
  * @return {?BufferGeometry} The merged geometry. Returns `null` if the merge does not succeed.
345
329
  */
346
- const mergeGeometries = ( geometries, useGroups = false ) => {
347
-
348
- const isIndexed = geometries[ 0 ].index !== null;
330
+ const mergeGeometries = (geometries, useGroups = false) => {
331
+ const isIndexed = geometries[0].index !== null;
349
332
 
350
- const attributesUsed = new Set( Object.keys( geometries[ 0 ].attributes ) );
351
- const morphAttributesUsed = new Set( Object.keys( geometries[ 0 ].morphAttributes ) );
333
+ const attributesUsed = new Set(Object.keys(geometries[0].attributes));
334
+ const morphAttributesUsed = new Set(Object.keys(geometries[0].morphAttributes));
352
335
 
353
336
  const attributes = {};
354
337
  const morphAttributes = {};
355
338
 
356
- const morphTargetsRelative = geometries[ 0 ].morphTargetsRelative;
339
+ const morphTargetsRelative = geometries[0].morphTargetsRelative;
357
340
 
358
341
  const mergedGeometry = new THREE.BufferGeometry();
359
342
 
360
343
  let offset = 0;
361
344
 
362
- for ( let i = 0; i < geometries.length; ++ i ) {
363
-
364
- const geometry = geometries[ i ];
345
+ for (let i = 0; i < geometries.length; ++i) {
346
+ const geometry = geometries[i];
365
347
  let attributesCount = 0;
366
348
 
367
349
  // ensure that all geometries are indexed, or none
368
350
 
369
- if ( isIndexed !== ( geometry.index !== null ) ) {
370
-
371
- console.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them.' );
351
+ if (isIndexed !== (geometry.index !== null)) {
352
+ console.error(
353
+ 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' +
354
+ i +
355
+ '. All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them.',
356
+ );
372
357
  return null;
373
-
374
358
  }
375
359
 
376
360
  // gather attributes, exit early if they're different
377
361
 
378
- for ( const name in geometry.attributes ) {
379
-
380
- if ( ! attributesUsed.has( name ) ) {
381
-
382
- console.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. All geometries must have compatible attributes; make sure "' + name + '" attribute exists among all geometries, or in none of them.' );
362
+ for (const name in geometry.attributes) {
363
+ if (!attributesUsed.has(name)) {
364
+ console.error(
365
+ 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' +
366
+ i +
367
+ '. All geometries must have compatible attributes; make sure "' +
368
+ name +
369
+ '" attribute exists among all geometries, or in none of them.',
370
+ );
383
371
  return null;
384
-
385
372
  }
386
373
 
387
- if ( attributes[ name ] === undefined ) attributes[ name ] = [];
374
+ if (attributes[name] === undefined) attributes[name] = [];
388
375
 
389
- attributes[ name ].push( geometry.attributes[ name ] );
390
-
391
- attributesCount ++;
376
+ attributes[name].push(geometry.attributes[name]);
392
377
 
378
+ attributesCount++;
393
379
  }
394
380
 
395
381
  // ensure geometries have the same number of attributes
396
382
 
397
- if ( attributesCount !== attributesUsed.size ) {
398
-
399
- console.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. Make sure all geometries have the same number of attributes.' );
383
+ if (attributesCount !== attributesUsed.size) {
384
+ console.error(
385
+ 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' +
386
+ i +
387
+ '. Make sure all geometries have the same number of attributes.',
388
+ );
400
389
  return null;
401
-
402
390
  }
403
391
 
404
392
  // gather morph attributes, exit early if they're different
405
393
 
406
- if ( morphTargetsRelative !== geometry.morphTargetsRelative ) {
407
-
408
- console.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. .morphTargetsRelative must be consistent throughout all geometries.' );
394
+ if (morphTargetsRelative !== geometry.morphTargetsRelative) {
395
+ console.error(
396
+ 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' +
397
+ i +
398
+ '. .morphTargetsRelative must be consistent throughout all geometries.',
399
+ );
409
400
  return null;
410
-
411
401
  }
412
402
 
413
- for ( const name in geometry.morphAttributes ) {
414
-
415
- if ( ! morphAttributesUsed.has( name ) ) {
416
-
417
- console.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. .morphAttributes must be consistent throughout all geometries.' );
403
+ for (const name in geometry.morphAttributes) {
404
+ if (!morphAttributesUsed.has(name)) {
405
+ console.error(
406
+ 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' +
407
+ i +
408
+ '. .morphAttributes must be consistent throughout all geometries.',
409
+ );
418
410
  return null;
419
-
420
411
  }
421
412
 
422
- if ( morphAttributes[ name ] === undefined ) morphAttributes[ name ] = [];
423
-
424
- morphAttributes[ name ].push( geometry.morphAttributes[ name ] );
413
+ if (morphAttributes[name] === undefined) morphAttributes[name] = [];
425
414
 
415
+ morphAttributes[name].push(geometry.morphAttributes[name]);
426
416
  }
427
417
 
428
- if ( useGroups ) {
429
-
418
+ if (useGroups) {
430
419
  let count;
431
420
 
432
- if ( isIndexed ) {
433
-
421
+ if (isIndexed) {
434
422
  count = geometry.index.count;
435
-
436
- } else if ( geometry.attributes.position !== undefined ) {
437
-
423
+ } else if (geometry.attributes.position !== undefined) {
438
424
  count = geometry.attributes.position.count;
439
-
440
425
  } else {
441
-
442
- console.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. The geometry must have either an index or a position attribute' );
426
+ console.error(
427
+ 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' +
428
+ i +
429
+ '. The geometry must have either an index or a position attribute',
430
+ );
443
431
  return null;
444
-
445
432
  }
446
433
 
447
- mergedGeometry.addGroup( offset, count, i );
434
+ mergedGeometry.addGroup(offset, count, i);
448
435
 
449
436
  offset += count;
450
-
451
437
  }
452
-
453
438
  }
454
439
 
455
440
  // merge indices
456
441
 
457
- if ( isIndexed ) {
458
-
442
+ if (isIndexed) {
459
443
  let indexOffset = 0;
460
444
  const mergedIndex = [];
461
445
 
462
- for ( let i = 0; i < geometries.length; ++ i ) {
463
-
464
- const index = geometries[ i ].index;
465
-
466
- for ( let j = 0; j < index.count; ++ j ) {
467
-
468
- mergedIndex.push( index.getX( j ) + indexOffset );
446
+ for (let i = 0; i < geometries.length; ++i) {
447
+ const index = geometries[i].index;
469
448
 
449
+ for (let j = 0; j < index.count; ++j) {
450
+ mergedIndex.push(index.getX(j) + indexOffset);
470
451
  }
471
452
 
472
- indexOffset += geometries[ i ].attributes.position.count;
473
-
453
+ indexOffset += geometries[i].attributes.position.count;
474
454
  }
475
455
 
476
- mergedGeometry.setIndex( mergedIndex );
477
-
456
+ mergedGeometry.setIndex(mergedIndex);
478
457
  }
479
458
 
480
459
  // merge attributes
481
460
 
482
- for ( const name in attributes ) {
483
-
484
- const mergedAttribute = mergeAttributes( attributes[ name ] );
485
-
486
- if ( ! mergedAttribute ) {
461
+ for (const name in attributes) {
462
+ const mergedAttribute = mergeAttributes(attributes[name]);
487
463
 
488
- console.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the ' + name + ' attribute.' );
464
+ if (!mergedAttribute) {
465
+ console.error(
466
+ 'THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the ' +
467
+ name +
468
+ ' attribute.',
469
+ );
489
470
  return null;
490
-
491
471
  }
492
472
 
493
- mergedGeometry.setAttribute( name, mergedAttribute );
494
-
473
+ mergedGeometry.setAttribute(name, mergedAttribute);
495
474
  }
496
475
 
497
476
  // merge morph attributes
498
477
 
499
- for ( const name in morphAttributes ) {
500
-
501
- const numMorphTargets = morphAttributes[ name ][ 0 ].length;
478
+ for (const name in morphAttributes) {
479
+ const numMorphTargets = morphAttributes[name][0].length;
502
480
 
503
- if ( numMorphTargets === 0 ) break;
481
+ if (numMorphTargets === 0) break;
504
482
 
505
483
  mergedGeometry.morphAttributes = mergedGeometry.morphAttributes || {};
506
- mergedGeometry.morphAttributes[ name ] = [];
507
-
508
- for ( let i = 0; i < numMorphTargets; ++ i ) {
484
+ mergedGeometry.morphAttributes[name] = [];
509
485
 
486
+ for (let i = 0; i < numMorphTargets; ++i) {
510
487
  const morphAttributesToMerge = [];
511
488
 
512
- for ( let j = 0; j < morphAttributes[ name ].length; ++ j ) {
513
-
514
- morphAttributesToMerge.push( morphAttributes[ name ][ j ][ i ] );
515
-
489
+ for (let j = 0; j < morphAttributes[name].length; ++j) {
490
+ morphAttributesToMerge.push(morphAttributes[name][j][i]);
516
491
  }
517
492
 
518
- const mergedMorphAttribute = mergeAttributes( morphAttributesToMerge );
519
-
520
- if ( ! mergedMorphAttribute ) {
493
+ const mergedMorphAttribute = mergeAttributes(morphAttributesToMerge);
521
494
 
522
- console.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the ' + name + ' morphAttribute.' );
495
+ if (!mergedMorphAttribute) {
496
+ console.error(
497
+ 'THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the ' +
498
+ name +
499
+ ' morphAttribute.',
500
+ );
523
501
  return null;
524
-
525
502
  }
526
503
 
527
- mergedGeometry.morphAttributes[ name ].push( mergedMorphAttribute );
528
-
504
+ mergedGeometry.morphAttributes[name].push(mergedMorphAttribute);
529
505
  }
530
-
531
506
  }
532
507
 
533
508
  return mergedGeometry;
509
+ };
534
510
 
535
- }
536
-
537
- const mergeVertices = ( geometry, tolerance = 1e-4 ) => {
538
-
539
- tolerance = Math.max( tolerance, Number.EPSILON );
511
+ const mergeVertices = (geometry, tolerance = 1e-4) => {
512
+ tolerance = Math.max(tolerance, Number.EPSILON);
540
513
 
541
514
  // Generate an index buffer if the geometry doesn't have one, or optimize it
542
515
  // if it's already available.
543
516
  var hashToIndex = {};
544
517
  var indices = geometry.getIndex();
545
- var positions = geometry.getAttribute( 'position' );
518
+ var positions = geometry.getAttribute('position');
546
519
  var vertexCount = indices ? indices.count : positions.count;
547
520
 
548
521
  // next value for triangle indices
549
522
  var nextIndex = 0;
550
523
 
551
524
  // attributes and new attribute arrays
552
- var attributeNames = Object.keys( geometry.attributes );
525
+ var attributeNames = Object.keys(geometry.attributes);
553
526
  var attrArrays = {};
554
527
  var morphAttrsArrays = {};
555
528
  var newIndices = [];
556
- var getters = [ 'getX', 'getY', 'getZ', 'getW' ];
529
+ var getters = ['getX', 'getY', 'getZ', 'getW'];
557
530
 
558
531
  // initialize the arrays
559
- for ( var i = 0, l = attributeNames.length; i < l; i ++ ) {
560
- var name = attributeNames[ i ];
561
-
562
- attrArrays[ name ] = [];
532
+ for (var i = 0, l = attributeNames.length; i < l; i++) {
533
+ var name = attributeNames[i];
563
534
 
564
- var morphAttr = geometry.morphAttributes[ name ];
565
- if ( morphAttr ) {
566
-
567
- morphAttrsArrays[ name ] = new Array( morphAttr.length ).fill().map( () => [] );
568
-
569
- }
535
+ attrArrays[name] = [];
570
536
 
537
+ var morphAttr = geometry.morphAttributes[name];
538
+ if (morphAttr) {
539
+ morphAttrsArrays[name] = new Array(morphAttr.length).fill().map(() => []);
540
+ }
571
541
  }
572
542
 
573
543
  // convert the error tolerance to an amount of decimal places to truncate to
574
- var decimalShift = Math.log10( 1 / tolerance );
575
- var shiftMultiplier = Math.pow( 10, decimalShift );
576
- for ( var i = 0; i < vertexCount; i ++ ) {
577
-
578
- var index = indices ? indices.getX( i ) : i;
579
-
580
- // Generate a hash for the vertex attributes at the current index 'i'
581
- var hash = '';
582
- for ( var j = 0, l = attributeNames.length; j < l; j ++ ) {
583
-
584
- var name = attributeNames[ j ];
585
- var attribute = geometry.getAttribute( name );
586
- var itemSize = attribute.itemSize;
587
-
588
- for ( var k = 0; k < itemSize; k ++ ) {
589
-
590
- // double tilde truncates the decimal value
591
- hash += `${ ~ ~ ( attribute[ getters[ k ] ]( index ) * shiftMultiplier ) },`;
592
-
593
- }
594
-
544
+ var decimalShift = Math.log10(1 / tolerance);
545
+ var shiftMultiplier = Math.pow(10, decimalShift);
546
+ for (var i = 0; i < vertexCount; i++) {
547
+ var index = indices ? indices.getX(i) : i;
548
+
549
+ // Generate a hash for the vertex attributes at the current index 'i'
550
+ var hash = '';
551
+ for (var j = 0, l = attributeNames.length; j < l; j++) {
552
+ var name = attributeNames[j];
553
+ var attribute = geometry.getAttribute(name);
554
+ var itemSize = attribute.itemSize;
555
+
556
+ for (var k = 0; k < itemSize; k++) {
557
+ // double tilde truncates the decimal value
558
+ hash += `${~~(attribute[getters[k]](index) * shiftMultiplier)},`;
595
559
  }
560
+ }
596
561
 
597
- // Add another reference to the vertex if it's already
598
- // used by another index
599
- if ( hash in hashToIndex ) {
600
-
601
- newIndices.push( hashToIndex[ hash ] );
602
-
603
- } else {
604
-
605
- // copy data to the new index in the attribute arrays
606
- for ( var j = 0, l = attributeNames.length; j < l; j ++ ) {
607
-
608
- var name = attributeNames[ j ];
609
- var attribute = geometry.getAttribute( name );
610
- var morphAttr = geometry.morphAttributes[ name ];
611
- var itemSize = attribute.itemSize;
612
- var newarray = attrArrays[ name ];
613
- var newMorphArrays = morphAttrsArrays[ name ];
614
-
615
- for ( var k = 0; k < itemSize; k ++ ) {
616
-
617
- var getterFunc = getters[ k ];
618
- newarray.push( attribute[ getterFunc ]( index ) );
619
-
620
- if ( morphAttr ) {
621
-
622
- for ( var m = 0, ml = morphAttr.length; m < ml; m ++ ) {
623
-
624
- newMorphArrays[ m ].push( morphAttr[ m ][ getterFunc ]( index ) );
625
-
626
- }
627
-
628
- }
629
-
630
- }
631
-
562
+ // Add another reference to the vertex if it's already
563
+ // used by another index
564
+ if (hash in hashToIndex) {
565
+ newIndices.push(hashToIndex[hash]);
566
+ } else {
567
+ // copy data to the new index in the attribute arrays
568
+ for (var j = 0, l = attributeNames.length; j < l; j++) {
569
+ var name = attributeNames[j];
570
+ var attribute = geometry.getAttribute(name);
571
+ var morphAttr = geometry.morphAttributes[name];
572
+ var itemSize = attribute.itemSize;
573
+ var newarray = attrArrays[name];
574
+ var newMorphArrays = morphAttrsArrays[name];
575
+
576
+ for (var k = 0; k < itemSize; k++) {
577
+ var getterFunc = getters[k];
578
+ newarray.push(attribute[getterFunc](index));
579
+
580
+ if (morphAttr) {
581
+ for (var m = 0, ml = morphAttr.length; m < ml; m++) {
582
+ newMorphArrays[m].push(morphAttr[m][getterFunc](index));
583
+ }
632
584
  }
633
-
634
- hashToIndex[ hash ] = nextIndex;
635
- newIndices.push( nextIndex );
636
- nextIndex ++;
637
-
585
+ }
638
586
  }
639
587
 
588
+ hashToIndex[hash] = nextIndex;
589
+ newIndices.push(nextIndex);
590
+ nextIndex++;
591
+ }
640
592
  }
641
593
 
642
594
  // Generate typed arrays from new attribute arrays and update
643
595
  // the attributeBuffers
644
596
  const result = geometry.clone();
645
- for ( var i = 0, l = attributeNames.length; i < l; i ++ ) {
646
-
647
- var name = attributeNames[ i ];
648
- var oldAttribute = geometry.getAttribute( name );
649
- var attribute;
650
-
651
- var buffer = new oldAttribute.array.constructor( attrArrays[ name ] );
652
- if ( oldAttribute.isInterleavedBufferAttribute ) {
653
-
654
- attribute = new THREE.BufferAttribute( buffer, oldAttribute.itemSize, oldAttribute.itemSize );
655
-
656
- } else {
657
-
658
- attribute = geometry.getAttribute( name ).clone();
659
- attribute.setArray( buffer );
660
-
661
- }
662
-
663
- result.setAttribute( name, attribute );
664
-
665
- // Update the attribute arrays
666
- if ( name in morphAttrsArrays ) {
667
-
668
- for ( var j = 0; j < morphAttrsArrays[ name ].length; j ++ ) {
597
+ for (var i = 0, l = attributeNames.length; i < l; i++) {
598
+ var name = attributeNames[i];
599
+ var oldAttribute = geometry.getAttribute(name);
600
+ var attribute;
601
+
602
+ var buffer = new oldAttribute.array.constructor(attrArrays[name]);
603
+ if (oldAttribute.isInterleavedBufferAttribute) {
604
+ attribute = new THREE.BufferAttribute(buffer, oldAttribute.itemSize, oldAttribute.itemSize);
605
+ } else {
606
+ attribute = geometry.getAttribute(name).clone();
607
+ attribute.setArray(buffer);
608
+ }
669
609
 
670
- var morphAttribute = geometry.morphAttributes[ name ][ j ].clone();
671
- morphAttribute.setArray( new morphAttribute.array.constructor( morphAttrsArrays[ name ][ j ] ) );
672
- result.morphAttributes[ name ][ j ] = morphAttribute;
673
-
674
- }
610
+ result.setAttribute(name, attribute);
675
611
 
612
+ // Update the attribute arrays
613
+ if (name in morphAttrsArrays) {
614
+ for (var j = 0; j < morphAttrsArrays[name].length; j++) {
615
+ var morphAttribute = geometry.morphAttributes[name][j].clone();
616
+ morphAttribute.setArray(new morphAttribute.array.constructor(morphAttrsArrays[name][j]));
617
+ result.morphAttributes[name][j] = morphAttribute;
676
618
  }
677
-
619
+ }
678
620
  }
679
621
 
680
622
  // Generate an index buffer typed array
681
623
  var cons = Uint8Array;
682
- if ( newIndices.length >= Math.pow( 2, 8 ) ) cons = Uint16Array;
683
- if ( newIndices.length >= Math.pow( 2, 16 ) ) cons = Uint32Array;
624
+ if (newIndices.length >= Math.pow(2, 8)) cons = Uint16Array;
625
+ if (newIndices.length >= Math.pow(2, 16)) cons = Uint32Array;
684
626
 
685
- var newIndexBuffer = new cons( newIndices );
627
+ var newIndexBuffer = new cons(newIndices);
686
628
  var newIndices = null;
687
- if ( indices === null ) {
688
-
689
- newIndices = new THREE.BufferAttribute( newIndexBuffer, 1 );
690
-
629
+ if (indices === null) {
630
+ newIndices = new THREE.BufferAttribute(newIndexBuffer, 1);
691
631
  } else {
692
-
693
- newIndices = geometry.getIndex().clone();
694
- newIndices.setArray( newIndexBuffer );
695
-
632
+ newIndices = geometry.getIndex().clone();
633
+ newIndices.setArray(newIndexBuffer);
696
634
  }
697
635
 
698
- result.setIndex( newIndices );
636
+ result.setIndex(newIndices);
699
637
 
700
638
  return result;
701
- }
639
+ };
702
640
 
703
641
  function PhongToToon(materialIn) {
704
- if (materialIn.isMeshPhongMaterial) {
705
- let material = new THREE.MeshToonMaterial({
706
- color : materialIn.color.clone(),
707
- vertexColors : materialIn.vertexColors,
708
- transparent : materialIn.transparent,
709
- opacity : materialIn.opacity,
710
- side : materialIn.side
711
- });
712
- if (materialIn.map)
713
- material.map = materialIn.map;
714
- return material;
715
- }
716
-
717
- return materialIn;
642
+ if (materialIn.isMeshPhongMaterial) {
643
+ let material = new THREE.MeshToonMaterial({
644
+ color: materialIn.color.clone(),
645
+ vertexColors: materialIn.vertexColors,
646
+ transparent: materialIn.transparent,
647
+ opacity: materialIn.opacity,
648
+ side: materialIn.side,
649
+ });
650
+ if (materialIn.map) material.map = materialIn.map;
651
+ return material;
652
+ }
653
+
654
+ return materialIn;
718
655
  }
719
656
 
720
657
  /**
@@ -722,21 +659,21 @@ function PhongToToon(materialIn) {
722
659
  * and initial coords.
723
660
  */
724
661
  function createBufferGeometry(length, coords) {
725
- if (coords && (length >= coords.length)) {
726
- const geometry = new THREE.BufferGeometry()
662
+ if (coords && length >= coords.length) {
663
+ const geometry = new THREE.BufferGeometry();
727
664
  const vertices = new Float32Array(length * 3);
728
665
  let i = 0;
729
- coords.forEach(coord => {
666
+ coords.forEach((coord) => {
730
667
  vertices[i++] = coord[0];
731
668
  vertices[i++] = coord[1];
732
669
  vertices[i++] = coord[2];
733
670
  });
734
- geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
671
+ geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
735
672
  geometry.setDrawRange(0, coords.length);
736
673
  return geometry;
737
674
  }
738
675
  return undefined;
739
- };
676
+ }
740
677
 
741
678
  /*
742
679
  * WebGPURenderer converts 16 bit index buffers to 32 bit and keeps the
@@ -830,23 +767,25 @@ function createNewSpriteText(text, height, colour, font, pixel, weight) {
830
767
  */
831
768
  function isRegionGroup(regionPath, groupName, comparePath) {
832
769
  if (comparePath) {
833
- const region = regionPath ? regionPath : "";
834
- const group = groupName ? groupName : "";
770
+ const region = regionPath ? regionPath : '';
771
+ const group = groupName ? groupName : '';
835
772
  const n = comparePath.lastIndexOf('/');
836
773
  if (n > -1) {
837
774
  let r = undefined;
838
775
  let g = undefined;
839
776
  r = comparePath.substring(0, n);
840
777
  g = comparePath.substring(n + 1);
841
- if (r === "*" || r === "**" || r.toLowerCase() === region.toLowerCase()) {
842
- if (g === "*" || g === "**" || g.toLowerCase() === group.toLowerCase()) {
778
+ if (r === '*' || r === '**' || r.toLowerCase() === region.toLowerCase()) {
779
+ if (g === '*' || g === '**' || g.toLowerCase() === group.toLowerCase()) {
843
780
  return true;
844
781
  }
845
782
  }
846
783
  } else {
847
784
  //one single value if one of the region / group matches
848
- if (region.toLowerCase() === comparePath.toLowerCase() ||
849
- group.toLowerCase() === comparePath.toLowerCase()) {
785
+ if (
786
+ region.toLowerCase() === comparePath.toLowerCase() ||
787
+ group.toLowerCase() === comparePath.toLowerCase()
788
+ ) {
850
789
  return true;
851
790
  }
852
791
  }
@@ -869,7 +808,7 @@ function removeVertexAtIndex(geometry, index, maintainLength) {
869
808
  // Helper to remove elements from a typed array
870
809
  const removeElements = (attribute, name) => {
871
810
  const array = attribute.array;
872
- if (array.length < (start + deleteCount)) {
811
+ if (array.length < start + deleteCount) {
873
812
  return false;
874
813
  }
875
814
  if (maintainLength) {
@@ -894,8 +833,8 @@ function removeVertexAtIndex(geometry, index, maintainLength) {
894
833
 
895
834
  // If the geometry is indexed, the index buffer will also need adjustment
896
835
  if (geometry.index !== null) {
897
- // This is more complex, typically easier to work with non-indexed geometry when modifying vertices
898
- console.warn("Removing vertices from indexed geometry requires index buffer recalculation.");
836
+ // This is more complex, typically easier to work with non-indexed geometry when modifying vertices
837
+ console.warn('Removing vertices from indexed geometry requires index buffer recalculation.');
899
838
  }
900
839
 
901
840
  return removed;
@@ -985,5 +924,4 @@ export {
985
924
  removeVertexAtIndex,
986
925
  updateMorphColorAttribute,
987
926
  toBufferGeometry,
988
- };
989
-
927
+ };