GLTFLoader.js 34.9 KB
Newer Older
1
/**
R
Rich Tibbett 已提交
2
 * @author Rich Tibbett / https://github.com/richtr
3
 * @author mrdoob / http://mrdoob.com/
R
Rich Tibbett 已提交
4
 * @author Tony Parisi / http://www.tonyparisi.com/
5 6
 */

M
Mr.doob 已提交
7
THREE.GLTFLoader = ( function () {
R
Rich Tibbett 已提交
8

M
Mr.doob 已提交
9
	function GLTFLoader( manager ) {
10

M
Mr.doob 已提交
11
		this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
12

M
Mr.doob 已提交
13
	}
R
Rich Tibbett 已提交
14

M
Mr.doob 已提交
15
	GLTFLoader.prototype = {
16

M
Mr.doob 已提交
17
		constructor: GLTFLoader,
18

M
Mr.doob 已提交
19
		load: function ( url, onLoad, onProgress, onError ) {
20

M
Mr.doob 已提交
21
			var scope = this;
22

M
Mr.doob 已提交
23
			var path = this.path && ( typeof this.path === "string" ) ? this.path : THREE.Loader.prototype.extractUrlBase( url );
24

M
Mr.doob 已提交
25 26
			var loader = new THREE.FileLoader( scope.manager );
			loader.load( url, function ( text ) {
R
Rich Tibbett 已提交
27

M
Mr.doob 已提交
28
				scope.parse( JSON.parse( text ), onLoad, path );
29

M
Mr.doob 已提交
30
			}, onProgress, onError );
31

M
Mr.doob 已提交
32
		},
33

M
Mr.doob 已提交
34
		setCrossOrigin: function ( value ) {
35

M
Mr.doob 已提交
36
			this.crossOrigin = value;
37

M
Mr.doob 已提交
38
		},
39

M
Mr.doob 已提交
40
		setPath: function ( value ) {
41

M
Mr.doob 已提交
42
			this.path = value;
43

M
Mr.doob 已提交
44
		},
45

M
Mr.doob 已提交
46
		parse: function ( json, callback, path ) {
47

M
Mr.doob 已提交
48
			console.time( 'GLTFLoader' );
49

M
Mr.doob 已提交
50
			var parser = new GLTFParser( json, {
51

M
Mr.doob 已提交
52
				path: path || this.path,
T
Takahiro 已提交
53
				crossOrigin: this.crossOrigin
54

M
Mr.doob 已提交
55
			} );
56

T
Takahiro 已提交
57
			parser.parse( function ( scene, scenes, cameras, animations ) {
58

M
Mr.doob 已提交
59
				console.timeEnd( 'GLTFLoader' );
R
Rich Tibbett 已提交
60

M
Mr.doob 已提交
61 62
				var glTF = {
					"scene": scene,
T
Takahiro 已提交
63
					"scenes": scenes,
M
Mr.doob 已提交
64
					"cameras": cameras,
65
					"animations": animations
M
Mr.doob 已提交
66
				};
R
Rich Tibbett 已提交
67

M
Mr.doob 已提交
68
				callback( glTF );
R
Rich Tibbett 已提交
69

M
Mr.doob 已提交
70
			} );
R
Rich Tibbett 已提交
71

M
Mr.doob 已提交
72
		}
R
Rich Tibbett 已提交
73

M
Mr.doob 已提交
74
	};
R
Rich Tibbett 已提交
75

M
Mr.doob 已提交
76
	/* GLTFREGISTRY */
R
Rich Tibbett 已提交
77

M
Mr.doob 已提交
78
	function GLTFRegistry() {
79

M
Mr.doob 已提交
80
		var objects = {};
81

M
Mr.doob 已提交
82
		return	{
R
Rich Tibbett 已提交
83

M
Mr.doob 已提交
84
			get: function ( key ) {
R
Rich Tibbett 已提交
85

M
Mr.doob 已提交
86
				return objects[ key ];
R
Rich Tibbett 已提交
87

M
Mr.doob 已提交
88
			},
R
Rich Tibbett 已提交
89

M
Mr.doob 已提交
90
			add: function ( key, object ) {
R
Rich Tibbett 已提交
91

M
Mr.doob 已提交
92
				objects[ key ] = object;
R
Rich Tibbett 已提交
93

M
Mr.doob 已提交
94
			},
R
Rich Tibbett 已提交
95

M
Mr.doob 已提交
96
			remove: function ( key ) {
R
Rich Tibbett 已提交
97

M
Mr.doob 已提交
98
				delete objects[ key ];
R
Rich Tibbett 已提交
99

M
Mr.doob 已提交
100
			},
R
Rich Tibbett 已提交
101

M
Mr.doob 已提交
102
			removeAll: function () {
R
Rich Tibbett 已提交
103

M
Mr.doob 已提交
104
				objects = {};
R
Rich Tibbett 已提交
105

M
Mr.doob 已提交
106
			},
R
Rich Tibbett 已提交
107

M
Mr.doob 已提交
108
			update: function ( scene, camera ) {
109

M
Mr.doob 已提交
110 111 112
				for ( var name in objects ) {

					var object = objects[ name ];
113

M
Mr.doob 已提交
114
					if ( object.update ) {
115

M
Mr.doob 已提交
116
						object.update( scene, camera );
117

M
Mr.doob 已提交
118
					}
119

M
Mr.doob 已提交
120
				}
121

M
Mr.doob 已提交
122
			}
123

M
Mr.doob 已提交
124
		};
125

M
Mr.doob 已提交
126
	}
127

M
Mr.doob 已提交
128
	/* GLTFSHADERS */
129

M
Mr.doob 已提交
130 131 132 133 134
	GLTFLoader.Shaders = new GLTFRegistry();

	/* GLTFSHADER */

	function GLTFShader( targetNode, allNodes ) {
R
Rich Tibbett 已提交
135

M
Mr.doob 已提交
136
		var boundUniforms = {};
M
Mr.doob 已提交
137 138

		// bind each uniform to its source node
M
Mr.doob 已提交
139 140 141 142 143 144

		var uniforms = targetNode.material.uniforms;

		for ( var uniformId in uniforms ) {

			var uniform = uniforms[ uniformId ];
R
Rich Tibbett 已提交
145

M
Mr.doob 已提交
146
			if ( uniform.semantic ) {
147

M
Mr.doob 已提交
148
				var sourceNodeRef = uniform.node;
149

M
Mr.doob 已提交
150
				var sourceNode = targetNode;
151

M
Mr.doob 已提交
152
				if ( sourceNodeRef ) {
153

M
Mr.doob 已提交
154
					sourceNode = allNodes[ sourceNodeRef ];
R
Rich Tibbett 已提交
155

M
Mr.doob 已提交
156
				}
R
Rich Tibbett 已提交
157

M
Mr.doob 已提交
158
				boundUniforms[ uniformId ] = {
M
Mr.doob 已提交
159 160 161 162 163
					semantic: uniform.semantic,
					sourceNode: sourceNode,
					targetNode: targetNode,
					uniform: uniform
				};
R
Rich Tibbett 已提交
164 165

			}
166

M
Mr.doob 已提交
167
		}
168

M
Mr.doob 已提交
169
		this.boundUniforms = boundUniforms;
M
Mr.doob 已提交
170
		this._m4 = new THREE.Matrix4();
171

M
Mr.doob 已提交
172
	}
173

M
Mr.doob 已提交
174 175
	// Update - update all the uniform values
	GLTFShader.prototype.update = function ( scene, camera ) {
176

M
Mr.doob 已提交
177
		// update scene graph
178

M
Mr.doob 已提交
179
		scene.updateMatrixWorld();
180

M
Mr.doob 已提交
181
		// update camera matrices and frustum
182

M
Mr.doob 已提交
183 184
		camera.updateMatrixWorld();
		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
185

M
Mr.doob 已提交
186 187 188 189 190
		var boundUniforms = this.boundUniforms;

		for ( var name in boundUniforms ) {

			var boundUniform = boundUniforms[ name ];
191

M
Mr.doob 已提交
192
			switch ( boundUniform.semantic ) {
R
Rich Tibbett 已提交
193

M
Mr.doob 已提交
194
				case "MODELVIEW":
R
Rich Tibbett 已提交
195

M
Mr.doob 已提交
196 197 198
					var m4 = boundUniform.uniform.value;
					m4.multiplyMatrices( camera.matrixWorldInverse, boundUniform.sourceNode.matrixWorld );
					break;
R
Rich Tibbett 已提交
199

M
Mr.doob 已提交
200
				case "MODELVIEWINVERSETRANSPOSE":
R
Rich Tibbett 已提交
201

M
Mr.doob 已提交
202 203 204 205
					var m3 = boundUniform.uniform.value;
					this._m4.multiplyMatrices( camera.matrixWorldInverse, boundUniform.sourceNode.matrixWorld );
					m3.getNormalMatrix( this._m4 );
					break;
R
Rich Tibbett 已提交
206

M
Mr.doob 已提交
207
				case "PROJECTION":
208

M
Mr.doob 已提交
209 210 211
					var m4 = boundUniform.uniform.value;
					m4.copy( camera.projectionMatrix );
					break;
R
Rich Tibbett 已提交
212

M
Mr.doob 已提交
213
				case "JOINTMATRIX":
R
Rich Tibbett 已提交
214

M
Mr.doob 已提交
215
					var m4v = boundUniform.uniform.value;
R
Rich Tibbett 已提交
216

M
Mr.doob 已提交
217
					for ( var mi = 0; mi < m4v.length; mi ++ ) {
R
Rich Tibbett 已提交
218

M
Mr.doob 已提交
219 220
						// So it goes like this:
						// SkinnedMesh world matrix is already baked into MODELVIEW;
T
Takahiro 已提交
221
						// transform joints to local space,
M
Mr.doob 已提交
222 223 224 225
						// then transform using joint's inverse
						m4v[ mi ]
							.getInverse( boundUniform.sourceNode.matrixWorld )
							.multiply( boundUniform.targetNode.skeleton.bones[ mi ].matrixWorld )
T
Takahiro 已提交
226 227
							.multiply( boundUniform.targetNode.skeleton.boneInverses[ mi ] )
							.multiply( boundUniform.targetNode.bindMatrix );
R
Rich Tibbett 已提交
228

M
Mr.doob 已提交
229
					}
230

M
Mr.doob 已提交
231 232 233
					break;

				default :
234

M
Mr.doob 已提交
235 236 237 238 239
					console.warn( "Unhandled shader semantic: " + boundUniform.semantic );
					break;

			}

M
Mr.doob 已提交
240
		}
M
Mr.doob 已提交
241 242

	};
243 244


245
	/* ANIMATION */
246

M
Mr.doob 已提交
247 248 249 250 251 252 253 254 255 256
	GLTFLoader.Animations = {

		update: function () {

			console.warn( 'THREE.GLTFLoader.Animation has been deprecated. Use THREE.AnimationMixer instead.' );

		}

	};

M
Mr.doob 已提交
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
	/*********************************/
	/********** INTERNALS ************/
	/*********************************/

	/* CONSTANTS */

	var WEBGL_CONSTANTS = {
		FLOAT: 5126,
		//FLOAT_MAT2: 35674,
		FLOAT_MAT3: 35675,
		FLOAT_MAT4: 35676,
		FLOAT_VEC2: 35664,
		FLOAT_VEC3: 35665,
		FLOAT_VEC4: 35666,
		LINEAR: 9729,
		REPEAT: 10497,
		SAMPLER_2D: 35678,
		TRIANGLES: 4,
275
		LINES: 1,
M
Mr.doob 已提交
276 277 278 279 280 281
		UNSIGNED_BYTE: 5121,
		UNSIGNED_SHORT: 5123,

		VERTEX_SHADER: 35633,
		FRAGMENT_SHADER: 35632
	};
282

M
Mr.doob 已提交
283 284 285 286 287 288 289 290 291 292
	var WEBGL_TYPE = {
		5126: Number,
		//35674: THREE.Matrix2,
		35675: THREE.Matrix3,
		35676: THREE.Matrix4,
		35664: THREE.Vector2,
		35665: THREE.Vector3,
		35666: THREE.Vector4,
		35678: THREE.Texture
	};
293

M
Mr.doob 已提交
294 295 296 297 298 299 300 301
	var WEBGL_COMPONENT_TYPES = {
		5120: Int8Array,
		5121: Uint8Array,
		5122: Int16Array,
		5123: Uint16Array,
		5125: Uint32Array,
		5126: Float32Array
	};
302

M
Mr.doob 已提交
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
	var WEBGL_FILTERS = {
		9728: THREE.NearestFilter,
		9729: THREE.LinearFilter,
		9984: THREE.NearestMipMapNearestFilter,
		9985: THREE.LinearMipMapNearestFilter,
		9986: THREE.NearestMipMapLinearFilter,
		9987: THREE.LinearMipMapLinearFilter
	};

	var WEBGL_WRAPPINGS = {
		33071: THREE.ClampToEdgeWrapping,
		33648: THREE.MirroredRepeatWrapping,
		10497: THREE.RepeatWrapping
	};

	var WEBGL_TYPE_SIZES = {
		'SCALAR': 1,
		'VEC2': 2,
		'VEC3': 3,
		'VEC4': 4,
		'MAT2': 4,
		'MAT3': 9,
		'MAT4': 16
	};

328 329 330 331 332 333 334
	var PATH_PROPERTIES = {
		scale: 'scale',
		translation: 'position',
		rotation: 'quaternion'
	};

	var INTERPOLATION = {
335 336
		LINEAR: THREE.InterpolateLinear,
		STEP: THREE.InterpolateDiscrete
337 338
	};

M
Mr.doob 已提交
339 340 341 342 343 344
	/* UTILITY FUNCTIONS */

	function _each( object, callback, thisObj ) {

		if ( !object ) {
			return Promise.resolve();
R
Rich Tibbett 已提交
345
		}
346

M
Mr.doob 已提交
347 348 349 350
		var results;
		var fns = [];

		if ( Object.prototype.toString.call( object ) === '[object Array]' ) {
R
Rich Tibbett 已提交
351

M
Mr.doob 已提交
352
			results = [];
R
Rich Tibbett 已提交
353

M
Mr.doob 已提交
354 355 356
			var length = object.length;
			for ( var idx = 0; idx < length; idx ++ ) {
				var value = callback.call( thisObj || this, object[ idx ], idx );
R
Rich Tibbett 已提交
357 358 359 360
				if ( value ) {
					fns.push( value );
					if ( value instanceof Promise ) {
						value.then( function( key, value ) {
M
Mr.doob 已提交
361
							results[ idx ] = value;
R
Rich Tibbett 已提交
362 363
						}.bind( this, key ));
					} else {
M
Mr.doob 已提交
364
						results[ idx ] = value;
R
Rich Tibbett 已提交
365 366
					}
				}
367
			}
R
Rich Tibbett 已提交
368

M
Mr.doob 已提交
369
		} else {
R
Rich Tibbett 已提交
370

M
Mr.doob 已提交
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
			results = {};

			for ( var key in object ) {
				if ( object.hasOwnProperty( key ) ) {
					var value = callback.call( thisObj || this, object[ key ], key );
					if ( value ) {
						fns.push( value );
						if ( value instanceof Promise ) {
							value.then( function( key, value ) {
								results[ key ] = value;
							}.bind( this, key ));
						} else {
							results[ key ] = value;
						}
					}
				}
			}
R
Rich Tibbett 已提交
388

M
Mr.doob 已提交
389
		}
R
Rich Tibbett 已提交
390

M
Mr.doob 已提交
391 392 393
		return Promise.all( fns ).then( function() {
			return results;
		});
R
Rich Tibbett 已提交
394 395 396

	}

M
Mr.doob 已提交
397
	function resolveURL( url, path ) {
R
Rich Tibbett 已提交
398

M
Mr.doob 已提交
399 400 401
		// Invalid URL
		if ( typeof url !== 'string' || url === '' )
			return '';
402

M
Mr.doob 已提交
403 404
		// Absolute URL
		if ( /^https?:\/\//i.test( url ) ) {
R
Rich Tibbett 已提交
405

M
Mr.doob 已提交
406
			return url;
R
Rich Tibbett 已提交
407

M
Mr.doob 已提交
408
		}
R
Rich Tibbett 已提交
409

M
Mr.doob 已提交
410 411
		// Data URI
		if ( /^data:.*,.*$/i.test( url ) ) {
R
Rich Tibbett 已提交
412

M
Mr.doob 已提交
413
			return url;
R
Rich Tibbett 已提交
414

M
Mr.doob 已提交
415
		}
R
Rich Tibbett 已提交
416

M
Mr.doob 已提交
417 418
		// Relative URL
		return ( path || '' ) + url;
R
Rich Tibbett 已提交
419

M
Mr.doob 已提交
420
	}
R
Rich Tibbett 已提交
421

M
Mr.doob 已提交
422 423 424
	// Three.js seems too dependent on attribute names so globally
	// replace those in the shader code
	function replaceTHREEShaderAttributes( shaderText, technique ) {
R
Rich Tibbett 已提交
425

M
Mr.doob 已提交
426 427
		// Expected technique attributes
		var attributes = {};
R
Rich Tibbett 已提交
428

M
Mr.doob 已提交
429 430 431
		for ( var attributeId in technique.attributes ) {

			var pname = technique.attributes[ attributeId ];
R
Rich Tibbett 已提交
432

M
Mr.doob 已提交
433 434 435
			var param = technique.parameters[ pname ];
			var atype = param.type;
			var semantic = param.semantic;
R
Rich Tibbett 已提交
436

M
Mr.doob 已提交
437 438 439 440
			attributes[ attributeId ] = {
				type: atype,
				semantic: semantic
			};
441

M
Mr.doob 已提交
442
		}
443

M
Mr.doob 已提交
444
		// Figure out which attributes to change in technique
445

M
Mr.doob 已提交
446 447 448
		var shaderParams = technique.parameters;
		var shaderAttributes = technique.attributes;
		var params = {};
449

M
Mr.doob 已提交
450
		for ( var attributeId in attributes ) {
451

M
Mr.doob 已提交
452 453 454 455
			var pname = shaderAttributes[ attributeId ];
			var shaderParam = shaderParams[ pname ];
			var semantic = shaderParam.semantic;
			if ( semantic ) {
456

M
Mr.doob 已提交
457
				params[ attributeId ] = shaderParam;
458

M
Mr.doob 已提交
459
			}
R
Rich Tibbett 已提交
460

M
Mr.doob 已提交
461
		}
R
Rich Tibbett 已提交
462

M
Mr.doob 已提交
463
		for ( var pname in params ) {
R
Rich Tibbett 已提交
464

M
Mr.doob 已提交
465
			var param = params[ pname ];
M
Mr.doob 已提交
466
			var semantic = param.semantic;
R
Rich Tibbett 已提交
467

M
Mr.doob 已提交
468
			var regEx = new RegExp( "\\b" + pname + "\\b", "g" );
R
Rich Tibbett 已提交
469

M
Mr.doob 已提交
470
			switch ( semantic ) {
R
Rich Tibbett 已提交
471

M
Mr.doob 已提交
472
				case "POSITION":
R
Rich Tibbett 已提交
473

M
Mr.doob 已提交
474 475
					shaderText = shaderText.replace( regEx, 'position' );
					break;
R
Rich Tibbett 已提交
476

M
Mr.doob 已提交
477
				case "NORMAL":
R
Rich Tibbett 已提交
478

M
Mr.doob 已提交
479 480
					shaderText = shaderText.replace( regEx, 'normal' );
					break;
481

M
Mr.doob 已提交
482 483 484
				case 'TEXCOORD_0':
				case 'TEXCOORD0':
				case 'TEXCOORD':
485

M
Mr.doob 已提交
486 487
					shaderText = shaderText.replace( regEx, 'uv' );
					break;
488

M
Mr.doob 已提交
489
				case "WEIGHT":
490

M
Mr.doob 已提交
491 492
					shaderText = shaderText.replace( regEx, 'skinWeight' );
					break;
493

M
Mr.doob 已提交
494
				case "JOINT":
495

M
Mr.doob 已提交
496 497
					shaderText = shaderText.replace( regEx, 'skinIndex' );
					break;
498

M
Mr.doob 已提交
499
			}
500

M
Mr.doob 已提交
501
		}
R
Rich Tibbett 已提交
502

M
Mr.doob 已提交
503
		return shaderText;
504

M
Mr.doob 已提交
505
	}
R
Rich Tibbett 已提交
506

M
Mr.doob 已提交
507 508
	// Deferred constructor for RawShaderMaterial types
	function DeferredShaderMaterial( params ) {
R
Rich Tibbett 已提交
509

M
Mr.doob 已提交
510
		this.isDeferredShaderMaterial = true;
R
Rich Tibbett 已提交
511

M
Mr.doob 已提交
512
		this.params = params;
513

M
Mr.doob 已提交
514
	}
515

M
Mr.doob 已提交
516
	DeferredShaderMaterial.prototype.create = function () {
517

M
Mr.doob 已提交
518
		var uniforms = THREE.UniformsUtils.clone( this.params.uniforms );
519

M
Mr.doob 已提交
520 521 522
		for ( var uniformId in this.params.uniforms ) {

			var originalUniform = this.params.uniforms[ uniformId ];
523

M
Mr.doob 已提交
524
			if ( originalUniform.value instanceof THREE.Texture ) {
R
Rich Tibbett 已提交
525

M
Mr.doob 已提交
526 527
				uniforms[ uniformId ].value = originalUniform.value;
				uniforms[ uniformId ].value.needsUpdate = true;
R
Rich Tibbett 已提交
528

M
Mr.doob 已提交
529
			}
R
Rich Tibbett 已提交
530

M
Mr.doob 已提交
531 532
			uniforms[ uniformId ].semantic = originalUniform.semantic;
			uniforms[ uniformId ].node = originalUniform.node;
R
Rich Tibbett 已提交
533

M
Mr.doob 已提交
534
		}
R
Rich Tibbett 已提交
535

M
Mr.doob 已提交
536
		this.params.uniforms = uniforms;
R
Rich Tibbett 已提交
537

M
Mr.doob 已提交
538
		return new THREE.RawShaderMaterial( this.params );
R
Rich Tibbett 已提交
539

M
Mr.doob 已提交
540
	};
R
Rich Tibbett 已提交
541

M
Mr.doob 已提交
542
	/* GLTF PARSER */
R
Rich Tibbett 已提交
543

M
Mr.doob 已提交
544
	function GLTFParser( json, options ) {
R
Rich Tibbett 已提交
545

M
Mr.doob 已提交
546 547
		this.json = json || {};
		this.options = options || {};
R
Rich Tibbett 已提交
548

M
Mr.doob 已提交
549 550
		// loader object cache
		this.cache = new GLTFRegistry();
R
Rich Tibbett 已提交
551

M
Mr.doob 已提交
552
	}
R
Rich Tibbett 已提交
553

M
Mr.doob 已提交
554
	GLTFParser.prototype._withDependencies = function ( dependencies ) {
R
Rich Tibbett 已提交
555

M
Mr.doob 已提交
556
		var _dependencies = {};
R
Rich Tibbett 已提交
557

M
Mr.doob 已提交
558
		for ( var i = 0; i < dependencies.length; i ++ ) {
R
Rich Tibbett 已提交
559

M
Mr.doob 已提交
560 561
			var dependency = dependencies[ i ];
			var fnName = "load" + dependency.charAt( 0 ).toUpperCase() + dependency.slice( 1 );
R
Rich Tibbett 已提交
562

M
Mr.doob 已提交
563
			var cached = this.cache.get( dependency );
564

M
Mr.doob 已提交
565
			if ( cached !== undefined ) {
566

M
Mr.doob 已提交
567
				_dependencies[ dependency ] = cached;
R
Rich Tibbett 已提交
568

M
Mr.doob 已提交
569
			} else if ( this[ fnName ] ) {
R
Rich Tibbett 已提交
570

M
Mr.doob 已提交
571 572
				var fn = this[ fnName ]();
				this.cache.add( dependency, fn );
R
Rich Tibbett 已提交
573

M
Mr.doob 已提交
574
				_dependencies[ dependency ] = fn;
R
Rich Tibbett 已提交
575

M
Mr.doob 已提交
576
			}
R
Rich Tibbett 已提交
577

M
Mr.doob 已提交
578
		}
R
Rich Tibbett 已提交
579

M
Mr.doob 已提交
580
		return _each( _dependencies, function ( dependency ) {
R
Rich Tibbett 已提交
581

M
Mr.doob 已提交
582
			return dependency;
R
Rich Tibbett 已提交
583

M
Mr.doob 已提交
584
		} );
R
Rich Tibbett 已提交
585

M
Mr.doob 已提交
586
	};
R
Rich Tibbett 已提交
587

M
Mr.doob 已提交
588
	GLTFParser.prototype.parse = function ( callback ) {
R
Rich Tibbett 已提交
589

M
Mr.doob 已提交
590 591
		var json = this.json;

M
Mr.doob 已提交
592 593
		// Clear the loader cache
		this.cache.removeAll();
R
Rich Tibbett 已提交
594

M
Mr.doob 已提交
595 596
		// Fire the callback on complete
		this._withDependencies( [
R
Rich Tibbett 已提交
597

M
Mr.doob 已提交
598 599
			"scenes",
			"cameras",
600
			"animations"
R
Rich Tibbett 已提交
601

M
Mr.doob 已提交
602
		] ).then( function ( dependencies ) {
R
Rich Tibbett 已提交
603

M
Mr.doob 已提交
604
			var scene = dependencies.scenes[ json.scene ];
R
Rich Tibbett 已提交
605

T
Takahiro 已提交
606 607 608 609 610 611 612 613
			var scenes = [];

			for ( var name in dependencies.scenes ) {

				scenes.push( dependencies.scenes[ name ] );

			}

M
Mr.doob 已提交
614
			var cameras = [];
R
Rich Tibbett 已提交
615

M
Mr.doob 已提交
616
			for ( var name in dependencies.cameras ) {
R
Rich Tibbett 已提交
617

M
Mr.doob 已提交
618
				var camera = dependencies.cameras[ name ];
M
Mr.doob 已提交
619
				cameras.push( camera );
R
Rich Tibbett 已提交
620

M
Mr.doob 已提交
621
			}
R
Rich Tibbett 已提交
622

623
			var animations = [];
R
Rich Tibbett 已提交
624

625
			for ( var name in dependencies.animations ) {
R
Rich Tibbett 已提交
626

627
				animations.push( dependencies.animations[ name ] );
R
Rich Tibbett 已提交
628

M
Mr.doob 已提交
629
			}
R
Rich Tibbett 已提交
630

T
Takahiro 已提交
631
			callback( scene, scenes, cameras, animations );
R
Rich Tibbett 已提交
632

M
Mr.doob 已提交
633
		} );
R
Rich Tibbett 已提交
634

M
Mr.doob 已提交
635
	};
R
Rich Tibbett 已提交
636

M
Mr.doob 已提交
637
	GLTFParser.prototype.loadShaders = function () {
R
Rich Tibbett 已提交
638

M
Mr.doob 已提交
639 640 641 642
		var json = this.json;
		var options = this.options;

		return _each( json.shaders, function ( shader ) {
R
Rich Tibbett 已提交
643

M
Mr.doob 已提交
644
			return new Promise( function ( resolve ) {
R
Rich Tibbett 已提交
645

646
				var loader = new THREE.FileLoader();
M
Mr.doob 已提交
647
				loader.responseType = 'text';
M
Mr.doob 已提交
648
				loader.load( resolveURL( shader.uri, options.path ), function ( shaderText ) {
R
Rich Tibbett 已提交
649

M
Mr.doob 已提交
650
					resolve( shaderText );
R
Rich Tibbett 已提交
651 652 653

				} );

M
Mr.doob 已提交
654
			} );
R
Rich Tibbett 已提交
655

M
Mr.doob 已提交
656
		} );
R
Rich Tibbett 已提交
657

M
Mr.doob 已提交
658
	};
R
Rich Tibbett 已提交
659

M
Mr.doob 已提交
660
	GLTFParser.prototype.loadBuffers = function () {
R
Rich Tibbett 已提交
661

M
Mr.doob 已提交
662 663 664 665
		var json = this.json;
		var options = this.options;

		return _each( json.buffers, function ( buffer ) {
R
Rich Tibbett 已提交
666

M
Mr.doob 已提交
667
			if ( buffer.type === 'arraybuffer' ) {
R
Rich Tibbett 已提交
668

M
Mr.doob 已提交
669
				return new Promise( function ( resolve ) {
R
Rich Tibbett 已提交
670

M
Mr.doob 已提交
671 672
					var loader = new THREE.FileLoader();
					loader.responseType = 'arraybuffer';
M
Mr.doob 已提交
673
					loader.load( resolveURL( buffer.uri, options.path ), function ( buffer ) {
R
Rich Tibbett 已提交
674

M
Mr.doob 已提交
675
						resolve( buffer );
R
Rich Tibbett 已提交
676

M
Mr.doob 已提交
677
					} );
R
Rich Tibbett 已提交
678

M
Mr.doob 已提交
679
				} );
R
Rich Tibbett 已提交
680

M
Mr.doob 已提交
681
			}
R
Rich Tibbett 已提交
682

M
Mr.doob 已提交
683
		} );
R
Rich Tibbett 已提交
684

M
Mr.doob 已提交
685
	};
R
Rich Tibbett 已提交
686

M
Mr.doob 已提交
687
	GLTFParser.prototype.loadBufferViews = function () {
R
Rich Tibbett 已提交
688

M
Mr.doob 已提交
689 690
		var json = this.json;

M
Mr.doob 已提交
691
		return this._withDependencies( [
R
Rich Tibbett 已提交
692

M
Mr.doob 已提交
693
			"buffers"
R
Rich Tibbett 已提交
694

M
Mr.doob 已提交
695
		] ).then( function ( dependencies ) {
696

M
Mr.doob 已提交
697
			return _each( json.bufferViews, function ( bufferView ) {
698

M
Mr.doob 已提交
699
				var arraybuffer = dependencies.buffers[ bufferView.buffer ];
700

M
Mr.doob 已提交
701
				return arraybuffer.slice( bufferView.byteOffset, bufferView.byteOffset + bufferView.byteLength );
702

M
Mr.doob 已提交
703
			} );
704

M
Mr.doob 已提交
705
		} );
706

M
Mr.doob 已提交
707
	};
708

M
Mr.doob 已提交
709
	GLTFParser.prototype.loadAccessors = function () {
R
Rich Tibbett 已提交
710

M
Mr.doob 已提交
711 712
		var json = this.json;

M
Mr.doob 已提交
713 714 715 716 717
		return this._withDependencies( [

			"bufferViews"

		] ).then( function ( dependencies ) {
R
Rich Tibbett 已提交
718

M
Mr.doob 已提交
719
			return _each( json.accessors, function ( accessor ) {
R
Rich Tibbett 已提交
720

M
Mr.doob 已提交
721 722 723
				var arraybuffer = dependencies.bufferViews[ accessor.bufferView ];
				var itemSize = WEBGL_TYPE_SIZES[ accessor.type ];
				var TypedArray = WEBGL_COMPONENT_TYPES[ accessor.componentType ];
R
Rich Tibbett 已提交
724

M
Mr.doob 已提交
725 726 727
				// For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.
				var elementBytes = TypedArray.BYTES_PER_ELEMENT;
				var itemBytes = elementBytes * itemSize;
R
Rich Tibbett 已提交
728

M
Mr.doob 已提交
729 730
				// The buffer is not interleaved if the stride is the item size in bytes.
				if ( accessor.byteStride && accessor.byteStride !== itemBytes ) {
R
Rich Tibbett 已提交
731

M
Mr.doob 已提交
732 733
					// Use the full buffer if it's interleaved.
					var array = new TypedArray( arraybuffer );
R
Rich Tibbett 已提交
734

M
Mr.doob 已提交
735 736
					// Integer parameters to IB/IBA are in array elements, not bytes.
					var ib = new THREE.InterleavedBuffer( array, accessor.byteStride / elementBytes );
R
Rich Tibbett 已提交
737

M
Mr.doob 已提交
738
					return new THREE.InterleavedBufferAttribute( ib, itemSize, accessor.byteOffset / elementBytes );
R
Rich Tibbett 已提交
739

M
Mr.doob 已提交
740 741 742
				} else {

					array = new TypedArray( arraybuffer, accessor.byteOffset, accessor.count * itemSize );
R
Rich Tibbett 已提交
743

M
Mr.doob 已提交
744
					return new THREE.BufferAttribute( array, itemSize );
R
Rich Tibbett 已提交
745 746 747

				}

M
Mr.doob 已提交
748
			} );
R
Rich Tibbett 已提交
749

M
Mr.doob 已提交
750
		} );
R
Rich Tibbett 已提交
751

M
Mr.doob 已提交
752
	};
R
Rich Tibbett 已提交
753

M
Mr.doob 已提交
754
	GLTFParser.prototype.loadTextures = function () {
R
Rich Tibbett 已提交
755

M
Mr.doob 已提交
756 757 758 759
		var json = this.json;
		var options = this.options;

		return _each( json.textures, function ( texture ) {
R
Rich Tibbett 已提交
760

M
Mr.doob 已提交
761
			if ( texture.source ) {
R
Rich Tibbett 已提交
762

M
Mr.doob 已提交
763
				return new Promise( function ( resolve ) {
R
Rich Tibbett 已提交
764

M
Mr.doob 已提交
765
					var source = json.images[ texture.source ];
R
Rich Tibbett 已提交
766

M
Mr.doob 已提交
767
					var textureLoader = THREE.Loader.Handlers.get( source.uri );
R
Rich Tibbett 已提交
768

M
Mr.doob 已提交
769
					if ( textureLoader === null ) {
R
Rich Tibbett 已提交
770

M
Mr.doob 已提交
771
						textureLoader = new THREE.TextureLoader();
R
Rich Tibbett 已提交
772

M
Mr.doob 已提交
773
					}
R
Rich Tibbett 已提交
774

775
					textureLoader.setCrossOrigin( options.crossOrigin );
R
Rich Tibbett 已提交
776

M
Mr.doob 已提交
777
					textureLoader.load( resolveURL( source.uri, options.path ), function ( _texture ) {
R
Rich Tibbett 已提交
778

M
Mr.doob 已提交
779
						_texture.flipY = false;
R
Rich Tibbett 已提交
780

M
Mr.doob 已提交
781
						if ( texture.sampler ) {
R
Rich Tibbett 已提交
782

M
Mr.doob 已提交
783
							var sampler = json.samplers[ texture.sampler ];
R
Rich Tibbett 已提交
784

M
Mr.doob 已提交
785 786 787 788
							_texture.magFilter = WEBGL_FILTERS[ sampler.magFilter ];
							_texture.minFilter = WEBGL_FILTERS[ sampler.minFilter ];
							_texture.wrapS = WEBGL_WRAPPINGS[ sampler.wrapS ];
							_texture.wrapT = WEBGL_WRAPPINGS[ sampler.wrapT ];
R
Rich Tibbett 已提交
789

M
Mr.doob 已提交
790 791 792
						}

						resolve( _texture );
R
Rich Tibbett 已提交
793

M
Mr.doob 已提交
794
					}, undefined, function () {
795 796 797 798

						resolve();

					} );
R
Rich Tibbett 已提交
799

M
Mr.doob 已提交
800
				} );
R
Rich Tibbett 已提交
801 802 803

			}

M
Mr.doob 已提交
804
		} );
R
Rich Tibbett 已提交
805

M
Mr.doob 已提交
806
	};
R
Rich Tibbett 已提交
807

M
Mr.doob 已提交
808
	GLTFParser.prototype.loadMaterials = function () {
R
Rich Tibbett 已提交
809

M
Mr.doob 已提交
810 811
		var json = this.json;

M
Mr.doob 已提交
812
		return this._withDependencies( [
R
Rich Tibbett 已提交
813

M
Mr.doob 已提交
814 815
			"shaders",
			"textures"
R
Rich Tibbett 已提交
816

M
Mr.doob 已提交
817
		] ).then( function ( dependencies ) {
R
Rich Tibbett 已提交
818

M
Mr.doob 已提交
819
			return _each( json.materials, function ( material ) {
R
Rich Tibbett 已提交
820

M
Mr.doob 已提交
821 822 823
				var materialType;
				var materialValues = {};
				var materialParams = {};
R
Rich Tibbett 已提交
824

M
Mr.doob 已提交
825
				var khr_material;
R
Rich Tibbett 已提交
826

M
Mr.doob 已提交
827
				if ( material.extensions && material.extensions.KHR_materials_common ) {
R
Rich Tibbett 已提交
828

M
Mr.doob 已提交
829
					khr_material = material.extensions.KHR_materials_common;
R
Rich Tibbett 已提交
830

M
Mr.doob 已提交
831
				} else if ( json.extensions && json.extensions.KHR_materials_common ) {
M
Mr.doob 已提交
832

M
Mr.doob 已提交
833
					khr_material = json.extensions.KHR_materials_common;
R
Rich Tibbett 已提交
834 835 836

				}

M
Mr.doob 已提交
837
				if ( khr_material ) {
R
Rich Tibbett 已提交
838

M
Mr.doob 已提交
839
					switch ( khr_material.technique ) {
R
Rich Tibbett 已提交
840

M
Mr.doob 已提交
841 842 843 844
						case 'BLINN' :
						case 'PHONG' :
							materialType = THREE.MeshPhongMaterial;
							break;
R
Rich Tibbett 已提交
845

M
Mr.doob 已提交
846 847 848
						case 'LAMBERT' :
							materialType = THREE.MeshLambertMaterial;
							break;
R
Rich Tibbett 已提交
849

M
Mr.doob 已提交
850 851 852 853
						case 'CONSTANT' :
						default :
							materialType = THREE.MeshBasicMaterial;
							break;
R
Rich Tibbett 已提交
854

M
Mr.doob 已提交
855
					}
R
Rich Tibbett 已提交
856

M
Mr.doob 已提交
857
					Object.assign( materialValues, khr_material.values );
R
Rich Tibbett 已提交
858

M
Mr.doob 已提交
859
					if ( khr_material.doubleSided || materialValues.doubleSided ) {
R
Rich Tibbett 已提交
860

M
Mr.doob 已提交
861
						materialParams.side = THREE.DoubleSide;
R
Rich Tibbett 已提交
862

M
Mr.doob 已提交
863
					}
R
Rich Tibbett 已提交
864

M
Mr.doob 已提交
865
					if ( khr_material.transparent || materialValues.transparent ) {
R
Rich Tibbett 已提交
866

M
Mr.doob 已提交
867 868
						materialParams.transparent = true;
						materialParams.opacity = ( materialValues.transparency !== undefined ) ? materialValues.transparency : 1;
R
Rich Tibbett 已提交
869 870 871

					}

M
Mr.doob 已提交
872
				} else if ( material.technique === undefined ) {
R
Rich Tibbett 已提交
873

M
Mr.doob 已提交
874
					materialType = THREE.MeshPhongMaterial;
R
Rich Tibbett 已提交
875

M
Mr.doob 已提交
876
					Object.assign( materialValues, material.values );
R
Rich Tibbett 已提交
877

M
Mr.doob 已提交
878
				} else {
R
Rich Tibbett 已提交
879

M
Mr.doob 已提交
880
					materialType = DeferredShaderMaterial;
R
Rich Tibbett 已提交
881

M
Mr.doob 已提交
882
					var technique = json.techniques[ material.technique ];
R
Rich Tibbett 已提交
883

M
Mr.doob 已提交
884
					materialParams.uniforms = {};
R
Rich Tibbett 已提交
885

M
Mr.doob 已提交
886
					var program = json.programs[ technique.program ];
R
Rich Tibbett 已提交
887

M
Mr.doob 已提交
888
					if ( program ) {
R
Rich Tibbett 已提交
889

M
Mr.doob 已提交
890
						materialParams.fragmentShader = dependencies.shaders[ program.fragmentShader ];
R
Rich Tibbett 已提交
891

M
Mr.doob 已提交
892
						if ( ! materialParams.fragmentShader ) {
R
Rich Tibbett 已提交
893

M
Mr.doob 已提交
894 895
							console.warn( "ERROR: Missing fragment shader definition:", program.fragmentShader );
							materialType = THREE.MeshPhongMaterial;
R
Rich Tibbett 已提交
896

M
Mr.doob 已提交
897
						}
R
Rich Tibbett 已提交
898

M
Mr.doob 已提交
899
						var vertexShader = dependencies.shaders[ program.vertexShader ];
R
Rich Tibbett 已提交
900

M
Mr.doob 已提交
901
						if ( ! vertexShader ) {
R
Rich Tibbett 已提交
902

M
Mr.doob 已提交
903 904
							console.warn( "ERROR: Missing vertex shader definition:", program.vertexShader );
							materialType = THREE.MeshPhongMaterial;
R
Rich Tibbett 已提交
905

M
Mr.doob 已提交
906
						}
R
Rich Tibbett 已提交
907

M
Mr.doob 已提交
908 909
						// IMPORTANT: FIX VERTEX SHADER ATTRIBUTE DEFINITIONS
						materialParams.vertexShader = replaceTHREEShaderAttributes( vertexShader, technique );
R
Rich Tibbett 已提交
910

M
Mr.doob 已提交
911
						var uniforms = technique.uniforms;
R
Rich Tibbett 已提交
912

M
Mr.doob 已提交
913
						for ( var uniformId in uniforms ) {
R
Rich Tibbett 已提交
914

M
Mr.doob 已提交
915
							var pname = uniforms[ uniformId ];
M
Mr.doob 已提交
916
							var shaderParam = technique.parameters[ pname ];
R
Rich Tibbett 已提交
917

M
Mr.doob 已提交
918
							var ptype = shaderParam.type;
R
Rich Tibbett 已提交
919

M
Mr.doob 已提交
920
							if ( WEBGL_TYPE[ ptype ] ) {
R
Rich Tibbett 已提交
921

M
Mr.doob 已提交
922 923
								var pcount = shaderParam.count;
								var value = material.values[ pname ];
R
Rich Tibbett 已提交
924

M
Mr.doob 已提交
925 926 927
								var uvalue = new WEBGL_TYPE[ ptype ]();
								var usemantic = shaderParam.semantic;
								var unode = shaderParam.node;
R
Rich Tibbett 已提交
928

M
Mr.doob 已提交
929
								switch ( ptype ) {
R
Rich Tibbett 已提交
930

M
Mr.doob 已提交
931
									case WEBGL_CONSTANTS.FLOAT:
R
Rich Tibbett 已提交
932

M
Mr.doob 已提交
933
										uvalue = shaderParam.value;
R
Rich Tibbett 已提交
934

M
Mr.doob 已提交
935
										if ( pname == "transparency" ) {
R
Rich Tibbett 已提交
936

M
Mr.doob 已提交
937
											materialParams.transparent = true;
R
Rich Tibbett 已提交
938

M
Mr.doob 已提交
939
										}
R
Rich Tibbett 已提交
940

M
Mr.doob 已提交
941
										if ( value !== undefined ) {
R
Rich Tibbett 已提交
942

M
Mr.doob 已提交
943
											uvalue = value;
R
Rich Tibbett 已提交
944

M
Mr.doob 已提交
945
										}
R
Rich Tibbett 已提交
946

M
Mr.doob 已提交
947
										break;
R
Rich Tibbett 已提交
948

M
Mr.doob 已提交
949 950 951 952
									case WEBGL_CONSTANTS.FLOAT_VEC2:
									case WEBGL_CONSTANTS.FLOAT_VEC3:
									case WEBGL_CONSTANTS.FLOAT_VEC4:
									case WEBGL_CONSTANTS.FLOAT_MAT3:
R
Rich Tibbett 已提交
953 954 955

										if ( shaderParam && shaderParam.value ) {

M
Mr.doob 已提交
956
											uvalue.fromArray( shaderParam.value );
R
Rich Tibbett 已提交
957 958 959 960 961 962 963 964 965

										}

										if ( value ) {

											uvalue.fromArray( value );

										}

M
Mr.doob 已提交
966
										break;
R
Rich Tibbett 已提交
967

M
Mr.doob 已提交
968
									case WEBGL_CONSTANTS.FLOAT_MAT2:
R
Rich Tibbett 已提交
969

M
Mr.doob 已提交
970 971 972
										// what to do?
										console.warn( "FLOAT_MAT2 is not a supported uniform type" );
										break;
R
Rich Tibbett 已提交
973

M
Mr.doob 已提交
974
									case WEBGL_CONSTANTS.FLOAT_MAT4:
R
Rich Tibbett 已提交
975

M
Mr.doob 已提交
976
										if ( pcount ) {
R
Rich Tibbett 已提交
977

M
Mr.doob 已提交
978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012
											uvalue = new Array( pcount );

											for ( var mi = 0; mi < pcount; mi ++ ) {

												uvalue[ mi ] = new WEBGL_TYPE[ ptype ]();

											}

											if ( shaderParam && shaderParam.value ) {

												var m4v = shaderParam.value;
												uvalue.fromArray( m4v );

											}

											if ( value ) {

												uvalue.fromArray( value );

											}

										}	else {

											if ( shaderParam && shaderParam.value ) {

												var m4 = shaderParam.value;
												uvalue.fromArray( m4 );

											}

											if ( value ) {

												uvalue.fromArray( value );

											}
R
Rich Tibbett 已提交
1013 1014 1015

										}

M
Mr.doob 已提交
1016
										break;
R
Rich Tibbett 已提交
1017

M
Mr.doob 已提交
1018
									case WEBGL_CONSTANTS.SAMPLER_2D:
R
Rich Tibbett 已提交
1019

M
Mr.doob 已提交
1020
										uvalue = value ? dependencies.textures[ value ] : null;
R
Rich Tibbett 已提交
1021

M
Mr.doob 已提交
1022
										break;
R
Rich Tibbett 已提交
1023

M
Mr.doob 已提交
1024
								}
R
Rich Tibbett 已提交
1025

M
Mr.doob 已提交
1026 1027 1028 1029 1030
								materialParams.uniforms[ uniformId ] = {
									value: uvalue,
									semantic: usemantic,
									node: unode
								};
R
Rich Tibbett 已提交
1031

M
Mr.doob 已提交
1032
							} else {
R
Rich Tibbett 已提交
1033

M
Mr.doob 已提交
1034
								throw new Error( "Unknown shader uniform param type: " + ptype );
R
Rich Tibbett 已提交
1035

M
Mr.doob 已提交
1036
							}
R
Rich Tibbett 已提交
1037

M
Mr.doob 已提交
1038
						}
R
Rich Tibbett 已提交
1039

M
Mr.doob 已提交
1040
					}
R
Rich Tibbett 已提交
1041 1042 1043

				}

M
Mr.doob 已提交
1044
				if ( Array.isArray( materialValues.diffuse ) ) {
R
Rich Tibbett 已提交
1045

M
Mr.doob 已提交
1046
					materialParams.color = new THREE.Color().fromArray( materialValues.diffuse );
R
Rich Tibbett 已提交
1047

M
Mr.doob 已提交
1048
				} else if ( typeof( materialValues.diffuse ) === 'string' ) {
R
Rich Tibbett 已提交
1049

M
Mr.doob 已提交
1050
					materialParams.map = dependencies.textures[ materialValues.diffuse ];
R
Rich Tibbett 已提交
1051

M
Mr.doob 已提交
1052
				}
R
Rich Tibbett 已提交
1053

M
Mr.doob 已提交
1054
				delete materialParams.diffuse;
R
Rich Tibbett 已提交
1055

M
Mr.doob 已提交
1056
				if ( typeof( materialValues.reflective ) === 'string' ) {
R
Rich Tibbett 已提交
1057

M
Mr.doob 已提交
1058
					materialParams.envMap = dependencies.textures[ materialValues.reflective ];
R
Rich Tibbett 已提交
1059

M
Mr.doob 已提交
1060
				}
R
Rich Tibbett 已提交
1061

M
Mr.doob 已提交
1062
				if ( typeof( materialValues.bump ) === 'string' ) {
R
Rich Tibbett 已提交
1063

M
Mr.doob 已提交
1064
					materialParams.bumpMap = dependencies.textures[ materialValues.bump ];
R
Rich Tibbett 已提交
1065

M
Mr.doob 已提交
1066
				}
R
Rich Tibbett 已提交
1067

M
Mr.doob 已提交
1068
				if ( Array.isArray( materialValues.emission ) ) {
R
Rich Tibbett 已提交
1069

1070 1071 1072 1073 1074 1075 1076 1077 1078
					if ( materialType === THREE.MeshBasicMaterial ) {

						materialParams.color = new THREE.Color().fromArray( materialValues.emission );

					} else {

						materialParams.emissive = new THREE.Color().fromArray( materialValues.emission );

					}
R
Rich Tibbett 已提交
1079

1080 1081
				} else if ( typeof( materialValues.emission ) === 'string' ) {

1082
					if ( materialType === THREE.MeshBasicMaterial ) {
1083

1084
						materialParams.map = dependencies.textures[ materialValues.emission ];
R
Rich Tibbett 已提交
1085

1086 1087 1088 1089 1090 1091 1092
					} else {

						materialParams.emissiveMap = dependencies.textures[ materialValues.emission ];

					}

				}
1093

M
Mr.doob 已提交
1094
				if ( Array.isArray( materialValues.specular ) ) {
R
Rich Tibbett 已提交
1095

M
Mr.doob 已提交
1096
					materialParams.specular = new THREE.Color().fromArray( materialValues.specular );
R
Rich Tibbett 已提交
1097

1098 1099 1100 1101
				} else if ( typeof( materialValues.specular ) === 'string' ) {

					materialParams.specularMap = dependencies.textures[ materialValues.specular ];

1102
				}
1103

M
Mr.doob 已提交
1104
				if ( materialValues.shininess !== undefined ) {
R
Rich Tibbett 已提交
1105

M
Mr.doob 已提交
1106
					materialParams.shininess = materialValues.shininess;
R
Rich Tibbett 已提交
1107

M
Mr.doob 已提交
1108
				}
R
Rich Tibbett 已提交
1109

M
Mr.doob 已提交
1110 1111
				var _material = new materialType( materialParams );
				_material.name = material.name;
R
Rich Tibbett 已提交
1112

M
Mr.doob 已提交
1113
				return _material;
R
Rich Tibbett 已提交
1114

M
Mr.doob 已提交
1115
			} );
R
Rich Tibbett 已提交
1116

M
Mr.doob 已提交
1117
		} );
R
Rich Tibbett 已提交
1118

M
Mr.doob 已提交
1119
	};
R
Rich Tibbett 已提交
1120

M
Mr.doob 已提交
1121
	GLTFParser.prototype.loadMeshes = function () {
R
Rich Tibbett 已提交
1122

M
Mr.doob 已提交
1123 1124
		var json = this.json;

M
Mr.doob 已提交
1125
		return this._withDependencies( [
R
Rich Tibbett 已提交
1126

M
Mr.doob 已提交
1127 1128
			"accessors",
			"materials"
R
Rich Tibbett 已提交
1129

M
Mr.doob 已提交
1130
		] ).then( function ( dependencies ) {
R
Rich Tibbett 已提交
1131

M
Mr.doob 已提交
1132
			return _each( json.meshes, function ( mesh ) {
R
Rich Tibbett 已提交
1133

M
Mr.doob 已提交
1134 1135
				var group = new THREE.Object3D();
				group.name = mesh.name;
1136 1137

				if ( mesh.extras ) group.userData = mesh.extras;
R
Rich Tibbett 已提交
1138

M
Mr.doob 已提交
1139
				var primitives = mesh.primitives;
R
Rich Tibbett 已提交
1140

M
Mr.doob 已提交
1141 1142 1143
				for ( var name in primitives ) {

					var primitive = primitives[ name ];
R
Rich Tibbett 已提交
1144

M
Mr.doob 已提交
1145
					if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES || primitive.mode === undefined ) {
R
Rich Tibbett 已提交
1146

M
Mr.doob 已提交
1147
						var geometry = new THREE.BufferGeometry();
R
Rich Tibbett 已提交
1148

M
Mr.doob 已提交
1149
						var attributes = primitive.attributes;
R
Rich Tibbett 已提交
1150

M
Mr.doob 已提交
1151 1152 1153
						for ( var attributeId in attributes ) {

							var attributeEntry = attributes[ attributeId ];
R
Rich Tibbett 已提交
1154

M
Mr.doob 已提交
1155
							if ( ! attributeEntry ) return;
R
Rich Tibbett 已提交
1156

M
Mr.doob 已提交
1157
							var bufferAttribute = dependencies.accessors[ attributeEntry ];
R
Rich Tibbett 已提交
1158

M
Mr.doob 已提交
1159
							switch ( attributeId ) {
R
Rich Tibbett 已提交
1160

M
Mr.doob 已提交
1161 1162 1163
								case 'POSITION':
									geometry.addAttribute( 'position', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1164

M
Mr.doob 已提交
1165 1166 1167
								case 'NORMAL':
									geometry.addAttribute( 'normal', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1168

M
Mr.doob 已提交
1169 1170 1171 1172 1173
								case 'TEXCOORD_0':
								case 'TEXCOORD0':
								case 'TEXCOORD':
									geometry.addAttribute( 'uv', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1174

M
Mr.doob 已提交
1175 1176 1177
								case 'WEIGHT':
									geometry.addAttribute( 'skinWeight', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1178

M
Mr.doob 已提交
1179 1180 1181
								case 'JOINT':
									geometry.addAttribute( 'skinIndex', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1182

M
Mr.doob 已提交
1183
							}
R
Rich Tibbett 已提交
1184

M
Mr.doob 已提交
1185
						}
R
Rich Tibbett 已提交
1186

M
Mr.doob 已提交
1187
						if ( primitive.indices ) {
R
Rich Tibbett 已提交
1188

M
Mr.doob 已提交
1189
							geometry.setIndex( dependencies.accessors[ primitive.indices ] );
R
Rich Tibbett 已提交
1190

M
Mr.doob 已提交
1191
						}
R
Rich Tibbett 已提交
1192

M
Mr.doob 已提交
1193
						var material = dependencies.materials[ primitive.material ];
R
Rich Tibbett 已提交
1194

M
Mr.doob 已提交
1195 1196
						var meshNode = new THREE.Mesh( geometry, material );
						meshNode.castShadow = true;
M
Mr.doob 已提交
1197

1198
						if ( primitive.extras ) meshNode.userData = primitive.extras;
M
Mr.doob 已提交
1199

1200 1201
						group.add( meshNode );

M
Mr.doob 已提交
1202
					} else if ( primitive.mode === WEBGL_CONSTANTS.LINES ) {
1203 1204 1205 1206 1207

						var geometry = new THREE.BufferGeometry();

						var attributes = primitive.attributes;

B
bdysvik 已提交
1208

1209 1210 1211
						for ( var attributeId in attributes ) {

							var attributeEntry = attributes[ attributeId ];
1212

M
Mr.doob 已提交
1213
							if ( ! attributeEntry ) return;
1214 1215 1216 1217 1218 1219 1220 1221

							var bufferAttribute = dependencies.accessors[ attributeEntry ];

							switch ( attributeId ) {

								case 'POSITION':
									geometry.addAttribute( 'position', bufferAttribute );
									break;
B
bdysvik 已提交
1222
				
1223 1224
								case 'COLOR_0':
								case 'COLOR0':
1225
								case 'COLOR':
M
Mr.doob 已提交
1226 1227
									geometry.addAttribute( 'color', bufferAttribute );
									break;
1228 1229

							}
1230
						};
1231

M
Mr.doob 已提交
1232 1233 1234
						var material = dependencies.materials[ primitive.material ];

						var meshNode;
1235 1236 1237

						if ( primitive.indices ) {

M
Mr.doob 已提交
1238
							geometry.setIndex( dependencies.accessors[ primitive.indices ] );
1239

M
Mr.doob 已提交
1240
							meshNode = new THREE.LineSegments( geometry, material );
1241

M
Mr.doob 已提交
1242
						} else {
1243

M
Mr.doob 已提交
1244
							meshNode = new THREE.Line( geometry, material );
1245 1246 1247

						}

1248
						if ( primitive.extras ) meshNode.userData = primitive.extras;
R
Rich Tibbett 已提交
1249

M
Mr.doob 已提交
1250
						group.add( meshNode );
R
Rich Tibbett 已提交
1251

M
Mr.doob 已提交
1252
					} else {
R
Rich Tibbett 已提交
1253

1254
						console.warn( "Only triangular and line primitives are supported" );
R
Rich Tibbett 已提交
1255

M
Mr.doob 已提交
1256
					}
R
Rich Tibbett 已提交
1257

M
Mr.doob 已提交
1258
				}
R
Rich Tibbett 已提交
1259

M
Mr.doob 已提交
1260
				return group;
R
Rich Tibbett 已提交
1261

M
Mr.doob 已提交
1262
			} );
R
Rich Tibbett 已提交
1263

M
Mr.doob 已提交
1264
		} );
R
Rich Tibbett 已提交
1265

M
Mr.doob 已提交
1266
	};
R
Rich Tibbett 已提交
1267

M
Mr.doob 已提交
1268
	GLTFParser.prototype.loadCameras = function () {
R
Rich Tibbett 已提交
1269

M
Mr.doob 已提交
1270 1271 1272
		var json = this.json;

		return _each( json.cameras, function ( camera ) {
R
Rich Tibbett 已提交
1273

M
Mr.doob 已提交
1274
			if ( camera.type == "perspective" && camera.perspective ) {
R
Rich Tibbett 已提交
1275

M
Mr.doob 已提交
1276 1277 1278
				var yfov = camera.perspective.yfov;
				var xfov = camera.perspective.xfov;
				var aspect_ratio = camera.perspective.aspect_ratio || 1;
R
Rich Tibbett 已提交
1279

M
Mr.doob 已提交
1280 1281 1282
				// According to COLLADA spec...
				// aspect_ratio = xfov / yfov
				xfov = ( xfov === undefined && yfov ) ? yfov * aspect_ratio : xfov;
R
Rich Tibbett 已提交
1283

M
Mr.doob 已提交
1284 1285 1286
				// According to COLLADA spec...
				// aspect_ratio = xfov / yfov
				// yfov = ( yfov === undefined && xfov ) ? xfov / aspect_ratio : yfov;
R
Rich Tibbett 已提交
1287

M
Mr.doob 已提交
1288 1289
				var _camera = new THREE.PerspectiveCamera( THREE.Math.radToDeg( xfov ), aspect_ratio, camera.perspective.znear || 1, camera.perspective.zfar || 2e6 );
				_camera.name = camera.name;
1290 1291

				if ( camera.extras ) _camera.userData = camera.extras;
R
Rich Tibbett 已提交
1292

M
Mr.doob 已提交
1293
				return _camera;
R
Rich Tibbett 已提交
1294

M
Mr.doob 已提交
1295
			} else if ( camera.type == "orthographic" && camera.orthographic ) {
R
Rich Tibbett 已提交
1296

M
Mr.doob 已提交
1297 1298
				var _camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, camera.orthographic.znear, camera.orthographic.zfar );
				_camera.name = camera.name;
1299 1300

				if ( camera.extras ) _camera.userData = camera.extras;
R
Rich Tibbett 已提交
1301

M
Mr.doob 已提交
1302
				return _camera;
R
Rich Tibbett 已提交
1303

M
Mr.doob 已提交
1304
			}
R
Rich Tibbett 已提交
1305

M
Mr.doob 已提交
1306
		} );
R
Rich Tibbett 已提交
1307

M
Mr.doob 已提交
1308
	};
R
Rich Tibbett 已提交
1309

M
Mr.doob 已提交
1310
	GLTFParser.prototype.loadSkins = function () {
R
Rich Tibbett 已提交
1311

M
Mr.doob 已提交
1312
		var json = this.json;
R
Rich Tibbett 已提交
1313

M
Mr.doob 已提交
1314
		return this._withDependencies( [
R
Rich Tibbett 已提交
1315

M
Mr.doob 已提交
1316
			"accessors"
R
Rich Tibbett 已提交
1317

M
Mr.doob 已提交
1318
		] ).then( function ( dependencies ) {
R
Rich Tibbett 已提交
1319

M
Mr.doob 已提交
1320
			return _each( json.skins, function ( skin ) {
M
Mr.doob 已提交
1321 1322 1323 1324 1325 1326 1327 1328 1329 1330

				var _skin = {
					bindShapeMatrix: new THREE.Matrix4().fromArray( skin.bindShapeMatrix ),
					jointNames: skin.jointNames,
					inverseBindMatrices: dependencies.accessors[ skin.inverseBindMatrices ]
				};

				return _skin;

			} );
R
Rich Tibbett 已提交
1331

M
Mr.doob 已提交
1332
		} );
R
Rich Tibbett 已提交
1333

M
Mr.doob 已提交
1334 1335
	};

1336
	GLTFParser.prototype.loadAnimations = function () {
R
Rich Tibbett 已提交
1337

M
Mr.doob 已提交
1338
		var json = this.json;
R
Rich Tibbett 已提交
1339

M
Mr.doob 已提交
1340
		return this._withDependencies( [
R
Rich Tibbett 已提交
1341

M
Mr.doob 已提交
1342 1343
			"accessors",
			"nodes"
R
Rich Tibbett 已提交
1344

M
Mr.doob 已提交
1345
		] ).then( function ( dependencies ) {
R
Rich Tibbett 已提交
1346

M
Mr.doob 已提交
1347
			return _each( json.animations, function ( animation, animationId ) {
R
Rich Tibbett 已提交
1348

D
Don McCurdy 已提交
1349
				var tracks = [];
R
Rich Tibbett 已提交
1350

M
Mr.doob 已提交
1351
				for ( var channelId in animation.channels ) {
M
Mr.doob 已提交
1352

M
Mr.doob 已提交
1353
					var channel = animation.channels[ channelId ];
M
Mr.doob 已提交
1354 1355 1356
					var sampler = animation.samplers[ channel.sampler ];

					if ( sampler && animation.parameters ) {
R
Rich Tibbett 已提交
1357 1358 1359

						var target = channel.target;
						var name = target.id;
M
Mr.doob 已提交
1360 1361
						var input = animation.parameters[ sampler.input ];
						var output = animation.parameters[ sampler.output ];
R
Rich Tibbett 已提交
1362 1363 1364 1365 1366 1367 1368 1369

						var inputAccessor = dependencies.accessors[ input ];
						var outputAccessor = dependencies.accessors[ output ];

						var node = dependencies.nodes[ name ];

						if ( node ) {

D
Don McCurdy 已提交
1370 1371
							node.updateMatrix();
							node.matrixAutoUpdate = true;
R
Rich Tibbett 已提交
1372

D
Don McCurdy 已提交
1373 1374 1375
							var TypedKeyframeTrack = PATH_PROPERTIES[ target.path ] === PATH_PROPERTIES.rotation
								? THREE.QuaternionKeyframeTrack
								: THREE.VectorKeyframeTrack;
R
Rich Tibbett 已提交
1376

D
Don McCurdy 已提交
1377 1378 1379 1380 1381 1382 1383 1384 1385
							// KeyframeTrack.optimize() will modify given 'times' and 'values'
							// buffers before creating a truncated copy to keep. Because buffers may
							// be reused by other tracks, make copies here.
							tracks.push( new TypedKeyframeTrack(
								node.name + '.' + PATH_PROPERTIES[ target.path ],
								THREE.AnimationUtils.arraySlice( inputAccessor.array, 0 ),
								THREE.AnimationUtils.arraySlice( outputAccessor.array, 0 ),
								INTERPOLATION[ sampler.interpolation ]
							) );
R
Rich Tibbett 已提交
1386 1387 1388

						}

M
Mr.doob 已提交
1389
					}
R
Rich Tibbett 已提交
1390

M
Mr.doob 已提交
1391
				}
R
Rich Tibbett 已提交
1392

D
Don McCurdy 已提交
1393
				return new THREE.AnimationClip( "animation_" + animationId, undefined, tracks );
R
Rich Tibbett 已提交
1394

M
Mr.doob 已提交
1395
			} );
R
Rich Tibbett 已提交
1396

M
Mr.doob 已提交
1397
		} );
R
Rich Tibbett 已提交
1398

M
Mr.doob 已提交
1399
	};
R
Rich Tibbett 已提交
1400

M
Mr.doob 已提交
1401
	GLTFParser.prototype.loadNodes = function () {
R
Rich Tibbett 已提交
1402

M
Mr.doob 已提交
1403 1404 1405 1406
		var json = this.json;
		var scope = this;

		return _each( json.nodes, function ( node ) {
R
Rich Tibbett 已提交
1407

M
Mr.doob 已提交
1408
			var matrix = new THREE.Matrix4();
R
Rich Tibbett 已提交
1409

M
Mr.doob 已提交
1410
			var _node;
R
Rich Tibbett 已提交
1411

M
Mr.doob 已提交
1412
			if ( node.jointName ) {
R
Rich Tibbett 已提交
1413

M
Mr.doob 已提交
1414 1415
				_node = new THREE.Bone();
				_node.jointName = node.jointName;
R
Rich Tibbett 已提交
1416

M
Mr.doob 已提交
1417
			} else {
R
Rich Tibbett 已提交
1418

M
Mr.doob 已提交
1419
				_node = new THREE.Object3D();
R
Rich Tibbett 已提交
1420

M
Mr.doob 已提交
1421
			}
R
Rich Tibbett 已提交
1422

M
Mr.doob 已提交
1423
			_node.name = node.name;
1424 1425

			if ( node.extras ) _node.userData = node.extras;
R
Rich Tibbett 已提交
1426

M
Mr.doob 已提交
1427
			_node.matrixAutoUpdate = false;
R
Rich Tibbett 已提交
1428

M
Mr.doob 已提交
1429
			if ( node.matrix !== undefined ) {
R
Rich Tibbett 已提交
1430

M
Mr.doob 已提交
1431 1432
				matrix.fromArray( node.matrix );
				_node.applyMatrix( matrix );
R
Rich Tibbett 已提交
1433

M
Mr.doob 已提交
1434
			} else {
R
Rich Tibbett 已提交
1435

M
Mr.doob 已提交
1436
				if ( node.translation !== undefined ) {
R
Rich Tibbett 已提交
1437

M
Mr.doob 已提交
1438
					_node.position.fromArray( node.translation );
R
Rich Tibbett 已提交
1439

M
Mr.doob 已提交
1440
				}
R
Rich Tibbett 已提交
1441

M
Mr.doob 已提交
1442
				if ( node.rotation !== undefined ) {
R
Rich Tibbett 已提交
1443

M
Mr.doob 已提交
1444
					_node.quaternion.fromArray( node.rotation );
R
Rich Tibbett 已提交
1445

M
Mr.doob 已提交
1446 1447 1448
				}

				if ( node.scale !== undefined ) {
R
Rich Tibbett 已提交
1449

M
Mr.doob 已提交
1450
					_node.scale.fromArray( node.scale );
R
Rich Tibbett 已提交
1451

M
Mr.doob 已提交
1452
				}
R
Rich Tibbett 已提交
1453 1454 1455

			}

M
Mr.doob 已提交
1456
			return _node;
R
Rich Tibbett 已提交
1457

M
Mr.doob 已提交
1458
		} ).then( function ( __nodes ) {
R
Rich Tibbett 已提交
1459

M
Mr.doob 已提交
1460
			return scope._withDependencies( [
R
Rich Tibbett 已提交
1461

M
Mr.doob 已提交
1462 1463 1464 1465
				"meshes",
				"skins",
				"cameras",
				"extensions"
R
Rich Tibbett 已提交
1466

M
Mr.doob 已提交
1467
			] ).then( function ( dependencies ) {
R
Rich Tibbett 已提交
1468

M
Mr.doob 已提交
1469
				return _each( __nodes, function ( _node, nodeId ) {
R
Rich Tibbett 已提交
1470

M
Mr.doob 已提交
1471
					var node = json.nodes[ nodeId ];
R
Rich Tibbett 已提交
1472

M
Mr.doob 已提交
1473
					if ( node.meshes !== undefined ) {
R
Rich Tibbett 已提交
1474

M
Mr.doob 已提交
1475
						for ( var meshId in node.meshes ) {
R
Rich Tibbett 已提交
1476

M
Mr.doob 已提交
1477 1478
							var mesh = node.meshes[ meshId ];
							var group = dependencies.meshes[ mesh ];
R
Rich Tibbett 已提交
1479

1480 1481 1482 1483 1484 1485 1486
							if ( group === undefined ) {

								console.warn( 'GLTFLoader: Couldn\'t find node "' + mesh + '".' );
								continue;

							}

M
Mr.doob 已提交
1487 1488 1489
							for ( var childrenId in group.children ) {

								var child = group.children[ childrenId ];
R
Rich Tibbett 已提交
1490

M
Mr.doob 已提交
1491
								// clone Mesh to add to _node
R
Rich Tibbett 已提交
1492

M
Mr.doob 已提交
1493 1494
								var originalMaterial = child.material;
								var originalGeometry = child.geometry;
1495
								var originalUserData = child.userData;
R
Rich Tibbett 已提交
1496

M
Mr.doob 已提交
1497
								var material;
R
Rich Tibbett 已提交
1498

M
Mr.doob 已提交
1499
								if ( originalMaterial.isDeferredShaderMaterial ) {
R
Rich Tibbett 已提交
1500

M
Mr.doob 已提交
1501
									originalMaterial = material = originalMaterial.create();
R
Rich Tibbett 已提交
1502

M
Mr.doob 已提交
1503
								} else {
R
Rich Tibbett 已提交
1504

M
Mr.doob 已提交
1505
									material = originalMaterial;
R
Rich Tibbett 已提交
1506

M
Mr.doob 已提交
1507
								}
M
Mr.doob 已提交
1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521

								switch ( child.type ) {

									case 'LineSegments':
										child = new THREE.LineSegments( originalGeometry, material );
										break;

									case 'Line':
										child = new THREE.Line( originalGeometry, material );
										break;

									default:
										child = new THREE.Mesh( originalGeometry, material );

1522
								}
M
Mr.doob 已提交
1523

M
Mr.doob 已提交
1524
								child.castShadow = true;
1525
								child.userData = originalUserData;
R
Rich Tibbett 已提交
1526

M
Mr.doob 已提交
1527
								var skinEntry;
M
Mr.doob 已提交
1528

M
Mr.doob 已提交
1529
								if ( node.skin ) {
R
Rich Tibbett 已提交
1530

M
Mr.doob 已提交
1531
									skinEntry = dependencies.skins[ node.skin ];
R
Rich Tibbett 已提交
1532

M
Mr.doob 已提交
1533
								}
R
Rich Tibbett 已提交
1534

M
Mr.doob 已提交
1535 1536
								// Replace Mesh with SkinnedMesh in library
								if ( skinEntry ) {
R
Rich Tibbett 已提交
1537

M
Mr.doob 已提交
1538 1539 1540
									var geometry = originalGeometry;
									var material = originalMaterial;
									material.skinning = true;
R
Rich Tibbett 已提交
1541

M
Mr.doob 已提交
1542 1543
									child = new THREE.SkinnedMesh( geometry, material, false );
									child.castShadow = true;
1544
									child.userData = originalUserData;
R
Rich Tibbett 已提交
1545

M
Mr.doob 已提交
1546 1547
									var bones = [];
									var boneInverses = [];
R
Rich Tibbett 已提交
1548

T
Takahiro 已提交
1549 1550
									var keys = Object.keys( __nodes );

M
Mr.doob 已提交
1551
									for ( var i = 0, l = skinEntry.jointNames.length; i < l; i ++ ) {
R
Rich Tibbett 已提交
1552

M
Mr.doob 已提交
1553
										var jointId = skinEntry.jointNames[ i ];
T
Takahiro 已提交
1554 1555 1556 1557 1558

										var jointNode;

										for ( var j = 0, jl = keys.length; j < jl; j ++ ) {

T
Takahiro 已提交
1559
											var n = __nodes[ keys[ j ] ];
T
Takahiro 已提交
1560

T
Takahiro 已提交
1561
											if ( n.jointName === jointId ) {
T
Takahiro 已提交
1562

T
Takahiro 已提交
1563
												jointNode = n;
T
Takahiro 已提交
1564 1565 1566 1567 1568
												break;

											}

										}
R
Rich Tibbett 已提交
1569

M
Mr.doob 已提交
1570
										if ( jointNode ) {
R
Rich Tibbett 已提交
1571

M
Mr.doob 已提交
1572
											jointNode.skin = child;
M
Mr.doob 已提交
1573
											bones.push( jointNode );
R
Rich Tibbett 已提交
1574

M
Mr.doob 已提交
1575 1576 1577
											var m = skinEntry.inverseBindMatrices.array;
											var mat = new THREE.Matrix4().fromArray( m, i * 16 );
											boneInverses.push( mat );
R
Rich Tibbett 已提交
1578

M
Mr.doob 已提交
1579
										} else {
R
Rich Tibbett 已提交
1580

M
Mr.doob 已提交
1581
											console.warn( "WARNING: joint: ''" + jointId + "' could not be found" );
R
Rich Tibbett 已提交
1582

M
Mr.doob 已提交
1583
										}
R
Rich Tibbett 已提交
1584

M
Mr.doob 已提交
1585
									}
R
Rich Tibbett 已提交
1586

M
Mr.doob 已提交
1587
									child.bind( new THREE.Skeleton( bones, boneInverses, false ), skinEntry.bindShapeMatrix );
R
Rich Tibbett 已提交
1588

M
Mr.doob 已提交
1589
								}
R
Rich Tibbett 已提交
1590

M
Mr.doob 已提交
1591
								_node.add( child );
R
Rich Tibbett 已提交
1592

M
Mr.doob 已提交
1593
							}
R
Rich Tibbett 已提交
1594

M
Mr.doob 已提交
1595
						}
R
Rich Tibbett 已提交
1596

M
Mr.doob 已提交
1597
					}
R
Rich Tibbett 已提交
1598

M
Mr.doob 已提交
1599
					if ( node.camera !== undefined ) {
R
Rich Tibbett 已提交
1600

M
Mr.doob 已提交
1601
						var camera = dependencies.cameras[ node.camera ];
R
Rich Tibbett 已提交
1602

M
Mr.doob 已提交
1603
						_node.add( camera );
R
Rich Tibbett 已提交
1604

M
Mr.doob 已提交
1605
					}
R
Rich Tibbett 已提交
1606

M
Mr.doob 已提交
1607
					if ( node.extensions && node.extensions.KHR_materials_common && node.extensions.KHR_materials_common.light ) {
R
Rich Tibbett 已提交
1608

M
Mr.doob 已提交
1609
						var light = dependencies.extensions.KHR_materials_common.lights[ node.extensions.KHR_materials_common.light ];
R
Rich Tibbett 已提交
1610

M
Mr.doob 已提交
1611
						_node.add( light );
R
Rich Tibbett 已提交
1612

M
Mr.doob 已提交
1613
					}
R
Rich Tibbett 已提交
1614

M
Mr.doob 已提交
1615
					return _node;
R
Rich Tibbett 已提交
1616

M
Mr.doob 已提交
1617
				} );
R
Rich Tibbett 已提交
1618

M
Mr.doob 已提交
1619
			} );
R
Rich Tibbett 已提交
1620

M
Mr.doob 已提交
1621
		} );
R
Rich Tibbett 已提交
1622

M
Mr.doob 已提交
1623
	};
R
Rich Tibbett 已提交
1624

M
Mr.doob 已提交
1625
	GLTFParser.prototype.loadExtensions = function () {
R
Rich Tibbett 已提交
1626

M
Mr.doob 已提交
1627 1628 1629
		var json = this.json;

		return _each( json.extensions, function ( extension, extensionId ) {
R
Rich Tibbett 已提交
1630

M
Mr.doob 已提交
1631
			switch ( extensionId ) {
R
Rich Tibbett 已提交
1632

M
Mr.doob 已提交
1633
				case "KHR_materials_common":
R
Rich Tibbett 已提交
1634

M
Mr.doob 已提交
1635 1636 1637
					var extensionNode = {
						lights: {}
					};
R
Rich Tibbett 已提交
1638

M
Mr.doob 已提交
1639
					var lights = extension.lights;
R
Rich Tibbett 已提交
1640

M
Mr.doob 已提交
1641
					for ( var lightId in lights ) {
R
Rich Tibbett 已提交
1642

M
Mr.doob 已提交
1643
						var light = lights[ lightId ];
M
Mr.doob 已提交
1644
						var lightNode;
R
Rich Tibbett 已提交
1645

M
Mr.doob 已提交
1646 1647
						var lightParams = light[ light.type ];
						var color = new THREE.Color().fromArray( lightParams.color );
R
Rich Tibbett 已提交
1648

M
Mr.doob 已提交
1649 1650 1651 1652 1653 1654
						switch ( light.type ) {

							case "directional":
								lightNode = new THREE.DirectionalLight( color );
								lightNode.position.set( 0, 0, 1 );
								break;
R
Rich Tibbett 已提交
1655

M
Mr.doob 已提交
1656 1657 1658
							case "point":
								lightNode = new THREE.PointLight( color );
								break;
R
Rich Tibbett 已提交
1659

M
Mr.doob 已提交
1660 1661 1662 1663
							case "spot ":
								lightNode = new THREE.SpotLight( color );
								lightNode.position.set( 0, 0, 1 );
								break;
R
Rich Tibbett 已提交
1664

M
Mr.doob 已提交
1665 1666 1667
							case "ambient":
								lightNode = new THREE.AmbientLight( color );
								break;
R
Rich Tibbett 已提交
1668

M
Mr.doob 已提交
1669
						}
R
Rich Tibbett 已提交
1670

M
Mr.doob 已提交
1671
						if ( lightNode ) {
R
Rich Tibbett 已提交
1672

M
Mr.doob 已提交
1673
							extensionNode.lights[ lightId ] = lightNode;
R
Rich Tibbett 已提交
1674

M
Mr.doob 已提交
1675
						}
R
Rich Tibbett 已提交
1676

M
Mr.doob 已提交
1677
					}
R
Rich Tibbett 已提交
1678

M
Mr.doob 已提交
1679
					return extensionNode;
R
Rich Tibbett 已提交
1680

M
Mr.doob 已提交
1681
					break;
R
Rich Tibbett 已提交
1682

M
Mr.doob 已提交
1683
			}
R
Rich Tibbett 已提交
1684

M
Mr.doob 已提交
1685
		} );
R
Rich Tibbett 已提交
1686

M
Mr.doob 已提交
1687
	};
R
Rich Tibbett 已提交
1688

M
Mr.doob 已提交
1689
	GLTFParser.prototype.loadScenes = function () {
R
Rich Tibbett 已提交
1690

M
Mr.doob 已提交
1691
		var json = this.json;
M
Mr.doob 已提交
1692 1693 1694 1695 1696 1697 1698 1699

		// scene node hierachy builder

		function buildNodeHierachy( nodeId, parentObject, allNodes ) {

			var _node = allNodes[ nodeId ];
			parentObject.add( _node );

M
Mr.doob 已提交
1700
			var node = json.nodes[ nodeId ];
M
Mr.doob 已提交
1701 1702 1703

			if ( node.children ) {

M
Mr.doob 已提交
1704 1705 1706
				var children = node.children;

				for ( var i = 0, l = children.length; i < l; i ++ ) {
M
Mr.doob 已提交
1707

M
Mr.doob 已提交
1708
					var child = children[ i ];
M
Mr.doob 已提交
1709 1710
					buildNodeHierachy( child, _node, allNodes );

M
Mr.doob 已提交
1711
				}
M
Mr.doob 已提交
1712 1713

			}
R
Rich Tibbett 已提交
1714 1715 1716

		}

M
Mr.doob 已提交
1717
		return this._withDependencies( [
R
Rich Tibbett 已提交
1718

M
Mr.doob 已提交
1719
			"nodes"
R
Rich Tibbett 已提交
1720

M
Mr.doob 已提交
1721
		] ).then( function ( dependencies ) {
R
Rich Tibbett 已提交
1722

M
Mr.doob 已提交
1723
			return _each( json.scenes, function ( scene ) {
R
Rich Tibbett 已提交
1724

M
Mr.doob 已提交
1725 1726
				var _scene = new THREE.Scene();
				_scene.name = scene.name;
1727 1728

				if ( scene.extras ) _scene.userData = scene.extras;
R
Rich Tibbett 已提交
1729

M
Mr.doob 已提交
1730
				var nodes = scene.nodes;
R
Rich Tibbett 已提交
1731

M
Mr.doob 已提交
1732 1733 1734
				for ( var i = 0, l = nodes.length; i < l; i ++ ) {

					var nodeId = nodes[ i ];
M
Mr.doob 已提交
1735
					buildNodeHierachy( nodeId, _scene, dependencies.nodes );
R
Rich Tibbett 已提交
1736

M
Mr.doob 已提交
1737
				}
R
Rich Tibbett 已提交
1738

M
Mr.doob 已提交
1739
				_scene.traverse( function ( child ) {
R
Rich Tibbett 已提交
1740

M
Mr.doob 已提交
1741 1742
					// Register raw material meshes with GLTFLoader.Shaders
					if ( child.material && child.material.isRawShaderMaterial ) {
R
Rich Tibbett 已提交
1743

M
Mr.doob 已提交
1744 1745
						var xshader = new GLTFShader( child, dependencies.nodes );
						GLTFLoader.Shaders.add( child.uuid, xshader );
R
Rich Tibbett 已提交
1746

M
Mr.doob 已提交
1747 1748 1749 1750 1751 1752 1753
					}

				} );

				return _scene;

			} );
R
Rich Tibbett 已提交
1754

M
Mr.doob 已提交
1755 1756 1757
		} );

	};
R
Rich Tibbett 已提交
1758

M
Mr.doob 已提交
1759
	return GLTFLoader;
R
Rich Tibbett 已提交
1760

M
Mr.doob 已提交
1761
} )();