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
@@ -16,550 +16,440 @@ const LoaderUtils = THREE.LoaderUtils;
16
16
  * @author alteredq / http://alteredqualia.com/
17
17
  */
18
18
 
19
- function JSONLoader( manager ) {
19
+ function JSONLoader(manager) {
20
+ if (typeof manager === 'boolean') {
21
+ console.warn('THREE.JSONLoader: showStatus parameter has been removed from constructor.');
22
+ manager = undefined;
23
+ }
20
24
 
21
- if ( typeof manager === 'boolean' ) {
25
+ this.manager = manager !== undefined ? manager : DefaultLoadingManager;
22
26
 
23
- console.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );
24
- manager = undefined;
25
-
26
- }
27
-
28
- this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
29
-
30
- this.withCredentials = false;
31
-
32
- this.paramsString = "";
27
+ this.withCredentials = false;
33
28
 
29
+ this.paramsString = '';
34
30
  }
35
31
 
36
- Object.assign( JSONLoader.prototype, {
37
-
38
- load: function ( url, onLoad, onProgress, onError ) {
32
+ Object.assign(JSONLoader.prototype, {
33
+ load: function (url, onLoad, onProgress, onError) {
34
+ var scope = this;
39
35
 
40
- var scope = this;
36
+ var texturePath =
37
+ this.texturePath && typeof this.texturePath === 'string'
38
+ ? this.texturePath
39
+ : LoaderUtils.extractUrlBase(url);
41
40
 
42
- var texturePath = this.texturePath && ( typeof this.texturePath === 'string' ) ? this.texturePath : LoaderUtils.extractUrlBase( url );
41
+ var loader = new FileLoader(this.manager);
43
42
 
44
- var loader = new FileLoader( this.manager );
45
-
46
- const params = url.split("?");
43
+ const params = url.split('?');
47
44
 
48
45
  //There are parameters, add them to the target
49
46
  if (url.length === 2) {
50
-
51
- this.paramsString = paramsStrings[1];
52
-
47
+ this.paramsString = paramsStrings[1];
53
48
  } else {
54
-
55
- this.paramsString = "";
56
-
49
+ this.paramsString = '';
57
50
  }
58
51
 
59
- loader.setWithCredentials( this.withCredentials );
60
- loader.load( url, function ( text ) {
61
-
62
- var json = undefined;
63
- try {
64
- json = JSON.parse(text);
65
- } catch (e) {
66
- console.error("The loader has encountered an error while parsing the content of a resource.");
67
- if (onError) {
68
- onError({responseURL: url});
69
- return;
70
- }
71
- }
72
-
73
- var metadata = json.metadata;
74
-
75
- if ( metadata !== undefined ) {
76
-
77
- var type = metadata.type;
78
-
79
- if ( type !== undefined ) {
80
-
81
- if ( type.toLowerCase() === 'object' ) {
82
-
83
- console.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );
84
- return;
85
-
86
- }
87
-
88
- }
89
-
90
- }
91
-
92
- if (scope && scope.parse) {
93
- try {
94
- var object = scope.parse( json, texturePath );
95
- onLoad( object.geometry, object.materials );
96
- } catch (e) {
97
- console.error("The loader has encountered aon loading the geometry");
98
- console.error(e);
99
- if (onError) {
100
- onError({responseURL: url});
101
- return;
102
- }
103
- }
104
- }
105
- }, onProgress, onError );
106
-
107
- },
108
-
109
- setTexturePath: function ( value ) {
110
-
111
- this.texturePath = value;
112
-
113
- },
114
-
115
- parse: ( function () {
116
-
117
- function isBitSet( value, position ) {
118
-
119
- return value & ( 1 << position );
120
-
121
- }
122
-
123
- //Walks json.faces once, decoding each triangle (quads are split into two)
124
- //into a flat vertex-index list plus a parallel per-triangle materialIndex,
125
- //in exactly the order the legacy Face3-based parser used to push faces -
126
- //that order is what computeGroups() below depends on.
127
- function parseFaces( json ) {
128
-
129
- const faces = json.faces;
130
-
131
- let nUvLayers = 0;
132
- if ( json.uvs !== undefined ) {
133
-
134
- for ( let i = 0; i < json.uvs.length; i ++ ) {
135
-
136
- if ( json.uvs[ i ].length ) nUvLayers ++;
137
-
138
- }
139
-
140
- }
141
-
142
- const indices = [];
143
- const materialIndices = [];
144
-
145
- let offset = 0;
146
- const zLength = faces.length;
147
-
148
- while ( offset < zLength ) {
149
-
150
- const type = faces[ offset ++ ];
151
-
152
- const isQuad = isBitSet( type, 0 );
153
- const hasMaterial = isBitSet( type, 1 );
154
- const hasFaceVertexUv = isBitSet( type, 3 );
155
- const hasFaceNormal = isBitSet( type, 4 );
156
- const hasFaceVertexNormal = isBitSet( type, 5 );
157
- const hasFaceColor = isBitSet( type, 6 );
158
- const hasFaceVertexColor = isBitSet( type, 7 );
159
-
160
- let a, b, c;
161
-
162
- if ( isQuad ) {
163
-
164
- const v0 = faces[ offset ];
165
- const v1 = faces[ offset + 1 ];
166
- const v2 = faces[ offset + 2 ];
167
- const v3 = faces[ offset + 3 ];
168
-
169
- offset += 4;
170
-
171
- let materialIndex = 0;
172
- if ( hasMaterial ) {
173
-
174
- materialIndex = faces[ offset ++ ];
52
+ loader.setWithCredentials(this.withCredentials);
53
+ loader.load(
54
+ url,
55
+ function (text) {
56
+ var json = undefined;
57
+ try {
58
+ json = JSON.parse(text);
59
+ } catch (e) {
60
+ console.error(
61
+ 'The loader has encountered an error while parsing the content of a resource.',
62
+ );
63
+ if (onError) {
64
+ onError({ responseURL: url });
65
+ return;
66
+ }
67
+ }
175
68
 
176
- }
69
+ var metadata = json.metadata;
177
70
 
178
- if ( hasFaceVertexUv ) {
71
+ if (metadata !== undefined) {
72
+ var type = metadata.type;
179
73
 
180
- offset += nUvLayers * 4;
74
+ if (type !== undefined) {
75
+ if (type.toLowerCase() === 'object') {
76
+ console.error(
77
+ 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.',
78
+ );
79
+ return;
80
+ }
81
+ }
82
+ }
83
+
84
+ if (scope && scope.parse) {
85
+ try {
86
+ var object = scope.parse(json, texturePath);
87
+ onLoad(object.geometry, object.materials);
88
+ } catch (e) {
89
+ console.error('The loader has encountered aon loading the geometry');
90
+ console.error(e);
91
+ if (onError) {
92
+ onError({ responseURL: url });
93
+ return;
94
+ }
95
+ }
96
+ }
97
+ },
98
+ onProgress,
99
+ onError,
100
+ );
101
+ },
102
+
103
+ setTexturePath: function (value) {
104
+ this.texturePath = value;
105
+ },
106
+
107
+ parse: (function () {
108
+ function isBitSet(value, position) {
109
+ return value & (1 << position);
110
+ }
181
111
 
182
- }
112
+ //Walks json.faces once, decoding each triangle (quads are split into two)
113
+ //into a flat vertex-index list plus a parallel per-triangle materialIndex,
114
+ //in exactly the order the legacy Face3-based parser used to push faces -
115
+ //that order is what computeGroups() below depends on.
116
+ function parseFaces(json) {
117
+ const faces = json.faces;
118
+
119
+ let nUvLayers = 0;
120
+ if (json.uvs !== undefined) {
121
+ for (let i = 0; i < json.uvs.length; i++) {
122
+ if (json.uvs[i].length) nUvLayers++;
123
+ }
124
+ }
125
+
126
+ const indices = [];
127
+ const materialIndices = [];
128
+
129
+ let offset = 0;
130
+ const zLength = faces.length;
131
+
132
+ while (offset < zLength) {
133
+ const type = faces[offset++];
134
+
135
+ const isQuad = isBitSet(type, 0);
136
+ const hasMaterial = isBitSet(type, 1);
137
+ const hasFaceVertexUv = isBitSet(type, 3);
138
+ const hasFaceNormal = isBitSet(type, 4);
139
+ const hasFaceVertexNormal = isBitSet(type, 5);
140
+ const hasFaceColor = isBitSet(type, 6);
141
+ const hasFaceVertexColor = isBitSet(type, 7);
142
+
143
+ let a, b, c;
144
+
145
+ if (isQuad) {
146
+ const v0 = faces[offset];
147
+ const v1 = faces[offset + 1];
148
+ const v2 = faces[offset + 2];
149
+ const v3 = faces[offset + 3];
150
+
151
+ offset += 4;
152
+
153
+ let materialIndex = 0;
154
+ if (hasMaterial) {
155
+ materialIndex = faces[offset++];
156
+ }
183
157
 
184
- if ( hasFaceNormal ) offset += 1;
185
- if ( hasFaceVertexNormal ) offset += 4;
186
- if ( hasFaceColor ) offset += 1;
187
- if ( hasFaceVertexColor ) offset += 4;
158
+ if (hasFaceVertexUv) {
159
+ offset += nUvLayers * 4;
160
+ }
188
161
 
189
- indices.push( v0, v1, v3 );
190
- materialIndices.push( materialIndex );
162
+ if (hasFaceNormal) offset += 1;
163
+ if (hasFaceVertexNormal) offset += 4;
164
+ if (hasFaceColor) offset += 1;
165
+ if (hasFaceVertexColor) offset += 4;
191
166
 
192
- indices.push( v1, v2, v3 );
193
- materialIndices.push( materialIndex );
167
+ indices.push(v0, v1, v3);
168
+ materialIndices.push(materialIndex);
194
169
 
195
- continue;
170
+ indices.push(v1, v2, v3);
171
+ materialIndices.push(materialIndex);
196
172
 
197
- }
173
+ continue;
174
+ }
198
175
 
199
- a = faces[ offset ++ ];
200
- b = faces[ offset ++ ];
201
- c = faces[ offset ++ ];
176
+ a = faces[offset++];
177
+ b = faces[offset++];
178
+ c = faces[offset++];
202
179
 
203
180
  //A hack to get things going
204
181
  if (!b) b = a;
205
182
  if (!c) c = b;
206
183
 
207
- let materialIndex = 0;
208
- if ( hasMaterial ) {
209
-
210
- materialIndex = faces[ offset ++ ];
211
-
212
- }
213
-
214
- if ( hasFaceVertexUv ) {
215
-
216
- offset += nUvLayers * 3;
217
-
218
- }
219
-
220
- if ( hasFaceNormal ) offset += 1;
221
- if ( hasFaceVertexNormal ) offset += 3;
222
- if ( hasFaceColor ) offset += 1;
223
- if ( hasFaceVertexColor ) offset += 3;
224
-
225
- indices.push( a, b, c );
226
- materialIndices.push( materialIndex );
227
-
228
- }
229
-
230
- return { indices, materialIndices };
231
-
232
- }
233
-
234
- //Material-index run-length groups over the triangle list, matching
235
- //the legacy Geometry.prototype.computeGroups() this replaced.
236
- function computeGroups( materialIndices ) {
237
-
238
- const groups = [];
239
- let group;
240
- let materialIndex = undefined;
241
-
242
- for ( let i = 0; i < materialIndices.length; i ++ ) {
243
-
244
- if ( materialIndices[ i ] !== materialIndex ) {
245
-
246
- materialIndex = materialIndices[ i ];
247
-
248
- if ( group !== undefined ) {
249
-
250
- group.count = ( i * 3 ) - group.start;
251
- groups.push( group );
252
-
253
- }
254
-
255
- group = { start: i * 3, materialIndex: materialIndex };
256
-
257
- }
258
-
259
- }
260
-
261
- if ( group !== undefined ) {
262
-
263
- group.count = ( materialIndices.length * 3 ) - group.start;
264
- groups.push( group );
265
-
266
- }
184
+ let materialIndex = 0;
185
+ if (hasMaterial) {
186
+ materialIndex = faces[offset++];
187
+ }
267
188
 
268
- return groups;
189
+ if (hasFaceVertexUv) {
190
+ offset += nUvLayers * 3;
191
+ }
269
192
 
270
- }
193
+ if (hasFaceNormal) offset += 1;
194
+ if (hasFaceVertexNormal) offset += 3;
195
+ if (hasFaceColor) offset += 1;
196
+ if (hasFaceVertexColor) offset += 3;
271
197
 
272
- //Computes per-vertex normals for a morph target's position set by
273
- //reusing the shared index and the standard BufferGeometry algorithm,
274
- //instead of hand-rolling face/vertex normal averaging.
275
- function computeMorphNormalAttribute( positionAttribute, indices ) {
198
+ indices.push(a, b, c);
199
+ materialIndices.push(materialIndex);
200
+ }
276
201
 
277
- const scratch = new BufferGeometry();
278
- scratch.setIndex( indices );
279
- scratch.setAttribute( 'position', positionAttribute );
280
- scratch.computeVertexNormals();
281
-
282
- const normalAttribute = scratch.getAttribute( 'normal' );
283
- normalAttribute.name = positionAttribute.name;
284
- return normalAttribute;
285
-
286
- }
287
-
288
- function parseMorphTargets( json, scale ) {
289
-
290
- const morphPositions = [];
291
-
292
- if ( json.morphTargets !== undefined ) {
293
-
294
- for ( let i = 0, l = json.morphTargets.length; i < l; i ++ ) {
295
-
296
- const srcVertices = json.morphTargets[ i ].vertices;
297
- const array = new Float32Array( srcVertices.length );
298
-
299
- for ( let v = 0, vl = srcVertices.length; v < vl; v ++ ) {
300
-
301
- array[ v ] = srcVertices[ v ] * scale;
302
-
303
- }
304
-
305
- const attribute = new BufferAttribute( array, 3 );
306
- attribute.name = json.morphTargets[ i ].name;
307
- morphPositions.push( attribute );
308
-
309
- }
310
-
311
- }
312
-
313
- const morphNormals = [];
314
-
315
- if ( json.morphNormals !== undefined ) {
316
-
317
- for ( let i = 0, l = json.morphNormals.length; i < l; i ++ ) {
318
-
319
- if ( morphPositions[ i ] ) {
320
-
321
- const srcNormals = json.morphNormals[ i ].normals;
322
- const array = Float32Array.from( srcNormals );
323
-
324
- const attribute = new BufferAttribute( array, 3 );
325
- attribute.name = morphPositions[ i ].name;
326
- morphNormals[ i ] = attribute;
327
-
328
- }
329
-
330
- }
331
-
332
- }
333
-
334
- return { morphPositions, morphNormals };
335
-
336
- }
337
-
338
- //Reproduces copyMorphColorsToIndexedBufferGeometry()/getColorsRGB() from
339
- //src/utilities.js exactly (that path has no test coverage today, so the
340
- //arithmetic - odd as some of it looks - is ported unchanged rather than
341
- //redesigned here).
342
- function parseMorphColors( json ) {
343
-
344
- if ( json.morphColors === undefined ) return undefined;
345
-
346
- const morphAttributes = [];
347
-
348
- for ( let i = 0, l = json.morphColors.length; i < l; i ++ ) {
349
-
350
- const srcColors = json.morphColors[ i ].colors;
351
- const colors = [];
352
-
353
- for ( let c = 0, cl = srcColors.length; c < cl; c += 3 ) {
354
-
355
- const color = new Color( 0xffaa00 );
356
- color.setRGB( srcColors[ c ], srcColors[ c + 1 ], srcColors[ c + 2 ] );
357
- colors.push( color );
358
-
359
- }
360
-
361
- const colorArray = [];
362
-
363
- for ( let j = 0, jl = colors.length * 3; j < jl; j ++ ) {
364
-
365
- const rgb = getColorsRGB( colors, j );
366
- colorArray.push( rgb[ 0 ], rgb[ 1 ], rgb[ 2 ] );
367
-
368
- }
369
-
370
- const attribute = new Float32BufferAttribute( colorArray, 3 );
371
- attribute.name = json.morphColors[ i ].name;
372
- morphAttributes.push( attribute );
373
-
374
- }
375
-
376
- return morphAttributes;
377
-
378
- }
379
-
380
- return function parse( json, texturePath ) {
381
-
382
- if ( json.data !== undefined ) {
383
-
384
- // Geometry 4.0 spec
385
- json = json.data;
386
-
387
- }
388
-
389
- const scale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;
390
-
391
- const srcVertices = json.vertices;
392
- const vertexCount = srcVertices.length / 3;
393
-
394
- const positions = new Float32Array( srcVertices.length );
395
- for ( let i = 0, l = srcVertices.length; i < l; i ++ ) {
396
-
397
- positions[ i ] = srcVertices[ i ] * scale;
398
-
399
- }
202
+ return { indices, materialIndices };
203
+ }
400
204
 
401
- const geometry = new BufferGeometry();
402
- geometry.setAttribute( 'position', new BufferAttribute( positions, 3 ) );
205
+ //Material-index run-length groups over the triangle list, matching
206
+ //the legacy Geometry.prototype.computeGroups() this replaced.
207
+ function computeGroups(materialIndices) {
208
+ const groups = [];
209
+ let group;
210
+ let materialIndex = undefined;
403
211
 
404
- if ( json.normals !== undefined && json.normals.length > 0 ) {
212
+ for (let i = 0; i < materialIndices.length; i++) {
213
+ if (materialIndices[i] !== materialIndex) {
214
+ materialIndex = materialIndices[i];
405
215
 
406
- geometry.setAttribute( 'normal', new BufferAttribute( Float32Array.from( json.normals ), 3 ) );
216
+ if (group !== undefined) {
217
+ group.count = i * 3 - group.start;
218
+ groups.push(group);
219
+ }
407
220
 
408
- }
221
+ group = { start: i * 3, materialIndex: materialIndex };
222
+ }
223
+ }
409
224
 
410
- if ( json.uvs !== undefined ) {
225
+ if (group !== undefined) {
226
+ group.count = materialIndices.length * 3 - group.start;
227
+ groups.push(group);
228
+ }
411
229
 
412
- if ( json.uvs[ 0 ] && json.uvs[ 0 ].length > 0 ) {
230
+ return groups;
231
+ }
413
232
 
414
- geometry.setAttribute( 'uv', new BufferAttribute( Float32Array.from( json.uvs[ 0 ] ), 2 ) );
233
+ //Computes per-vertex normals for a morph target's position set by
234
+ //reusing the shared index and the standard BufferGeometry algorithm,
235
+ //instead of hand-rolling face/vertex normal averaging.
236
+ function computeMorphNormalAttribute(positionAttribute, indices) {
237
+ const scratch = new BufferGeometry();
238
+ scratch.setIndex(indices);
239
+ scratch.setAttribute('position', positionAttribute);
240
+ scratch.computeVertexNormals();
241
+
242
+ const normalAttribute = scratch.getAttribute('normal');
243
+ normalAttribute.name = positionAttribute.name;
244
+ return normalAttribute;
245
+ }
415
246
 
416
- }
247
+ function parseMorphTargets(json, scale) {
248
+ const morphPositions = [];
417
249
 
418
- if ( json.uvs[ 1 ] && json.uvs[ 1 ].length > 0 ) {
250
+ if (json.morphTargets !== undefined) {
251
+ for (let i = 0, l = json.morphTargets.length; i < l; i++) {
252
+ const srcVertices = json.morphTargets[i].vertices;
253
+ const array = new Float32Array(srcVertices.length);
419
254
 
420
- geometry.setAttribute( 'uv2', new BufferAttribute( Float32Array.from( json.uvs[ 1 ] ), 2 ) );
255
+ for (let v = 0, vl = srcVertices.length; v < vl; v++) {
256
+ array[v] = srcVertices[v] * scale;
257
+ }
421
258
 
422
- }
259
+ const attribute = new BufferAttribute(array, 3);
260
+ attribute.name = json.morphTargets[i].name;
261
+ morphPositions.push(attribute);
262
+ }
263
+ }
423
264
 
424
- }
265
+ const morphNormals = [];
425
266
 
426
- if ( json.colors !== undefined && json.colors.length > 0 ) {
267
+ if (json.morphNormals !== undefined) {
268
+ for (let i = 0, l = json.morphNormals.length; i < l; i++) {
269
+ if (morphPositions[i]) {
270
+ const srcNormals = json.morphNormals[i].normals;
271
+ const array = Float32Array.from(srcNormals);
427
272
 
428
- const colorArray = new Float32Array( json.colors.length * 3 );
273
+ const attribute = new BufferAttribute(array, 3);
274
+ attribute.name = morphPositions[i].name;
275
+ morphNormals[i] = attribute;
276
+ }
277
+ }
278
+ }
429
279
 
430
- for ( let i = 0, l = json.colors.length; i < l; i ++ ) {
280
+ return { morphPositions, morphNormals };
281
+ }
431
282
 
432
- const color = new Color( json.colors[ i ] );
433
- colorArray[ i * 3 ] = color.r;
434
- colorArray[ i * 3 + 1 ] = color.g;
435
- colorArray[ i * 3 + 2 ] = color.b;
283
+ //Reproduces copyMorphColorsToIndexedBufferGeometry()/getColorsRGB() from
284
+ //src/utilities.js exactly (that path has no test coverage today, so the
285
+ //arithmetic - odd as some of it looks - is ported unchanged rather than
286
+ //redesigned here).
287
+ function parseMorphColors(json) {
288
+ if (json.morphColors === undefined) return undefined;
436
289
 
437
- }
290
+ const morphAttributes = [];
438
291
 
439
- geometry.setAttribute( 'color', new BufferAttribute( colorArray, 3 ) );
292
+ for (let i = 0, l = json.morphColors.length; i < l; i++) {
293
+ const srcColors = json.morphColors[i].colors;
294
+ const colors = [];
440
295
 
441
- } else {
296
+ for (let c = 0, cl = srcColors.length; c < cl; c += 3) {
297
+ const color = new Color(0xffaa00);
298
+ color.setRGB(srcColors[c], srcColors[c + 1], srcColors[c + 2]);
299
+ colors.push(color);
300
+ }
442
301
 
443
- const colorArray = new Float32Array( vertexCount * 3 ).fill( 1.0 );
444
- geometry.setAttribute( 'color', new BufferAttribute( colorArray, 3 ) );
302
+ const colorArray = [];
445
303
 
446
- }
304
+ for (let j = 0, jl = colors.length * 3; j < jl; j++) {
305
+ const rgb = getColorsRGB(colors, j);
306
+ colorArray.push(rgb[0], rgb[1], rgb[2]);
307
+ }
447
308
 
448
- const { indices, materialIndices } = parseFaces( json );
309
+ const attribute = new Float32BufferAttribute(colorArray, 3);
310
+ attribute.name = json.morphColors[i].name;
311
+ morphAttributes.push(attribute);
312
+ }
449
313
 
450
- if ( indices.length > 0 ) {
314
+ return morphAttributes;
315
+ }
451
316
 
452
- geometry.setIndex( indices );
453
- geometry.groups = computeGroups( materialIndices );
317
+ return function parse(json, texturePath) {
318
+ if (json.data !== undefined) {
319
+ // Geometry 4.0 spec
320
+ json = json.data;
321
+ }
454
322
 
455
- }
323
+ const scale = json.scale !== undefined ? 1.0 / json.scale : 1.0;
456
324
 
457
- const { morphPositions, morphNormals } = parseMorphTargets( json, scale );
325
+ const srcVertices = json.vertices;
326
+ const vertexCount = srcVertices.length / 3;
458
327
 
459
- if ( morphPositions.length > 0 ) {
328
+ const positions = new Float32Array(srcVertices.length);
329
+ for (let i = 0, l = srcVertices.length; i < l; i++) {
330
+ positions[i] = srcVertices[i] * scale;
331
+ }
460
332
 
461
- geometry.morphAttributes.position = morphPositions;
333
+ const geometry = new BufferGeometry();
334
+ geometry.setAttribute('position', new BufferAttribute(positions, 3));
462
335
 
463
- const resolvedMorphNormals = [];
336
+ if (json.normals !== undefined && json.normals.length > 0) {
337
+ geometry.setAttribute('normal', new BufferAttribute(Float32Array.from(json.normals), 3));
338
+ }
464
339
 
465
- for ( let i = 0; i < morphPositions.length; i ++ ) {
340
+ if (json.uvs !== undefined) {
341
+ if (json.uvs[0] && json.uvs[0].length > 0) {
342
+ geometry.setAttribute('uv', new BufferAttribute(Float32Array.from(json.uvs[0]), 2));
343
+ }
466
344
 
467
- if ( morphNormals[ i ] ) {
345
+ if (json.uvs[1] && json.uvs[1].length > 0) {
346
+ geometry.setAttribute('uv2', new BufferAttribute(Float32Array.from(json.uvs[1]), 2));
347
+ }
348
+ }
468
349
 
469
- resolvedMorphNormals.push( morphNormals[ i ] );
350
+ if (json.colors !== undefined && json.colors.length > 0) {
351
+ const colorArray = new Float32Array(json.colors.length * 3);
470
352
 
471
- } else if ( indices.length > 0 ) {
353
+ for (let i = 0, l = json.colors.length; i < l; i++) {
354
+ const color = new Color(json.colors[i]);
355
+ colorArray[i * 3] = color.r;
356
+ colorArray[i * 3 + 1] = color.g;
357
+ colorArray[i * 3 + 2] = color.b;
358
+ }
472
359
 
473
- resolvedMorphNormals.push( computeMorphNormalAttribute( morphPositions[ i ], indices ) );
360
+ geometry.setAttribute('color', new BufferAttribute(colorArray, 3));
361
+ } else {
362
+ const colorArray = new Float32Array(vertexCount * 3).fill(1.0);
363
+ geometry.setAttribute('color', new BufferAttribute(colorArray, 3));
364
+ }
474
365
 
475
- }
366
+ const { indices, materialIndices } = parseFaces(json);
476
367
 
477
- }
368
+ if (indices.length > 0) {
369
+ geometry.setIndex(indices);
370
+ geometry.groups = computeGroups(materialIndices);
371
+ }
478
372
 
479
- if ( resolvedMorphNormals.length > 0 ) {
373
+ const { morphPositions, morphNormals } = parseMorphTargets(json, scale);
480
374
 
481
- geometry.morphAttributes.normal = resolvedMorphNormals;
375
+ if (morphPositions.length > 0) {
376
+ geometry.morphAttributes.position = morphPositions;
482
377
 
483
- }
378
+ const resolvedMorphNormals = [];
484
379
 
485
- }
380
+ for (let i = 0; i < morphPositions.length; i++) {
381
+ if (morphNormals[i]) {
382
+ resolvedMorphNormals.push(morphNormals[i]);
383
+ } else if (indices.length > 0) {
384
+ resolvedMorphNormals.push(computeMorphNormalAttribute(morphPositions[i], indices));
385
+ }
386
+ }
486
387
 
487
- const morphColorAttributes = parseMorphColors( json );
388
+ if (resolvedMorphNormals.length > 0) {
389
+ geometry.morphAttributes.normal = resolvedMorphNormals;
390
+ }
391
+ }
488
392
 
489
- if ( morphColorAttributes !== undefined ) {
393
+ const morphColorAttributes = parseMorphColors(json);
490
394
 
491
- geometry.morphAttributes.color = morphColorAttributes;
395
+ if (morphColorAttributes !== undefined) {
396
+ geometry.morphAttributes.color = morphColorAttributes;
492
397
 
493
- //Support cases where only morphColorAttributes is available
398
+ //Support cases where only morphColorAttributes is available
494
399
  //without morphPositionAttributes
495
- if ( geometry.morphAttributes.position === undefined ) {
496
-
497
- const basePosition = geometry.getAttribute( 'position' );
498
-
499
- geometry.morphAttributes.position = morphColorAttributes.map( ( colorAttribute ) => {
500
-
501
- const positionAttribute = new BufferAttribute( basePosition.array, basePosition.itemSize );
502
-
503
- positionAttribute.name = colorAttribute.name;
504
-
505
- return positionAttribute;
506
-
507
- } );
508
-
509
- }
510
-
511
- }
512
-
513
- geometry.computeBoundingBox();
514
- geometry.computeBoundingSphere();
400
+ if (geometry.morphAttributes.position === undefined) {
401
+ const basePosition = geometry.getAttribute('position');
515
402
 
516
- if ( json.materials === undefined || json.materials.length === 0 ) {
403
+ geometry.morphAttributes.position = morphColorAttributes.map((colorAttribute) => {
404
+ const positionAttribute = new BufferAttribute(
405
+ basePosition.array,
406
+ basePosition.itemSize,
407
+ );
517
408
 
518
- return { geometry: geometry };
409
+ positionAttribute.name = colorAttribute.name;
519
410
 
520
- } else {
411
+ return positionAttribute;
412
+ });
413
+ }
414
+ }
521
415
 
522
- var materials = Loader.prototype.initMaterials( json.materials, texturePath, 'Anonymous' );
416
+ geometry.computeBoundingBox();
417
+ geometry.computeBoundingSphere();
523
418
 
419
+ if (json.materials === undefined || json.materials.length === 0) {
420
+ return { geometry: geometry };
421
+ } else {
422
+ var materials = Loader.prototype.initMaterials(json.materials, texturePath, 'Anonymous');
524
423
 
525
- if (json.materials[0].video) {
526
-
527
- var fullPath = texturePath + json.materials[0].video;
424
+ if (json.materials[0].video) {
425
+ var fullPath = texturePath + json.materials[0].video;
528
426
 
529
427
  if (this.paramsString) {
530
-
531
428
  fullPath = fullPath + `?${this.paramsString}`;
532
-
533
429
  }
534
430
 
535
- const videoHandler = new VideoHandler(fullPath);
431
+ const videoHandler = new VideoHandler(fullPath);
536
432
 
537
- geometry._video = videoHandler;
433
+ geometry._video = videoHandler;
434
+ }
538
435
 
539
- }
540
-
541
- if (materials && materials.length > 0) {
542
- if (json.materials[0].singleSided) {
543
- materials[0].side = THREE.FrontSide;
544
- } else if (json.materials[0].flipSided){
545
- materials[0].side = THREE.BackSide;
546
- } else {
547
- materials[0].side = THREE.DoubleSide;
436
+ if (materials && materials.length > 0) {
437
+ if (json.materials[0].singleSided) {
438
+ materials[0].side = THREE.FrontSide;
439
+ } else if (json.materials[0].flipSided) {
440
+ materials[0].side = THREE.BackSide;
441
+ } else {
442
+ materials[0].side = THREE.DoubleSide;
548
443
  }
549
444
  if (json.materials[0].specularCoef) {
550
445
  materials[0].shininess = Math.floor(json.materials[0].specularCoef / 3);
551
446
  }
552
- }
553
-
554
- return { geometry: geometry, materials: materials };
555
-
556
- }
557
-
558
- };
559
-
560
- } )()
561
-
562
- } );
447
+ }
563
448
 
449
+ return { geometry: geometry, materials: materials };
450
+ }
451
+ };
452
+ })(),
453
+ });
564
454
 
565
455
  export { JSONLoader };