zincjs 2.4.0 → 2.4.1-beta.0

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 +3 -4
  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 +204 -377
  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 +17 -13
  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,385 @@ 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
140
  }
171
141
 
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
- }
186
-
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 ) {
184
+ if ( hasFaceNormal ) offset += 1;
185
+ if ( hasFaceVertexNormal ) offset += 4;
186
+ if ( hasFaceColor ) offset += 1;
187
+ if ( hasFaceVertexColor ) offset += 4;
295
188
 
296
- normalIndex = faces[ offset ++ ] * 3;
189
+ indices.push( v0, v1, v3 );
190
+ materialIndices.push( materialIndex );
297
191
 
298
- faceA.normal.set(
299
- normals[ normalIndex ++ ],
300
- normals[ normalIndex ++ ],
301
- normals[ normalIndex ]
302
- );
192
+ indices.push( v1, v2, v3 );
193
+ materialIndices.push( materialIndex );
303
194
 
304
- faceB.normal.copy( faceA.normal );
195
+ continue;
305
196
 
306
- }
307
-
308
- if ( hasFaceVertexNormal ) {
309
-
310
- for ( i = 0; i < 4; i ++ ) {
311
-
312
- normalIndex = faces[ offset ++ ] * 3;
313
-
314
- normal = new Vector3(
315
- normals[ normalIndex ++ ],
316
- normals[ normalIndex ++ ],
317
- normals[ normalIndex ]
318
- );
319
-
320
-
321
- if ( i !== 2 ) faceA.vertexNormals.push( normal );
322
- if ( i !== 0 ) faceB.vertexNormals.push( normal );
323
-
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;
255
+ group = { start: i * 3, materialIndex: materialIndex };
379
256
 
380
- if ( hasFaceVertexUv ) {
381
-
382
- for ( i = 0; i < nUvLayers; i ++ ) {
383
-
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
 
461
- }
334
+ return { morphPositions, morphNormals };
462
335
 
463
- function parseSkin( json, geometry ) {
336
+ }
464
337
 
465
- var influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;
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 ) {
466
343
 
467
- if ( json.skinWeights ) {
344
+ if ( json.morphColors === undefined ) return undefined;
468
345
 
469
- for ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {
346
+ const morphAttributes = [];
470
347
 
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;
348
+ for ( let i = 0, l = json.morphColors.length; i < l; i ++ ) {
475
349
 
476
- geometry.skinWeights.push( new Vector4( x, y, z, w ) );
350
+ const srcColors = json.morphColors[ i ].colors;
351
+ const colors = [];
477
352
 
478
- }
353
+ for ( let c = 0, cl = srcColors.length; c < cl; c += 3 ) {
479
354
 
480
- }
355
+ const color = new Color( 0xffaa00 );
356
+ color.setRGB( srcColors[ c ], srcColors[ c + 1 ], srcColors[ c + 2 ] );
357
+ colors.push( color );
481
358
 
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 ) {
376
+ return morphAttributes;
509
377
 
510
- var scale = json.scale;
378
+ }
511
379
 
512
- if ( json.morphTargets !== undefined ) {
380
+ return function parse( json, texturePath ) {
513
381
 
514
- for ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {
382
+ if ( json.data !== undefined ) {
515
383
 
516
- geometry.morphTargets[ i ] = {};
517
- geometry.morphTargets[ i ].name = json.morphTargets[ i ].name;
518
- geometry.morphTargets[ i ].vertices = [];
384
+ // Geometry 4.0 spec
385
+ json = json.data;
519
386
 
520
- var dstVertices = geometry.morphTargets[ i ].vertices;
521
- var srcVertices = json.morphTargets[ i ].vertices;
387
+ }
522
388
 
523
- for ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {
389
+ const scale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;
524
390
 
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;
391
+ const srcVertices = json.vertices;
392
+ const vertexCount = srcVertices.length / 3;
529
393
 
530
- dstVertices.push( vertex );
394
+ const positions = new Float32Array( srcVertices.length );
395
+ for ( let i = 0, l = srcVertices.length; i < l; i ++ ) {
531
396
 
532
- }
533
-
534
- }
397
+ positions[ i ] = srcVertices[ i ] * scale;
535
398
 
536
399
  }
537
400
 
538
- if ( json.morphNormals !== undefined ) {
401
+ const geometry = new BufferGeometry();
402
+ geometry.setAttribute( 'position', new BufferAttribute( positions, 3 ) );
539
403
 
540
- for ( var i = 0, l = json.morphNormals.length; i < l; i ++ ) {
404
+ if ( json.normals !== undefined && json.normals.length > 0 ) {
541
405
 
542
- if (geometry.morphTargets[ i ]) {
406
+ geometry.setAttribute( 'normal', new BufferAttribute( Float32Array.from( json.normals ), 3 ) );
543
407
 
544
- geometry.morphTargets[ i ].normals = [];
545
-
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;
580
-
581
- for ( c = 0, cl = srcColors.length; c < cl; c += 3 ) {
582
-
583
- color = new THREE.Color( 0xffaa00 );
584
- color.setRGB( srcColors[ c ], srcColors[ c + 1 ], srcColors[ c + 2 ] );
585
- dstColors.push( color );
586
-
587
- }
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;
588
436
 
589
437
  }
590
438
 
591
- }
592
-
593
- }
594
-
595
- function parseAnimations( json, geometry ) {
596
-
597
- var outputAnimations = [];
439
+ geometry.setAttribute( 'color', new BufferAttribute( colorArray, 3 ) );
598
440
 
599
- // parse old style Bone/Hierarchy animations
600
- var animations = [];
601
-
602
- if ( json.animation !== undefined ) {
441
+ } else {
603
442
 
604
- animations.push( json.animation );
443
+ const colorArray = new Float32Array( vertexCount * 3 ).fill( 1.0 );
444
+ geometry.setAttribute( 'color', new BufferAttribute( colorArray, 3 ) );
605
445
 
606
446
  }
607
447
 
608
- if ( json.animations !== undefined ) {
448
+ const { indices, materialIndices } = parseFaces( json );
609
449
 
610
- if ( json.animations.length ) {
450
+ if ( indices.length > 0 ) {
611
451
 
612
- animations = animations.concat( json.animations );
452
+ geometry.setIndex( indices );
453
+ geometry.groups = computeGroups( materialIndices );
613
454
 
614
- } else {
455
+ }
615
456
 
616
- animations.push( json.animations );
457
+ const { morphPositions, morphNormals } = parseMorphTargets( json, scale );
617
458
 
618
- }
459
+ if ( morphPositions.length > 0 ) {
619
460
 
620
- }
461
+ geometry.morphAttributes.position = morphPositions;
621
462
 
622
- for ( var i = 0; i < animations.length; i ++ ) {
463
+ const resolvedMorphNormals = [];
623
464
 
624
- var clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones );
625
- if ( clip ) outputAnimations.push( clip );
465
+ for ( let i = 0; i < morphPositions.length; i ++ ) {
626
466
 
627
- }
467
+ if ( morphNormals[ i ] ) {
628
468
 
629
- // parse implicit morph animations
630
- if ( geometry.morphTargets ) {
469
+ resolvedMorphNormals.push( morphNormals[ i ] );
631
470
 
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 );
471
+ } else if ( indices.length > 0 ) {
635
472
 
636
- }
473
+ resolvedMorphNormals.push( computeMorphNormalAttribute( morphPositions[ i ], indices ) );
637
474
 
638
- if ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;
475
+ }
639
476
 
640
- }
477
+ }
641
478
 
642
- return function parse( json, texturePath ) {
479
+ if ( resolvedMorphNormals.length > 0 ) {
643
480
 
644
- if ( json.data !== undefined ) {
481
+ geometry.morphAttributes.normal = resolvedMorphNormals;
645
482
 
646
- // Geometry 4.0 spec
647
- json = json.data;
483
+ }
648
484
 
649
485
  }
650
486
 
651
- if ( json.scale !== undefined ) {
652
-
653
- json.scale = 1.0 / json.scale;
487
+ const morphColorAttributes = parseMorphColors( json );
654
488
 
655
- } else {
489
+ if ( morphColorAttributes !== undefined ) {
656
490
 
657
- json.scale = 1.0;
491
+ geometry.morphAttributes.color = morphColorAttributes;
658
492
 
659
493
  }
660
494
 
661
- var geometry = new Geometry();
662
- geometry.morphColors = [];
663
- parseModel( json, geometry );
664
- parseSkin( json, geometry );
665
- parseMorphing( json, geometry );
666
- parseAnimations( json, geometry );
667
-
668
- geometry.computeFaceNormals();
495
+ geometry.computeBoundingBox();
669
496
  geometry.computeBoundingSphere();
670
497
 
671
498
  if ( json.materials === undefined || json.materials.length === 0 ) {