zincjs 2.4.0 → 2.4.1-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/build/zinc.js +3 -486
  2. package/build/zinc.js.map +1 -1
  3. package/package.json +6 -7
  4. package/src/controls.js +1 -1
  5. package/src/geometryCSG.js +1 -1
  6. package/src/glyphsetCSG.js +1 -1
  7. package/src/loaders/GLTFToZincJSLoader.js +1 -1
  8. package/src/loaders/JSONLoader.js +216 -371
  9. package/src/loaders/OBJLoader.js +1 -1
  10. package/src/loaders/STLLoader.js +1 -1
  11. package/src/loaders/niftiReader.js +6 -4
  12. package/src/loaders/primitivesLoader.js +7 -9
  13. package/src/minimap.js +1 -1
  14. package/src/primitives/geometry.js +11 -29
  15. package/src/primitives/glyph.js +1 -1
  16. package/src/primitives/glyphset.js +2 -4
  17. package/src/primitives/label.js +1 -1
  18. package/src/primitives/lines.js +12 -5
  19. package/src/primitives/lines2.js +4 -8
  20. package/src/primitives/lod.js +9 -3
  21. package/src/primitives/marker.js +1 -1
  22. package/src/primitives/markerCluster.js +1 -1
  23. package/src/primitives/pointset.js +368 -52
  24. package/src/primitives/textureSlides.js +59 -16
  25. package/src/primitives/textureVolume.js +1 -1
  26. package/src/primitives/tubeLines.js +20 -3
  27. package/src/primitives/zincObject.js +13 -1
  28. package/src/region.js +1 -1
  29. package/src/renderer.js +36 -17
  30. package/src/scene.js +20 -8
  31. package/src/sceneLoader.js +1 -1
  32. package/src/shaders/rgbVolumeRender.js +1 -1
  33. package/src/shaders/textureSlide.js +1 -1
  34. package/src/texture/texture.js +1 -1
  35. package/src/texture/textureArray.js +9 -2
  36. package/src/three/GLTFExporter.js +55 -2
  37. package/src/three/InstancedPoints.js +73 -0
  38. package/src/three/Loader.js +1 -1
  39. package/src/three/line/Line.js +1 -1
  40. package/src/three/line/LineSegments.js +1 -1
  41. package/src/three/line/LineSegments2.js +24 -39
  42. package/src/three/line/LineSegmentsGeometry.js +1 -1
  43. package/src/tls/morphColorMaterial.js +65 -0
  44. package/src/tls/pointsMaterial.js +79 -0
  45. package/src/tls/textureSlides.js +126 -0
  46. package/src/utilities.js +47 -70
  47. package/src/videoHandler.js +1 -2
  48. package/src/workers/geometryCSG.worker.js +1 -1
  49. package/src/workers/geometryCSGInternal.js +1 -1
  50. package/src/zinc.js +1 -1
  51. package/vite.config.js +3 -1
  52. package/src/primitives/augmentShader.js +0 -45
  53. package/src/three/Geometry.js +0 -2176
  54. package/src/three/Points.js +0 -224
  55. package/src/three/line/LineMaterial.js +0 -726
@@ -1,17 +1,15 @@
1
- import * as THREE from 'three';
2
- import { Face3 } from '../three/Geometry';
3
- import { Geometry } from '../three/Geometry';
1
+ import * as THREE from 'three/webgpu';
4
2
  import { Loader } from '../three/Loader';
5
3
  import { VideoHandler } from '../videoHandler';
4
+ import { getColorsRGB } from '../utilities';
6
5
 
7
- const AnimationClip = THREE.AnimationClip;
6
+ const BufferAttribute = THREE.BufferAttribute;
7
+ const BufferGeometry = THREE.BufferGeometry;
8
8
  const Color = THREE.Color;
9
9
  const DefaultLoadingManager = THREE.DefaultLoadingManager;
10
10
  const FileLoader = THREE.FileLoader;
11
+ const Float32BufferAttribute = THREE.Float32BufferAttribute;
11
12
  const LoaderUtils = THREE.LoaderUtils;
12
- const Vector2 = THREE.Vector2;
13
- const Vector3 = THREE.Vector3;
14
- const Vector4 = THREE.Vector4;
15
13
 
