@@ -32,161 +32,160 @@ export interface GltfGeneratorSchema {
3232 verbose : boolean ;
3333}
3434
35- export async function gltfGenerator ( tree : Tree , options : GltfGeneratorSchema ) {
36- const { loadGLTF, AnalyzedGLTF, gltfTransform, Log, allPruneStrategies, compareFileSizes } = await import (
37- '@rosskevin/gltfjsx'
38- ) ;
35+ // @ts -expect-error - type only import
36+ function normalizeOptions ( tree : Tree , options : GltfGeneratorSchema , gltfJsx : typeof import ( '@rosskevin/gltfjsx' ) ) {
37+ const { Log } = gltfJsx ;
3938
40- const modelPath = join ( tree . root , options . modelPath ) ;
39+ const { fileName , className } = names ( options . className ) ;
4140 const log = new Log ( { debug : options . verbose , silent : false } ) ;
4241
42+ const gltfJsxOptions = {
43+ log,
44+ bones : options . bones ,
45+ meta : options . meta ,
46+ shadows : options . shadows ,
47+ instance : options . instance ,
48+ instanceall : options . instanceAll ,
49+ keepgroups : options . keepGroups ,
50+ keepnames : options . keepNames ,
51+ precision : options . precision ,
52+ } ;
53+
54+ const transformOptions = {
55+ format : options . format ,
56+ degrade : options . degrade ,
57+ degraderesolution : options . degradeResolution ,
58+ simplify : options . simplify ? { ratio : options . ratio , error : options . error } : false ,
59+ keepattributes : options . keepAttributes ,
60+ keepmeshes : options . keepMeshes ,
61+ keepmaterials : options . keepMaterials ,
62+ resolution : options . resolution ,
63+ } ;
64+
65+ const modelPathFromRoot = join ( tree . root , options . modelPath ) ;
66+ const outputDir = dirname ( options . output ) ;
67+
68+ const injectGLTFOptions = options . draco ? `{ useDraco: true }` : '' ;
69+
70+ const selector = `${ options . selectorPrefix } -${ fileName } ` ;
71+
72+ const gltfAnimationTypeName = className + 'AnimationClips' ;
73+ const gltfAnimationApiTypeName = className + 'AnimationApi' ;
74+ const gltfName = className + 'GLTF' ;
75+ const gltfResultTypeName = gltfName + 'GLTFResult' ;
76+
77+ return {
78+ log,
79+ selector,
80+ fileName,
81+ className,
82+ gltfJsxOptions,
83+ transformOptions,
84+ modelPathFromRoot,
85+ outputDir,
86+ injectGLTFOptions,
87+ gltfAnimationTypeName,
88+ gltfAnimationApiTypeName,
89+ gltfName,
90+ gltfResultTypeName,
91+ } ;
92+ }
93+
94+ export async function gltfGenerator ( tree : Tree , options : GltfGeneratorSchema ) {
95+ const gltfjsx = await import ( '@rosskevin/gltfjsx' ) ;
96+ const { loadGLTF, AnalyzedGLTF, gltfTransform, compareFileSizes } = gltfjsx ;
97+
98+ const {
99+ selector,
100+ className,
101+ fileName,
102+ modelPathFromRoot,
103+ log,
104+ gltfJsxOptions,
105+ transformOptions,
106+ outputDir,
107+ injectGLTFOptions,
108+ gltfAnimationTypeName,
109+ gltfAnimationApiTypeName,
110+ gltfName,
111+ gltfResultTypeName,
112+ } = normalizeOptions ( tree , options , gltfjsx ) ;
113+
43114 //
44115 // Transform the GLTF file if necessary using gltf-transform
45116 //
46117 let size = '' ;
47118 let transformedModelPath : string | undefined = undefined ;
48119 if ( options . transform ) {
49- transformedModelPath = resolve ( modelPath + '-transformed.glb' ) ;
50- await gltfTransform ( modelPath , transformedModelPath , {
51- format : options . format ,
52- degrade : options . degrade ,
53- degraderesolution : options . degradeResolution ,
54- simplify : options . simplify ? { ratio : options . ratio , error : options . error } : false ,
55- log,
56- bones : options . bones ,
57- meta : options . meta ,
58- shadows : options . shadows ,
59- instance : options . instance ,
60- instanceall : options . instanceAll ,
61- keepgroups : options . keepGroups ,
62- keepnames : options . keepNames ,
63- precision : options . precision ,
64- keepattributes : options . keepAttributes ,
65- keepmeshes : options . keepMeshes ,
66- keepmaterials : options . keepMaterials ,
67- resolution : options . resolution ,
68- } ) ;
69- size = compareFileSizes ( modelPath , transformedModelPath ) ;
120+ transformedModelPath = resolve ( modelPathFromRoot + '-transformed.glb' ) ;
121+ await gltfTransform ( modelPathFromRoot , transformedModelPath , Object . assign ( transformOptions , gltfJsxOptions ) ) ;
122+ size = compareFileSizes ( modelPathFromRoot , transformedModelPath ) ;
70123 }
71124
72- const gltf = await loadGLTF ( modelPath ) ;
73-
74- const analyzed = new AnalyzedGLTF (
75- gltf ,
76- {
77- log,
78- bones : options . bones ,
79- meta : options . meta ,
80- shadows : options . shadows ,
81- instance : options . instance ,
82- instanceall : options . instanceAll ,
83- keepgroups : options . keepGroups ,
84- keepnames : options . keepNames ,
85- precision : options . precision ,
86- } ,
87- allPruneStrategies ,
88- ) ;
89-
90- const generateNGT = new GenerateNGT ( analyzed , options ) ;
91-
92- const scene = await generateNGT . generate ( ) ;
93-
94- const args = generateNGT . args ;
95- const perspective = generateNGT . ngtTypes . has ( 'PerspectiveCamera' ) ;
96- const orthographic = generateNGT . ngtTypes . has ( 'OrthographicCamera' ) ;
97-
98- const { className, fileName } = names ( options . className ) ;
99- const gltfExtras = analyzed . gltf . parser . json . asset && analyzed . gltf . parser . json . asset . extras ;
100- const extras = gltfExtras
101- ? Object . keys ( gltfExtras )
102- . map ( ( key ) => `${ key . charAt ( 0 ) . toUpperCase ( ) + key . slice ( 1 ) } : ${ gltfExtras [ key ] } ` )
103- . join ( '\n' )
104- : '' ;
105-
106- const ngtTypesArr = Array . from ( generateNGT . ngtTypes ) . filter (
107- ( t ) =>
108- // group always is the top-level object
109- t !== 'Group' &&
110- // we render ngts-perspective-camera instead of ngt-perspective-camera
111- t !== 'PerspectiveCamera' &&
112- // we render ngts-orthographic-camera instead of ngt-orthographic-camera
113- t !== 'OrthographicCamera' &&
114- // we don't render ngt-bone
115- t !== 'Bone' &&
116- // we don't render ngt-object3D
117- t !== 'Object3D' ,
118- ) ;
119- const threeImports = ngtTypesArr . length ? `, ${ ngtTypesArr . join ( ',' ) } ` : '' ;
120- let gltfPath =
121- ! transformedModelPath && modelPath . startsWith ( 'http' )
122- ? modelPath
123- : relative ( dirname ( options . output ) , transformedModelPath || modelPath ) ;
124-
125- if ( ! gltfPath . startsWith ( 'http' ) && ! gltfPath . startsWith ( '.' ) ) {
126- gltfPath = `./${ gltfPath } ` ;
127- }
125+ const modelPath = transformedModelPath || modelPathFromRoot ;
128126
129- const gltfAnimationTypeName = className + 'AnimationClips' ;
130- const gltfAnimationApiTypeName = className + 'AnimationApi' ;
131- const gltfName = className + 'GLTF' ;
132- const gltfResultTypeName = gltfName + 'GLTFResult' ;
133-
134- const angularImports = [ ] ;
135-
136- if ( args ) {
137- angularImports . push ( 'NgtArgs' ) ;
127+ //
128+ // Read the model
129+ //
130+ let dracoLoader : import ( 'node-three-gltf' ) . DRACOLoader | undefined = undefined ; // global instance, instantiate once, dispose once
131+ if ( options . draco ) {
132+ log . debug ( 'Instantiating DracoLoader' ) ;
133+ const { DRACOLoader } = await import ( 'node-three-gltf' ) ;
134+ dracoLoader = new DRACOLoader ( ) ;
138135 }
139136
140- if ( perspective ) {
141- angularImports . push ( 'NgtsPerspectiveCamera' ) ;
142- }
137+ log . debug ( 'Loading model: ' , modelPath ) ;
138+
139+ try {
140+ const gltf = await loadGLTF ( modelPath , dracoLoader ) ;
141+ const analyzed = new AnalyzedGLTF ( gltf , gltfJsxOptions ) ;
142+ const generateNGT = new GenerateNGT ( analyzed , gltfjsx , options ) ;
143+
144+ const scene = generateNGT . generate ( ) ;
145+ const generateOptions = generateNGT . getGenerateOptions ( ) ;
146+
147+ let gltfPath =
148+ ! transformedModelPath && modelPath . startsWith ( 'http' ) ? modelPath : relative ( outputDir , modelPath ) ;
149+
150+ if ( ! gltfPath . startsWith ( 'http' ) && ! gltfPath . startsWith ( '.' ) ) {
151+ gltfPath = `./${ gltfPath } ` ;
152+ }
153+
154+ generateFiles ( tree , join ( __dirname , 'files' ) , outputDir , {
155+ tmpl : '' ,
156+ ...generateOptions ,
157+ scene,
158+ fileName,
159+ className,
160+ selector,
161+ animations : analyzed . gltf . animations || [ ] ,
162+ useImportAttribute : ! modelPath . startsWith ( 'http' ) ,
163+ preload : true ,
164+ gltfName,
165+ gltfAnimationTypeName,
166+ gltfAnimationApiTypeName,
167+ gltfResultTypeName,
168+ gltfPath,
169+ gltfOptions : injectGLTFOptions ,
170+ header : options . header ,
171+ size,
172+ } ) ;
143173
144- if ( perspective ) {
145- angularImports . push ( 'NgtsOrthographicCamera' ) ;
174+ if ( options . console ) {
175+ const outputPath = join ( outputDir , `${ fileName } .ts` ) ;
176+ const outputContent = tree . read ( outputPath , 'utf8' ) ;
177+ console . log ( outputContent ) ;
178+ tree . delete ( outputPath ) ;
179+ }
180+ } catch ( err ) {
181+ log . error ( err ) ;
182+ dracoLoader ?. dispose ( ) ;
183+ return process . exit ( 1 ) ;
184+ } finally {
185+ log . debug ( 'Disposing of DracoLoader' ) ;
186+ dracoLoader ?. dispose ( ) ;
146187 }
147188
148- const gltfOptions = options . draco ? `{ useDraco: true }` : '' ;
149- const meshesTypes = analyzed
150- . getMeshes ( )
151- . map ( ( { name, type } ) => "\'" + name + "\'" + ': THREE.' + type )
152- . join ( ';\n' ) ;
153- const bonesTypes = analyzed
154- . getBones ( )
155- . map ( ( { name, type } ) => "\'" + name + "\'" + ': THREE.' + type )
156- . join ( ';\n' ) ;
157- const materials = analyzed . getMaterials ( ) ;
158- const materialsTypes = materials . map ( ( { name, type } ) => "\'" + name + "\'" + ': THREE.' + type ) . join ( ';\n' ) ;
159-
160- log . debug ( materialsTypes ) ;
161-
162- generateFiles ( tree , join ( __dirname , 'files' ) , dirname ( options . output ) , {
163- tmpl : '' ,
164- scene,
165- fileName,
166- className,
167- selector : `${ options . selectorPrefix } -${ fileName } ` ,
168- animations : analyzed . gltf . animations || [ ] ,
169- extras,
170- threeImports,
171- args,
172- perspective,
173- orthographic,
174- useImportAttribute : ! modelPath . startsWith ( 'http' ) ,
175- preload : true ,
176- gltfName,
177- gltfAnimationTypeName,
178- gltfAnimationApiTypeName,
179- gltfResultTypeName,
180- gltfPath,
181- gltfOptions,
182- meshesTypes,
183- bonesTypes,
184- materialsTypes,
185- angularImports,
186- header : options . header ,
187- size,
188- } ) ;
189-
190189 await formatFiles ( tree ) ;
191190}
192191
0 commit comments