@plastic-software/three 0.178.0 → 0.179.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 (141) hide show
  1. package/README.md +1 -1
  2. package/build/three.cjs +856 -196
  3. package/build/three.core.js +647 -123
  4. package/build/three.core.min.js +1 -1
  5. package/build/three.module.js +211 -76
  6. package/build/three.module.min.js +1 -1
  7. package/build/three.tsl.js +70 -21
  8. package/build/three.tsl.min.js +1 -1
  9. package/build/three.webgpu.js +1796 -557
  10. package/build/three.webgpu.min.js +1 -1
  11. package/build/three.webgpu.nodes.js +1754 -557
  12. package/build/three.webgpu.nodes.min.js +1 -1
  13. package/examples/jsm/Addons.js +1 -2
  14. package/examples/jsm/capabilities/WebGPU.js +1 -1
  15. package/examples/jsm/csm/CSMShadowNode.js +4 -4
  16. package/examples/jsm/environments/RoomEnvironment.js +8 -3
  17. package/examples/jsm/exporters/USDZExporter.js +676 -299
  18. package/examples/jsm/geometries/RoundedBoxGeometry.js +47 -8
  19. package/examples/jsm/interactive/HTMLMesh.js +5 -3
  20. package/examples/jsm/libs/meshopt_decoder.module.js +75 -58
  21. package/examples/jsm/lights/LightProbeGenerator.js +14 -3
  22. package/examples/jsm/loaders/EXRLoader.js +210 -22
  23. package/examples/jsm/loaders/FBXLoader.js +1 -1
  24. package/examples/jsm/loaders/MaterialXLoader.js +212 -30
  25. package/examples/jsm/loaders/TTFLoader.js +13 -1
  26. package/examples/jsm/loaders/USDLoader.js +219 -0
  27. package/examples/jsm/loaders/USDZLoader.js +4 -892
  28. package/examples/jsm/loaders/usd/USDAParser.js +741 -0
  29. package/examples/jsm/loaders/usd/USDCParser.js +17 -0
  30. package/examples/jsm/objects/LensflareMesh.js +3 -3
  31. package/examples/jsm/objects/SkyMesh.js +2 -2
  32. package/examples/jsm/physics/RapierPhysics.js +14 -5
  33. package/examples/jsm/postprocessing/GTAOPass.js +10 -9
  34. package/examples/jsm/postprocessing/OutlinePass.js +17 -17
  35. package/examples/jsm/postprocessing/SSAOPass.js +10 -9
  36. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +11 -2
  37. package/examples/jsm/transpiler/GLSLDecoder.js +2 -2
  38. package/examples/jsm/tsl/display/BloomNode.js +8 -7
  39. package/examples/jsm/tsl/display/GaussianBlurNode.js +6 -8
  40. package/examples/jsm/tsl/display/{TRAAPassNode.js → TRAANode.js} +181 -172
  41. package/examples/jsm/tsl/lighting/TiledLightsNode.js +1 -1
  42. package/package.json +1 -1
  43. package/src/Three.Core.js +1 -0
  44. package/src/Three.TSL.js +69 -20
  45. package/src/animation/KeyframeTrack.js +1 -1
  46. package/src/animation/tracks/BooleanKeyframeTrack.js +1 -1
  47. package/src/animation/tracks/StringKeyframeTrack.js +1 -1
  48. package/src/cameras/Camera.js +14 -0
  49. package/src/cameras/OrthographicCamera.js +1 -1
  50. package/src/cameras/PerspectiveCamera.js +1 -1
  51. package/src/constants.js +1 -1
  52. package/{examples/jsm/misc → src/core}/Timer.js +4 -42
  53. package/src/extras/PMREMGenerator.js +11 -0
  54. package/src/helpers/CameraHelper.js +41 -11
  55. package/src/helpers/SkeletonHelper.js +35 -6
  56. package/src/lights/LightShadow.js +21 -8
  57. package/src/lights/PointLightShadow.js +1 -1
  58. package/src/loaders/FileLoader.js +25 -2
  59. package/src/loaders/ImageBitmapLoader.js +23 -0
  60. package/src/loaders/Loader.js +14 -0
  61. package/src/loaders/LoadingManager.js +23 -0
  62. package/src/materials/MeshBasicMaterial.js +1 -1
  63. package/src/materials/nodes/Line2NodeMaterial.js +0 -8
  64. package/src/materials/nodes/NodeMaterial.js +1 -1
  65. package/src/materials/nodes/PointsNodeMaterial.js +5 -0
  66. package/src/materials/nodes/manager/NodeMaterialObserver.js +87 -2
  67. package/src/math/Frustum.js +19 -8
  68. package/src/math/FrustumArray.js +10 -5
  69. package/src/math/Line3.js +129 -2
  70. package/src/math/Matrix4.js +48 -27
  71. package/src/math/Spherical.js +2 -2
  72. package/src/nodes/Nodes.js +1 -0
  73. package/src/nodes/TSL.js +1 -0
  74. package/src/nodes/accessors/Camera.js +12 -12
  75. package/src/nodes/accessors/Normal.js +11 -11
  76. package/src/nodes/accessors/ReferenceNode.js +18 -3
  77. package/src/nodes/accessors/SceneNode.js +1 -1
  78. package/src/nodes/accessors/StorageTextureNode.js +1 -1
  79. package/src/nodes/accessors/TextureNode.js +12 -0
  80. package/src/nodes/core/ArrayNode.js +12 -0
  81. package/src/nodes/core/AssignNode.js +3 -0
  82. package/src/nodes/core/ContextNode.js +20 -1
  83. package/src/nodes/core/Node.js +14 -2
  84. package/src/nodes/core/NodeBuilder.js +25 -20
  85. package/src/nodes/core/NodeUtils.js +4 -1
  86. package/src/nodes/core/StackNode.js +42 -0
  87. package/src/nodes/core/UniformNode.js +63 -5
  88. package/src/nodes/core/VarNode.js +91 -2
  89. package/src/nodes/display/PassNode.js +148 -2
  90. package/src/nodes/display/ViewportTextureNode.js +67 -7
  91. package/src/nodes/functions/PhysicalLightingModel.js +2 -2
  92. package/src/nodes/gpgpu/AtomicFunctionNode.js +1 -1
  93. package/src/nodes/gpgpu/ComputeNode.js +67 -23
  94. package/src/nodes/gpgpu/WorkgroupInfoNode.js +28 -3
  95. package/src/nodes/lighting/ProjectorLightNode.js +19 -6
  96. package/src/nodes/lighting/ShadowFilterNode.js +1 -1
  97. package/src/nodes/materialx/MaterialXNodes.js +131 -2
  98. package/src/nodes/materialx/lib/mx_noise.js +165 -1
  99. package/src/nodes/math/ConditionalNode.js +1 -1
  100. package/src/nodes/math/MathNode.js +78 -54
  101. package/src/nodes/math/OperatorNode.js +22 -22
  102. package/src/nodes/tsl/TSLCore.js +64 -9
  103. package/src/nodes/utils/DebugNode.js +1 -1
  104. package/src/nodes/utils/EventNode.js +83 -0
  105. package/src/nodes/utils/RTTNode.js +9 -0
  106. package/src/objects/BatchedMesh.js +4 -2
  107. package/src/renderers/WebGLRenderer.js +21 -22
  108. package/src/renderers/common/Bindings.js +19 -18
  109. package/src/renderers/common/Color4.js +2 -2
  110. package/src/renderers/common/PostProcessing.js +60 -5
  111. package/src/renderers/common/Renderer.js +18 -15
  112. package/src/renderers/common/SampledTexture.js +3 -71
  113. package/src/renderers/common/Sampler.js +79 -0
  114. package/src/renderers/common/Storage3DTexture.js +21 -0
  115. package/src/renderers/common/StorageArrayTexture.js +21 -0
  116. package/src/renderers/common/StorageTexture.js +19 -0
  117. package/src/renderers/common/Textures.js +19 -3
  118. package/src/renderers/common/XRManager.js +26 -8
  119. package/src/renderers/common/nodes/NodeSampledTexture.js +0 -12
  120. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +20 -2
  121. package/src/renderers/shaders/ShaderLib/depth.glsl.js +11 -2
  122. package/src/renderers/webgl/WebGLCapabilities.js +2 -2
  123. package/src/renderers/webgl/WebGLMaterials.js +6 -6
  124. package/src/renderers/webgl/WebGLProgram.js +22 -16
  125. package/src/renderers/webgl/WebGLPrograms.js +4 -4
  126. package/src/renderers/webgl/WebGLShadowMap.js +11 -1
  127. package/src/renderers/webgl/WebGLTextures.js +19 -7
  128. package/src/renderers/webgl-fallback/WebGLBackend.js +22 -12
  129. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +2 -2
  130. package/src/renderers/webgpu/WebGPUBackend.js +54 -15
  131. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +53 -73
  132. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +35 -31
  133. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +1 -1
  134. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +11 -64
  135. package/src/renderers/webgpu/utils/WebGPUUtils.js +2 -17
  136. package/src/renderers/webxr/WebXRDepthSensing.js +6 -10
  137. package/src/renderers/webxr/WebXRManager.js +68 -8
  138. package/src/textures/ExternalTexture.js +45 -0
  139. package/src/textures/FramebufferTexture.js +2 -2
  140. package/src/textures/Source.js +11 -1
  141. package/src/textures/VideoTexture.js +30 -2
