@@ -340,8 +340,11 @@ class USDZLoader extends Loader {
340340
341341 const geometry = new BufferGeometry ( ) ;
342342 let indices = null ;
343+ let counts = null ;
343344 let uvs = null ;
344345
346+ let positionsLength = - 1 ;
347+
345348 // index
346349
347350 if ( 'int[] faceVertexIndices' in data ) {
@@ -350,11 +353,21 @@ class USDZLoader extends Loader {
350353
351354 }
352355
356+ // face count
357+
358+ if ( 'int[] faceVertexCounts' in data ) {
359+
360+ counts = JSON . parse ( data [ 'int[] faceVertexCounts' ] ) ;
361+ indices = toTriangleIndices ( indices , counts ) ;
362+
363+ }
364+
353365 // position
354366
355367 if ( 'point3f[] points' in data ) {
356368
357369 const positions = JSON . parse ( data [ 'point3f[] points' ] . replace ( / [ ( ) ] * / g, '' ) ) ;
370+ positionsLength = positions . length ;
358371 let attribute = new BufferAttribute ( new Float32Array ( positions ) , 3 ) ;
359372
360373 if ( indices !== null ) attribute = toFlatBufferAttribute ( attribute , indices ) ;
@@ -387,7 +400,8 @@ class USDZLoader extends Loader {
387400 // custom uv index, overwrite uvs with new data
388401
389402 const attribute = new BufferAttribute ( new Float32Array ( uvs ) , 2 ) ;
390- const indices = JSON . parse ( data [ 'int[] primvars:st:indices' ] ) ;
403+ let indices = JSON . parse ( data [ 'int[] primvars:st:indices' ] ) ;
404+ indices = toTriangleIndices ( indices , counts ) ;
391405 geometry . setAttribute ( 'uv' , toFlatBufferAttribute ( attribute , indices ) ) ;
392406
393407 }
@@ -399,8 +413,20 @@ class USDZLoader extends Loader {
399413 const normals = JSON . parse ( data [ 'normal3f[] normals' ] . replace ( / [ ( ) ] * / g, '' ) ) ;
400414 let attribute = new BufferAttribute ( new Float32Array ( normals ) , 3 ) ;
401415
402- if ( attribute . count !== geometry . attributes . position . count && indices !== null ) {
416+ // normals require a special treatment in USD
417+
418+ if ( normals . length === positionsLength ) {
419+
420+ // raw normal and position data have equal length (like produced by USDZExporter)
421+
422+ if ( indices !== null ) attribute = toFlatBufferAttribute ( attribute , indices ) ;
403423
424+ } else {
425+
426+ // unequal length, normals are independent of faceVertexIndices
427+
428+ let indices = Array . from ( Array ( normals . length / 3 ) . keys ( ) ) ; // [ 0, 1, 2, 3 ... ]
429+ indices = toTriangleIndices ( indices , counts ) ;
404430 attribute = toFlatBufferAttribute ( attribute , indices ) ;
405431
406432 }
@@ -409,6 +435,8 @@ class USDZLoader extends Loader {
409435
410436 } else {
411437
438+ // compute flat vertex normals
439+
412440 geometry . computeVertexNormals ( ) ;
413441
414442 }
@@ -417,6 +445,46 @@ class USDZLoader extends Loader {
417445
418446 }
419447
448+ function toTriangleIndices ( rawIndices , counts ) {
449+
450+ const indices = [ ] ;
451+
452+ for ( let i = 0 ; i < counts . length ; i ++ ) {
453+
454+ const count = counts [ i ] ;
455+
456+ const stride = i * count ;
457+
458+ if ( count === 3 ) {
459+
460+ const a = rawIndices [ stride + 0 ] ;
461+ const b = rawIndices [ stride + 1 ] ;
462+ const c = rawIndices [ stride + 2 ] ;
463+
464+ indices . push ( a , b , c ) ;
465+
466+ } else if ( count === 4 ) {
467+
468+ const a = rawIndices [ stride + 0 ] ;
469+ const b = rawIndices [ stride + 1 ] ;
470+ const c = rawIndices [ stride + 2 ] ;
471+ const d = rawIndices [ stride + 3 ] ;
472+
473+ indices . push ( a , b , c ) ;
474+ indices . push ( a , c , d ) ;
475+
476+ } else {
477+
478+ console . warn ( 'THREE.USDZLoader: Face vertex count of %s unsupported.' , count ) ;
479+
480+ }
481+
482+ }
483+
484+ return indices ;
485+
486+ }
487+
420488 function toFlatBufferAttribute ( attribute , indices ) {
421489
422490 const array = attribute . array ;
0 commit comments