66import * as fflate from '../libs/fflate.module.js' ;
77import { USDAParser } from './usd/USDAParser.js' ;
88import { USDCParser } from './usd/USDCParser.js' ;
9+ import { USDComposer } from './usd/USDComposer.js' ;
910
1011/**
1112 * A loader for the USD format (USDA, USDC, USDZ).
@@ -114,12 +115,19 @@ class USDLoader extends Loader {
114115
115116 if ( isCrateFile ( zip [ filename ] ) ) {
116117
117- data [ filename ] = usdc . parse ( zip [ filename ] . buffer , data ) ;
118+ // Store parsed data (specsByPath) for on-demand composition
119+ const parsedData = usdc . parseData ( zip [ filename ] . buffer ) ;
120+ data [ filename ] = parsedData ;
121+ // Store raw buffer for re-parsing with variant selections
122+ data [ filename + ':buffer' ] = zip [ filename ] . buffer ;
118123
119124 } else {
120125
121126 const text = fflate . strFromU8 ( zip [ filename ] ) ;
122- data [ filename ] = usda . parseText ( text ) ;
127+ // Store parsed data (specsByPath) for on-demand composition
128+ data [ filename ] = usda . parseData ( text ) ;
129+ // Store raw text for re-parsing with variant selections
130+ data [ filename + ':text' ] = text ;
123131
124132 }
125133
@@ -151,15 +159,18 @@ class USDLoader extends Loader {
151159
152160 function findUSD ( zip ) {
153161
154- if ( zip . length < 1 ) return undefined ;
162+ if ( zip . length < 1 ) return { file : undefined , basePath : '' } ;
155163
156164 const firstFileName = Object . keys ( zip ) [ 0 ] ;
157165 let isCrate = false ;
158166
167+ const lastSlash = firstFileName . lastIndexOf ( '/' ) ;
168+ const basePath = lastSlash >= 0 ? firstFileName . slice ( 0 , lastSlash ) : '' ;
169+
159170 // As per the USD specification, the first entry in the zip archive is used as the main file ("UsdStage").
160171 // ASCII files can end in either .usda or .usd.
161172 // See https://openusd.org/release/spec_usdz.html#layout
162- if ( firstFileName . endsWith ( 'usda' ) ) return zip [ firstFileName ] ;
173+ if ( firstFileName . endsWith ( 'usda' ) ) return { file : zip [ firstFileName ] , basePath } ;
163174
164175 if ( firstFileName . endsWith ( 'usdc' ) ) {
165176
@@ -170,7 +181,7 @@ class USDLoader extends Loader {
170181 // If this is not a crate file, we assume it is a plain USDA file.
171182 if ( ! isCrateFile ( zip [ firstFileName ] ) ) {
172183
173- return zip [ firstFileName ] ;
184+ return { file : zip [ firstFileName ] , basePath } ;
174185
175186 } else {
176187
@@ -182,25 +193,31 @@ class USDLoader extends Loader {
182193
183194 if ( isCrate ) {
184195
185- return zip [ firstFileName ] ;
196+ return { file : zip [ firstFileName ] , basePath } ;
186197
187198 }
188199
200+ return { file : undefined , basePath : '' } ;
201+
189202 }
190203
191- // USDA
204+ // USDA (standalone)
192205
193206 if ( typeof buffer === 'string' ) {
194207
195- return usda . parse ( buffer , { } ) ;
208+ const composer = new USDComposer ( ) ;
209+ const data = usda . parseData ( buffer ) ;
210+ return composer . compose ( data , { } ) ;
196211
197212 }
198213
199- // USDC
214+ // USDC (standalone)
200215
201216 if ( isCrateFile ( buffer ) ) {
202217
203- return usdc . parse ( buffer ) ;
218+ const composer = new USDComposer ( ) ;
219+ const data = usdc . parseData ( buffer ) ;
220+ return composer . compose ( data , { } ) ;
204221
205222 }
206223
@@ -210,20 +227,24 @@ class USDLoader extends Loader {
210227
211228 const assets = parseAssets ( zip ) ;
212229
213- // console.log( assets );
230+ const { file , basePath } = findUSD ( zip ) ;
214231
215- const file = findUSD ( zip ) ;
232+ // Compose the main file using USDComposer (works for both USDC and USDA)
233+ const composer = new USDComposer ( ) ;
234+ let data ;
216235
217- // Check if the main file is USDC (binary) or USDA (ASCII)
218236 if ( isCrateFile ( file ) ) {
219237
220- return usdc . parse ( file . buffer , assets ) ;
238+ data = usdc . parseData ( file . buffer ) ;
221239
222- }
240+ } else {
223241
224- const text = fflate . strFromU8 ( file ) ;
242+ const text = fflate . strFromU8 ( file ) ;
243+ data = usda . parseData ( text ) ;
244+
245+ }
225246
226- return usda . parse ( text , assets ) ;
247+ return composer . compose ( data , assets , { } , basePath ) ;
227248
228249 }
229250
0 commit comments