16
14
  /**
17
15
  * @author mrdoob / http://mrdoob.com/
@@ -116,556 +114,403 @@ Object.assign( JSONLoader.prototype, {
116
114
 
117
115
  parse: ( function () {
118
116
 
119
- function parseModel( json, geometry ) {
117
+ function isBitSet( value, position ) {
120
118
 
121
- function isBitSet( value, position ) {
119
+ return value & ( 1 << position );
122
120
 
123
- return value & ( 1 << position );
124
-
125
- }
126
-
127
- var i, j, fi,
128
-
129
- offset, zLength,
130
-
131
- colorIndex, normalIndex, uvIndex, materialIndex,
132
-
133
- type,
134
- isQuad,
135
- hasMaterial,
136
- hasFaceVertexUv,
137
- hasFaceNormal, hasFaceVertexNormal,
138
- hasFaceColor, hasFaceVertexColor,
139
-
140
- vertex, face, faceA, faceB, hex, normal,
141
-
142
- uvLayer, uv, u, v,
143
-
144
- faces = json.faces,
145
- vertices = json.vertices,
146
- normals = json.normals,
147
- colors = json.colors,
148
-
149
- scale = json.scale,
121
+ }
150
122
 
151
- nUvLayers = 0;
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 ) {
152
128
 
129
+ const faces = json.faces;
153
130
 
131
+ let nUvLayers = 0;
154
132
  if ( json.uvs !== undefined ) {
155
133
 
156
- // disregard empty arrays
157
-
158
- for ( i = 0; i < json.uvs.length; i ++ ) {
134
+ for ( let i = 0; i < json.uvs.length; i ++ ) {
159
135
 
160
136
  if ( json.uvs[ i ].length ) nUvLayers ++;
161
137
 
162
138
  }
163
139
 
164
- for ( i = 0; i < nUvLayers; i ++ ) {
165
-
166
- geometry.faceVertexUvs[ i ] = [];
167
-
168
- }
169
-
170
- }
171
-
172
- offset = 0;
173
- zLength = vertices.length;
174
-
175
- while ( offset < zLength ) {
176
-
177
- vertex = new Vector3();
178
-
179
- vertex.x = vertices[ offset ++ ] * scale;
180
- vertex.y = vertices[ offset ++ ] * scale;
181
- vertex.z = vertices[ offset ++ ] * scale;
182
-
183
- geometry.vertices.push( vertex );
184
-
185
140
  }
186
141
 
187
- offset = 0;
188
- zLength = faces.length;
189
-
190
- if (json.uvs) {
191
-
192
- for ( i = 0; i < json.uvs.length; i ++ ) {
193
-
194
- geometry.uvs[i] = [];
195
-
196
- for ( let k = 0; k < json.uvs[i].length ; k++ ) {
197
-
198
- geometry.uvs[i][k] = json.uvs[i][k];
199
-
200
- }
201
-
202
- }
203
-
204
- }
205
-
206
- if (normals) {
207
-
208
- for ( i = 0; i < normals.length; i ++ ) {
209
-
210
- geometry.normals[i] = normals[i];
211
-
212
- }
213
-
214
- }
215
-
216
- if (colors) {
217
-
218
- for ( i = 0; i < colors.length; i ++ ) {
219
-
220
- geometry.colors[i] = colors[i];
221
-
222
- }
223
-
224
- }
142
+ const indices = [];
143
+ const materialIndices = [];
225
144
 
145
+ let offset = 0;
146
+ const zLength = faces.length;
226
147
 
227
148
  while ( offset < zLength ) {
228
149
 
229
- type = faces[ offset ++ ];
150
+ const type = faces[ offset ++ ];
230
151
 
231
- isQuad = isBitSet( type, 0 );
232
- hasMaterial = isBitSet( type, 1 );
233
- hasFaceVertexUv = isBitSet( type, 3 );
234
- hasFaceNormal = isBitSet( type, 4 );
235
- hasFaceVertexNormal = isBitSet( type, 5 );
236
- hasFaceColor = isBitSet( type, 6 );
237
- hasFaceVertexColor = isBitSet( type, 7 );
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 );
238
159
 
239
- // console.log("type", type, "bits", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);
160
+ let a, b, c;
240
161
 
241
162
  if ( isQuad ) {
242
163
 
243
- faceA = new Face3();
244
- faceA.a = faces[ offset ];
245
- faceA.b = faces[ offset + 1 ];
246
- faceA.c = faces[ offset + 3 ];
247
-
248
- faceB = new Face3();
249
- faceB.a = faces[ offset + 1 ];
250
- faceB.b = faces[ offset + 2 ];
251
- faceB.c = faces[ offset + 3 ];
164
+ const v0 = faces[ offset ];
165
+ const v1 = faces[ offset + 1 ];
166
+ const v2 = faces[ offset + 2 ];
167
+ const v3 = faces[ offset + 3 ];
252
168
 
253
169
  offset += 4;
254
170
 
171
+ let materialIndex = 0;
255
172
  if ( hasMaterial ) {
256
173
 
257
174
  materialIndex = faces[ offset ++ ];
258
- faceA.materialIndex = materialIndex;
259
- faceB.materialIndex = materialIndex;
260
175
 
261
176
  }
262
177
 
263
- // to get face <=> uv index correspondence
264
-
265
- fi = geometry.faces.length;
266
-
267
178
  if ( hasFaceVertexUv ) {
268
179
 
269
- for ( i = 0; i < nUvLayers; i ++ ) {
270
-
271
- uvLayer = json.uvs[ i ];
272
-
273
- geometry.faceVertexUvs[ i ][ fi ] = [];
274
- geometry.faceVertexUvs[ i ][ fi + 1 ] = [];
275
-
276
- for ( j = 0; j < 4; j ++ ) {
277
-
278
- uvIndex = faces[ offset ++ ];
279
-
280
- u = uvLayer[ uvIndex * 2 ];
281
- v = uvLayer[ uvIndex * 2 + 1 ];
282
-
283
- uv = new Vector2( u, v );
284
-
285
- if ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );
286
- if ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );
287
-
288
- }
289
-
290
- }
180
+ offset += nUvLayers * 4;
291
181
 
292
182
  }
293
183
 
294
- if ( hasFaceNormal ) {
295
-
296
- normalIndex = faces[ offset ++ ] * 3;
297
-
298
- faceA.normal.set(
299
- normals[ normalIndex ++ ],
300
- normals[ normalIndex ++ ],
301
- normals[ normalIndex ]
302
- );
303
-
304
- faceB.normal.copy( faceA.normal );
305
-
306
- }
307
-
308
- if ( hasFaceVertexNormal ) {
309
-
310
- for ( i = 0; i < 4; i ++ ) {
311
-
312
- normalIndex = faces[ offset ++ ] * 3;
184
+ if ( hasFaceNormal ) offset += 1;
185
+ if ( hasFaceVertexNormal ) offset += 4;
186
+ if ( hasFaceColor ) offset += 1;
187
+ if ( hasFaceVertexColor ) offset += 4;
313
188
 
314
- normal = new Vector3(
315
- normals[ normalIndex ++ ],
316
- normals[ normalIndex ++ ],
317
- normals[ normalIndex ]
318
- );
189
+ indices.push( v0, v1, v3 );
190
+ materialIndices.push( materialIndex );
319
191
 
192
+ indices.push( v1, v2, v3 );
193
+ materialIndices.push( materialIndex );
320
194
 
321
- if ( i !== 2 ) faceA.vertexNormals.push( normal );
322
- if ( i !== 0 ) faceB.vertexNormals.push( normal );
195
+ continue;
323
196
 
324
- }
197
+ }
325
198
 
326
- }
199
+ a = faces[ offset ++ ];
200
+ b = faces[ offset ++ ];
201
+ c = faces[ offset ++ ];
327
202
 
203
+ //A hack to get things going
204
+ if (!b) b = a;
205
+ if (!c) c = b;
328
206
 
329
- if ( hasFaceColor ) {
207
+ let materialIndex = 0;
208
+ if ( hasMaterial ) {
330
209
 
331
- colorIndex = faces[ offset ++ ];
332
- hex = colors[ colorIndex ];
210
+ materialIndex = faces[ offset ++ ];
333
211
 
334
- faceA.color.setHex( hex );
335
- faceB.color.setHex( hex );
212
+ }
336
213
 
337
- }
214
+ if ( hasFaceVertexUv ) {
338
215
 
216
+ offset += nUvLayers * 3;
339
217
 
340
- if ( hasFaceVertexColor ) {
218
+ }
341
219
 
342
- for ( i = 0; i < 4; i ++ ) {
220
+ if ( hasFaceNormal ) offset += 1;
221
+ if ( hasFaceVertexNormal ) offset += 3;
222
+ if ( hasFaceColor ) offset += 1;
223
+ if ( hasFaceVertexColor ) offset += 3;
343
224
 
344
- colorIndex = faces[ offset ++ ];
345
- hex = colors[ colorIndex ];
225
+ indices.push( a, b, c );
226
+ materialIndices.push( materialIndex );
346
227
 
347
- if ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) );
348
- if ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) );
228
+ }
349
229
 
350
- }
230
+ return { indices, materialIndices };
351
231
 
352
- }
232
+ }
353
233
 
354
- geometry.faces.push( faceA );
355
- geometry.faces.push( faceB );
234
+ //Material-index run-length groups over the triangle list, matching
235
+ //the legacy Geometry.prototype.computeGroups() this replaced.
236
+ function computeGroups( materialIndices ) {
356
237
 
357
- } else {
238
+ const groups = [];
239
+ let group;
240
+ let materialIndex = undefined;
358
241
 
359
- face = new Face3();
360
- face.a = faces[ offset ++ ];
361
- face.b = faces[ offset ++ ];
362
- face.c = faces[ offset ++ ];
242
+ for ( let i = 0; i < materialIndices.length; i ++ ) {
363
243
 
364
- //A hack to get things going
365
- if (!face.b) face.b = face.a;
366
- if (!face.c) face.c = face.b;
244
+ if ( materialIndices[ i ] !== materialIndex ) {
367
245
 
246
+ materialIndex = materialIndices[ i ];
368
247
 
369
- if ( hasMaterial ) {
248
+ if ( group !== undefined ) {
370
249
 
371
- materialIndex = faces[ offset ++ ];
372
- face.materialIndex = materialIndex;
250
+ group.count = ( i * 3 ) - group.start;
251
+ groups.push( group );
373
252
 
374
253
  }
375
254
 
376
- // to get face <=> uv index correspondence
377
-
378
- fi = geometry.faces.length;
379
-
380
- if ( hasFaceVertexUv ) {
381
-
382
- for ( i = 0; i < nUvLayers; i ++ ) {
255
+ group = { start: i * 3, materialIndex: materialIndex };
383
256
 
384
- uvLayer = json.uvs[ i ];
385
-
386
- geometry.faceVertexUvs[ i ][ fi ] = [];
387
-
388
- for ( j = 0; j < 3; j ++ ) {
257
+ }
389
258
 
390
- uvIndex = faces[ offset ++ ];
259
+ }
391
260
 
392
- u = uvLayer[ uvIndex * 2 ];
393
- v = uvLayer[ uvIndex * 2 + 1 ];
261
+ if ( group !== undefined ) {
394
262
 
395
- uv = new Vector2( u, v );
263
+ group.count = ( materialIndices.length * 3 ) - group.start;
264
+ groups.push( group );
396
265
 
397
- geometry.faceVertexUvs[ i ][ fi ].push( uv );
266
+ }
398
267
 
399
- }
268
+ return groups;
400
269
 
401
- }
270
+ }
402
271
 
403
- }
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 ) {
404
276
 
405
- if ( hasFaceNormal ) {
277
+ const scratch = new BufferGeometry();
278
+ scratch.setIndex( indices );
279
+ scratch.setAttribute( 'position', positionAttribute );
280
+ scratch.computeVertexNormals();
406
281
 
407
- normalIndex = faces[ offset ++ ] * 3;
282
+ const normalAttribute = scratch.getAttribute( 'normal' );
283
+ normalAttribute.name = positionAttribute.name;
284
+ return normalAttribute;
408
285
 
409
- face.normal.set(
410
- normals[ normalIndex ++ ],
411
- normals[ normalIndex ++ ],
412
- normals[ normalIndex ]
413
- );
286
+ }
414
287
 
415
- }
288
+ function parseMorphTargets( json, scale ) {
416
289
 
417
- if ( hasFaceVertexNormal ) {
290
+ const morphPositions = [];
418
291
 
419
- for ( i = 0; i < 3; i ++ ) {
292
+ if ( json.morphTargets !== undefined ) {
420
293
 
421
- normalIndex = faces[ offset ++ ] * 3;
294
+ for ( let i = 0, l = json.morphTargets.length; i < l; i ++ ) {
422
295
 
423
- normal = new Vector3(
424
- normals[ normalIndex ++ ],
425
- normals[ normalIndex ++ ],
426
- normals[ normalIndex ]
427
- );
296
+ const srcVertices = json.morphTargets[ i ].vertices;
297
+ const array = new Float32Array( srcVertices.length );
428
298
 
429
- face.vertexNormals.push( normal );
299
+ for ( let v = 0, vl = srcVertices.length; v < vl; v ++ ) {
430
300
 
431
- }
301
+ array[ v ] = srcVertices[ v ] * scale;
432
302
 
433
303
  }
434
304
 
305
+ const attribute = new Float32BufferAttribute( array, 3 );
306
+ attribute.name = json.morphTargets[ i ].name;
307
+ morphPositions.push( attribute );
435
308
 
436
- if ( hasFaceColor ) {
309
+ }
437
310
 
438
- colorIndex = faces[ offset ++ ];
439
- face.color.setHex( colors[ colorIndex ] );
311
+ }
440
312
 
441
- }
313
+ const morphNormals = [];
442
314
 
315
+ if ( json.morphNormals !== undefined ) {
443
316
 
444
- if ( hasFaceVertexColor ) {
317
+ for ( let i = 0, l = json.morphNormals.length; i < l; i ++ ) {
445
318
 
446
- for ( i = 0; i < 3; i ++ ) {
319
+ if ( morphPositions[ i ] ) {
447
320
 
448
- colorIndex = faces[ offset ++ ];
449
- face.vertexColors.push( new Color( colors[ colorIndex ] ) );
321
+ const srcNormals = json.morphNormals[ i ].normals;
322
+ const array = Float32Array.from( srcNormals );
450
323
 
451
- }
324
+ const attribute = new Float32BufferAttribute( array, 3 );
325
+ attribute.name = morphPositions[ i ].name;
326
+ morphNormals[ i ] = attribute;
452
327
 
453
328
  }
454
329
 
455
- geometry.faces.push( face );
456
-
457
330
  }
458
331
 
459
332
  }
460
333
 
334
+ return { morphPositions, morphNormals };
335
+
461
336
  }
462
337
 
463
- function parseSkin( json, geometry ) {
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 ) {
464
343
 
465
- var influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;
344
+ if ( json.morphColors === undefined ) return undefined;
466
345
 
467
- if ( json.skinWeights ) {
346
+ const morphAttributes = [];
468
347
 
469
- for ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {
348
+ for ( let i = 0, l = json.morphColors.length; i < l; i ++ ) {
470
349
 
471
- var x = json.skinWeights[ i ];
472
- var y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;
473
- var z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;
474
- var w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;
350
+ const srcColors = json.morphColors[ i ].colors;
351
+ const colors = [];
475
352
 
476
- geometry.skinWeights.push( new Vector4( x, y, z, w ) );
353
+ for ( let c = 0, cl = srcColors.length; c < cl; c += 3 ) {
477
354
 
478
- }
355
+ const color = new Color( 0xffaa00 );
356
+ color.setRGB( srcColors[ c ], srcColors[ c + 1 ], srcColors[ c + 2 ] );
357
+ colors.push( color );
479
358
 
480
- }
481
-
482
- if ( json.skinIndices ) {
359
+ }
483
360
 
484
- for ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {
361
+ const colorArray = [];
485
362
 
486
- var a = json.skinIndices[ i ];
487
- var b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;
488
- var c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;
489
- var d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;
363
+ for ( let j = 0, jl = colors.length * 3; j < jl; j ++ ) {
490
364
 
491
- geometry.skinIndices.push( new Vector4( a, b, c, d ) );
365
+ const rgb = getColorsRGB( colors, j );
366
+ colorArray.push( rgb[ 0 ], rgb[ 1 ], rgb[ 2 ] );
492
367
 
493
368
  }
494
369
 
495
- }
496
-
497
- geometry.bones = json.bones;
498
-
499
- if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {
500
-
501
- console.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +
502
- geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );
370
+ const attribute = new Float32BufferAttribute( colorArray, 3 );
371
+ attribute.name = json.morphColors[ i ].name;
372
+ morphAttributes.push( attribute );
503
373
 
504
374
  }
505
375
 
506
- }
507
-
508
- function parseMorphing( json, geometry ) {
509
-
510
- var scale = json.scale;
376
+ return morphAttributes;
511
377
 
512
- if ( json.morphTargets !== undefined ) {
378
+ }
513
379
 
514
- for ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {
380
+ return function parse( json, texturePath ) {
515
381
 
516
- geometry.morphTargets[ i ] = {};
517
- geometry.morphTargets[ i ].name = json.morphTargets[ i ].name;
518
- geometry.morphTargets[ i ].vertices = [];
382
+ if ( json.data !== undefined ) {
519
383
 
520
- var dstVertices = geometry.morphTargets[ i ].vertices;
521
- var srcVertices = json.morphTargets[ i ].vertices;
384
+ // Geometry 4.0 spec
385
+ json = json.data;
522
386
 
523
- for ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {
387
+ }
524
388
 
525
- var vertex = new Vector3();
526
- vertex.x = srcVertices[ v ] * scale;
527
- vertex.y = srcVertices[ v + 1 ] * scale;
528
- vertex.z = srcVertices[ v + 2 ] * scale;
389
+ const scale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;
529
390
 
530
- dstVertices.push( vertex );
391
+ const srcVertices = json.vertices;
392
+ const vertexCount = srcVertices.length / 3;
531
393
 
532
- }
394
+ const positions = new Float32Array( srcVertices.length );
395
+ for ( let i = 0, l = srcVertices.length; i < l; i ++ ) {
533
396
 
534
- }
397
+ positions[ i ] = srcVertices[ i ] * scale;
535
398
 
536
399
  }
537
400
 
538
- if ( json.morphNormals !== undefined ) {
539
-
540
- for ( var i = 0, l = json.morphNormals.length; i < l; i ++ ) {
401
+ const geometry = new BufferGeometry();
402
+ geometry.setAttribute( 'position', new BufferAttribute( positions, 3 ) );
541
403
 
542
- if (geometry.morphTargets[ i ]) {
404
+ if ( json.normals !== undefined && json.normals.length > 0 ) {
543
405
 
544
- geometry.morphTargets[ i ].normals = [];
406
+ geometry.setAttribute( 'normal', new BufferAttribute( Float32Array.from( json.normals ), 3 ) );
545
407
 
546
- var dstNormals = geometry.morphTargets[ i ].normals;
547
- var srcNormals = json.morphNormals[ i ].normals;
408
+ }
548
409
 
549
- for ( var v = 0, vl = srcNormals.length; v < vl; v += 3 ) {
410
+ if ( json.uvs !== undefined ) {
550
411
 
551
- var normals = new Vector3();
552
- normals.x = srcNormals[ v ];
553
- normals.y = srcNormals[ v + 1 ] ;
554
- normals.z = srcNormals[ v + 2 ] ;
412
+ if ( json.uvs[ 0 ] && json.uvs[ 0 ].length > 0 ) {
555
413
 
556
- dstNormals.push( normals );
414
+ geometry.setAttribute( 'uv', new BufferAttribute( Float32Array.from( json.uvs[ 0 ] ), 2 ) );
557
415
 
558
- }
416
+ }
559
417
 
560
- geometry.morphNormalsReady = true;
418
+ if ( json.uvs[ 1 ] && json.uvs[ 1 ].length > 0 ) {
561
419
 
562
- }
420
+ geometry.setAttribute( 'uv2', new BufferAttribute( Float32Array.from( json.uvs[ 1 ] ), 2 ) );
563
421
 
564
422
  }
565
423
 
566
424
  }
567
425
 
568
- if ( json.morphColors !== undefined ) {
569
-
570
- var i, l, c, cl, dstColors, srcColors, color;
426
+ if ( json.colors !== undefined && json.colors.length > 0 ) {
571
427
 
572
- for ( i = 0, l = json.morphColors.length; i < l; i ++ ) {
428
+ const colorArray = new Float32Array( json.colors.length * 3 );
573
429
 
574
- geometry.morphColors[ i ] = {};
575
- geometry.morphColors[ i ].name = json.morphColors[ i ].name;
576
- geometry.morphColors[ i ].colors = [];
430
+ for ( let i = 0, l = json.colors.length; i < l; i ++ ) {
577
431
 
578
- dstColors = geometry.morphColors[ i ].colors;
579
- srcColors = json.morphColors[ i ].colors;
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;
580
436
 
581
- for ( c = 0, cl = srcColors.length; c < cl; c += 3 ) {
437
+ }
582
438
 
583
- color = new THREE.Color( 0xffaa00 );
584
- color.setRGB( srcColors[ c ], srcColors[ c + 1 ], srcColors[ c + 2 ] );
585
- dstColors.push( color );
439
+ geometry.setAttribute( 'color', new BufferAttribute( colorArray, 3 ) );
586
440
 
587
- }
441
+ } else {
588
442
 
589
- }
443
+ const colorArray = new Float32Array( vertexCount * 3 ).fill( 1.0 );
444
+ geometry.setAttribute( 'color', new BufferAttribute( colorArray, 3 ) );
590
445
 
591
446
  }
592
447
 
593
- }
594
-
595
- function parseAnimations( json, geometry ) {
448
+ const { indices, materialIndices } = parseFaces( json );
596
449
 
597
- var outputAnimations = [];
450
+ if ( indices.length > 0 ) {
598
451
 
599
- // parse old style Bone/Hierarchy animations
600
- var animations = [];
452
+ geometry.setIndex( indices );
453
+ geometry.groups = computeGroups( materialIndices );
601
454
 
602
- if ( json.animation !== undefined ) {
455
+ }
603
456
 
604
- animations.push( json.animation );
457
+ const { morphPositions, morphNormals } = parseMorphTargets( json, scale );
605
458
 
606
- }
459
+ if ( morphPositions.length > 0 ) {
607
460
 
608
- if ( json.animations !== undefined ) {
461
+ geometry.morphAttributes.position = morphPositions;
609
462
 
610
- if ( json.animations.length ) {
463
+ const resolvedMorphNormals = [];
611
464
 
612
- animations = animations.concat( json.animations );
465
+ for ( let i = 0; i < morphPositions.length; i ++ ) {
613
466
 
614
- } else {
467
+ if ( morphNormals[ i ] ) {
615
468
 
616
- animations.push( json.animations );
469
+ resolvedMorphNormals.push( morphNormals[ i ] );
617
470
 
618
- }
471
+ } else if ( indices.length > 0 ) {
619
472
 
620
- }
473
+ resolvedMorphNormals.push( computeMorphNormalAttribute( morphPositions[ i ], indices ) );
621
474
 
622
- for ( var i = 0; i < animations.length; i ++ ) {
475
+ }
623
476
 
624
- var clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones );
625
- if ( clip ) outputAnimations.push( clip );
477
+ }
626
478
 
627
- }
479
+ if ( resolvedMorphNormals.length > 0 ) {
628
480
 
629
- // parse implicit morph animations
630
- if ( geometry.morphTargets ) {
481
+ geometry.morphAttributes.normal = resolvedMorphNormals;
631
482
 
632
- // TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary.
633
- var morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );
634
- outputAnimations = outputAnimations.concat( morphAnimationClips );
483
+ }
635
484
 
636
485
  }
637
486
 
638
- if ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;
487
+ const morphColorAttributes = parseMorphColors( json );
639
488
 
640
- }
489
+ if ( morphColorAttributes !== undefined ) {
641
490
 
642
- return function parse( json, texturePath ) {
491
+ geometry.morphAttributes.color = morphColorAttributes;
643
492
 
644
- if ( json.data !== undefined ) {
493
+ //Support cases where only morphColorAttributes is available
494
+ //without morphPositionAttributes
495
+ if ( geometry.morphAttributes.position === undefined ) {
645
496
 
646
- // Geometry 4.0 spec
647
- json = json.data;
497
+ const basePosition = geometry.getAttribute( 'position' );
648
498
 
649
- }
499
+ geometry.morphAttributes.position = morphColorAttributes.map( ( colorAttribute ) => {
650
500
 
651
- if ( json.scale !== undefined ) {
501
+ const positionAttribute = new BufferAttribute( basePosition.array, basePosition.itemSize );
652
502
 
653
- json.scale = 1.0 / json.scale;
503
+ positionAttribute.name = colorAttribute.name;
654
504
 
655
- } else {
505
+ return positionAttribute;
656
506
 
657
- json.scale = 1.0;
507
+ } );
658
508
 
659
- }
509
+ }
660
510
 
661
- var geometry = new Geometry();
662
- geometry.morphColors = [];
663
- parseModel( json, geometry );
664
- parseSkin( json, geometry );
665
- parseMorphing( json, geometry );
666
- parseAnimations( json, geometry );
511
+ }
667
512
 
668
- geometry.computeFaceNormals();
513
+ geometry.computeBoundingBox();
669
514
  geometry.computeBoundingSphere();
670
515
 
671
516
  if ( json.materials === undefined || json.materials.length === 0 ) {