@@ -0,0 +1,741 @@
1
+ import {
2
+ BufferAttribute,
3
+ BufferGeometry,
4
+ ClampToEdgeWrapping,
5
+ Group,
6
+ NoColorSpace,
7
+ Mesh,
8
+ MeshPhysicalMaterial,
9
+ MirroredRepeatWrapping,
10
+ RepeatWrapping,
11
+ SRGBColorSpace,
12
+ TextureLoader,
13
+ Object3D,
14
+ Vector2
15
+ } from 'three';
16
+
17
+ class USDAParser {
18
+
19
+ parseText( text ) {
20
+
21
+ const root = {};
22
+
23
+ const lines = text.split( '\n' );
24
+
25
+ let string = null;
26
+ let target = root;
27
+
28
+ const stack = [ root ];
29
+
30
+ // Parse USDA file
31
+
32
+ for ( const line of lines ) {
33
+
34
+ // console.log( line );
35
+
36
+ if ( line.includes( '=' ) ) {
37
+
38
+ const assignment = line.split( '=' );
39
+
40
+ const lhs = assignment[ 0 ].trim();
41
+ const rhs = assignment[ 1 ].trim();
42
+
43
+ if ( rhs.endsWith( '{' ) ) {
44
+
45
+ const group = {};
46
+ stack.push( group );
47
+
48
+ target[ lhs ] = group;
49
+ target = group;
50
+
51
+ } else if ( rhs.endsWith( '(' ) ) {
52
+
53
+ // see #28631
54
+
55
+ const values = rhs.slice( 0, - 1 );
56
+ target[ lhs ] = values;
57
+
58
+ const meta = {};
59
+ stack.push( meta );
60
+
61
+ target = meta;
62
+
63
+ } else {
64
+
65
+ target[ lhs ] = rhs;
66
+
67
+ }
68
+
69
+ } else if ( line.endsWith( '{' ) ) {
70
+
71
+ const group = target[ string ] || {};
72
+ stack.push( group );
73
+
74
+ target[ string ] = group;
75
+ target = group;
76
+
77
+ } else if ( line.endsWith( '}' ) ) {
78
+
79
+ stack.pop();
80
+
81
+ if ( stack.length === 0 ) continue;
82
+
83
+ target = stack[ stack.length - 1 ];
84
+
85
+ } else if ( line.endsWith( '(' ) ) {
86
+
87
+ const meta = {};
88
+ stack.push( meta );
89
+
90
+ string = line.split( '(' )[ 0 ].trim() || string;
91
+
92
+ target[ string ] = meta;
93
+ target = meta;
94
+
95
+ } else if ( line.endsWith( ')' ) ) {
96
+
97
+ stack.pop();
98
+
99
+ target = stack[ stack.length - 1 ];
100
+
101
+ } else {
102
+
103
+ string = line.trim();
104
+
105
+ }
106
+
107
+ }
108
+
109
+ return root;
110
+
111
+ }
112
+
113
+ parse( text, assets ) {
114
+
115
+ const root = this.parseText( text );
116
+
117
+ // Build scene graph
118
+
119
+ function findMeshGeometry( data ) {
120
+
121
+ if ( ! data ) return undefined;
122
+
123
+ if ( 'prepend references' in data ) {
124
+
125
+ const reference = data[ 'prepend references' ];
126
+ const parts = reference.split( '@' );
127
+ const path = parts[ 1 ].replace( /^.\//, '' );
128
+ const id = parts[ 2 ].replace( /^<\//, '' ).replace( />$/, '' );
129
+
130
+ return findGeometry( assets[ path ], id );
131
+
132
+ }
133
+
134
+ return findGeometry( data );
135
+
136
+ }
137
+
138
+ function findGeometry( data, id ) {
139
+
140
+ if ( ! data ) return undefined;
141
+
142
+ if ( id !== undefined ) {
143
+
144
+ const def = `def Mesh "${id}"`;
145
+
146
+ if ( def in data ) {
147
+
148
+ return data[ def ];
149
+
150
+ }
151
+
152
+ }
153
+
154
+ for ( const name in data ) {
155
+
156
+ const object = data[ name ];
157
+
158
+ if ( name.startsWith( 'def Mesh' ) ) {
159
+
160
+ return object;
161
+
162
+ }
163
+
164
+
165
+ if ( typeof object === 'object' ) {
166
+
167
+ const geometry = findGeometry( object );
168
+
169
+ if ( geometry ) return geometry;
170
+
171
+ }
172
+
173
+ }
174
+
175
+ }
176
+
177
+ function buildGeometry( data ) {
178
+
179
+ if ( ! data ) return undefined;
180
+
181
+ const geometry = new BufferGeometry();
182
+ let indices = null;
183
+ let counts = null;
184
+ let uvs = null;
185
+
186
+ let positionsLength = - 1;
187
+
188
+ // index
189
+
190
+ if ( 'int[] faceVertexIndices' in data ) {
191
+
192
+ indices = JSON.parse( data[ 'int[] faceVertexIndices' ] );
193
+
194
+ }
195
+
196
+ // face count
197
+
198
+ if ( 'int[] faceVertexCounts' in data ) {
199
+
200
+ counts = JSON.parse( data[ 'int[] faceVertexCounts' ] );
201
+ indices = toTriangleIndices( indices, counts );
202
+
203
+ }
204
+
205
+ // position
206
+
207
+ if ( 'point3f[] points' in data ) {
208
+
209
+ const positions = JSON.parse( data[ 'point3f[] points' ].replace( /[()]*/g, '' ) );
210
+ positionsLength = positions.length;
211
+ let attribute = new BufferAttribute( new Float32Array( positions ), 3 );
212
+
213
+ if ( indices !== null ) attribute = toFlatBufferAttribute( attribute, indices );
214
+
215
+ geometry.setAttribute( 'position', attribute );
216
+
217
+ }
218
+
219
+ // uv
220
+
221
+ if ( 'float2[] primvars:st' in data ) {
222
+
223
+ data[ 'texCoord2f[] primvars:st' ] = data[ 'float2[] primvars:st' ];
224
+
225
+ }
226
+
227
+ if ( 'texCoord2f[] primvars:st' in data ) {
228
+
229
+ uvs = JSON.parse( data[ 'texCoord2f[] primvars:st' ].replace( /[()]*/g, '' ) );
230
+ let attribute = new BufferAttribute( new Float32Array( uvs ), 2 );
231
+
232
+ if ( indices !== null ) attribute = toFlatBufferAttribute( attribute, indices );
233
+
234
+ geometry.setAttribute( 'uv', attribute );
235
+
236
+ }
237
+
238
+ if ( 'int[] primvars:st:indices' in data && uvs !== null ) {
239
+
240
+ // custom uv index, overwrite uvs with new data
241
+
242
+ const attribute = new BufferAttribute( new Float32Array( uvs ), 2 );
243
+ let indices = JSON.parse( data[ 'int[] primvars:st:indices' ] );
244
+ indices = toTriangleIndices( indices, counts );
245
+ geometry.setAttribute( 'uv', toFlatBufferAttribute( attribute, indices ) );
246
+
247
+ }
248
+
249
+ // normal
250
+
251
+ if ( 'normal3f[] normals' in data ) {
252
+
253
+ const normals = JSON.parse( data[ 'normal3f[] normals' ].replace( /[()]*/g, '' ) );
254
+ let attribute = new BufferAttribute( new Float32Array( normals ), 3 );
255
+
256
+ // normals require a special treatment in USD
257
+
258
+ if ( normals.length === positionsLength ) {
259
+
260
+ // raw normal and position data have equal length (like produced by USDZExporter)
261
+
262
+ if ( indices !== null ) attribute = toFlatBufferAttribute( attribute, indices );
263
+
264
+ } else {
265
+
266
+ // unequal length, normals are independent of faceVertexIndices
267
+
268
+ let indices = Array.from( Array( normals.length / 3 ).keys() ); // [ 0, 1, 2, 3 ... ]
269
+ indices = toTriangleIndices( indices, counts );
270
+ attribute = toFlatBufferAttribute( attribute, indices );
271
+
272
+ }
273
+
274
+ geometry.setAttribute( 'normal', attribute );
275
+
276
+ } else {
277
+
278
+ // compute flat vertex normals
279
+
280
+ geometry.computeVertexNormals();
281
+
282
+ }
283
+
284
+ return geometry;
285
+
286
+ }
287
+
288
+ function toTriangleIndices( rawIndices, counts ) {
289
+
290
+ const indices = [];
291
+
292
+ for ( let i = 0; i < counts.length; i ++ ) {
293
+
294
+ const count = counts[ i ];
295
+
296
+ const stride = i * count;
297
+
298
+ if ( count === 3 ) {
299
+
300
+ const a = rawIndices[ stride + 0 ];
301
+ const b = rawIndices[ stride + 1 ];
302
+ const c = rawIndices[ stride + 2 ];
303
+
304
+ indices.push( a, b, c );
305
+
306
+ } else if ( count === 4 ) {
307
+
308
+ const a = rawIndices[ stride + 0 ];
309
+ const b = rawIndices[ stride + 1 ];
310
+ const c = rawIndices[ stride + 2 ];
311
+ const d = rawIndices[ stride + 3 ];
312
+
313
+ indices.push( a, b, c );
314
+ indices.push( a, c, d );
315
+
316
+ } else {
317
+
318
+ console.warn( 'THREE.USDZLoader: Face vertex count of %s unsupported.', count );
319
+
320
+ }
321
+
322
+ }
323
+
324
+ return indices;
325
+
326
+ }
327
+
328
+ function toFlatBufferAttribute( attribute, indices ) {
329
+
330
+ const array = attribute.array;
331
+ const itemSize = attribute.itemSize;
332
+
333
+ const array2 = new array.constructor( indices.length * itemSize );
334
+
335
+ let index = 0, index2 = 0;
336
+
337
+ for ( let i = 0, l = indices.length; i < l; i ++ ) {
338
+
339
+ index = indices[ i ] * itemSize;
340
+
341
+ for ( let j = 0; j < itemSize; j ++ ) {
342
+
343
+ array2[ index2 ++ ] = array[ index ++ ];
344
+
345
+ }
346
+
347
+ }
348
+
349
+ return new BufferAttribute( array2, itemSize );
350
+
351
+ }
352
+
353
+ function findMeshMaterial( data ) {
354
+
355
+ if ( ! data ) return undefined;
356
+
357
+ if ( 'rel material:binding' in data ) {
358
+
359
+ const reference = data[ 'rel material:binding' ];
360
+ const id = reference.replace( /^<\//, '' ).replace( />$/, '' );
361
+ const parts = id.split( '/' );
362
+
363
+ return findMaterial( root, ` "${ parts[ 1 ] }"` );
364
+
365
+ }
366
+
367
+ return findMaterial( data );
368
+
369
+ }
370
+
371
+ function findMaterial( data, id = '' ) {
372
+
373
+ for ( const name in data ) {
374
+
375
+ const object = data[ name ];
376
+
377
+ if ( name.startsWith( 'def Material' + id ) ) {
378
+
379
+ return object;
380
+
381
+ }
382
+
383
+ if ( typeof object === 'object' ) {
384
+
385
+ const material = findMaterial( object, id );
386
+
387
+ if ( material ) return material;
388
+
389
+ }
390
+
391
+ }
392
+
393
+ }
394
+
395
+ function setTextureParams( map, data_value ) {
396
+
397
+ // rotation, scale and translation
398
+
399
+ if ( data_value[ 'float inputs:rotation' ] ) {
400
+
401
+ map.rotation = parseFloat( data_value[ 'float inputs:rotation' ] );
402
+
403
+ }
404
+
405
+ if ( data_value[ 'float2 inputs:scale' ] ) {
406
+
407
+ map.repeat = new Vector2().fromArray( JSON.parse( '[' + data_value[ 'float2 inputs:scale' ].replace( /[()]*/g, '' ) + ']' ) );
408
+
409
+ }
410
+
411
+ if ( data_value[ 'float2 inputs:translation' ] ) {
412
+
413
+ map.offset = new Vector2().fromArray( JSON.parse( '[' + data_value[ 'float2 inputs:translation' ].replace( /[()]*/g, '' ) + ']' ) );
414
+
415
+ }
416
+
417
+ }
418
+
419
+ function buildMaterial( data ) {
420
+
421
+ const material = new MeshPhysicalMaterial();
422
+
423
+ if ( data !== undefined ) {
424
+
425
+ let surface = undefined;
426
+
427
+ const surfaceConnection = data[ 'token outputs:surface.connect' ];
428
+
429
+ if ( surfaceConnection ) {
430
+
431
+ const match = /(\w+)\.output/.exec( surfaceConnection );
432
+
433
+ if ( match ) {
434
+
435
+ const surfaceName = match[ 1 ];
436
+ surface = data[ `def Shader "${surfaceName}"` ];
437
+
438
+ }
439
+
440
+ }
441
+
442
+ if ( surface !== undefined ) {
443
+
444
+ if ( 'color3f inputs:diffuseColor.connect' in surface ) {
445
+
446
+ const path = surface[ 'color3f inputs:diffuseColor.connect' ];
447
+ const sampler = findTexture( root, /(\w+).output/.exec( path )[ 1 ] );
448
+
449
+ material.map = buildTexture( sampler );
450
+ material.map.colorSpace = SRGBColorSpace;
451
+
452
+ if ( 'def Shader "Transform2d_diffuse"' in data ) {
453
+
454
+ setTextureParams( material.map, data[ 'def Shader "Transform2d_diffuse"' ] );
455
+
456
+ }
457
+
458
+ } else if ( 'color3f inputs:diffuseColor' in surface ) {
459
+
460
+ const color = surface[ 'color3f inputs:diffuseColor' ].replace( /[()]*/g, '' );
461
+ material.color.fromArray( JSON.parse( '[' + color + ']' ) );
462
+
463
+ }
464
+
465
+ if ( 'color3f inputs:emissiveColor.connect' in surface ) {
466
+
467
+ const path = surface[ 'color3f inputs:emissiveColor.connect' ];
468
+ const sampler = findTexture( root, /(\w+).output/.exec( path )[ 1 ] );
469
+
470
+ material.emissiveMap = buildTexture( sampler );
471
+ material.emissiveMap.colorSpace = SRGBColorSpace;
472
+ material.emissive.set( 0xffffff );
473
+
474
+ if ( 'def Shader "Transform2d_emissive"' in data ) {
475
+
476
+ setTextureParams( material.emissiveMap, data[ 'def Shader "Transform2d_emissive"' ] );
477
+
478
+ }
479
+
480
+ } else if ( 'color3f inputs:emissiveColor' in surface ) {
481
+
482
+ const color = surface[ 'color3f inputs:emissiveColor' ].replace( /[()]*/g, '' );
483
+ material.emissive.fromArray( JSON.parse( '[' + color + ']' ) );
484
+
485
+ }
486
+
487
+ if ( 'normal3f inputs:normal.connect' in surface ) {
488
+
489
+ const path = surface[ 'normal3f inputs:normal.connect' ];
490
+ const sampler = findTexture( root, /(\w+).output/.exec( path )[ 1 ] );
491
+
492
+ material.normalMap = buildTexture( sampler );
493
+ material.normalMap.colorSpace = NoColorSpace;
494
+
495
+ if ( 'def Shader "Transform2d_normal"' in data ) {
496
+
497
+ setTextureParams( material.normalMap, data[ 'def Shader "Transform2d_normal"' ] );
498
+
499
+ }
500
+
501
+ }
502
+
503
+ if ( 'float inputs:roughness.connect' in surface ) {
504
+
505
+ const path = surface[ 'float inputs:roughness.connect' ];
506
+ const sampler = findTexture( root, /(\w+).output/.exec( path )[ 1 ] );
507
+
508
+ material.roughness = 1.0;
509
+ material.roughnessMap = buildTexture( sampler );
510
+ material.roughnessMap.colorSpace = NoColorSpace;
511
+
512
+ if ( 'def Shader "Transform2d_roughness"' in data ) {
513
+
514
+ setTextureParams( material.roughnessMap, data[ 'def Shader "Transform2d_roughness"' ] );
515
+
516
+ }
517
+
518
+ } else if ( 'float inputs:roughness' in surface ) {
519
+
520
+ material.roughness = parseFloat( surface[ 'float inputs:roughness' ] );
521
+
522
+ }
523
+
524
+ if ( 'float inputs:metallic.connect' in surface ) {
525
+
526
+ const path = surface[ 'float inputs:metallic.connect' ];
527
+ const sampler = findTexture( root, /(\w+).output/.exec( path )[ 1 ] );
528
+
529
+ material.metalness = 1.0;
530
+ material.metalnessMap = buildTexture( sampler );
531
+ material.metalnessMap.colorSpace = NoColorSpace;
532
+
533
+ if ( 'def Shader "Transform2d_metallic"' in data ) {
534
+
535
+ setTextureParams( material.metalnessMap, data[ 'def Shader "Transform2d_metallic"' ] );
536
+
537
+ }
538
+
539
+ } else if ( 'float inputs:metallic' in surface ) {
540
+
541
+ material.metalness = parseFloat( surface[ 'float inputs:metallic' ] );
542
+
543
+ }
544
+
545
+ if ( 'float inputs:clearcoat.connect' in surface ) {
546
+
547
+ const path = surface[ 'float inputs:clearcoat.connect' ];
548
+ const sampler = findTexture( root, /(\w+).output/.exec( path )[ 1 ] );
549
+
550
+ material.clearcoat = 1.0;
551
+ material.clearcoatMap = buildTexture( sampler );
552
+ material.clearcoatMap.colorSpace = NoColorSpace;
553
+
554
+ if ( 'def Shader "Transform2d_clearcoat"' in data ) {
555
+
556
+ setTextureParams( material.clearcoatMap, data[ 'def Shader "Transform2d_clearcoat"' ] );
557
+
558
+ }
559
+
560
+ } else if ( 'float inputs:clearcoat' in surface ) {
561
+
562
+ material.clearcoat = parseFloat( surface[ 'float inputs:clearcoat' ] );
563
+
564
+ }
565
+
566
+ if ( 'float inputs:clearcoatRoughness.connect' in surface ) {
567
+
568
+ const path = surface[ 'float inputs:clearcoatRoughness.connect' ];
569
+ const sampler = findTexture( root, /(\w+).output/.exec( path )[ 1 ] );
570
+
571
+ material.clearcoatRoughness = 1.0;
572
+ material.clearcoatRoughnessMap = buildTexture( sampler );
573
+ material.clearcoatRoughnessMap.colorSpace = NoColorSpace;
574
+
575
+ if ( 'def Shader "Transform2d_clearcoatRoughness"' in data ) {
576
+
577
+ setTextureParams( material.clearcoatRoughnessMap, data[ 'def Shader "Transform2d_clearcoatRoughness"' ] );
578
+
579
+ }
580
+
581
+ } else if ( 'float inputs:clearcoatRoughness' in surface ) {
582
+
583
+ material.clearcoatRoughness = parseFloat( surface[ 'float inputs:clearcoatRoughness' ] );
584
+
585
+ }
586
+
587
+ if ( 'float inputs:ior' in surface ) {
588
+
589
+ material.ior = parseFloat( surface[ 'float inputs:ior' ] );
590
+
591
+ }
592
+
593
+ if ( 'float inputs:occlusion.connect' in surface ) {
594
+
595
+ const path = surface[ 'float inputs:occlusion.connect' ];
596
+ const sampler = findTexture( root, /(\w+).output/.exec( path )[ 1 ] );
597
+
598
+ material.aoMap = buildTexture( sampler );
599
+ material.aoMap.colorSpace = NoColorSpace;
600
+
601
+ if ( 'def Shader "Transform2d_occlusion"' in data ) {
602
+
603
+ setTextureParams( material.aoMap, data[ 'def Shader "Transform2d_occlusion"' ] );
604
+
605
+ }
606
+
607
+ }
608
+
609
+ }
610
+
611
+ }
612
+
613
+ return material;
614
+
615
+ }
616
+
617
+ function findTexture( data, id ) {
618
+
619
+ for ( const name in data ) {
620
+
621
+ const object = data[ name ];
622
+
623
+ if ( name.startsWith( `def Shader "${ id }"` ) ) {
624
+
625
+ return object;
626
+
627
+ }
628
+
629
+ if ( typeof object === 'object' ) {
630
+
631
+ const texture = findTexture( object, id );
632
+
633
+ if ( texture ) return texture;
634
+
635
+ }
636
+
637
+ }
638
+
639
+ }
640
+
641
+ function buildTexture( data ) {
642
+
643
+ if ( 'asset inputs:file' in data ) {
644
+
645
+ const path = data[ 'asset inputs:file' ].replace( /@*/g, '' ).trim();
646
+
647
+ const loader = new TextureLoader();
648
+
649
+ const texture = loader.load( assets[ path ] );
650
+
651
+ const map = {
652
+ '"clamp"': ClampToEdgeWrapping,
653
+ '"mirror"': MirroredRepeatWrapping,
654
+ '"repeat"': RepeatWrapping
655
+ };
656
+
657
+ if ( 'token inputs:wrapS' in data ) {
658
+
659
+ texture.wrapS = map[ data[ 'token inputs:wrapS' ] ];
660
+
661
+ }
662
+
663
+ if ( 'token inputs:wrapT' in data ) {
664
+
665
+ texture.wrapT = map[ data[ 'token inputs:wrapT' ] ];
666
+
667
+ }
668
+
669
+ return texture;
670
+
671
+ }
672
+
673
+ return null;
674
+
675
+ }
676
+
677
+ function buildObject( data ) {
678
+
679
+ const geometry = buildGeometry( findMeshGeometry( data ) );
680
+ const material = buildMaterial( findMeshMaterial( data ) );
681
+
682
+ const mesh = geometry ? new Mesh( geometry, material ) : new Object3D();
683
+
684
+ if ( 'matrix4d xformOp:transform' in data ) {
685
+
686
+ const array = JSON.parse( '[' + data[ 'matrix4d xformOp:transform' ].replace( /[()]*/g, '' ) + ']' );
687
+
688
+ mesh.matrix.fromArray( array );
689
+ mesh.matrix.decompose( mesh.position, mesh.quaternion, mesh.scale );
690
+
691
+ }
692
+
693
+ return mesh;
694
+
695
+ }
696
+
697
+ function buildHierarchy( data, group ) {
698
+
699
+ for ( const name in data ) {
700
+
701
+ if ( name.startsWith( 'def Scope' ) ) {
702
+
703
+ buildHierarchy( data[ name ], group );
704
+
705
+ } else if ( name.startsWith( 'def Xform' ) ) {
706
+
707
+ const mesh = buildObject( data[ name ] );
708
+
709
+ if ( /def Xform "(\w+)"/.test( name ) ) {
710
+
711
+ mesh.name = /def Xform "(\w+)"/.exec( name )[ 1 ];
712
+
713
+ }
714
+
715
+ group.add( mesh );
716
+
717
+ buildHierarchy( data[ name ], mesh );
718
+
719
+ }
720
+
721
+ }
722
+
723
+ }
724
+
725
+ function buildGroup( data ) {
726
+
727
+ const group = new Group();
728
+
729
+ buildHierarchy( data, group );
730
+
731
+ return group;
732
+
733
+ }
734
+
735
+ return buildGroup( root );
736
+
737
+ }
738
+
739
+ }
740
+
741
+ export { USDAParser };