@@ -32,161 +32,160 @@ export interface GltfGeneratorSchema {
32
32
verbose : boolean ;
33
33
}
34
34
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 ;
39
38
40
- const modelPath = join ( tree . root , options . modelPath ) ;
39
+ const { fileName , className } = names ( options . className ) ;
41
40
const log = new Log ( { debug : options . verbose , silent : false } ) ;
42
41
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
+
43
114
//
44
115
// Transform the GLTF file if necessary using gltf-transform
45
116
//
46
117
let size = '' ;
47
118
let transformedModelPath : string | undefined = undefined ;
48
119
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 ) ;
70
123
}
71
124
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 ;
128
126
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 ( ) ;
138
135
}
139
136
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
+ } ) ;
143
173
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 ( ) ;
146
187
}
147
188
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
-
190
189
await formatFiles ( tree ) ;
191
190
}
192
191
0 commit comments