@@ -240,59 +240,7 @@ class USDZExporter {
240
240
const materials = { } ;
241
241
const textures = { } ;
242
242
243
- scene . traverseVisible ( ( object ) => {
244
-
245
- if ( object . isMesh ) {
246
-
247
- const geometry = object . geometry ;
248
- const material = object . material ;
249
-
250
- if ( material . isMeshStandardMaterial ) {
251
-
252
- const geometryFileName =
253
- 'geometries/Geometry_' + geometry . id + '.usda' ;
254
-
255
- if ( ! ( geometryFileName in files ) ) {
256
-
257
- const meshObject = buildMeshObject ( geometry ) ;
258
- files [ geometryFileName ] = strToU8 (
259
- buildHeader ( ) + '\n' + meshObject . toString ( )
260
- ) ;
261
-
262
- }
263
-
264
- if ( ! ( material . uuid in materials ) ) {
265
-
266
- materials [ material . uuid ] = material ;
267
-
268
- }
269
-
270
- const node = buildXform (
271
- object ,
272
- geometry ,
273
- materials [ material . uuid ] ,
274
- usedNames
275
- ) ;
276
- sceneNode . addChild ( node ) ;
277
-
278
- } else {
279
-
280
- console . warn (
281
- 'THREE.USDZExporter: Unsupported material type (USDZ only supports MeshStandardMaterial)' ,
282
- object
283
- ) ;
284
-
285
- }
286
-
287
- } else if ( object . isCamera ) {
288
-
289
- const cameraNode = buildCamera ( object , usedNames ) ;
290
-
291
- sceneNode . addChild ( cameraNode ) ;
292
-
293
- }
294
-
295
- } ) ;
243
+ buildHierarchy ( scene , sceneNode , materials , usedNames , files ) ;
296
244
297
245
const materialsNode = buildMaterials (
298
246
materials ,
@@ -478,12 +426,83 @@ function buildHeader() {
478
426
479
427
// Xform
480
428
481
- function buildXform ( object , geometry , material , usedNames ) {
429
+ function buildHierarchy ( object , parentNode , materials , usedNames , files ) {
430
+
431
+ for ( let i = 0 , l = object . children . length ; i < l ; i ++ ) {
432
+
433
+ const child = object . children [ i ] ;
434
+
435
+ if ( ! child . visible ) continue ;
436
+
437
+ let childNode ;
438
+
439
+ if ( child . isMesh ) {
440
+
441
+ const geometry = child . geometry ;
442
+ const material = child . material ;
443
+
444
+ if ( material . isMeshStandardMaterial ) {
445
+
446
+ const geometryFileName = 'geometries/Geometry_' + geometry . id + '.usda' ;
447
+
448
+ if ( ! ( geometryFileName in files ) ) {
449
+
450
+ const meshObject = buildMeshObject ( geometry ) ;
451
+ files [ geometryFileName ] = strToU8 (
452
+ buildHeader ( ) + '\n' + meshObject . toString ( )
453
+ ) ;
454
+
455
+ }
456
+
457
+ if ( ! ( material . uuid in materials ) ) {
458
+
459
+ materials [ material . uuid ] = material ;
460
+
461
+ }
462
+
463
+ childNode = buildMesh (
464
+ child ,
465
+ geometry ,
466
+ materials [ material . uuid ] ,
467
+ usedNames
468
+ ) ;
469
+
470
+ } else {
471
+
472
+ console . warn (
473
+ 'THREE.USDZExporter: Unsupported material type (USDZ only supports MeshStandardMaterial)' ,
474
+ child
475
+ ) ;
476
+
477
+ }
478
+
479
+ } else if ( child . isCamera ) {
480
+
481
+ childNode = buildCamera ( child , usedNames ) ;
482
+
483
+ } else {
484
+
485
+ childNode = buildXform ( child , usedNames ) ;
486
+
487
+ }
488
+
489
+ if ( childNode ) {
490
+
491
+ parentNode . addChild ( childNode ) ;
492
+ buildHierarchy ( child , childNode , materials , usedNames , files ) ;
493
+
494
+ }
495
+
496
+ }
497
+
498
+ }
499
+
500
+ function buildXform ( object , usedNames ) {
482
501
483
502
const name = getName ( object , usedNames ) ;
484
- const transform = buildMatrix ( object . matrixWorld ) ;
503
+ const transform = buildMatrix ( object . matrix ) ;
485
504
486
- if ( object . matrixWorld . determinant ( ) < 0 ) {
505
+ if ( object . matrix . determinant ( ) < 0 ) {
487
506
488
507
console . warn (
489
508
'THREE.USDZExporter: USDZ does not support negative scales' ,
@@ -494,15 +513,23 @@ function buildXform( object, geometry, material, usedNames ) {
494
513
495
514
const node = new USDNode ( name , 'Xform' ) ;
496
515
516
+ node . addProperty ( `matrix4d xformOp:transform = ${ transform } ` ) ;
517
+ node . addProperty ( 'uniform token[] xformOpOrder = ["xformOp:transform"]' ) ;
518
+
519
+ return node ;
520
+
521
+ }
522
+
523
+ function buildMesh ( object , geometry , material , usedNames ) {
524
+
525
+ const node = buildXform ( object , usedNames ) ;
526
+
497
527
node . addMetadata (
498
528
'prepend references' ,
499
529
`@./geometries/Geometry_${ geometry . id } .usda@</Geometry>`
500
530
) ;
501
531
node . addMetadata ( 'prepend apiSchemas' , '["MaterialBindingAPI"]' ) ;
502
532
503
- node . addProperty ( `matrix4d xformOp:transform = ${ transform } ` ) ;
504
- node . addProperty ( 'uniform token[] xformOpOrder = ["xformOp:transform"]' ) ;
505
-
506
533
node . addProperty (
507
534
`rel material:binding = </Materials/Material_${ material . id } >`
508
535
) ;
@@ -879,7 +906,6 @@ function buildMaterial( material, textures, quickLookCompatible = false ) {
879
906
880
907
}
881
908
882
- // Handle emissive
883
909
if ( material . emissiveMap !== null ) {
884
910
885
911
previewSurfaceNode . addProperty (
@@ -906,7 +932,6 @@ function buildMaterial( material, textures, quickLookCompatible = false ) {
906
932
907
933
}
908
934
909
- // Handle normal
910
935
if ( material . normalMap !== null ) {
911
936
912
937
previewSurfaceNode . addProperty (
@@ -918,7 +943,6 @@ function buildMaterial( material, textures, quickLookCompatible = false ) {
918
943
919
944
}
920
945
921
- // Handle ambient occlusion
922
946
if ( material . aoMap !== null ) {
923
947
924
948
previewSurfaceNode . addProperty (
@@ -1102,9 +1126,9 @@ function buildCamera( camera, usedNames ) {
1102
1126
1103
1127
const name = getName ( camera , usedNames ) ;
1104
1128
1105
- const transform = buildMatrix ( camera . matrixWorld ) ;
1129
+ const transform = buildMatrix ( camera . matrix ) ;
1106
1130
1107
- if ( camera . matrixWorld . determinant ( ) < 0 ) {
1131
+ if ( camera . matrix . determinant ( ) < 0 ) {
1108
1132
1109
1133
console . warn (
1110
1134
'THREE.USDZExporter: USDZ does not support negative scales' ,
0 commit comments