elation-engine 0.9.113 → 0.9.115
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.
- package/css/systems/render.css +5 -1
- package/package.json +1 -1
- package/scripts/assets.js +103 -20
- package/scripts/assetworker.js +18 -1
- package/scripts/external/holoplay.js +1494 -0
- package/scripts/external/octree.js +0 -0
- package/scripts/external/three/CSS3DRenderer.js +46 -43
- package/scripts/external/three/CubemapToEquirectangular.js +1 -1
- package/scripts/external/three/three-extras.js +1553 -392
- package/scripts/external/three/three-icosa.js +2575 -0
- package/scripts/external/three/three-loaders.js +925 -133
- package/scripts/external/three/three-postprocessing.js +3 -3
- package/scripts/external/three/three-r116dev.js +50930 -0
- package/scripts/external/three/three-spotlighttextures.js +50953 -0
- package/scripts/external/three/three-vrm.js +2 -2
- package/scripts/external/three/three-working.js +35968 -0
- package/scripts/external/three/three.js +38532 -24087
- package/scripts/external/three-mesh-bvh.js +5370 -0
- package/scripts/external/three-old/BVHLoader.js +406 -0
- package/scripts/external/three-old/ColladaLoader.js +5519 -0
- package/scripts/external/three-old/ColladaLoader2.js +1694 -0
- package/scripts/external/three-old/CubemapToEquirectangular.js +188 -0
- package/scripts/external/three-old/DDSLoader.js +269 -0
- package/scripts/external/three-old/FBXLoader-mine.js +5063 -0
- package/scripts/external/three-old/FBXLoader.js +5112 -0
- package/scripts/external/three-old/FlyControls.js +295 -0
- package/scripts/external/three-old/GLTF2Loader.js +2950 -0
- package/scripts/external/three-old/GLTFLoader.js +2213 -0
- package/scripts/external/three-old/JSONLoader.js +435 -0
- package/scripts/external/three-old/MTLLoader.js +533 -0
- package/scripts/external/three-old/OBJLoader-experimental.js +874 -0
- package/scripts/external/three-old/OBJLoader-working.js +727 -0
- package/scripts/external/three-old/OBJLoader.js +723 -0
- package/scripts/external/three-old/OBJMTLLoader.js +440 -0
- package/scripts/external/three-old/OrbitControls.js +592 -0
- package/scripts/external/three-old/PLYLoader.js +517 -0
- package/scripts/external/three-old/TransformControls.js +1100 -0
- package/scripts/external/three-old/VRMLLoader.js +1021 -0
- package/scripts/external/three-old/glTFLoader-combined.js +2513 -0
- package/scripts/external/three-old/nodethree.js +44018 -0
- package/scripts/external/three-old/render/BleachBypassShader.js +64 -0
- package/scripts/external/three-old/render/BloomPass.js +116 -0
- package/scripts/external/three-old/render/CSS3DRenderer.js +310 -0
- package/scripts/external/three-old/render/ClearPass.js +44 -0
- package/scripts/external/three-old/render/ConvolutionShader.js +101 -0
- package/scripts/external/three-old/render/CopyShader.js +46 -0
- package/scripts/external/three-old/render/EffectComposer.js +211 -0
- package/scripts/external/three-old/render/FXAAShader.js +88 -0
- package/scripts/external/three-old/render/FilmPass.js +60 -0
- package/scripts/external/three-old/render/FilmShader.js +104 -0
- package/scripts/external/three-old/render/ManualMSAARenderPass.js +168 -0
- package/scripts/external/three-old/render/MaskPass.js +97 -0
- package/scripts/external/three-old/render/OculusRenderPass.js +84 -0
- package/scripts/external/three-old/render/OculusRiftEffect.js +240 -0
- package/scripts/external/three-old/render/PortalRenderPass.js +166 -0
- package/scripts/external/three-old/render/RecordingPass.js +208 -0
- package/scripts/external/three-old/render/RenderPass.js +57 -0
- package/scripts/external/three-old/render/SSAOShader.js +259 -0
- package/scripts/external/three-old/render/SepiaShader.js +54 -0
- package/scripts/external/three-old/render/ShaderPass.js +66 -0
- package/scripts/external/three-old/render/VREffect.js +482 -0
- package/scripts/external/three-old/shimthree.js +23 -0
- package/scripts/external/three-old/stats.js +6 -0
- package/scripts/external/three-old/three-88dev.js +45004 -0
- package/scripts/external/three-old/three-backgroundoptimization.js +44432 -0
- package/scripts/external/three-old/three-updates.js +44735 -0
- package/scripts/external/three-old/three-working.js +44719 -0
- package/scripts/external/three-old/three.js +44431 -0
- package/scripts/external/three-old/threex.rendererstats.js +66 -0
- package/scripts/external/three-old/tween.js +13 -0
- package/scripts/external/webvr-polyfill-new.js +3497 -0
- package/scripts/external/webvr-polyfill-newest.js +3491 -0
- package/scripts/external/webvr-polyfill-old.js +6337 -0
- package/scripts/geometries.js +2 -2
- package/scripts/math.js +6 -6
- package/scripts/systems/admin.js +1 -1
- package/scripts/systems/controls.js +6 -4
- package/scripts/systems/physics.js +10 -10
- package/scripts/systems/render.js +58 -20
- package/scripts/systems/render2.js +38 -0
- package/scripts/things/camera.js +6 -1
- package/scripts/things/generic-trackedvectors.js +1875 -0
- package/scripts/things/generic.js +3 -4
- package/scripts/things/label2d.js +1 -1
- package/scripts/things/leapmotion.js +6 -6
- package/scripts/things/menu.js +1 -1
- package/scripts/things/player-bak.js +638 -0
- package/scripts/things/player.js +28 -10
- package/scripts/things/skysphere.js +1 -1
- package/scripts/things/terrain.js +1 -1
- package/scripts/things/text.js +1 -1
|
@@ -0,0 +1,2950 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author Rich Tibbett / https://github.com/richtr
|
|
3
|
+
* @author mrdoob / http://mrdoob.com/
|
|
4
|
+
* @author Tony Parisi / http://www.tonyparisi.com/
|
|
5
|
+
* @author Takahiro / https://github.com/takahirox
|
|
6
|
+
* @author Don McCurdy / https://www.donmccurdy.com
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
THREE.GLTF2Loader = ( function () {
|
|
10
|
+
|
|
11
|
+
function GLTF2Loader( manager ) {
|
|
12
|
+
|
|
13
|
+
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
GLTF2Loader.prototype = {
|
|
18
|
+
|
|
19
|
+
constructor: GLTF2Loader,
|
|
20
|
+
|
|
21
|
+
load: function ( url, onLoad, onProgress, onError ) {
|
|
22
|
+
|
|
23
|
+
var scope = this;
|
|
24
|
+
|
|
25
|
+
var path = this.path && ( typeof this.path === 'string' ) ? this.path : THREE.Loader.prototype.extractUrlBase( url );
|
|
26
|
+
|
|
27
|
+
var loader = new THREE.FileLoader( scope.manager );
|
|
28
|
+
|
|
29
|
+
loader.setResponseType( 'arraybuffer' );
|
|
30
|
+
|
|
31
|
+
loader.load( url, function ( data ) {
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
|
|
35
|
+
scope.parse( data, path, onLoad, onError );
|
|
36
|
+
|
|
37
|
+
} catch ( e ) {
|
|
38
|
+
|
|
39
|
+
// For SyntaxError or TypeError, return a generic failure message.
|
|
40
|
+
onError( e.constructor === Error ? e : new Error( 'THREE.GLTF2Loader: Unable to parse model.' ) );
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
}, onProgress, onError );
|
|
45
|
+
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
setCrossOrigin: function ( value ) {
|
|
49
|
+
|
|
50
|
+
this.crossOrigin = value;
|
|
51
|
+
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
setPath: function ( value ) {
|
|
55
|
+
|
|
56
|
+
this.path = value;
|
|
57
|
+
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
parse: function ( data, path, onLoad, onError ) {
|
|
61
|
+
|
|
62
|
+
var content;
|
|
63
|
+
var extensions = {};
|
|
64
|
+
|
|
65
|
+
var magic = convertUint8ArrayToString( new Uint8Array( data, 0, 4 ) );
|
|
66
|
+
|
|
67
|
+
if ( magic === BINARY_EXTENSION_HEADER_MAGIC ) {
|
|
68
|
+
|
|
69
|
+
extensions[ EXTENSIONS.KHR_BINARY_GLTF ] = new GLTFBinaryExtension( data );
|
|
70
|
+
content = extensions[ EXTENSIONS.KHR_BINARY_GLTF ].content;
|
|
71
|
+
|
|
72
|
+
} else {
|
|
73
|
+
|
|
74
|
+
content = convertUint8ArrayToString( new Uint8Array( data ) );
|
|
75
|
+
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
var json = JSON.parse( content );
|
|
79
|
+
|
|
80
|
+
if ( json.asset.version[0] < 2 ) {
|
|
81
|
+
|
|
82
|
+
onError( new Error( 'THREE.GLTF2Loader: Legacy glTF detected. Use THREE.GLTFLoader instead.' ) );
|
|
83
|
+
return;
|
|
84
|
+
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if ( json.extensionsUsed ) {
|
|
88
|
+
|
|
89
|
+
if( json.extensionsUsed.indexOf( EXTENSIONS.KHR_LIGHTS ) >= 0 ) {
|
|
90
|
+
|
|
91
|
+
extensions[ EXTENSIONS.KHR_LIGHTS ] = new GLTFLightsExtension( json );
|
|
92
|
+
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if( json.extensionsUsed.indexOf( EXTENSIONS.KHR_MATERIALS_COMMON ) >= 0 ) {
|
|
96
|
+
|
|
97
|
+
extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ] = new GLTFMaterialsCommonExtension( json );
|
|
98
|
+
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if( json.extensionsUsed.indexOf( EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ) >= 0 ) {
|
|
102
|
+
|
|
103
|
+
extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ] = new GLTFMaterialsPbrSpecularGlossinessExtension();
|
|
104
|
+
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if ( json.extensionsUsed.indexOf( EXTENSIONS.KHR_TECHNIQUE_WEBGL ) >= 0 ) {
|
|
108
|
+
|
|
109
|
+
extensions[ EXTENSIONS.KHR_TECHNIQUE_WEBGL ] = new GLTFTechniqueWebglExtension( json );
|
|
110
|
+
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
console.time( 'GLTF2Loader' );
|
|
116
|
+
|
|
117
|
+
var parser = new GLTFParser( json, extensions, {
|
|
118
|
+
|
|
119
|
+
path: path || this.path,
|
|
120
|
+
crossOrigin: this.crossOrigin
|
|
121
|
+
|
|
122
|
+
} );
|
|
123
|
+
|
|
124
|
+
parser.parse( function ( scene, scenes, cameras, animations ) {
|
|
125
|
+
|
|
126
|
+
console.timeEnd( 'GLTF2Loader' );
|
|
127
|
+
|
|
128
|
+
var glTF = {
|
|
129
|
+
scene: scene,
|
|
130
|
+
scenes: scenes,
|
|
131
|
+
cameras: cameras,
|
|
132
|
+
animations: animations
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
onLoad( glTF );
|
|
136
|
+
|
|
137
|
+
}, onError );
|
|
138
|
+
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
/* GLTFREGISTRY */
|
|
144
|
+
|
|
145
|
+
function GLTFRegistry() {
|
|
146
|
+
|
|
147
|
+
var objects = {};
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
|
|
151
|
+
get: function ( key ) {
|
|
152
|
+
|
|
153
|
+
return objects[ key ];
|
|
154
|
+
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
add: function ( key, object ) {
|
|
158
|
+
|
|
159
|
+
objects[ key ] = object;
|
|
160
|
+
|
|
161
|
+
},
|
|
162
|
+
|
|
163
|
+
remove: function ( key ) {
|
|
164
|
+
|
|
165
|
+
delete objects[ key ];
|
|
166
|
+
|
|
167
|
+
},
|
|
168
|
+
|
|
169
|
+
removeAll: function () {
|
|
170
|
+
|
|
171
|
+
objects = {};
|
|
172
|
+
|
|
173
|
+
},
|
|
174
|
+
|
|
175
|
+
update: function ( scene, camera ) {
|
|
176
|
+
|
|
177
|
+
for ( var name in objects ) {
|
|
178
|
+
|
|
179
|
+
var object = objects[ name ];
|
|
180
|
+
|
|
181
|
+
if ( object.update ) {
|
|
182
|
+
|
|
183
|
+
object.update( scene, camera );
|
|
184
|
+
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/* GLTFSHADER */
|
|
196
|
+
|
|
197
|
+
function GLTFShader( targetNode, allNodes ) {
|
|
198
|
+
|
|
199
|
+
var boundUniforms = {};
|
|
200
|
+
|
|
201
|
+
// bind each uniform to its source node
|
|
202
|
+
|
|
203
|
+
var uniforms = targetNode.material.uniforms;
|
|
204
|
+
|
|
205
|
+
for ( var uniformId in uniforms ) {
|
|
206
|
+
|
|
207
|
+
var uniform = uniforms[ uniformId ];
|
|
208
|
+
|
|
209
|
+
if ( uniform.semantic ) {
|
|
210
|
+
|
|
211
|
+
var sourceNodeRef = uniform.node;
|
|
212
|
+
|
|
213
|
+
var sourceNode = targetNode;
|
|
214
|
+
|
|
215
|
+
if ( sourceNodeRef ) {
|
|
216
|
+
|
|
217
|
+
sourceNode = allNodes[ sourceNodeRef ];
|
|
218
|
+
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
boundUniforms[ uniformId ] = {
|
|
222
|
+
semantic: uniform.semantic,
|
|
223
|
+
sourceNode: sourceNode,
|
|
224
|
+
targetNode: targetNode,
|
|
225
|
+
uniform: uniform
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
this.boundUniforms = boundUniforms;
|
|
233
|
+
this._m4 = new THREE.Matrix4();
|
|
234
|
+
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Update - update all the uniform values
|
|
238
|
+
GLTFShader.prototype.update = function ( scene, camera ) {
|
|
239
|
+
|
|
240
|
+
var boundUniforms = this.boundUniforms;
|
|
241
|
+
|
|
242
|
+
for ( var name in boundUniforms ) {
|
|
243
|
+
|
|
244
|
+
var boundUniform = boundUniforms[ name ];
|
|
245
|
+
|
|
246
|
+
switch ( boundUniform.semantic ) {
|
|
247
|
+
|
|
248
|
+
case 'MODELVIEW':
|
|
249
|
+
|
|
250
|
+
var m4 = boundUniform.uniform.value;
|
|
251
|
+
m4.multiplyMatrices( camera.matrixWorldInverse, boundUniform.sourceNode.matrixWorld );
|
|
252
|
+
break;
|
|
253
|
+
|
|
254
|
+
case 'MODELVIEWINVERSETRANSPOSE':
|
|
255
|
+
|
|
256
|
+
var m3 = boundUniform.uniform.value;
|
|
257
|
+
this._m4.multiplyMatrices( camera.matrixWorldInverse, boundUniform.sourceNode.matrixWorld );
|
|
258
|
+
m3.getNormalMatrix( this._m4 );
|
|
259
|
+
break;
|
|
260
|
+
|
|
261
|
+
case 'PROJECTION':
|
|
262
|
+
|
|
263
|
+
var m4 = boundUniform.uniform.value;
|
|
264
|
+
m4.copy( camera.projectionMatrix );
|
|
265
|
+
break;
|
|
266
|
+
|
|
267
|
+
case 'JOINTMATRIX':
|
|
268
|
+
|
|
269
|
+
var m4v = boundUniform.uniform.value;
|
|
270
|
+
|
|
271
|
+
for ( var mi = 0; mi < m4v.length; mi ++ ) {
|
|
272
|
+
|
|
273
|
+
// So it goes like this:
|
|
274
|
+
// SkinnedMesh world matrix is already baked into MODELVIEW;
|
|
275
|
+
// transform joints to local space,
|
|
276
|
+
// then transform using joint's inverse
|
|
277
|
+
m4v[ mi ]
|
|
278
|
+
.getInverse( boundUniform.sourceNode.matrixWorld )
|
|
279
|
+
.multiply( boundUniform.targetNode.skeleton.bones[ mi ].matrixWorld )
|
|
280
|
+
.multiply( boundUniform.targetNode.skeleton.boneInverses[ mi ] )
|
|
281
|
+
.multiply( boundUniform.targetNode.bindMatrix );
|
|
282
|
+
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
break;
|
|
286
|
+
|
|
287
|
+
default :
|
|
288
|
+
|
|
289
|
+
console.warn( 'THREE.GLTF2Loader: Unhandled shader semantic: ' + boundUniform.semantic );
|
|
290
|
+
break;
|
|
291
|
+
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
/*********************************/
|
|
299
|
+
/********** EXTENSIONS ***********/
|
|
300
|
+
/*********************************/
|
|
301
|
+
|
|
302
|
+
var EXTENSIONS = {
|
|
303
|
+
KHR_BINARY_GLTF: 'KHR_binary_glTF',
|
|
304
|
+
KHR_LIGHTS: 'KHR_lights',
|
|
305
|
+
KHR_MATERIALS_COMMON: 'KHR_materials_common',
|
|
306
|
+
KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: 'KHR_materials_pbrSpecularGlossiness',
|
|
307
|
+
KHR_TECHNIQUE_WEBGL: 'KHR_technique_webgl',
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Lights Extension
|
|
312
|
+
*
|
|
313
|
+
* Specification: PENDING
|
|
314
|
+
*/
|
|
315
|
+
function GLTFLightsExtension( json ) {
|
|
316
|
+
|
|
317
|
+
this.name = EXTENSIONS.KHR_LIGHTS;
|
|
318
|
+
|
|
319
|
+
this.lights = {};
|
|
320
|
+
|
|
321
|
+
var extension = ( json.extensions && json.extensions[ EXTENSIONS.KHR_LIGHTS ] ) || {};
|
|
322
|
+
var lights = extension.lights || {};
|
|
323
|
+
|
|
324
|
+
for ( var lightId in lights ) {
|
|
325
|
+
|
|
326
|
+
var light = lights[ lightId ];
|
|
327
|
+
var lightNode;
|
|
328
|
+
|
|
329
|
+
var color = new THREE.Color().fromArray( light.color );
|
|
330
|
+
|
|
331
|
+
switch ( light.type ) {
|
|
332
|
+
|
|
333
|
+
case 'directional':
|
|
334
|
+
lightNode = new THREE.DirectionalLight( color );
|
|
335
|
+
lightNode.position.set( 0, 0, 1 );
|
|
336
|
+
break;
|
|
337
|
+
|
|
338
|
+
case 'point':
|
|
339
|
+
lightNode = new THREE.PointLight( color );
|
|
340
|
+
break;
|
|
341
|
+
|
|
342
|
+
case 'spot':
|
|
343
|
+
lightNode = new THREE.SpotLight( color );
|
|
344
|
+
lightNode.position.set( 0, 0, 1 );
|
|
345
|
+
break;
|
|
346
|
+
|
|
347
|
+
case 'ambient':
|
|
348
|
+
lightNode = new THREE.AmbientLight( color );
|
|
349
|
+
break;
|
|
350
|
+
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if ( lightNode ) {
|
|
354
|
+
|
|
355
|
+
if ( light.constantAttenuation !== undefined ) {
|
|
356
|
+
|
|
357
|
+
lightNode.intensity = light.constantAttenuation;
|
|
358
|
+
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if ( light.linearAttenuation !== undefined ) {
|
|
362
|
+
|
|
363
|
+
lightNode.distance = 1 / light.linearAttenuation;
|
|
364
|
+
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
if ( light.quadraticAttenuation !== undefined ) {
|
|
368
|
+
|
|
369
|
+
lightNode.decay = light.quadraticAttenuation;
|
|
370
|
+
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
if ( light.fallOffAngle !== undefined ) {
|
|
374
|
+
|
|
375
|
+
lightNode.angle = light.fallOffAngle;
|
|
376
|
+
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
if ( light.fallOffExponent !== undefined ) {
|
|
380
|
+
|
|
381
|
+
console.warn( 'THREE.GLTF2Loader:: light.fallOffExponent not currently supported.' );
|
|
382
|
+
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
lightNode.name = light.name || ( 'light_' + lightId );
|
|
386
|
+
this.lights[ lightId ] = lightNode;
|
|
387
|
+
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Common Materials Extension
|
|
396
|
+
*
|
|
397
|
+
* Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/Khronos/KHR_materials_common
|
|
398
|
+
*/
|
|
399
|
+
function GLTFMaterialsCommonExtension( json ) {
|
|
400
|
+
|
|
401
|
+
this.name = EXTENSIONS.KHR_MATERIALS_COMMON;
|
|
402
|
+
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
GLTFMaterialsCommonExtension.prototype.getMaterialType = function ( material ) {
|
|
406
|
+
|
|
407
|
+
var khrMaterial = material.extensions[ this.name ];
|
|
408
|
+
|
|
409
|
+
switch ( khrMaterial.type ) {
|
|
410
|
+
|
|
411
|
+
case 'commonBlinn' :
|
|
412
|
+
case 'commonPhong' :
|
|
413
|
+
return THREE.MeshPhongMaterial;
|
|
414
|
+
|
|
415
|
+
case 'commonLambert' :
|
|
416
|
+
return THREE.MeshLambertMaterial;
|
|
417
|
+
|
|
418
|
+
case 'commonConstant' :
|
|
419
|
+
default :
|
|
420
|
+
return THREE.MeshBasicMaterial;
|
|
421
|
+
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
GLTFMaterialsCommonExtension.prototype.extendParams = function ( materialParams, material, dependencies ) {
|
|
427
|
+
|
|
428
|
+
var khrMaterial = material.extensions[ this.name ];
|
|
429
|
+
|
|
430
|
+
var keys = [];
|
|
431
|
+
|
|
432
|
+
// TODO: Currently ignored: 'ambientFactor', 'ambientTexture'
|
|
433
|
+
switch ( khrMaterial.type ) {
|
|
434
|
+
|
|
435
|
+
case 'commonBlinn' :
|
|
436
|
+
case 'commonPhong' :
|
|
437
|
+
keys.push( 'diffuseFactor', 'diffuseTexture', 'specularFactor', 'specularTexture', 'shininessFactor' );
|
|
438
|
+
break;
|
|
439
|
+
|
|
440
|
+
case 'commonLambert' :
|
|
441
|
+
keys.push( 'diffuseFactor', 'diffuseTexture' );
|
|
442
|
+
break;
|
|
443
|
+
|
|
444
|
+
case 'commonConstant' :
|
|
445
|
+
default :
|
|
446
|
+
break;
|
|
447
|
+
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
var materialValues = {};
|
|
451
|
+
|
|
452
|
+
keys.forEach( function( v ) {
|
|
453
|
+
|
|
454
|
+
if ( khrMaterial[ v ] !== undefined ) materialValues[ v ] = khrMaterial[ v ];
|
|
455
|
+
|
|
456
|
+
} );
|
|
457
|
+
|
|
458
|
+
if ( materialValues.diffuseFactor !== undefined ) {
|
|
459
|
+
|
|
460
|
+
materialParams.color = new THREE.Color().fromArray( materialValues.diffuseFactor );
|
|
461
|
+
materialParams.opacity = materialValues.diffuseFactor[ 3 ];
|
|
462
|
+
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
if ( materialValues.diffuseTexture !== undefined ) {
|
|
466
|
+
|
|
467
|
+
materialParams.map = dependencies.textures[ materialValues.diffuseTexture.index ];
|
|
468
|
+
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
if ( materialValues.specularFactor !== undefined ) {
|
|
472
|
+
|
|
473
|
+
materialParams.specular = new THREE.Color().fromArray( materialValues.specularFactor );
|
|
474
|
+
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
if ( materialValues.specularTexture !== undefined ) {
|
|
478
|
+
|
|
479
|
+
materialParams.specularMap = dependencies.textures[ materialValues.specularTexture.index ];
|
|
480
|
+
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
if ( materialValues.shininessFactor !== undefined ) {
|
|
484
|
+
|
|
485
|
+
materialParams.shininess = materialValues.shininessFactor;
|
|
486
|
+
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
};
|
|
490
|
+
|
|
491
|
+
/* BINARY EXTENSION */
|
|
492
|
+
|
|
493
|
+
var BINARY_EXTENSION_BUFFER_NAME = 'binary_glTF';
|
|
494
|
+
var BINARY_EXTENSION_HEADER_MAGIC = 'glTF';
|
|
495
|
+
var BINARY_EXTENSION_HEADER_LENGTH = 12;
|
|
496
|
+
var BINARY_EXTENSION_CHUNK_TYPES = { JSON: 0x4E4F534A, BIN: 0x004E4942 };
|
|
497
|
+
|
|
498
|
+
function GLTFBinaryExtension( data ) {
|
|
499
|
+
|
|
500
|
+
this.name = EXTENSIONS.KHR_BINARY_GLTF;
|
|
501
|
+
this.content = null;
|
|
502
|
+
this.body = null;
|
|
503
|
+
|
|
504
|
+
var headerView = new DataView( data, 0, BINARY_EXTENSION_HEADER_LENGTH );
|
|
505
|
+
|
|
506
|
+
this.header = {
|
|
507
|
+
magic: convertUint8ArrayToString( new Uint8Array( data.slice( 0, 4 ) ) ),
|
|
508
|
+
version: headerView.getUint32( 4, true ),
|
|
509
|
+
length: headerView.getUint32( 8, true )
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
if ( this.header.magic !== BINARY_EXTENSION_HEADER_MAGIC ) {
|
|
513
|
+
|
|
514
|
+
throw new Error( 'THREE.GLTF2Loader: Unsupported glTF-Binary header.' );
|
|
515
|
+
|
|
516
|
+
} else if ( this.header.version < 2.0 ) {
|
|
517
|
+
|
|
518
|
+
throw new Error( 'THREE.GLTF2Loader: Legacy binary file detected. Use GLTFLoader instead.' );
|
|
519
|
+
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
var chunkView = new DataView( data, BINARY_EXTENSION_HEADER_LENGTH );
|
|
523
|
+
var chunkIndex = 0;
|
|
524
|
+
|
|
525
|
+
while ( chunkIndex < chunkView.byteLength ) {
|
|
526
|
+
|
|
527
|
+
var chunkLength = chunkView.getUint32( chunkIndex, true );
|
|
528
|
+
chunkIndex += 4;
|
|
529
|
+
|
|
530
|
+
var chunkType = chunkView.getUint32( chunkIndex, true );
|
|
531
|
+
chunkIndex += 4;
|
|
532
|
+
|
|
533
|
+
if ( chunkType === BINARY_EXTENSION_CHUNK_TYPES.JSON ) {
|
|
534
|
+
|
|
535
|
+
var contentArray = new Uint8Array( data, BINARY_EXTENSION_HEADER_LENGTH + chunkIndex, chunkLength );
|
|
536
|
+
this.content = convertUint8ArrayToString( contentArray );
|
|
537
|
+
|
|
538
|
+
} else if ( chunkType === BINARY_EXTENSION_CHUNK_TYPES.BIN ) {
|
|
539
|
+
|
|
540
|
+
var byteOffset = BINARY_EXTENSION_HEADER_LENGTH + chunkIndex;
|
|
541
|
+
this.body = data.slice( byteOffset, byteOffset + chunkLength );
|
|
542
|
+
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// Clients must ignore chunks with unknown types.
|
|
546
|
+
|
|
547
|
+
chunkIndex += chunkLength;
|
|
548
|
+
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
if ( this.content === null ) {
|
|
552
|
+
|
|
553
|
+
throw new Error( 'THREE.GLTF2Loader: JSON content not found.' );
|
|
554
|
+
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/**
|
|
560
|
+
* WebGL Technique Extension
|
|
561
|
+
*
|
|
562
|
+
* Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/Khronos/KHR_technique_webgl
|
|
563
|
+
*/
|
|
564
|
+
function GLTFTechniqueWebglExtension( json ) {
|
|
565
|
+
|
|
566
|
+
this.name = EXTENSIONS.KHR_TECHNIQUE_WEBGL;
|
|
567
|
+
|
|
568
|
+
var extension = ( json.extensions && json.extensions[ EXTENSIONS.KHR_TECHNIQUE_WEBGL ] ) || {};
|
|
569
|
+
|
|
570
|
+
this.techniques = extension.techniques || {};
|
|
571
|
+
this.programs = extension.programs || {};
|
|
572
|
+
this.shaders = extension.shaders || {};
|
|
573
|
+
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
GLTFTechniqueWebglExtension.prototype.getMaterialType = function () {
|
|
577
|
+
|
|
578
|
+
return DeferredShaderMaterial;
|
|
579
|
+
|
|
580
|
+
};
|
|
581
|
+
|
|
582
|
+
GLTFTechniqueWebglExtension.prototype.extendParams = function ( materialParams, material, dependencies ) {
|
|
583
|
+
|
|
584
|
+
var extension = material[ EXTENSIONS.KHR_TECHNIQUE_WEBGL ];
|
|
585
|
+
var technique = dependencies.techniques[ extension.technique ];
|
|
586
|
+
|
|
587
|
+
materialParams.uniforms = {};
|
|
588
|
+
|
|
589
|
+
var program = dependencies.programs[ technique.program ];
|
|
590
|
+
|
|
591
|
+
if ( program === undefined ) {
|
|
592
|
+
|
|
593
|
+
return;
|
|
594
|
+
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
materialParams.fragmentShader = dependencies.shaders[ program.fragmentShader ];
|
|
598
|
+
|
|
599
|
+
if ( ! materialParams.fragmentShader ) {
|
|
600
|
+
|
|
601
|
+
throw new Error( 'THREE.GLTF2Loader: Missing fragment shader definition: ' + program.fragmentShader );
|
|
602
|
+
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
var vertexShader = dependencies.shaders[ program.vertexShader ];
|
|
606
|
+
|
|
607
|
+
if ( ! vertexShader ) {
|
|
608
|
+
|
|
609
|
+
throw new Error( 'THREE.GLTF2Loader: Missing vertex shader definition: ' + program.vertexShader );
|
|
610
|
+
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
// IMPORTANT: FIX VERTEX SHADER ATTRIBUTE DEFINITIONS
|
|
614
|
+
materialParams.vertexShader = replaceTHREEShaderAttributes( vertexShader, technique );
|
|
615
|
+
|
|
616
|
+
var uniforms = technique.uniforms;
|
|
617
|
+
|
|
618
|
+
for ( var uniformId in uniforms ) {
|
|
619
|
+
|
|
620
|
+
var pname = uniforms[ uniformId ];
|
|
621
|
+
var shaderParam = technique.parameters[ pname ];
|
|
622
|
+
|
|
623
|
+
var ptype = shaderParam.type;
|
|
624
|
+
|
|
625
|
+
if ( WEBGL_TYPE[ ptype ] ) {
|
|
626
|
+
|
|
627
|
+
var pcount = shaderParam.count;
|
|
628
|
+
var value;
|
|
629
|
+
|
|
630
|
+
if ( material.values !== undefined ) value = material.values[ pname ];
|
|
631
|
+
|
|
632
|
+
var uvalue = new WEBGL_TYPE[ ptype ]();
|
|
633
|
+
var usemantic = shaderParam.semantic;
|
|
634
|
+
var unode = shaderParam.node;
|
|
635
|
+
|
|
636
|
+
switch ( ptype ) {
|
|
637
|
+
|
|
638
|
+
case WEBGL_CONSTANTS.FLOAT:
|
|
639
|
+
|
|
640
|
+
uvalue = shaderParam.value;
|
|
641
|
+
|
|
642
|
+
if ( pname === 'transparency' ) {
|
|
643
|
+
|
|
644
|
+
materialParams.transparent = true;
|
|
645
|
+
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
if ( value !== undefined ) {
|
|
649
|
+
|
|
650
|
+
uvalue = value;
|
|
651
|
+
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
break;
|
|
655
|
+
|
|
656
|
+
case WEBGL_CONSTANTS.FLOAT_VEC2:
|
|
657
|
+
case WEBGL_CONSTANTS.FLOAT_VEC3:
|
|
658
|
+
case WEBGL_CONSTANTS.FLOAT_VEC4:
|
|
659
|
+
case WEBGL_CONSTANTS.FLOAT_MAT3:
|
|
660
|
+
|
|
661
|
+
if ( shaderParam && shaderParam.value ) {
|
|
662
|
+
|
|
663
|
+
uvalue.fromArray( shaderParam.value );
|
|
664
|
+
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
if ( value ) {
|
|
668
|
+
|
|
669
|
+
uvalue.fromArray( value );
|
|
670
|
+
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
break;
|
|
674
|
+
|
|
675
|
+
case WEBGL_CONSTANTS.FLOAT_MAT2:
|
|
676
|
+
|
|
677
|
+
// what to do?
|
|
678
|
+
console.warn( 'THREE.GLTF2Loader: FLOAT_MAT2 is not a supported uniform type.' );
|
|
679
|
+
break;
|
|
680
|
+
|
|
681
|
+
case WEBGL_CONSTANTS.FLOAT_MAT4:
|
|
682
|
+
|
|
683
|
+
if ( pcount ) {
|
|
684
|
+
|
|
685
|
+
uvalue = new Array( pcount );
|
|
686
|
+
|
|
687
|
+
for ( var mi = 0; mi < pcount; mi ++ ) {
|
|
688
|
+
|
|
689
|
+
uvalue[ mi ] = new WEBGL_TYPE[ ptype ]();
|
|
690
|
+
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
if ( shaderParam && shaderParam.value ) {
|
|
694
|
+
|
|
695
|
+
var m4v = shaderParam.value;
|
|
696
|
+
uvalue.fromArray( m4v );
|
|
697
|
+
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
if ( value ) {
|
|
701
|
+
|
|
702
|
+
uvalue.fromArray( value );
|
|
703
|
+
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
} else {
|
|
707
|
+
|
|
708
|
+
if ( shaderParam && shaderParam.value ) {
|
|
709
|
+
|
|
710
|
+
var m4 = shaderParam.value;
|
|
711
|
+
uvalue.fromArray( m4 );
|
|
712
|
+
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
if ( value ) {
|
|
716
|
+
|
|
717
|
+
uvalue.fromArray( value );
|
|
718
|
+
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
break;
|
|
724
|
+
|
|
725
|
+
case WEBGL_CONSTANTS.SAMPLER_2D:
|
|
726
|
+
|
|
727
|
+
if ( value !== undefined ) {
|
|
728
|
+
|
|
729
|
+
uvalue = dependencies.textures[ value ];
|
|
730
|
+
|
|
731
|
+
} else if ( shaderParam.value !== undefined ) {
|
|
732
|
+
|
|
733
|
+
uvalue = dependencies.textures[ shaderParam.value ];
|
|
734
|
+
|
|
735
|
+
} else {
|
|
736
|
+
|
|
737
|
+
uvalue = null;
|
|
738
|
+
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
break;
|
|
742
|
+
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
materialParams.uniforms[ uniformId ] = {
|
|
746
|
+
value: uvalue,
|
|
747
|
+
semantic: usemantic,
|
|
748
|
+
node: unode
|
|
749
|
+
};
|
|
750
|
+
|
|
751
|
+
} else {
|
|
752
|
+
|
|
753
|
+
throw new Error( 'THREE.GLTF2Loader: Unknown shader uniform param type: ' + ptype );
|
|
754
|
+
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
var states = technique.states || {};
|
|
760
|
+
var enables = states.enable || [];
|
|
761
|
+
var functions = states.functions || {};
|
|
762
|
+
|
|
763
|
+
var enableCullFace = false;
|
|
764
|
+
var enableDepthTest = false;
|
|
765
|
+
var enableBlend = false;
|
|
766
|
+
|
|
767
|
+
for ( var i = 0, il = enables.length; i < il; i ++ ) {
|
|
768
|
+
|
|
769
|
+
var enable = enables[ i ];
|
|
770
|
+
|
|
771
|
+
switch ( STATES_ENABLES[ enable ] ) {
|
|
772
|
+
|
|
773
|
+
case 'CULL_FACE':
|
|
774
|
+
|
|
775
|
+
enableCullFace = true;
|
|
776
|
+
|
|
777
|
+
break;
|
|
778
|
+
|
|
779
|
+
case 'DEPTH_TEST':
|
|
780
|
+
|
|
781
|
+
enableDepthTest = true;
|
|
782
|
+
|
|
783
|
+
break;
|
|
784
|
+
|
|
785
|
+
case 'BLEND':
|
|
786
|
+
|
|
787
|
+
enableBlend = true;
|
|
788
|
+
|
|
789
|
+
break;
|
|
790
|
+
|
|
791
|
+
// TODO: implement
|
|
792
|
+
case 'SCISSOR_TEST':
|
|
793
|
+
case 'POLYGON_OFFSET_FILL':
|
|
794
|
+
case 'SAMPLE_ALPHA_TO_COVERAGE':
|
|
795
|
+
|
|
796
|
+
break;
|
|
797
|
+
|
|
798
|
+
default:
|
|
799
|
+
|
|
800
|
+
throw new Error( 'THREE.GLTF2Loader: Unknown technique.states.enable: ' + enable );
|
|
801
|
+
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
if ( enableCullFace ) {
|
|
807
|
+
|
|
808
|
+
materialParams.side = functions.cullFace !== undefined ? WEBGL_SIDES[ functions.cullFace ] : THREE.FrontSide;
|
|
809
|
+
|
|
810
|
+
} else {
|
|
811
|
+
|
|
812
|
+
materialParams.side = THREE.DoubleSide;
|
|
813
|
+
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
materialParams.depthTest = enableDepthTest;
|
|
817
|
+
materialParams.depthFunc = functions.depthFunc !== undefined ? WEBGL_DEPTH_FUNCS[ functions.depthFunc ] : THREE.LessDepth;
|
|
818
|
+
materialParams.depthWrite = functions.depthMask !== undefined ? functions.depthMask[ 0 ] : true;
|
|
819
|
+
|
|
820
|
+
materialParams.blending = enableBlend ? THREE.CustomBlending : THREE.NoBlending;
|
|
821
|
+
materialParams.transparent = enableBlend;
|
|
822
|
+
|
|
823
|
+
var blendEquationSeparate = functions.blendEquationSeparate;
|
|
824
|
+
|
|
825
|
+
if ( blendEquationSeparate !== undefined ) {
|
|
826
|
+
|
|
827
|
+
materialParams.blendEquation = WEBGL_BLEND_EQUATIONS[ blendEquationSeparate[ 0 ] ];
|
|
828
|
+
materialParams.blendEquationAlpha = WEBGL_BLEND_EQUATIONS[ blendEquationSeparate[ 1 ] ];
|
|
829
|
+
|
|
830
|
+
} else {
|
|
831
|
+
|
|
832
|
+
materialParams.blendEquation = THREE.AddEquation;
|
|
833
|
+
materialParams.blendEquationAlpha = THREE.AddEquation;
|
|
834
|
+
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
var blendFuncSeparate = functions.blendFuncSeparate;
|
|
838
|
+
|
|
839
|
+
if ( blendFuncSeparate !== undefined ) {
|
|
840
|
+
|
|
841
|
+
materialParams.blendSrc = WEBGL_BLEND_FUNCS[ blendFuncSeparate[ 0 ] ];
|
|
842
|
+
materialParams.blendDst = WEBGL_BLEND_FUNCS[ blendFuncSeparate[ 1 ] ];
|
|
843
|
+
materialParams.blendSrcAlpha = WEBGL_BLEND_FUNCS[ blendFuncSeparate[ 2 ] ];
|
|
844
|
+
materialParams.blendDstAlpha = WEBGL_BLEND_FUNCS[ blendFuncSeparate[ 3 ] ];
|
|
845
|
+
|
|
846
|
+
} else {
|
|
847
|
+
|
|
848
|
+
materialParams.blendSrc = THREE.OneFactor;
|
|
849
|
+
materialParams.blendDst = THREE.ZeroFactor;
|
|
850
|
+
materialParams.blendSrcAlpha = THREE.OneFactor;
|
|
851
|
+
materialParams.blendDstAlpha = THREE.ZeroFactor;
|
|
852
|
+
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
};
|
|
856
|
+
|
|
857
|
+
/**
|
|
858
|
+
* Specular-Glossiness Extension
|
|
859
|
+
*
|
|
860
|
+
* Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/Khronos/KHR_materials_pbrSpecularGlossiness
|
|
861
|
+
*/
|
|
862
|
+
function GLTFMaterialsPbrSpecularGlossinessExtension() {
|
|
863
|
+
|
|
864
|
+
return {
|
|
865
|
+
|
|
866
|
+
name: EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS,
|
|
867
|
+
|
|
868
|
+
getMaterialType: function () {
|
|
869
|
+
|
|
870
|
+
return THREE.ShaderMaterial;
|
|
871
|
+
|
|
872
|
+
},
|
|
873
|
+
|
|
874
|
+
extendParams: function ( params, material, dependencies ) {
|
|
875
|
+
|
|
876
|
+
// specification
|
|
877
|
+
// https://github.com/sbtron/glTF/tree/KHRpbrSpecGloss/extensions/Khronos/KHR_materials_pbrSpecularGlossiness
|
|
878
|
+
|
|
879
|
+
var pbrSpecularGlossiness = material.extensions[ this.name ];
|
|
880
|
+
|
|
881
|
+
var shader = THREE.ShaderLib[ 'standard' ];
|
|
882
|
+
|
|
883
|
+
var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
|
|
884
|
+
|
|
885
|
+
var specularMapParsFragmentChunk = [
|
|
886
|
+
'#ifdef USE_SPECULARMAP',
|
|
887
|
+
' uniform sampler2D specularMap;',
|
|
888
|
+
'#endif'
|
|
889
|
+
].join( '\n' );
|
|
890
|
+
|
|
891
|
+
var glossinessMapParsFragmentChunk = [
|
|
892
|
+
'#ifdef USE_GLOSSINESSMAP',
|
|
893
|
+
' uniform sampler2D glossinessMap;',
|
|
894
|
+
'#endif'
|
|
895
|
+
].join( '\n' );
|
|
896
|
+
|
|
897
|
+
var specularMapFragmentChunk = [
|
|
898
|
+
'vec3 specularFactor = specular;',
|
|
899
|
+
'#ifdef USE_SPECULARMAP',
|
|
900
|
+
' vec4 texelSpecular = texture2D( specularMap, vUv );',
|
|
901
|
+
' // reads channel RGB, compatible with a glTF Specular-Glossiness (RGBA) texture',
|
|
902
|
+
' specularFactor *= texelSpecular.rgb;',
|
|
903
|
+
'#endif'
|
|
904
|
+
].join( '\n' );
|
|
905
|
+
|
|
906
|
+
var glossinessMapFragmentChunk = [
|
|
907
|
+
'float glossinessFactor = glossiness;',
|
|
908
|
+
'#ifdef USE_GLOSSINESSMAP',
|
|
909
|
+
' vec4 texelGlossiness = texture2D( glossinessMap, vUv );',
|
|
910
|
+
' // reads channel A, compatible with a glTF Specular-Glossiness (RGBA) texture',
|
|
911
|
+
' glossinessFactor *= texelGlossiness.a;',
|
|
912
|
+
'#endif'
|
|
913
|
+
].join( '\n' );
|
|
914
|
+
|
|
915
|
+
var lightPhysicalFragmentChunk = [
|
|
916
|
+
'PhysicalMaterial material;',
|
|
917
|
+
'material.diffuseColor = diffuseColor.rgb;',
|
|
918
|
+
'material.specularRoughness = clamp( 1.0 - glossinessFactor, 0.04, 1.0 );',
|
|
919
|
+
'material.specularColor = specularFactor.rgb;',
|
|
920
|
+
].join( '\n' );
|
|
921
|
+
|
|
922
|
+
var fragmentShader = shader.fragmentShader
|
|
923
|
+
.replace( '#include <specularmap_fragment>', '' )
|
|
924
|
+
.replace( 'uniform float roughness;', 'uniform vec3 specular;' )
|
|
925
|
+
.replace( 'uniform float metalness;', 'uniform float glossiness;' )
|
|
926
|
+
.replace( '#include <roughnessmap_pars_fragment>', specularMapParsFragmentChunk )
|
|
927
|
+
.replace( '#include <metalnessmap_pars_fragment>', glossinessMapParsFragmentChunk )
|
|
928
|
+
.replace( '#include <roughnessmap_fragment>', specularMapFragmentChunk )
|
|
929
|
+
.replace( '#include <metalnessmap_fragment>', glossinessMapFragmentChunk )
|
|
930
|
+
.replace( '#include <lights_physical_fragment>', lightPhysicalFragmentChunk );
|
|
931
|
+
|
|
932
|
+
delete uniforms.roughness;
|
|
933
|
+
delete uniforms.metalness;
|
|
934
|
+
delete uniforms.roughnessMap;
|
|
935
|
+
delete uniforms.metalnessMap;
|
|
936
|
+
|
|
937
|
+
uniforms.specular = { value: new THREE.Color().setHex( 0x111111 ) };
|
|
938
|
+
uniforms.glossiness = { value: 0.5 };
|
|
939
|
+
uniforms.specularMap = { value: null };
|
|
940
|
+
uniforms.glossinessMap = { value: null };
|
|
941
|
+
|
|
942
|
+
params.vertexShader = shader.vertexShader;
|
|
943
|
+
params.fragmentShader = fragmentShader;
|
|
944
|
+
params.uniforms = uniforms;
|
|
945
|
+
params.defines = { 'STANDARD': '' };
|
|
946
|
+
|
|
947
|
+
params.color = new THREE.Color( 1.0, 1.0, 1.0 );
|
|
948
|
+
params.opacity = 1.0;
|
|
949
|
+
|
|
950
|
+
if ( Array.isArray( pbrSpecularGlossiness.diffuseFactor ) ) {
|
|
951
|
+
|
|
952
|
+
var array = pbrSpecularGlossiness.diffuseFactor;
|
|
953
|
+
|
|
954
|
+
params.color.fromArray( array );
|
|
955
|
+
params.opacity = array[ 3 ];
|
|
956
|
+
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
if ( pbrSpecularGlossiness.diffuseTexture !== undefined ) {
|
|
960
|
+
|
|
961
|
+
params.map = dependencies.textures[ pbrSpecularGlossiness.diffuseTexture.index ];
|
|
962
|
+
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
params.emissive = new THREE.Color( 0.0, 0.0, 0.0 );
|
|
966
|
+
params.glossiness = pbrSpecularGlossiness.glossinessFactor !== undefined ? pbrSpecularGlossiness.glossinessFactor : 1.0;
|
|
967
|
+
params.specular = new THREE.Color( 1.0, 1.0, 1.0 );
|
|
968
|
+
|
|
969
|
+
if ( Array.isArray( pbrSpecularGlossiness.specularFactor ) ) {
|
|
970
|
+
|
|
971
|
+
params.specular.fromArray( pbrSpecularGlossiness.specularFactor );
|
|
972
|
+
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
if ( pbrSpecularGlossiness.specularGlossinessTexture !== undefined ) {
|
|
976
|
+
|
|
977
|
+
params.glossinessMap = dependencies.textures[ pbrSpecularGlossiness.specularGlossinessTexture.index ];
|
|
978
|
+
params.specularMap = dependencies.textures[ pbrSpecularGlossiness.specularGlossinessTexture.index ];
|
|
979
|
+
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
},
|
|
983
|
+
|
|
984
|
+
createMaterial: function ( params ) {
|
|
985
|
+
|
|
986
|
+
// setup material properties based on MeshStandardMaterial for Specular-Glossiness
|
|
987
|
+
|
|
988
|
+
var material = new THREE.ShaderMaterial( {
|
|
989
|
+
defines: params.defines,
|
|
990
|
+
vertexShader: params.vertexShader,
|
|
991
|
+
fragmentShader: params.fragmentShader,
|
|
992
|
+
uniforms: params.uniforms,
|
|
993
|
+
fog: true,
|
|
994
|
+
lights: true,
|
|
995
|
+
opacity: params.opacity,
|
|
996
|
+
transparent: params.transparent
|
|
997
|
+
} );
|
|
998
|
+
|
|
999
|
+
material.isGLTFSpecularGlossinessMaterial = true;
|
|
1000
|
+
|
|
1001
|
+
material.color = params.color;
|
|
1002
|
+
|
|
1003
|
+
material.map = params.map === undefined ? null : params.map;
|
|
1004
|
+
|
|
1005
|
+
material.lightMap = null;
|
|
1006
|
+
material.lightMapIntensity = 1.0;
|
|
1007
|
+
|
|
1008
|
+
material.aoMap = params.aoMap === undefined ? null : params.aoMap;
|
|
1009
|
+
material.aoMapIntensity = 1.0;
|
|
1010
|
+
|
|
1011
|
+
material.emissive = params.emissive;
|
|
1012
|
+
material.emissiveIntensity = 1.0;
|
|
1013
|
+
material.emissiveMap = params.emissiveMap === undefined ? null : params.emissiveMap;
|
|
1014
|
+
|
|
1015
|
+
material.bumpMap = params.bumpMap === undefined ? null : params.bumpMap;
|
|
1016
|
+
material.bumpScale = 1;
|
|
1017
|
+
|
|
1018
|
+
material.normalMap = params.normalMap === undefined ? null : params.normalMap;
|
|
1019
|
+
material.normalScale = new THREE.Vector2( 1, 1 );
|
|
1020
|
+
|
|
1021
|
+
material.displacementMap = null;
|
|
1022
|
+
material.displacementScale = 1;
|
|
1023
|
+
material.displacementBias = 0;
|
|
1024
|
+
|
|
1025
|
+
material.specularMap = params.specularMap === undefined ? null : params.specularMap;
|
|
1026
|
+
material.specular = params.specular;
|
|
1027
|
+
|
|
1028
|
+
material.glossinessMap = params.glossinessMap === undefined ? null : params.glossinessMap;
|
|
1029
|
+
material.glossiness = params.glossiness;
|
|
1030
|
+
|
|
1031
|
+
material.alphaMap = null;
|
|
1032
|
+
|
|
1033
|
+
material.envMap = params.envMap === undefined ? null : params.envMap;
|
|
1034
|
+
material.envMapIntensity = 1.0;
|
|
1035
|
+
|
|
1036
|
+
material.refractionRatio = 0.98;
|
|
1037
|
+
|
|
1038
|
+
material.extensions.derivatives = true;
|
|
1039
|
+
|
|
1040
|
+
return material;
|
|
1041
|
+
|
|
1042
|
+
},
|
|
1043
|
+
|
|
1044
|
+
// Here's based on refreshUniformsCommon() and refreshUniformsStandard() in WebGLRenderer.
|
|
1045
|
+
refreshUniforms: function ( renderer, scene, camera, geometry, material, group ) {
|
|
1046
|
+
|
|
1047
|
+
var uniforms = material.uniforms;
|
|
1048
|
+
var defines = material.defines;
|
|
1049
|
+
|
|
1050
|
+
uniforms.opacity.value = material.opacity;
|
|
1051
|
+
|
|
1052
|
+
uniforms.diffuse.value.copy( material.color );
|
|
1053
|
+
uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
|
|
1054
|
+
|
|
1055
|
+
uniforms.map.value = material.map;
|
|
1056
|
+
uniforms.specularMap.value = material.specularMap;
|
|
1057
|
+
uniforms.alphaMap.value = material.alphaMap;
|
|
1058
|
+
|
|
1059
|
+
uniforms.lightMap.value = material.lightMap;
|
|
1060
|
+
uniforms.lightMapIntensity.value = material.lightMapIntensity;
|
|
1061
|
+
|
|
1062
|
+
uniforms.aoMap.value = material.aoMap;
|
|
1063
|
+
uniforms.aoMapIntensity.value = material.aoMapIntensity;
|
|
1064
|
+
|
|
1065
|
+
// uv repeat and offset setting priorities
|
|
1066
|
+
// 1. color map
|
|
1067
|
+
// 2. specular map
|
|
1068
|
+
// 3. normal map
|
|
1069
|
+
// 4. bump map
|
|
1070
|
+
// 5. alpha map
|
|
1071
|
+
// 6. emissive map
|
|
1072
|
+
|
|
1073
|
+
var uvScaleMap;
|
|
1074
|
+
|
|
1075
|
+
if ( material.map ) {
|
|
1076
|
+
|
|
1077
|
+
uvScaleMap = material.map;
|
|
1078
|
+
|
|
1079
|
+
} else if ( material.specularMap ) {
|
|
1080
|
+
|
|
1081
|
+
uvScaleMap = material.specularMap;
|
|
1082
|
+
|
|
1083
|
+
} else if ( material.displacementMap ) {
|
|
1084
|
+
|
|
1085
|
+
uvScaleMap = material.displacementMap;
|
|
1086
|
+
|
|
1087
|
+
} else if ( material.normalMap ) {
|
|
1088
|
+
|
|
1089
|
+
uvScaleMap = material.normalMap;
|
|
1090
|
+
|
|
1091
|
+
} else if ( material.bumpMap ) {
|
|
1092
|
+
|
|
1093
|
+
uvScaleMap = material.bumpMap;
|
|
1094
|
+
|
|
1095
|
+
} else if ( material.glossinessMap ) {
|
|
1096
|
+
|
|
1097
|
+
uvScaleMap = material.glossinessMap;
|
|
1098
|
+
|
|
1099
|
+
} else if ( material.alphaMap ) {
|
|
1100
|
+
|
|
1101
|
+
uvScaleMap = material.alphaMap;
|
|
1102
|
+
|
|
1103
|
+
} else if ( material.emissiveMap ) {
|
|
1104
|
+
|
|
1105
|
+
uvScaleMap = material.emissiveMap;
|
|
1106
|
+
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
if ( uvScaleMap !== undefined ) {
|
|
1110
|
+
|
|
1111
|
+
// backwards compatibility
|
|
1112
|
+
if ( uvScaleMap.isWebGLRenderTarget ) {
|
|
1113
|
+
|
|
1114
|
+
uvScaleMap = uvScaleMap.texture;
|
|
1115
|
+
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
var offset = uvScaleMap.offset;
|
|
1119
|
+
var repeat = uvScaleMap.repeat;
|
|
1120
|
+
|
|
1121
|
+
uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
|
|
1122
|
+
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
uniforms.envMap.value = material.envMap;
|
|
1126
|
+
uniforms.envMapIntensity.value = material.envMapIntensity;
|
|
1127
|
+
uniforms.flipEnvMap.value = ( material.envMap && material.envMap.isCubeTexture ) ? -1 : 1;
|
|
1128
|
+
|
|
1129
|
+
uniforms.refractionRatio.value = material.refractionRatio;
|
|
1130
|
+
|
|
1131
|
+
uniforms.specular.value.copy( material.specular );
|
|
1132
|
+
uniforms.glossiness.value = material.glossiness;
|
|
1133
|
+
|
|
1134
|
+
uniforms.glossinessMap.value = material.glossinessMap;
|
|
1135
|
+
|
|
1136
|
+
uniforms.emissiveMap.value = material.emissiveMap;
|
|
1137
|
+
uniforms.bumpMap.value = material.bumpMap;
|
|
1138
|
+
uniforms.normalMap.value = material.normalMap;
|
|
1139
|
+
|
|
1140
|
+
uniforms.displacementMap.value = material.displacementMap;
|
|
1141
|
+
uniforms.displacementScale.value = material.displacementScale;
|
|
1142
|
+
uniforms.displacementBias.value = material.displacementBias;
|
|
1143
|
+
|
|
1144
|
+
if ( uniforms.glossinessMap.value !== null && defines.USE_GLOSSINESSMAP === undefined ) {
|
|
1145
|
+
|
|
1146
|
+
defines.USE_GLOSSINESSMAP = '';
|
|
1147
|
+
// set USE_ROUGHNESSMAP to enable vUv
|
|
1148
|
+
defines.USE_ROUGHNESSMAP = ''
|
|
1149
|
+
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
if ( uniforms.glossinessMap.value === null && defines.USE_GLOSSINESSMAP !== undefined ) {
|
|
1153
|
+
|
|
1154
|
+
delete defines.USE_GLOSSINESSMAP;
|
|
1155
|
+
delete defines.USE_ROUGHNESSMAP;
|
|
1156
|
+
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
};
|
|
1162
|
+
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
/*********************************/
|
|
1166
|
+
/********** INTERNALS ************/
|
|
1167
|
+
/*********************************/
|
|
1168
|
+
|
|
1169
|
+
/* CONSTANTS */
|
|
1170
|
+
|
|
1171
|
+
var WEBGL_CONSTANTS = {
|
|
1172
|
+
FLOAT: 5126,
|
|
1173
|
+
//FLOAT_MAT2: 35674,
|
|
1174
|
+
FLOAT_MAT3: 35675,
|
|
1175
|
+
FLOAT_MAT4: 35676,
|
|
1176
|
+
FLOAT_VEC2: 35664,
|
|
1177
|
+
FLOAT_VEC3: 35665,
|
|
1178
|
+
FLOAT_VEC4: 35666,
|
|
1179
|
+
LINEAR: 9729,
|
|
1180
|
+
REPEAT: 10497,
|
|
1181
|
+
SAMPLER_2D: 35678,
|
|
1182
|
+
TRIANGLES: 4,
|
|
1183
|
+
LINES: 1,
|
|
1184
|
+
UNSIGNED_BYTE: 5121,
|
|
1185
|
+
UNSIGNED_SHORT: 5123,
|
|
1186
|
+
|
|
1187
|
+
VERTEX_SHADER: 35633,
|
|
1188
|
+
FRAGMENT_SHADER: 35632
|
|
1189
|
+
};
|
|
1190
|
+
|
|
1191
|
+
var WEBGL_TYPE = {
|
|
1192
|
+
5126: Number,
|
|
1193
|
+
//35674: THREE.Matrix2,
|
|
1194
|
+
35675: THREE.Matrix3,
|
|
1195
|
+
35676: THREE.Matrix4,
|
|
1196
|
+
35664: THREE.Vector2,
|
|
1197
|
+
35665: THREE.Vector3,
|
|
1198
|
+
35666: THREE.Vector4,
|
|
1199
|
+
35678: THREE.Texture
|
|
1200
|
+
};
|
|
1201
|
+
|
|
1202
|
+
var WEBGL_COMPONENT_TYPES = {
|
|
1203
|
+
5120: Int8Array,
|
|
1204
|
+
5121: Uint8Array,
|
|
1205
|
+
5122: Int16Array,
|
|
1206
|
+
5123: Uint16Array,
|
|
1207
|
+
5125: Uint32Array,
|
|
1208
|
+
5126: Float32Array
|
|
1209
|
+
};
|
|
1210
|
+
|
|
1211
|
+
var WEBGL_FILTERS = {
|
|
1212
|
+
9728: THREE.NearestFilter,
|
|
1213
|
+
9729: THREE.LinearFilter,
|
|
1214
|
+
9984: THREE.NearestMipMapNearestFilter,
|
|
1215
|
+
9985: THREE.LinearMipMapNearestFilter,
|
|
1216
|
+
9986: THREE.NearestMipMapLinearFilter,
|
|
1217
|
+
9987: THREE.LinearMipMapLinearFilter
|
|
1218
|
+
};
|
|
1219
|
+
|
|
1220
|
+
var WEBGL_WRAPPINGS = {
|
|
1221
|
+
33071: THREE.ClampToEdgeWrapping,
|
|
1222
|
+
33648: THREE.MirroredRepeatWrapping,
|
|
1223
|
+
10497: THREE.RepeatWrapping
|
|
1224
|
+
};
|
|
1225
|
+
|
|
1226
|
+
var WEBGL_TEXTURE_FORMATS = {
|
|
1227
|
+
6406: THREE.AlphaFormat,
|
|
1228
|
+
6407: THREE.RGBFormat,
|
|
1229
|
+
6408: THREE.RGBAFormat,
|
|
1230
|
+
6409: THREE.LuminanceFormat,
|
|
1231
|
+
6410: THREE.LuminanceAlphaFormat
|
|
1232
|
+
};
|
|
1233
|
+
|
|
1234
|
+
var WEBGL_TEXTURE_DATATYPES = {
|
|
1235
|
+
5121: THREE.UnsignedByteType,
|
|
1236
|
+
32819: THREE.UnsignedShort4444Type,
|
|
1237
|
+
32820: THREE.UnsignedShort5551Type,
|
|
1238
|
+
33635: THREE.UnsignedShort565Type
|
|
1239
|
+
};
|
|
1240
|
+
|
|
1241
|
+
var WEBGL_SIDES = {
|
|
1242
|
+
1028: THREE.BackSide, // Culling front
|
|
1243
|
+
1029: THREE.FrontSide // Culling back
|
|
1244
|
+
//1032: THREE.NoSide // Culling front and back, what to do?
|
|
1245
|
+
};
|
|
1246
|
+
|
|
1247
|
+
var WEBGL_DEPTH_FUNCS = {
|
|
1248
|
+
512: THREE.NeverDepth,
|
|
1249
|
+
513: THREE.LessDepth,
|
|
1250
|
+
514: THREE.EqualDepth,
|
|
1251
|
+
515: THREE.LessEqualDepth,
|
|
1252
|
+
516: THREE.GreaterEqualDepth,
|
|
1253
|
+
517: THREE.NotEqualDepth,
|
|
1254
|
+
518: THREE.GreaterEqualDepth,
|
|
1255
|
+
519: THREE.AlwaysDepth
|
|
1256
|
+
};
|
|
1257
|
+
|
|
1258
|
+
var WEBGL_BLEND_EQUATIONS = {
|
|
1259
|
+
32774: THREE.AddEquation,
|
|
1260
|
+
32778: THREE.SubtractEquation,
|
|
1261
|
+
32779: THREE.ReverseSubtractEquation
|
|
1262
|
+
};
|
|
1263
|
+
|
|
1264
|
+
var WEBGL_BLEND_FUNCS = {
|
|
1265
|
+
0: THREE.ZeroFactor,
|
|
1266
|
+
1: THREE.OneFactor,
|
|
1267
|
+
768: THREE.SrcColorFactor,
|
|
1268
|
+
769: THREE.OneMinusSrcColorFactor,
|
|
1269
|
+
770: THREE.SrcAlphaFactor,
|
|
1270
|
+
771: THREE.OneMinusSrcAlphaFactor,
|
|
1271
|
+
772: THREE.DstAlphaFactor,
|
|
1272
|
+
773: THREE.OneMinusDstAlphaFactor,
|
|
1273
|
+
774: THREE.DstColorFactor,
|
|
1274
|
+
775: THREE.OneMinusDstColorFactor,
|
|
1275
|
+
776: THREE.SrcAlphaSaturateFactor
|
|
1276
|
+
// The followings are not supported by Three.js yet
|
|
1277
|
+
//32769: CONSTANT_COLOR,
|
|
1278
|
+
//32770: ONE_MINUS_CONSTANT_COLOR,
|
|
1279
|
+
//32771: CONSTANT_ALPHA,
|
|
1280
|
+
//32772: ONE_MINUS_CONSTANT_COLOR
|
|
1281
|
+
};
|
|
1282
|
+
|
|
1283
|
+
var WEBGL_TYPE_SIZES = {
|
|
1284
|
+
'SCALAR': 1,
|
|
1285
|
+
'VEC2': 2,
|
|
1286
|
+
'VEC3': 3,
|
|
1287
|
+
'VEC4': 4,
|
|
1288
|
+
'MAT2': 4,
|
|
1289
|
+
'MAT3': 9,
|
|
1290
|
+
'MAT4': 16
|
|
1291
|
+
};
|
|
1292
|
+
|
|
1293
|
+
var PATH_PROPERTIES = {
|
|
1294
|
+
scale: 'scale',
|
|
1295
|
+
translation: 'position',
|
|
1296
|
+
rotation: 'quaternion',
|
|
1297
|
+
weights: 'morphTargetInfluences'
|
|
1298
|
+
};
|
|
1299
|
+
|
|
1300
|
+
var INTERPOLATION = {
|
|
1301
|
+
CATMULLROMSPLINE: THREE.InterpolateSmooth,
|
|
1302
|
+
CUBICSPLINE: THREE.InterpolateSmooth,
|
|
1303
|
+
LINEAR: THREE.InterpolateLinear,
|
|
1304
|
+
STEP: THREE.InterpolateDiscrete
|
|
1305
|
+
};
|
|
1306
|
+
|
|
1307
|
+
var STATES_ENABLES = {
|
|
1308
|
+
2884: 'CULL_FACE',
|
|
1309
|
+
2929: 'DEPTH_TEST',
|
|
1310
|
+
3042: 'BLEND',
|
|
1311
|
+
3089: 'SCISSOR_TEST',
|
|
1312
|
+
32823: 'POLYGON_OFFSET_FILL',
|
|
1313
|
+
32926: 'SAMPLE_ALPHA_TO_COVERAGE'
|
|
1314
|
+
};
|
|
1315
|
+
|
|
1316
|
+
var ALPHA_MODES = {
|
|
1317
|
+
OPAQUE: 'OPAQUE',
|
|
1318
|
+
MASK: 'MASK',
|
|
1319
|
+
BLEND: 'BLEND'
|
|
1320
|
+
};
|
|
1321
|
+
|
|
1322
|
+
/* UTILITY FUNCTIONS */
|
|
1323
|
+
|
|
1324
|
+
function _each( object, callback, thisObj ) {
|
|
1325
|
+
|
|
1326
|
+
if ( !object ) {
|
|
1327
|
+
return Promise.resolve();
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
var results;
|
|
1331
|
+
var fns = [];
|
|
1332
|
+
|
|
1333
|
+
if ( Object.prototype.toString.call( object ) === '[object Array]' ) {
|
|
1334
|
+
|
|
1335
|
+
results = [];
|
|
1336
|
+
|
|
1337
|
+
var length = object.length;
|
|
1338
|
+
|
|
1339
|
+
for ( var idx = 0; idx < length; idx ++ ) {
|
|
1340
|
+
|
|
1341
|
+
var value = callback.call( thisObj || this, object[ idx ], idx );
|
|
1342
|
+
|
|
1343
|
+
if ( value ) {
|
|
1344
|
+
|
|
1345
|
+
fns.push( value );
|
|
1346
|
+
|
|
1347
|
+
if ( value instanceof Promise ) {
|
|
1348
|
+
|
|
1349
|
+
value.then( function( key, value ) {
|
|
1350
|
+
|
|
1351
|
+
results[ key ] = value;
|
|
1352
|
+
|
|
1353
|
+
}.bind( this, idx ));
|
|
1354
|
+
|
|
1355
|
+
} else {
|
|
1356
|
+
|
|
1357
|
+
results[ idx ] = value;
|
|
1358
|
+
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
} else {
|
|
1366
|
+
|
|
1367
|
+
results = {};
|
|
1368
|
+
|
|
1369
|
+
for ( var key in object ) {
|
|
1370
|
+
|
|
1371
|
+
if ( object.hasOwnProperty( key ) ) {
|
|
1372
|
+
|
|
1373
|
+
var value = callback.call( thisObj || this, object[ key ], key );
|
|
1374
|
+
|
|
1375
|
+
if ( value ) {
|
|
1376
|
+
|
|
1377
|
+
fns.push( value );
|
|
1378
|
+
|
|
1379
|
+
if ( value instanceof Promise ) {
|
|
1380
|
+
|
|
1381
|
+
value.then( function( key, value ) {
|
|
1382
|
+
|
|
1383
|
+
results[ key ] = value;
|
|
1384
|
+
|
|
1385
|
+
}.bind( this, key ));
|
|
1386
|
+
|
|
1387
|
+
} else {
|
|
1388
|
+
|
|
1389
|
+
results[ key ] = value;
|
|
1390
|
+
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
return Promise.all( fns ).then( function() {
|
|
1402
|
+
|
|
1403
|
+
return results;
|
|
1404
|
+
|
|
1405
|
+
});
|
|
1406
|
+
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1409
|
+
function resolveURL( url, path ) {
|
|
1410
|
+
|
|
1411
|
+
// Invalid URL
|
|
1412
|
+
if ( typeof url !== 'string' || url === '' )
|
|
1413
|
+
return '';
|
|
1414
|
+
|
|
1415
|
+
// Absolute URL http://,https://,//
|
|
1416
|
+
if ( /^(https?:)?\/\//i.test( url ) ) {
|
|
1417
|
+
|
|
1418
|
+
return url;
|
|
1419
|
+
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
// Data URI
|
|
1423
|
+
if ( /^data:.*,.*$/i.test( url ) ) {
|
|
1424
|
+
|
|
1425
|
+
return url;
|
|
1426
|
+
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
// Blob URL
|
|
1430
|
+
if ( /^blob:.*$/i.test( url ) ) {
|
|
1431
|
+
|
|
1432
|
+
return url;
|
|
1433
|
+
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1436
|
+
// Relative URL
|
|
1437
|
+
return ( path || '' ) + url;
|
|
1438
|
+
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
function convertUint8ArrayToString( array ) {
|
|
1442
|
+
|
|
1443
|
+
if ( TextDecoder !== undefined ) {
|
|
1444
|
+
|
|
1445
|
+
return new TextDecoder().decode( array );
|
|
1446
|
+
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
// Avoid the String.fromCharCode.apply(null, array) shortcut, which
|
|
1450
|
+
// throws a "maximum call stack size exceeded" error for large arrays.
|
|
1451
|
+
|
|
1452
|
+
var s = '';
|
|
1453
|
+
|
|
1454
|
+
for ( var i = 0, il = array.length; i < il; i ++ ) {
|
|
1455
|
+
|
|
1456
|
+
s += String.fromCharCode( array[ i ] );
|
|
1457
|
+
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
return s;
|
|
1461
|
+
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
// Three.js seems too dependent on attribute names so globally
|
|
1465
|
+
// replace those in the shader code
|
|
1466
|
+
function replaceTHREEShaderAttributes( shaderText, technique ) {
|
|
1467
|
+
|
|
1468
|
+
// Expected technique attributes
|
|
1469
|
+
var attributes = {};
|
|
1470
|
+
|
|
1471
|
+
for ( var attributeId in technique.attributes ) {
|
|
1472
|
+
|
|
1473
|
+
var pname = technique.attributes[ attributeId ];
|
|
1474
|
+
|
|
1475
|
+
var param = technique.parameters[ pname ];
|
|
1476
|
+
var atype = param.type;
|
|
1477
|
+
var semantic = param.semantic;
|
|
1478
|
+
|
|
1479
|
+
attributes[ attributeId ] = {
|
|
1480
|
+
type: atype,
|
|
1481
|
+
semantic: semantic
|
|
1482
|
+
};
|
|
1483
|
+
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1486
|
+
// Figure out which attributes to change in technique
|
|
1487
|
+
|
|
1488
|
+
var shaderParams = technique.parameters;
|
|
1489
|
+
var shaderAttributes = technique.attributes;
|
|
1490
|
+
var params = {};
|
|
1491
|
+
|
|
1492
|
+
for ( var attributeId in attributes ) {
|
|
1493
|
+
|
|
1494
|
+
var pname = shaderAttributes[ attributeId ];
|
|
1495
|
+
var shaderParam = shaderParams[ pname ];
|
|
1496
|
+
var semantic = shaderParam.semantic;
|
|
1497
|
+
if ( semantic ) {
|
|
1498
|
+
|
|
1499
|
+
params[ attributeId ] = shaderParam;
|
|
1500
|
+
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
for ( var pname in params ) {
|
|
1506
|
+
|
|
1507
|
+
var param = params[ pname ];
|
|
1508
|
+
var semantic = param.semantic;
|
|
1509
|
+
|
|
1510
|
+
var regEx = new RegExp( '\\b' + pname + '\\b', 'g' );
|
|
1511
|
+
|
|
1512
|
+
switch ( semantic ) {
|
|
1513
|
+
|
|
1514
|
+
case 'POSITION':
|
|
1515
|
+
|
|
1516
|
+
shaderText = shaderText.replace( regEx, 'position' );
|
|
1517
|
+
break;
|
|
1518
|
+
|
|
1519
|
+
case 'NORMAL':
|
|
1520
|
+
|
|
1521
|
+
shaderText = shaderText.replace( regEx, 'normal' );
|
|
1522
|
+
break;
|
|
1523
|
+
|
|
1524
|
+
case 'TEXCOORD_0':
|
|
1525
|
+
case 'TEXCOORD0':
|
|
1526
|
+
case 'TEXCOORD':
|
|
1527
|
+
|
|
1528
|
+
shaderText = shaderText.replace( regEx, 'uv' );
|
|
1529
|
+
break;
|
|
1530
|
+
|
|
1531
|
+
case 'TEXCOORD_1':
|
|
1532
|
+
|
|
1533
|
+
shaderText = shaderText.replace( regEx, 'uv2' );
|
|
1534
|
+
break;
|
|
1535
|
+
|
|
1536
|
+
case 'COLOR_0':
|
|
1537
|
+
case 'COLOR0':
|
|
1538
|
+
case 'COLOR':
|
|
1539
|
+
|
|
1540
|
+
shaderText = shaderText.replace( regEx, 'color' );
|
|
1541
|
+
break;
|
|
1542
|
+
|
|
1543
|
+
case 'WEIGHTS_0':
|
|
1544
|
+
case 'WEIGHT': // WEIGHT semantic deprecated.
|
|
1545
|
+
|
|
1546
|
+
shaderText = shaderText.replace( regEx, 'skinWeight' );
|
|
1547
|
+
break;
|
|
1548
|
+
|
|
1549
|
+
case 'JOINTS_0':
|
|
1550
|
+
case 'JOINT': // JOINT semantic deprecated.
|
|
1551
|
+
|
|
1552
|
+
shaderText = shaderText.replace( regEx, 'skinIndex' );
|
|
1553
|
+
break;
|
|
1554
|
+
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1559
|
+
return shaderText;
|
|
1560
|
+
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
/**
|
|
1564
|
+
* Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#default-material
|
|
1565
|
+
*/
|
|
1566
|
+
function createDefaultMaterial() {
|
|
1567
|
+
|
|
1568
|
+
return new THREE.MeshStandardMaterial( {
|
|
1569
|
+
color: 0xFFFFFF,
|
|
1570
|
+
emissive: 0x000000,
|
|
1571
|
+
metalness: 1,
|
|
1572
|
+
roughness: 1,
|
|
1573
|
+
transparent: false,
|
|
1574
|
+
depthTest: true,
|
|
1575
|
+
side: THREE.FrontSide
|
|
1576
|
+
} );
|
|
1577
|
+
|
|
1578
|
+
}
|
|
1579
|
+
|
|
1580
|
+
// Deferred constructor for RawShaderMaterial types
|
|
1581
|
+
function DeferredShaderMaterial( params ) {
|
|
1582
|
+
|
|
1583
|
+
this.isDeferredShaderMaterial = true;
|
|
1584
|
+
|
|
1585
|
+
this.params = params;
|
|
1586
|
+
|
|
1587
|
+
}
|
|
1588
|
+
|
|
1589
|
+
DeferredShaderMaterial.prototype.create = function () {
|
|
1590
|
+
|
|
1591
|
+
var uniforms = THREE.UniformsUtils.clone( this.params.uniforms );
|
|
1592
|
+
|
|
1593
|
+
for ( var uniformId in this.params.uniforms ) {
|
|
1594
|
+
|
|
1595
|
+
var originalUniform = this.params.uniforms[ uniformId ];
|
|
1596
|
+
|
|
1597
|
+
if ( originalUniform.value instanceof THREE.Texture ) {
|
|
1598
|
+
|
|
1599
|
+
uniforms[ uniformId ].value = originalUniform.value;
|
|
1600
|
+
uniforms[ uniformId ].value.needsUpdate = true;
|
|
1601
|
+
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1604
|
+
uniforms[ uniformId ].semantic = originalUniform.semantic;
|
|
1605
|
+
uniforms[ uniformId ].node = originalUniform.node;
|
|
1606
|
+
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1609
|
+
this.params.uniforms = uniforms;
|
|
1610
|
+
|
|
1611
|
+
return new THREE.RawShaderMaterial( this.params );
|
|
1612
|
+
|
|
1613
|
+
};
|
|
1614
|
+
|
|
1615
|
+
/* GLTF PARSER */
|
|
1616
|
+
|
|
1617
|
+
function GLTFParser( json, extensions, options ) {
|
|
1618
|
+
|
|
1619
|
+
this.json = json || {};
|
|
1620
|
+
this.extensions = extensions || {};
|
|
1621
|
+
this.options = options || {};
|
|
1622
|
+
|
|
1623
|
+
// loader object cache
|
|
1624
|
+
this.cache = new GLTFRegistry();
|
|
1625
|
+
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
GLTFParser.prototype._withDependencies = function ( dependencies ) {
|
|
1629
|
+
|
|
1630
|
+
var _dependencies = {};
|
|
1631
|
+
|
|
1632
|
+
for ( var i = 0; i < dependencies.length; i ++ ) {
|
|
1633
|
+
|
|
1634
|
+
var dependency = dependencies[ i ];
|
|
1635
|
+
var fnName = 'load' + dependency.charAt( 0 ).toUpperCase() + dependency.slice( 1 );
|
|
1636
|
+
|
|
1637
|
+
var cached = this.cache.get( dependency );
|
|
1638
|
+
|
|
1639
|
+
if ( cached !== undefined ) {
|
|
1640
|
+
|
|
1641
|
+
_dependencies[ dependency ] = cached;
|
|
1642
|
+
|
|
1643
|
+
} else if ( this[ fnName ] ) {
|
|
1644
|
+
|
|
1645
|
+
var fn = this[ fnName ]();
|
|
1646
|
+
this.cache.add( dependency, fn );
|
|
1647
|
+
|
|
1648
|
+
_dependencies[ dependency ] = fn;
|
|
1649
|
+
|
|
1650
|
+
}
|
|
1651
|
+
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
return _each( _dependencies, function ( dependency ) {
|
|
1655
|
+
|
|
1656
|
+
return dependency;
|
|
1657
|
+
|
|
1658
|
+
} );
|
|
1659
|
+
|
|
1660
|
+
};
|
|
1661
|
+
|
|
1662
|
+
GLTFParser.prototype.parse = function ( onLoad, onError ) {
|
|
1663
|
+
|
|
1664
|
+
var json = this.json;
|
|
1665
|
+
|
|
1666
|
+
// Clear the loader cache
|
|
1667
|
+
this.cache.removeAll();
|
|
1668
|
+
|
|
1669
|
+
// Fire the callback on complete
|
|
1670
|
+
this._withDependencies( [
|
|
1671
|
+
|
|
1672
|
+
'scenes',
|
|
1673
|
+
'cameras',
|
|
1674
|
+
'animations'
|
|
1675
|
+
|
|
1676
|
+
] ).then( function ( dependencies ) {
|
|
1677
|
+
|
|
1678
|
+
var scenes = [];
|
|
1679
|
+
|
|
1680
|
+
for ( var name in dependencies.scenes ) {
|
|
1681
|
+
|
|
1682
|
+
scenes.push( dependencies.scenes[ name ] );
|
|
1683
|
+
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
var scene = json.scene !== undefined ? dependencies.scenes[ json.scene ] : scenes[ 0 ];
|
|
1687
|
+
|
|
1688
|
+
var cameras = [];
|
|
1689
|
+
|
|
1690
|
+
for ( var name in dependencies.cameras ) {
|
|
1691
|
+
|
|
1692
|
+
var camera = dependencies.cameras[ name ];
|
|
1693
|
+
cameras.push( camera );
|
|
1694
|
+
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
var animations = [];
|
|
1698
|
+
|
|
1699
|
+
for ( var name in dependencies.animations ) {
|
|
1700
|
+
|
|
1701
|
+
animations.push( dependencies.animations[ name ] );
|
|
1702
|
+
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1705
|
+
onLoad( scene, scenes, cameras, animations );
|
|
1706
|
+
|
|
1707
|
+
} ).catch( onError );
|
|
1708
|
+
|
|
1709
|
+
};
|
|
1710
|
+
|
|
1711
|
+
GLTFParser.prototype.loadShaders = function () {
|
|
1712
|
+
|
|
1713
|
+
var json = this.json;
|
|
1714
|
+
var options = this.options;
|
|
1715
|
+
var extensions = this.extensions;
|
|
1716
|
+
|
|
1717
|
+
return this._withDependencies( [
|
|
1718
|
+
|
|
1719
|
+
'bufferViews'
|
|
1720
|
+
|
|
1721
|
+
] ).then( function ( dependencies ) {
|
|
1722
|
+
|
|
1723
|
+
var shaders = extensions[ EXTENSIONS.KHR_TECHNIQUE_WEBGL ] !== undefined ? extensions[ EXTENSIONS.KHR_TECHNIQUE_WEBGL ].shaders : json.shaders;
|
|
1724
|
+
|
|
1725
|
+
if ( shaders === undefined ) shaders = {};
|
|
1726
|
+
|
|
1727
|
+
return _each( shaders, function ( shader ) {
|
|
1728
|
+
|
|
1729
|
+
if ( shader.bufferView !== undefined ) {
|
|
1730
|
+
|
|
1731
|
+
var bufferView = dependencies.bufferViews[ shader.bufferView ];
|
|
1732
|
+
var array = new Uint8Array( bufferView );
|
|
1733
|
+
return convertUint8ArrayToString( array );
|
|
1734
|
+
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
return new Promise( function ( resolve ) {
|
|
1738
|
+
|
|
1739
|
+
var loader = new THREE.FileLoader();
|
|
1740
|
+
loader.setResponseType( 'text' );
|
|
1741
|
+
loader.load( resolveURL( shader.uri, options.path ), function ( shaderText ) {
|
|
1742
|
+
|
|
1743
|
+
resolve( shaderText );
|
|
1744
|
+
|
|
1745
|
+
} );
|
|
1746
|
+
|
|
1747
|
+
} );
|
|
1748
|
+
|
|
1749
|
+
} );
|
|
1750
|
+
|
|
1751
|
+
} );
|
|
1752
|
+
|
|
1753
|
+
};
|
|
1754
|
+
|
|
1755
|
+
GLTFParser.prototype.loadBuffers = function () {
|
|
1756
|
+
|
|
1757
|
+
var json = this.json;
|
|
1758
|
+
var extensions = this.extensions;
|
|
1759
|
+
var options = this.options;
|
|
1760
|
+
|
|
1761
|
+
return _each( json.buffers, function ( buffer, name ) {
|
|
1762
|
+
|
|
1763
|
+
if ( buffer.type === 'arraybuffer' || buffer.type === undefined ) {
|
|
1764
|
+
|
|
1765
|
+
// If present, GLB container is required to be the first buffer.
|
|
1766
|
+
if ( buffer.uri === undefined && name === 0 ) {
|
|
1767
|
+
|
|
1768
|
+
return extensions[ EXTENSIONS.KHR_BINARY_GLTF ].body;
|
|
1769
|
+
|
|
1770
|
+
}
|
|
1771
|
+
|
|
1772
|
+
return new Promise( function ( resolve ) {
|
|
1773
|
+
|
|
1774
|
+
var loader = new THREE.FileLoader();
|
|
1775
|
+
loader.setResponseType( 'arraybuffer' );
|
|
1776
|
+
loader.load( resolveURL( buffer.uri, options.path ), function ( buffer ) {
|
|
1777
|
+
|
|
1778
|
+
resolve( buffer );
|
|
1779
|
+
|
|
1780
|
+
} );
|
|
1781
|
+
|
|
1782
|
+
} );
|
|
1783
|
+
|
|
1784
|
+
} else {
|
|
1785
|
+
|
|
1786
|
+
console.warn( 'THREE.GLTF2Loader: %s buffer type is not supported.', buffer.type );
|
|
1787
|
+
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
} );
|
|
1791
|
+
|
|
1792
|
+
};
|
|
1793
|
+
|
|
1794
|
+
GLTFParser.prototype.loadBufferViews = function () {
|
|
1795
|
+
|
|
1796
|
+
var json = this.json;
|
|
1797
|
+
|
|
1798
|
+
return this._withDependencies( [
|
|
1799
|
+
|
|
1800
|
+
'buffers'
|
|
1801
|
+
|
|
1802
|
+
] ).then( function ( dependencies ) {
|
|
1803
|
+
|
|
1804
|
+
return _each( json.bufferViews, function ( bufferView ) {
|
|
1805
|
+
|
|
1806
|
+
var arraybuffer = dependencies.buffers[ bufferView.buffer ];
|
|
1807
|
+
|
|
1808
|
+
var byteLength = bufferView.byteLength || 0;
|
|
1809
|
+
var byteOffset = bufferView.byteOffset || 0;
|
|
1810
|
+
|
|
1811
|
+
return arraybuffer.slice( byteOffset, byteOffset + byteLength );
|
|
1812
|
+
|
|
1813
|
+
} );
|
|
1814
|
+
|
|
1815
|
+
} );
|
|
1816
|
+
|
|
1817
|
+
};
|
|
1818
|
+
|
|
1819
|
+
GLTFParser.prototype.loadAccessors = function () {
|
|
1820
|
+
|
|
1821
|
+
var json = this.json;
|
|
1822
|
+
|
|
1823
|
+
return this._withDependencies( [
|
|
1824
|
+
|
|
1825
|
+
'bufferViews'
|
|
1826
|
+
|
|
1827
|
+
] ).then( function ( dependencies ) {
|
|
1828
|
+
|
|
1829
|
+
return _each( json.accessors, function ( accessor ) {
|
|
1830
|
+
|
|
1831
|
+
var arraybuffer = dependencies.bufferViews[ accessor.bufferView ];
|
|
1832
|
+
var itemSize = WEBGL_TYPE_SIZES[ accessor.type ];
|
|
1833
|
+
var TypedArray = WEBGL_COMPONENT_TYPES[ accessor.componentType ];
|
|
1834
|
+
|
|
1835
|
+
// For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.
|
|
1836
|
+
var elementBytes = TypedArray.BYTES_PER_ELEMENT;
|
|
1837
|
+
var itemBytes = elementBytes * itemSize;
|
|
1838
|
+
var byteStride = json.bufferViews[ accessor.bufferView ].byteStride;
|
|
1839
|
+
var array;
|
|
1840
|
+
|
|
1841
|
+
// The buffer is not interleaved if the stride is the item size in bytes.
|
|
1842
|
+
if ( byteStride && byteStride !== itemBytes ) {
|
|
1843
|
+
|
|
1844
|
+
// Use the full buffer if it's interleaved.
|
|
1845
|
+
array = new TypedArray( arraybuffer );
|
|
1846
|
+
|
|
1847
|
+
// Integer parameters to IB/IBA are in array elements, not bytes.
|
|
1848
|
+
var ib = new THREE.InterleavedBuffer( array, byteStride / elementBytes );
|
|
1849
|
+
|
|
1850
|
+
return new THREE.InterleavedBufferAttribute( ib, itemSize, accessor.byteOffset / elementBytes );
|
|
1851
|
+
|
|
1852
|
+
} else {
|
|
1853
|
+
|
|
1854
|
+
array = new TypedArray( arraybuffer, accessor.byteOffset, accessor.count * itemSize );
|
|
1855
|
+
|
|
1856
|
+
return new THREE.BufferAttribute( array, itemSize );
|
|
1857
|
+
|
|
1858
|
+
}
|
|
1859
|
+
|
|
1860
|
+
} );
|
|
1861
|
+
|
|
1862
|
+
} );
|
|
1863
|
+
|
|
1864
|
+
};
|
|
1865
|
+
|
|
1866
|
+
GLTFParser.prototype.loadTextures = function () {
|
|
1867
|
+
|
|
1868
|
+
var json = this.json;
|
|
1869
|
+
var options = this.options;
|
|
1870
|
+
|
|
1871
|
+
return this._withDependencies( [
|
|
1872
|
+
|
|
1873
|
+
'bufferViews'
|
|
1874
|
+
|
|
1875
|
+
] ).then( function ( dependencies ) {
|
|
1876
|
+
|
|
1877
|
+
return _each( json.textures, function ( texture ) {
|
|
1878
|
+
|
|
1879
|
+
if ( texture.source !== undefined ) {
|
|
1880
|
+
|
|
1881
|
+
return new Promise( function ( resolve ) {
|
|
1882
|
+
|
|
1883
|
+
var source = json.images[ texture.source ];
|
|
1884
|
+
var sourceUri = source.uri;
|
|
1885
|
+
|
|
1886
|
+
var urlCreator;
|
|
1887
|
+
|
|
1888
|
+
if ( source.bufferView !== undefined ) {
|
|
1889
|
+
|
|
1890
|
+
var bufferView = dependencies.bufferViews[ source.bufferView ];
|
|
1891
|
+
var blob = new Blob( [ bufferView ], { type: source.mimeType } );
|
|
1892
|
+
urlCreator = URL || webkitURL;
|
|
1893
|
+
sourceUri = urlCreator.createObjectURL( blob );
|
|
1894
|
+
|
|
1895
|
+
}
|
|
1896
|
+
|
|
1897
|
+
var textureLoader = THREE.Loader.Handlers.get( sourceUri );
|
|
1898
|
+
|
|
1899
|
+
if ( textureLoader === null ) {
|
|
1900
|
+
|
|
1901
|
+
textureLoader = new THREE.TextureLoader();
|
|
1902
|
+
|
|
1903
|
+
}
|
|
1904
|
+
|
|
1905
|
+
textureLoader.setCrossOrigin( options.crossOrigin );
|
|
1906
|
+
|
|
1907
|
+
textureLoader.load( resolveURL( sourceUri, options.path ), function ( _texture ) {
|
|
1908
|
+
|
|
1909
|
+
if ( urlCreator !== undefined ) {
|
|
1910
|
+
|
|
1911
|
+
urlCreator.revokeObjectURL( sourceUri );
|
|
1912
|
+
|
|
1913
|
+
}
|
|
1914
|
+
|
|
1915
|
+
_texture.flipY = false;
|
|
1916
|
+
|
|
1917
|
+
if ( texture.name !== undefined ) _texture.name = texture.name;
|
|
1918
|
+
|
|
1919
|
+
_texture.format = texture.format !== undefined ? WEBGL_TEXTURE_FORMATS[ texture.format ] : THREE.RGBAFormat;
|
|
1920
|
+
|
|
1921
|
+
if ( texture.internalFormat !== undefined && _texture.format !== WEBGL_TEXTURE_FORMATS[ texture.internalFormat ] ) {
|
|
1922
|
+
|
|
1923
|
+
console.warn( 'THREE.GLTF2Loader: Three.js does not support texture internalFormat which is different from texture format. ' +
|
|
1924
|
+
'internalFormat will be forced to be the same value as format.' );
|
|
1925
|
+
|
|
1926
|
+
}
|
|
1927
|
+
|
|
1928
|
+
_texture.type = texture.type !== undefined ? WEBGL_TEXTURE_DATATYPES[ texture.type ] : THREE.UnsignedByteType;
|
|
1929
|
+
|
|
1930
|
+
var samplers = json.samplers || {};
|
|
1931
|
+
var sampler = samplers[ texture.sampler ] || {};
|
|
1932
|
+
|
|
1933
|
+
_texture.magFilter = WEBGL_FILTERS[ sampler.magFilter ] || THREE.LinearFilter;
|
|
1934
|
+
_texture.minFilter = WEBGL_FILTERS[ sampler.minFilter ] || THREE.LinearMipMapLinearFilter;
|
|
1935
|
+
_texture.wrapS = WEBGL_WRAPPINGS[ sampler.wrapS ] || THREE.RepeatWrapping;
|
|
1936
|
+
_texture.wrapT = WEBGL_WRAPPINGS[ sampler.wrapT ] || THREE.RepeatWrapping;
|
|
1937
|
+
|
|
1938
|
+
resolve( _texture );
|
|
1939
|
+
|
|
1940
|
+
}, undefined, function () {
|
|
1941
|
+
|
|
1942
|
+
resolve();
|
|
1943
|
+
|
|
1944
|
+
} );
|
|
1945
|
+
|
|
1946
|
+
} );
|
|
1947
|
+
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1950
|
+
} );
|
|
1951
|
+
|
|
1952
|
+
} );
|
|
1953
|
+
|
|
1954
|
+
};
|
|
1955
|
+
|
|
1956
|
+
GLTFParser.prototype.loadMaterials = function () {
|
|
1957
|
+
|
|
1958
|
+
var json = this.json;
|
|
1959
|
+
var extensions = this.extensions;
|
|
1960
|
+
|
|
1961
|
+
return this._withDependencies( [
|
|
1962
|
+
|
|
1963
|
+
'shaders',
|
|
1964
|
+
'textures'
|
|
1965
|
+
|
|
1966
|
+
] ).then( function ( dependencies ) {
|
|
1967
|
+
|
|
1968
|
+
return _each( json.materials, function ( material ) {
|
|
1969
|
+
|
|
1970
|
+
var materialType;
|
|
1971
|
+
var materialParams = {};
|
|
1972
|
+
var materialExtensions = material.extensions || {};
|
|
1973
|
+
|
|
1974
|
+
if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_COMMON ] ) {
|
|
1975
|
+
|
|
1976
|
+
materialType = extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ].getMaterialType( material );
|
|
1977
|
+
extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ].extendParams( materialParams, material, dependencies );
|
|
1978
|
+
|
|
1979
|
+
} else if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ] ) {
|
|
1980
|
+
|
|
1981
|
+
materialType = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].getMaterialType( material );
|
|
1982
|
+
extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].extendParams( materialParams, material, dependencies );
|
|
1983
|
+
|
|
1984
|
+
} else if ( materialExtensions[ EXTENSIONS.KHR_TECHNIQUE_WEBGL ] ) {
|
|
1985
|
+
|
|
1986
|
+
materialType = extensions[ EXTENSIONS.KHR_TECHNIQUE_WEBGL ].getMaterialType( material );
|
|
1987
|
+
extensions[ EXTENSIONS.KHR_TECHNIQUE_WEBGL ].extendParams( materialParams, material, dependencies );
|
|
1988
|
+
|
|
1989
|
+
} else if ( material.pbrMetallicRoughness !== undefined ) {
|
|
1990
|
+
|
|
1991
|
+
// Specification:
|
|
1992
|
+
// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#metallic-roughness-material
|
|
1993
|
+
|
|
1994
|
+
materialType = THREE.MeshStandardMaterial;
|
|
1995
|
+
|
|
1996
|
+
var metallicRoughness = material.pbrMetallicRoughness;
|
|
1997
|
+
|
|
1998
|
+
materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 );
|
|
1999
|
+
materialParams.opacity = 1.0;
|
|
2000
|
+
|
|
2001
|
+
if ( Array.isArray( metallicRoughness.baseColorFactor ) ) {
|
|
2002
|
+
|
|
2003
|
+
var array = metallicRoughness.baseColorFactor;
|
|
2004
|
+
|
|
2005
|
+
materialParams.color.fromArray( array );
|
|
2006
|
+
materialParams.opacity = array[ 3 ];
|
|
2007
|
+
|
|
2008
|
+
}
|
|
2009
|
+
|
|
2010
|
+
if ( metallicRoughness.baseColorTexture !== undefined ) {
|
|
2011
|
+
|
|
2012
|
+
materialParams.map = dependencies.textures[ metallicRoughness.baseColorTexture.index ];
|
|
2013
|
+
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
materialParams.metalness = metallicRoughness.metallicFactor !== undefined ? metallicRoughness.metallicFactor : 1.0;
|
|
2017
|
+
materialParams.roughness = metallicRoughness.roughnessFactor !== undefined ? metallicRoughness.roughnessFactor : 1.0;
|
|
2018
|
+
|
|
2019
|
+
if ( metallicRoughness.metallicRoughnessTexture !== undefined ) {
|
|
2020
|
+
|
|
2021
|
+
var textureIndex = metallicRoughness.metallicRoughnessTexture.index;
|
|
2022
|
+
materialParams.metalnessMap = dependencies.textures[ textureIndex ];
|
|
2023
|
+
materialParams.roughnessMap = dependencies.textures[ textureIndex ];
|
|
2024
|
+
|
|
2025
|
+
}
|
|
2026
|
+
|
|
2027
|
+
} else {
|
|
2028
|
+
|
|
2029
|
+
materialType = THREE.MeshPhongMaterial;
|
|
2030
|
+
|
|
2031
|
+
}
|
|
2032
|
+
|
|
2033
|
+
if ( material.doubleSided === true ) {
|
|
2034
|
+
|
|
2035
|
+
materialParams.side = THREE.DoubleSide;
|
|
2036
|
+
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
var alphaMode = material.alphaMode || ALPHA_MODES.OPAQUE;
|
|
2040
|
+
|
|
2041
|
+
if ( alphaMode !== ALPHA_MODES.OPAQUE ) {
|
|
2042
|
+
|
|
2043
|
+
materialParams.transparent = true;
|
|
2044
|
+
|
|
2045
|
+
} else {
|
|
2046
|
+
|
|
2047
|
+
materialParams.transparent = false;
|
|
2048
|
+
|
|
2049
|
+
}
|
|
2050
|
+
|
|
2051
|
+
if ( material.normalTexture !== undefined ) {
|
|
2052
|
+
|
|
2053
|
+
materialParams.normalMap = dependencies.textures[ material.normalTexture.index ];
|
|
2054
|
+
|
|
2055
|
+
}
|
|
2056
|
+
|
|
2057
|
+
if ( material.occlusionTexture !== undefined ) {
|
|
2058
|
+
|
|
2059
|
+
materialParams.aoMap = dependencies.textures[ material.occlusionTexture.index ];
|
|
2060
|
+
|
|
2061
|
+
}
|
|
2062
|
+
|
|
2063
|
+
if ( material.emissiveFactor !== undefined ) {
|
|
2064
|
+
|
|
2065
|
+
if ( materialType === THREE.MeshBasicMaterial ) {
|
|
2066
|
+
|
|
2067
|
+
materialParams.color = new THREE.Color().fromArray( material.emissiveFactor );
|
|
2068
|
+
|
|
2069
|
+
} else {
|
|
2070
|
+
|
|
2071
|
+
materialParams.emissive = new THREE.Color().fromArray( material.emissiveFactor );
|
|
2072
|
+
|
|
2073
|
+
}
|
|
2074
|
+
|
|
2075
|
+
}
|
|
2076
|
+
|
|
2077
|
+
if ( material.emissiveTexture !== undefined ) {
|
|
2078
|
+
|
|
2079
|
+
if ( materialType === THREE.MeshBasicMaterial ) {
|
|
2080
|
+
|
|
2081
|
+
materialParams.map = dependencies.textures[ material.emissiveTexture.index ];
|
|
2082
|
+
|
|
2083
|
+
} else {
|
|
2084
|
+
|
|
2085
|
+
materialParams.emissiveMap = dependencies.textures[ material.emissiveTexture.index ];
|
|
2086
|
+
|
|
2087
|
+
}
|
|
2088
|
+
|
|
2089
|
+
}
|
|
2090
|
+
|
|
2091
|
+
var _material;
|
|
2092
|
+
|
|
2093
|
+
if ( materialType === THREE.ShaderMaterial ) {
|
|
2094
|
+
|
|
2095
|
+
_material = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].createMaterial( materialParams );
|
|
2096
|
+
|
|
2097
|
+
} else {
|
|
2098
|
+
|
|
2099
|
+
_material = new materialType( materialParams );
|
|
2100
|
+
|
|
2101
|
+
}
|
|
2102
|
+
|
|
2103
|
+
if ( material.name !== undefined ) _material.name = material.name;
|
|
2104
|
+
|
|
2105
|
+
// Normal map textures use OpenGL conventions:
|
|
2106
|
+
// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#materialnormaltexture
|
|
2107
|
+
_material.normalScale.x = -1;
|
|
2108
|
+
|
|
2109
|
+
return _material;
|
|
2110
|
+
|
|
2111
|
+
} );
|
|
2112
|
+
|
|
2113
|
+
} );
|
|
2114
|
+
|
|
2115
|
+
};
|
|
2116
|
+
|
|
2117
|
+
GLTFParser.prototype.loadMeshes = function () {
|
|
2118
|
+
|
|
2119
|
+
var json = this.json;
|
|
2120
|
+
|
|
2121
|
+
return this._withDependencies( [
|
|
2122
|
+
|
|
2123
|
+
'accessors',
|
|
2124
|
+
'materials'
|
|
2125
|
+
|
|
2126
|
+
] ).then( function ( dependencies ) {
|
|
2127
|
+
|
|
2128
|
+
return _each( json.meshes, function ( mesh ) {
|
|
2129
|
+
|
|
2130
|
+
var group = new THREE.Group();
|
|
2131
|
+
if ( mesh.name !== undefined ) group.name = mesh.name;
|
|
2132
|
+
|
|
2133
|
+
if ( mesh.extras ) group.userData = mesh.extras;
|
|
2134
|
+
|
|
2135
|
+
var primitives = mesh.primitives || [];
|
|
2136
|
+
|
|
2137
|
+
for ( var name in primitives ) {
|
|
2138
|
+
|
|
2139
|
+
var primitive = primitives[ name ];
|
|
2140
|
+
|
|
2141
|
+
var material = primitive.material !== undefined ? dependencies.materials[ primitive.material ] : createDefaultMaterial();
|
|
2142
|
+
|
|
2143
|
+
var geometry;
|
|
2144
|
+
|
|
2145
|
+
var meshNode;
|
|
2146
|
+
|
|
2147
|
+
if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES || primitive.mode === undefined ) {
|
|
2148
|
+
|
|
2149
|
+
geometry = new THREE.BufferGeometry();
|
|
2150
|
+
|
|
2151
|
+
var attributes = primitive.attributes;
|
|
2152
|
+
|
|
2153
|
+
for ( var attributeId in attributes ) {
|
|
2154
|
+
|
|
2155
|
+
var attributeEntry = attributes[ attributeId ];
|
|
2156
|
+
|
|
2157
|
+
if ( attributeEntry === undefined ) return;
|
|
2158
|
+
|
|
2159
|
+
var bufferAttribute = dependencies.accessors[ attributeEntry ];
|
|
2160
|
+
|
|
2161
|
+
switch ( attributeId ) {
|
|
2162
|
+
|
|
2163
|
+
case 'POSITION':
|
|
2164
|
+
|
|
2165
|
+
geometry.addAttribute( 'position', bufferAttribute );
|
|
2166
|
+
break;
|
|
2167
|
+
|
|
2168
|
+
case 'NORMAL':
|
|
2169
|
+
|
|
2170
|
+
geometry.addAttribute( 'normal', bufferAttribute );
|
|
2171
|
+
break;
|
|
2172
|
+
|
|
2173
|
+
case 'TEXCOORD_0':
|
|
2174
|
+
case 'TEXCOORD0':
|
|
2175
|
+
case 'TEXCOORD':
|
|
2176
|
+
|
|
2177
|
+
geometry.addAttribute( 'uv', bufferAttribute );
|
|
2178
|
+
break;
|
|
2179
|
+
|
|
2180
|
+
case 'TEXCOORD_1':
|
|
2181
|
+
|
|
2182
|
+
geometry.addAttribute( 'uv2', bufferAttribute );
|
|
2183
|
+
break;
|
|
2184
|
+
|
|
2185
|
+
case 'COLOR_0':
|
|
2186
|
+
case 'COLOR0':
|
|
2187
|
+
case 'COLOR':
|
|
2188
|
+
|
|
2189
|
+
geometry.addAttribute( 'color', bufferAttribute );
|
|
2190
|
+
break;
|
|
2191
|
+
|
|
2192
|
+
case 'WEIGHTS_0':
|
|
2193
|
+
case 'WEIGHT': // WEIGHT semantic deprecated.
|
|
2194
|
+
|
|
2195
|
+
geometry.addAttribute( 'skinWeight', bufferAttribute );
|
|
2196
|
+
break;
|
|
2197
|
+
|
|
2198
|
+
case 'JOINTS_0':
|
|
2199
|
+
case 'JOINT': // JOINT semantic deprecated.
|
|
2200
|
+
|
|
2201
|
+
geometry.addAttribute( 'skinIndex', bufferAttribute );
|
|
2202
|
+
break;
|
|
2203
|
+
|
|
2204
|
+
}
|
|
2205
|
+
|
|
2206
|
+
}
|
|
2207
|
+
|
|
2208
|
+
if ( primitive.indices !== undefined ) {
|
|
2209
|
+
|
|
2210
|
+
geometry.setIndex( dependencies.accessors[ primitive.indices ] );
|
|
2211
|
+
|
|
2212
|
+
}
|
|
2213
|
+
|
|
2214
|
+
if ( material.aoMap
|
|
2215
|
+
&& geometry.attributes.uv2 === undefined
|
|
2216
|
+
&& geometry.attributes.uv !== undefined ) {
|
|
2217
|
+
|
|
2218
|
+
console.log( 'THREE.GLTF2Loader: Duplicating UVs to support aoMap.' );
|
|
2219
|
+
geometry.addAttribute( 'uv2', new THREE.BufferAttribute( geometry.attributes.uv.array, 2 ) );
|
|
2220
|
+
|
|
2221
|
+
}
|
|
2222
|
+
|
|
2223
|
+
if ( geometry.attributes.normal === undefined ) {
|
|
2224
|
+
|
|
2225
|
+
if ( material.flatShading !== undefined ) {
|
|
2226
|
+
|
|
2227
|
+
material.flatShading = true;
|
|
2228
|
+
|
|
2229
|
+
} else {
|
|
2230
|
+
|
|
2231
|
+
// TODO: Remove this backwards-compatibility fix after r87 release.
|
|
2232
|
+
material.shading = THREE.FlatShading;
|
|
2233
|
+
|
|
2234
|
+
}
|
|
2235
|
+
|
|
2236
|
+
}
|
|
2237
|
+
|
|
2238
|
+
meshNode = new THREE.Mesh( geometry, material );
|
|
2239
|
+
meshNode.castShadow = true;
|
|
2240
|
+
|
|
2241
|
+
if ( primitive.targets !== undefined ) {
|
|
2242
|
+
|
|
2243
|
+
var targets = primitive.targets;
|
|
2244
|
+
var morphAttributes = geometry.morphAttributes;
|
|
2245
|
+
|
|
2246
|
+
morphAttributes.position = [];
|
|
2247
|
+
morphAttributes.normal = [];
|
|
2248
|
+
|
|
2249
|
+
material.morphTargets = true;
|
|
2250
|
+
|
|
2251
|
+
for ( var i = 0, il = targets.length; i < il; i ++ ) {
|
|
2252
|
+
|
|
2253
|
+
var target = targets[ i ];
|
|
2254
|
+
var attributeName = 'morphTarget' + i;
|
|
2255
|
+
|
|
2256
|
+
var positionAttribute, normalAttribute;
|
|
2257
|
+
|
|
2258
|
+
if ( target.POSITION !== undefined ) {
|
|
2259
|
+
|
|
2260
|
+
// Three.js morph formula is
|
|
2261
|
+
// position
|
|
2262
|
+
// + weight0 * ( morphTarget0 - position )
|
|
2263
|
+
// + weight1 * ( morphTarget1 - position )
|
|
2264
|
+
// ...
|
|
2265
|
+
// while the glTF one is
|
|
2266
|
+
// position
|
|
2267
|
+
// + weight0 * morphTarget0
|
|
2268
|
+
// + weight1 * morphTarget1
|
|
2269
|
+
// ...
|
|
2270
|
+
// then adding position to morphTarget.
|
|
2271
|
+
// So morphTarget value will depend on mesh's position, then cloning attribute
|
|
2272
|
+
// for the case if attribute is shared among two or more meshes.
|
|
2273
|
+
|
|
2274
|
+
positionAttribute = dependencies.accessors[ target.POSITION ].clone();
|
|
2275
|
+
var position = geometry.attributes.position;
|
|
2276
|
+
|
|
2277
|
+
for ( var j = 0, jl = positionAttribute.count; j < jl; j ++ ) {
|
|
2278
|
+
|
|
2279
|
+
positionAttribute.setXYZ(
|
|
2280
|
+
j,
|
|
2281
|
+
positionAttribute.getX( j ) + position.getX( j ),
|
|
2282
|
+
positionAttribute.getY( j ) + position.getY( j ),
|
|
2283
|
+
positionAttribute.getZ( j ) + position.getZ( j )
|
|
2284
|
+
);
|
|
2285
|
+
|
|
2286
|
+
}
|
|
2287
|
+
|
|
2288
|
+
} else if ( geometry.attributes.position ) {
|
|
2289
|
+
|
|
2290
|
+
// Copying the original position not to affect the final position.
|
|
2291
|
+
// See the formula above.
|
|
2292
|
+
positionAttribute = geometry.attributes.position.clone();
|
|
2293
|
+
|
|
2294
|
+
}
|
|
2295
|
+
|
|
2296
|
+
if ( target.NORMAL !== undefined ) {
|
|
2297
|
+
|
|
2298
|
+
material.morphNormals = true;
|
|
2299
|
+
|
|
2300
|
+
// see target.POSITION's comment
|
|
2301
|
+
|
|
2302
|
+
normalAttribute = dependencies.accessors[ target.NORMAL ].clone();
|
|
2303
|
+
var normal = geometry.attributes.normal;
|
|
2304
|
+
|
|
2305
|
+
for ( var j = 0, jl = normalAttribute.count; j < jl; j ++ ) {
|
|
2306
|
+
|
|
2307
|
+
normalAttribute.setXYZ(
|
|
2308
|
+
j,
|
|
2309
|
+
normalAttribute.getX( j ) + normal.getX( j ),
|
|
2310
|
+
normalAttribute.getY( j ) + normal.getY( j ),
|
|
2311
|
+
normalAttribute.getZ( j ) + normal.getZ( j )
|
|
2312
|
+
);
|
|
2313
|
+
|
|
2314
|
+
}
|
|
2315
|
+
|
|
2316
|
+
} else if ( geometry.attributes.normal ) {
|
|
2317
|
+
|
|
2318
|
+
normalAttribute = geometry.attributes.normal.clone();
|
|
2319
|
+
|
|
2320
|
+
}
|
|
2321
|
+
|
|
2322
|
+
// TODO: implement
|
|
2323
|
+
if ( target.TANGENT !== undefined ) {
|
|
2324
|
+
|
|
2325
|
+
}
|
|
2326
|
+
|
|
2327
|
+
if ( positionAttribute ) {
|
|
2328
|
+
|
|
2329
|
+
positionAttribute.name = attributeName;
|
|
2330
|
+
morphAttributes.position.push( positionAttribute );
|
|
2331
|
+
|
|
2332
|
+
}
|
|
2333
|
+
|
|
2334
|
+
if ( normalAttribute ) {
|
|
2335
|
+
|
|
2336
|
+
normalAttribute.name = attributeName;
|
|
2337
|
+
morphAttributes.normal.push( normalAttribute );
|
|
2338
|
+
|
|
2339
|
+
}
|
|
2340
|
+
|
|
2341
|
+
}
|
|
2342
|
+
|
|
2343
|
+
meshNode.updateMorphTargets();
|
|
2344
|
+
|
|
2345
|
+
if ( mesh.weights !== undefined ) {
|
|
2346
|
+
|
|
2347
|
+
for ( var i = 0, il = mesh.weights.length; i < il; i ++ ) {
|
|
2348
|
+
|
|
2349
|
+
meshNode.morphTargetInfluences[ i ] = mesh.weights[ i ];
|
|
2350
|
+
|
|
2351
|
+
}
|
|
2352
|
+
|
|
2353
|
+
}
|
|
2354
|
+
|
|
2355
|
+
}
|
|
2356
|
+
|
|
2357
|
+
} else if ( primitive.mode === WEBGL_CONSTANTS.LINES ) {
|
|
2358
|
+
|
|
2359
|
+
geometry = new THREE.BufferGeometry();
|
|
2360
|
+
|
|
2361
|
+
var attributes = primitive.attributes;
|
|
2362
|
+
|
|
2363
|
+
for ( var attributeId in attributes ) {
|
|
2364
|
+
|
|
2365
|
+
var attributeEntry = attributes[ attributeId ];
|
|
2366
|
+
|
|
2367
|
+
if ( ! attributeEntry ) return;
|
|
2368
|
+
|
|
2369
|
+
var bufferAttribute = dependencies.accessors[ attributeEntry ];
|
|
2370
|
+
|
|
2371
|
+
switch ( attributeId ) {
|
|
2372
|
+
|
|
2373
|
+
case 'POSITION':
|
|
2374
|
+
geometry.addAttribute( 'position', bufferAttribute );
|
|
2375
|
+
break;
|
|
2376
|
+
|
|
2377
|
+
case 'COLOR_0':
|
|
2378
|
+
case 'COLOR0':
|
|
2379
|
+
case 'COLOR':
|
|
2380
|
+
geometry.addAttribute( 'color', bufferAttribute );
|
|
2381
|
+
break;
|
|
2382
|
+
|
|
2383
|
+
}
|
|
2384
|
+
|
|
2385
|
+
}
|
|
2386
|
+
|
|
2387
|
+
if ( primitive.indices !== undefined ) {
|
|
2388
|
+
|
|
2389
|
+
geometry.setIndex( dependencies.accessors[ primitive.indices ] );
|
|
2390
|
+
|
|
2391
|
+
}
|
|
2392
|
+
|
|
2393
|
+
meshNode = new THREE.LineSegments( geometry, material );
|
|
2394
|
+
|
|
2395
|
+
} else {
|
|
2396
|
+
|
|
2397
|
+
throw new Error( 'THREE.GLTF2Loader: Only triangular and line primitives are supported.' );
|
|
2398
|
+
|
|
2399
|
+
}
|
|
2400
|
+
|
|
2401
|
+
if ( geometry.attributes.color !== undefined ) {
|
|
2402
|
+
|
|
2403
|
+
material.vertexColors = THREE.VertexColors;
|
|
2404
|
+
material.needsUpdate = true;
|
|
2405
|
+
|
|
2406
|
+
}
|
|
2407
|
+
|
|
2408
|
+
meshNode.name = group.name + '_' + name;
|
|
2409
|
+
|
|
2410
|
+
if ( primitive.extras ) meshNode.userData = primitive.extras;
|
|
2411
|
+
|
|
2412
|
+
group.add( meshNode );
|
|
2413
|
+
|
|
2414
|
+
}
|
|
2415
|
+
|
|
2416
|
+
return group;
|
|
2417
|
+
|
|
2418
|
+
} );
|
|
2419
|
+
|
|
2420
|
+
} );
|
|
2421
|
+
|
|
2422
|
+
};
|
|
2423
|
+
|
|
2424
|
+
/**
|
|
2425
|
+
* Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#cameras
|
|
2426
|
+
*/
|
|
2427
|
+
GLTFParser.prototype.loadCameras = function () {
|
|
2428
|
+
|
|
2429
|
+
var json = this.json;
|
|
2430
|
+
|
|
2431
|
+
return _each( json.cameras, function ( camera ) {
|
|
2432
|
+
|
|
2433
|
+
var _camera;
|
|
2434
|
+
|
|
2435
|
+
var params = camera[ camera.type ];
|
|
2436
|
+
|
|
2437
|
+
if ( !params ) {
|
|
2438
|
+
|
|
2439
|
+
console.warn( 'THREE.GLTF2Loader: Missing camera parameters.' );
|
|
2440
|
+
return;
|
|
2441
|
+
|
|
2442
|
+
}
|
|
2443
|
+
|
|
2444
|
+
if ( camera.type === 'perspective' ) {
|
|
2445
|
+
|
|
2446
|
+
var aspectRatio = params.aspectRatio || 1;
|
|
2447
|
+
var xfov = params.yfov * aspectRatio;
|
|
2448
|
+
|
|
2449
|
+
_camera = new THREE.PerspectiveCamera( THREE.Math.radToDeg( xfov ), aspectRatio, params.znear || 1, params.zfar || 2e6 );
|
|
2450
|
+
|
|
2451
|
+
} else if ( camera.type === 'orthographic' ) {
|
|
2452
|
+
|
|
2453
|
+
_camera = new THREE.OrthographicCamera( params.xmag / -2, params.xmag / 2, params.ymag / 2, params.ymag / -2, params.znear, params.zfar );
|
|
2454
|
+
|
|
2455
|
+
}
|
|
2456
|
+
|
|
2457
|
+
if ( camera.name !== undefined ) _camera.name = camera.name;
|
|
2458
|
+
if ( camera.extras ) _camera.userData = camera.extras;
|
|
2459
|
+
|
|
2460
|
+
return _camera;
|
|
2461
|
+
|
|
2462
|
+
} );
|
|
2463
|
+
|
|
2464
|
+
};
|
|
2465
|
+
|
|
2466
|
+
GLTFParser.prototype.loadSkins = function () {
|
|
2467
|
+
|
|
2468
|
+
var json = this.json;
|
|
2469
|
+
|
|
2470
|
+
return this._withDependencies( [
|
|
2471
|
+
|
|
2472
|
+
'accessors'
|
|
2473
|
+
|
|
2474
|
+
] ).then( function ( dependencies ) {
|
|
2475
|
+
|
|
2476
|
+
return _each( json.skins, function ( skin ) {
|
|
2477
|
+
|
|
2478
|
+
var _skin = {
|
|
2479
|
+
joints: skin.joints,
|
|
2480
|
+
inverseBindMatrices: dependencies.accessors[ skin.inverseBindMatrices ]
|
|
2481
|
+
};
|
|
2482
|
+
|
|
2483
|
+
return _skin;
|
|
2484
|
+
|
|
2485
|
+
} );
|
|
2486
|
+
|
|
2487
|
+
} );
|
|
2488
|
+
|
|
2489
|
+
};
|
|
2490
|
+
|
|
2491
|
+
GLTFParser.prototype.loadAnimations = function () {
|
|
2492
|
+
|
|
2493
|
+
var json = this.json;
|
|
2494
|
+
|
|
2495
|
+
return this._withDependencies( [
|
|
2496
|
+
|
|
2497
|
+
'accessors',
|
|
2498
|
+
'nodes'
|
|
2499
|
+
|
|
2500
|
+
] ).then( function ( dependencies ) {
|
|
2501
|
+
|
|
2502
|
+
return _each( json.animations, function ( animation, animationId ) {
|
|
2503
|
+
|
|
2504
|
+
var tracks = [];
|
|
2505
|
+
|
|
2506
|
+
for ( var channelId in animation.channels ) {
|
|
2507
|
+
|
|
2508
|
+
var channel = animation.channels[ channelId ];
|
|
2509
|
+
var sampler = animation.samplers[ channel.sampler ];
|
|
2510
|
+
|
|
2511
|
+
if ( sampler ) {
|
|
2512
|
+
|
|
2513
|
+
var target = channel.target;
|
|
2514
|
+
var name = target.node !== undefined ? target.node : target.id; // NOTE: target.id is deprecated.
|
|
2515
|
+
var input = animation.parameters !== undefined ? animation.parameters[ sampler.input ] : sampler.input;
|
|
2516
|
+
var output = animation.parameters !== undefined ? animation.parameters[ sampler.output ] : sampler.output;
|
|
2517
|
+
|
|
2518
|
+
var inputAccessor = dependencies.accessors[ input ];
|
|
2519
|
+
var outputAccessor = dependencies.accessors[ output ];
|
|
2520
|
+
|
|
2521
|
+
var node = dependencies.nodes[ name ];
|
|
2522
|
+
|
|
2523
|
+
if ( node ) {
|
|
2524
|
+
|
|
2525
|
+
node.updateMatrix();
|
|
2526
|
+
node.matrixAutoUpdate = true;
|
|
2527
|
+
|
|
2528
|
+
var TypedKeyframeTrack;
|
|
2529
|
+
|
|
2530
|
+
switch ( PATH_PROPERTIES[ target.path ] ) {
|
|
2531
|
+
|
|
2532
|
+
case PATH_PROPERTIES.weights:
|
|
2533
|
+
|
|
2534
|
+
TypedKeyframeTrack = THREE.NumberKeyframeTrack;
|
|
2535
|
+
break;
|
|
2536
|
+
|
|
2537
|
+
case PATH_PROPERTIES.rotation:
|
|
2538
|
+
|
|
2539
|
+
TypedKeyframeTrack = THREE.QuaternionKeyframeTrack;
|
|
2540
|
+
break;
|
|
2541
|
+
|
|
2542
|
+
case PATH_PROPERTIES.position:
|
|
2543
|
+
case PATH_PROPERTIES.scale:
|
|
2544
|
+
default:
|
|
2545
|
+
|
|
2546
|
+
TypedKeyframeTrack = THREE.VectorKeyframeTrack;
|
|
2547
|
+
break;
|
|
2548
|
+
|
|
2549
|
+
}
|
|
2550
|
+
|
|
2551
|
+
var targetName = node.name ? node.name : node.uuid;
|
|
2552
|
+
|
|
2553
|
+
if ( sampler.interpolation === 'CATMULLROMSPLINE' ) {
|
|
2554
|
+
|
|
2555
|
+
console.warn( 'THREE.GLTF2Loader: CATMULLROMSPLINE interpolation is not supported. Using CUBICSPLINE instead.' );
|
|
2556
|
+
|
|
2557
|
+
}
|
|
2558
|
+
|
|
2559
|
+
var interpolation = sampler.interpolation !== undefined ? INTERPOLATION[ sampler.interpolation ] : THREE.InterpolateLinear;
|
|
2560
|
+
|
|
2561
|
+
var targetNames = [];
|
|
2562
|
+
|
|
2563
|
+
if ( PATH_PROPERTIES[ target.path ] === PATH_PROPERTIES.weights ) {
|
|
2564
|
+
|
|
2565
|
+
// node should be THREE.Group here but
|
|
2566
|
+
// PATH_PROPERTIES.weights(morphTargetInfluences) should be
|
|
2567
|
+
// the property of a mesh object under node.
|
|
2568
|
+
// So finding targets here.
|
|
2569
|
+
|
|
2570
|
+
node.traverse( function ( object ) {
|
|
2571
|
+
|
|
2572
|
+
if ( object.isMesh === true && object.material.morphTargets === true ) {
|
|
2573
|
+
|
|
2574
|
+
targetNames.push( object.name ? object.name : object.uuid );
|
|
2575
|
+
|
|
2576
|
+
}
|
|
2577
|
+
|
|
2578
|
+
} );
|
|
2579
|
+
|
|
2580
|
+
} else {
|
|
2581
|
+
|
|
2582
|
+
targetNames.push( targetName );
|
|
2583
|
+
|
|
2584
|
+
}
|
|
2585
|
+
|
|
2586
|
+
// KeyframeTrack.optimize() will modify given 'times' and 'values'
|
|
2587
|
+
// buffers before creating a truncated copy to keep. Because buffers may
|
|
2588
|
+
// be reused by other tracks, make copies here.
|
|
2589
|
+
for ( var i = 0, il = targetNames.length; i < il; i ++ ) {
|
|
2590
|
+
|
|
2591
|
+
tracks.push( new TypedKeyframeTrack(
|
|
2592
|
+
targetNames[ i ] + '.' + PATH_PROPERTIES[ target.path ],
|
|
2593
|
+
THREE.AnimationUtils.arraySlice( inputAccessor.array, 0 ),
|
|
2594
|
+
THREE.AnimationUtils.arraySlice( outputAccessor.array, 0 ),
|
|
2595
|
+
interpolation
|
|
2596
|
+
) );
|
|
2597
|
+
|
|
2598
|
+
}
|
|
2599
|
+
|
|
2600
|
+
}
|
|
2601
|
+
|
|
2602
|
+
}
|
|
2603
|
+
|
|
2604
|
+
}
|
|
2605
|
+
|
|
2606
|
+
var name = animation.name !== undefined ? animation.name : 'animation_' + animationId;
|
|
2607
|
+
|
|
2608
|
+
return new THREE.AnimationClip( name, undefined, tracks );
|
|
2609
|
+
|
|
2610
|
+
} );
|
|
2611
|
+
|
|
2612
|
+
} );
|
|
2613
|
+
|
|
2614
|
+
};
|
|
2615
|
+
|
|
2616
|
+
GLTFParser.prototype.loadNodes = function () {
|
|
2617
|
+
|
|
2618
|
+
var json = this.json;
|
|
2619
|
+
var extensions = this.extensions;
|
|
2620
|
+
var scope = this;
|
|
2621
|
+
|
|
2622
|
+
var nodes = json.nodes || [];
|
|
2623
|
+
var skins = json.skins || [];
|
|
2624
|
+
|
|
2625
|
+
// Nothing in the node definition indicates whether it is a Bone or an
|
|
2626
|
+
// Object3D. Use the skins' joint references to mark bones.
|
|
2627
|
+
skins.forEach( function ( skin ) {
|
|
2628
|
+
|
|
2629
|
+
skin.joints.forEach( function ( id ) {
|
|
2630
|
+
|
|
2631
|
+
nodes[ id ].isBone = true;
|
|
2632
|
+
|
|
2633
|
+
} );
|
|
2634
|
+
|
|
2635
|
+
} );
|
|
2636
|
+
|
|
2637
|
+
return _each( json.nodes, function ( node ) {
|
|
2638
|
+
|
|
2639
|
+
var matrix = new THREE.Matrix4();
|
|
2640
|
+
|
|
2641
|
+
var _node = node.isBone === true ? new THREE.Bone() : new THREE.Object3D();
|
|
2642
|
+
|
|
2643
|
+
if ( node.name !== undefined ) {
|
|
2644
|
+
|
|
2645
|
+
_node.name = THREE.PropertyBinding.sanitizeNodeName( node.name );
|
|
2646
|
+
|
|
2647
|
+
}
|
|
2648
|
+
|
|
2649
|
+
if ( node.extras ) _node.userData = node.extras;
|
|
2650
|
+
|
|
2651
|
+
if ( node.matrix !== undefined ) {
|
|
2652
|
+
|
|
2653
|
+
matrix.fromArray( node.matrix );
|
|
2654
|
+
_node.applyMatrix( matrix );
|
|
2655
|
+
|
|
2656
|
+
} else {
|
|
2657
|
+
|
|
2658
|
+
if ( node.translation !== undefined ) {
|
|
2659
|
+
|
|
2660
|
+
_node.position.fromArray( node.translation );
|
|
2661
|
+
|
|
2662
|
+
}
|
|
2663
|
+
|
|
2664
|
+
if ( node.rotation !== undefined ) {
|
|
2665
|
+
|
|
2666
|
+
_node.quaternion.fromArray( node.rotation );
|
|
2667
|
+
|
|
2668
|
+
}
|
|
2669
|
+
|
|
2670
|
+
if ( node.scale !== undefined ) {
|
|
2671
|
+
|
|
2672
|
+
_node.scale.fromArray( node.scale );
|
|
2673
|
+
|
|
2674
|
+
}
|
|
2675
|
+
|
|
2676
|
+
}
|
|
2677
|
+
|
|
2678
|
+
return _node;
|
|
2679
|
+
|
|
2680
|
+
} ).then( function ( __nodes ) {
|
|
2681
|
+
|
|
2682
|
+
return scope._withDependencies( [
|
|
2683
|
+
|
|
2684
|
+
'meshes',
|
|
2685
|
+
'skins',
|
|
2686
|
+
'cameras'
|
|
2687
|
+
|
|
2688
|
+
] ).then( function ( dependencies ) {
|
|
2689
|
+
|
|
2690
|
+
return _each( __nodes, function ( _node, nodeId ) {
|
|
2691
|
+
|
|
2692
|
+
var node = json.nodes[ nodeId ];
|
|
2693
|
+
|
|
2694
|
+
var meshes;
|
|
2695
|
+
|
|
2696
|
+
if ( node.mesh !== undefined) {
|
|
2697
|
+
|
|
2698
|
+
meshes = [ node.mesh ];
|
|
2699
|
+
|
|
2700
|
+
} else if ( node.meshes !== undefined ) {
|
|
2701
|
+
|
|
2702
|
+
console.warn( 'THREE.GLTF2Loader: Legacy glTF file detected. Nodes may have no more than one mesh.' );
|
|
2703
|
+
|
|
2704
|
+
meshes = node.meshes;
|
|
2705
|
+
|
|
2706
|
+
}
|
|
2707
|
+
|
|
2708
|
+
if ( meshes !== undefined ) {
|
|
2709
|
+
|
|
2710
|
+
for ( var meshId in meshes ) {
|
|
2711
|
+
|
|
2712
|
+
var mesh = meshes[ meshId ];
|
|
2713
|
+
var group = dependencies.meshes[ mesh ];
|
|
2714
|
+
|
|
2715
|
+
if ( group === undefined ) {
|
|
2716
|
+
|
|
2717
|
+
console.warn( 'THREE.GLTF2Loader: Could not find node "' + mesh + '".' );
|
|
2718
|
+
continue;
|
|
2719
|
+
|
|
2720
|
+
}
|
|
2721
|
+
|
|
2722
|
+
// do not clone children as they will be replaced anyway
|
|
2723
|
+
var clonedgroup = group.clone( false );
|
|
2724
|
+
|
|
2725
|
+
for ( var childrenId in group.children ) {
|
|
2726
|
+
|
|
2727
|
+
var child = group.children[ childrenId ];
|
|
2728
|
+
|
|
2729
|
+
// clone Mesh to add to _node
|
|
2730
|
+
|
|
2731
|
+
var originalMaterial = child.material;
|
|
2732
|
+
var originalGeometry = child.geometry;
|
|
2733
|
+
var originalInfluences = child.morphTargetInfluences;
|
|
2734
|
+
var originalUserData = child.userData;
|
|
2735
|
+
var originalName = child.name;
|
|
2736
|
+
|
|
2737
|
+
var material;
|
|
2738
|
+
|
|
2739
|
+
if ( originalMaterial.isDeferredShaderMaterial ) {
|
|
2740
|
+
|
|
2741
|
+
originalMaterial = material = originalMaterial.create();
|
|
2742
|
+
|
|
2743
|
+
} else {
|
|
2744
|
+
|
|
2745
|
+
material = originalMaterial;
|
|
2746
|
+
|
|
2747
|
+
}
|
|
2748
|
+
|
|
2749
|
+
switch ( child.type ) {
|
|
2750
|
+
|
|
2751
|
+
case 'LineSegments':
|
|
2752
|
+
child = new THREE.LineSegments( originalGeometry, material );
|
|
2753
|
+
break;
|
|
2754
|
+
|
|
2755
|
+
case 'LineLoop':
|
|
2756
|
+
child = new THREE.LineLoop( originalGeometry, material );
|
|
2757
|
+
break;
|
|
2758
|
+
|
|
2759
|
+
case 'Line':
|
|
2760
|
+
child = new THREE.Line( originalGeometry, material );
|
|
2761
|
+
break;
|
|
2762
|
+
|
|
2763
|
+
default:
|
|
2764
|
+
child = new THREE.Mesh( originalGeometry, material );
|
|
2765
|
+
|
|
2766
|
+
}
|
|
2767
|
+
|
|
2768
|
+
child.castShadow = true;
|
|
2769
|
+
child.morphTargetInfluences = originalInfluences;
|
|
2770
|
+
child.userData = originalUserData;
|
|
2771
|
+
child.name = originalName;
|
|
2772
|
+
|
|
2773
|
+
var skinEntry;
|
|
2774
|
+
|
|
2775
|
+
if ( node.skin !== undefined ) {
|
|
2776
|
+
|
|
2777
|
+
skinEntry = dependencies.skins[ node.skin ];
|
|
2778
|
+
|
|
2779
|
+
}
|
|
2780
|
+
|
|
2781
|
+
// Replace Mesh with SkinnedMesh in library
|
|
2782
|
+
if ( skinEntry ) {
|
|
2783
|
+
|
|
2784
|
+
var geometry = originalGeometry;
|
|
2785
|
+
material = originalMaterial;
|
|
2786
|
+
material.skinning = true;
|
|
2787
|
+
|
|
2788
|
+
child = new THREE.SkinnedMesh( geometry, material );
|
|
2789
|
+
child.castShadow = true;
|
|
2790
|
+
child.userData = originalUserData;
|
|
2791
|
+
child.name = originalName;
|
|
2792
|
+
|
|
2793
|
+
var bones = [];
|
|
2794
|
+
var boneInverses = [];
|
|
2795
|
+
|
|
2796
|
+
for ( var i = 0, l = skinEntry.joints.length; i < l; i ++ ) {
|
|
2797
|
+
|
|
2798
|
+
var jointId = skinEntry.joints[ i ];
|
|
2799
|
+
var jointNode = __nodes[ jointId ];
|
|
2800
|
+
|
|
2801
|
+
if ( jointNode ) {
|
|
2802
|
+
|
|
2803
|
+
bones.push( jointNode );
|
|
2804
|
+
|
|
2805
|
+
var m = skinEntry.inverseBindMatrices.array;
|
|
2806
|
+
var mat = new THREE.Matrix4().fromArray( m, i * 16 );
|
|
2807
|
+
boneInverses.push( mat );
|
|
2808
|
+
|
|
2809
|
+
} else {
|
|
2810
|
+
|
|
2811
|
+
console.warn( 'THREE.GLTF2Loader: Joint "%s" could not be found.', jointId );
|
|
2812
|
+
|
|
2813
|
+
}
|
|
2814
|
+
|
|
2815
|
+
}
|
|
2816
|
+
|
|
2817
|
+
child.bind( new THREE.Skeleton( bones, boneInverses ), child.matrixWorld );
|
|
2818
|
+
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2821
|
+
clonedgroup.add( child );
|
|
2822
|
+
|
|
2823
|
+
}
|
|
2824
|
+
|
|
2825
|
+
_node.add( clonedgroup );
|
|
2826
|
+
|
|
2827
|
+
}
|
|
2828
|
+
|
|
2829
|
+
}
|
|
2830
|
+
|
|
2831
|
+
if ( node.camera !== undefined ) {
|
|
2832
|
+
|
|
2833
|
+
var camera = dependencies.cameras[ node.camera ];
|
|
2834
|
+
|
|
2835
|
+
_node.add( camera );
|
|
2836
|
+
|
|
2837
|
+
}
|
|
2838
|
+
|
|
2839
|
+
if ( node.extensions
|
|
2840
|
+
&& node.extensions[ EXTENSIONS.KHR_LIGHTS ]
|
|
2841
|
+
&& node.extensions[ EXTENSIONS.KHR_LIGHTS ].light !== undefined ) {
|
|
2842
|
+
|
|
2843
|
+
var lights = extensions[ EXTENSIONS.KHR_LIGHTS ].lights;
|
|
2844
|
+
_node.add( lights[ node.extensions[ EXTENSIONS.KHR_LIGHTS ].light ] );
|
|
2845
|
+
|
|
2846
|
+
}
|
|
2847
|
+
|
|
2848
|
+
return _node;
|
|
2849
|
+
|
|
2850
|
+
} );
|
|
2851
|
+
|
|
2852
|
+
} );
|
|
2853
|
+
|
|
2854
|
+
} );
|
|
2855
|
+
|
|
2856
|
+
};
|
|
2857
|
+
|
|
2858
|
+
GLTFParser.prototype.loadScenes = function () {
|
|
2859
|
+
|
|
2860
|
+
var json = this.json;
|
|
2861
|
+
var extensions = this.extensions;
|
|
2862
|
+
|
|
2863
|
+
// scene node hierachy builder
|
|
2864
|
+
|
|
2865
|
+
function buildNodeHierachy( nodeId, parentObject, allNodes ) {
|
|
2866
|
+
|
|
2867
|
+
var _node = allNodes[ nodeId ];
|
|
2868
|
+
parentObject.add( _node );
|
|
2869
|
+
|
|
2870
|
+
var node = json.nodes[ nodeId ];
|
|
2871
|
+
|
|
2872
|
+
if ( node.children ) {
|
|
2873
|
+
|
|
2874
|
+
var children = node.children;
|
|
2875
|
+
|
|
2876
|
+
for ( var i = 0, l = children.length; i < l; i ++ ) {
|
|
2877
|
+
|
|
2878
|
+
var child = children[ i ];
|
|
2879
|
+
buildNodeHierachy( child, _node, allNodes );
|
|
2880
|
+
|
|
2881
|
+
}
|
|
2882
|
+
|
|
2883
|
+
}
|
|
2884
|
+
|
|
2885
|
+
}
|
|
2886
|
+
|
|
2887
|
+
return this._withDependencies( [
|
|
2888
|
+
|
|
2889
|
+
'nodes'
|
|
2890
|
+
|
|
2891
|
+
] ).then( function ( dependencies ) {
|
|
2892
|
+
|
|
2893
|
+
return _each( json.scenes, function ( scene ) {
|
|
2894
|
+
|
|
2895
|
+
var _scene = new THREE.Scene();
|
|
2896
|
+
if ( scene.name !== undefined ) _scene.name = scene.name;
|
|
2897
|
+
|
|
2898
|
+
if ( scene.extras ) _scene.userData = scene.extras;
|
|
2899
|
+
|
|
2900
|
+
var nodes = scene.nodes || [];
|
|
2901
|
+
|
|
2902
|
+
for ( var i = 0, l = nodes.length; i < l; i ++ ) {
|
|
2903
|
+
|
|
2904
|
+
var nodeId = nodes[ i ];
|
|
2905
|
+
buildNodeHierachy( nodeId, _scene, dependencies.nodes );
|
|
2906
|
+
|
|
2907
|
+
}
|
|
2908
|
+
|
|
2909
|
+
_scene.traverse( function ( child ) {
|
|
2910
|
+
|
|
2911
|
+
// Register raw material meshes with GLTF2Loader.Shaders
|
|
2912
|
+
if ( child.material && child.material.isRawShaderMaterial ) {
|
|
2913
|
+
|
|
2914
|
+
child.gltfShader = new GLTFShader( child, dependencies.nodes );
|
|
2915
|
+
child.onBeforeRender = function(renderer, scene, camera){
|
|
2916
|
+
this.gltfShader.update(scene, camera);
|
|
2917
|
+
};
|
|
2918
|
+
|
|
2919
|
+
}
|
|
2920
|
+
|
|
2921
|
+
// for Specular-Glossiness.
|
|
2922
|
+
if ( child.material && child.material.isGLTFSpecularGlossinessMaterial ) {
|
|
2923
|
+
|
|
2924
|
+
child.onBeforeRender = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].refreshUniforms;
|
|
2925
|
+
|
|
2926
|
+
}
|
|
2927
|
+
|
|
2928
|
+
} );
|
|
2929
|
+
|
|
2930
|
+
// Ambient lighting, if present, is always attached to the scene root.
|
|
2931
|
+
if ( scene.extensions
|
|
2932
|
+
&& scene.extensions[ EXTENSIONS.KHR_LIGHTS ]
|
|
2933
|
+
&& scene.extensions[ EXTENSIONS.KHR_LIGHTS ].light !== undefined ) {
|
|
2934
|
+
|
|
2935
|
+
var lights = extensions[ EXTENSIONS.KHR_LIGHTS ].lights;
|
|
2936
|
+
_scene.add( lights[ scene.extensions[ EXTENSIONS.KHR_LIGHTS ].light ] );
|
|
2937
|
+
|
|
2938
|
+
}
|
|
2939
|
+
|
|
2940
|
+
return _scene;
|
|
2941
|
+
|
|
2942
|
+
} );
|
|
2943
|
+
|
|
2944
|
+
} );
|
|
2945
|
+
|
|
2946
|
+
};
|
|
2947
|
+
|
|
2948
|
+
return GLTF2Loader;
|
|
2949
|
+
|
|
2950
|
+
} )();
|