GLTFLoader.js 35.3 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 53
				path: path || this.path,
				crossOrigin: !! this.crossOrigin
54

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

M
Mr.doob 已提交
57
			parser.parse( function ( scene, cameras, animations ) {
58

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

					var object = objects[ name ];
112

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

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

M
Mr.doob 已提交
117
					}
118

M
Mr.doob 已提交
119
				}
120

M
Mr.doob 已提交
121
			}
122

M
Mr.doob 已提交
123
		};
124

M
Mr.doob 已提交
125
	}
126

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

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

	/* GLTFSHADER */

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

M
Mr.doob 已提交
135 136 137 138 139
		var scope = this;

		this.boundUniforms = {};

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

		var uniforms = targetNode.material.uniforms;

		for ( var uniformId in uniforms ) {

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

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

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

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

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

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

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

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

			}
167

M
Mr.doob 已提交
168
		}
169

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 221 222 223 224 225 226
						// So it goes like this:
						// SkinnedMesh world matrix is already baked into MODELVIEW;
						// ransform joints to local space,
						// then transform using joint's inverse
						m4v[ mi ]
							.getInverse( boundUniform.sourceNode.matrixWorld )
							.multiply( boundUniform.targetNode.skeleton.bones[ mi ].matrixWorld )
							.multiply( boundUniform.targetNode.skeleton.boneInverses[ mi ] );
R
Rich Tibbett 已提交
227

M
Mr.doob 已提交
228
					}
229

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

				default :
233

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

			}

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

	};
242 243


M
Mr.doob 已提交
244
	/* GLTFANIMATION */
245

M
Mr.doob 已提交
246
	GLTFLoader.Animations = new GLTFRegistry();
247

M
Mr.doob 已提交
248 249
	// Construction/initialization
	function GLTFAnimation( interps ) {
250

M
Mr.doob 已提交
251 252 253 254 255
		this.running = false;
		this.loop = false;
		this.duration = 0;
		this.startTime = 0;
		this.interps = [];
256

M
Mr.doob 已提交
257
		this.uuid = THREE.Math.generateUUID();
258

M
Mr.doob 已提交
259
		if ( interps ) {
260

M
Mr.doob 已提交
261
			this.createInterpolators( interps );
262

M
Mr.doob 已提交
263
		}
264

R
Rich Tibbett 已提交
265
	}
266

M
Mr.doob 已提交
267
	GLTFAnimation.prototype.createInterpolators = function ( interps ) {
268

M
Mr.doob 已提交
269
		for ( var i = 0, len = interps.length; i < len; i ++ ) {
270

M
Mr.doob 已提交
271 272 273
			var interp = new GLTFInterpolator( interps[ i ] );
			this.interps.push( interp );
			this.duration = Math.max( this.duration, interp.duration );
274

M
Mr.doob 已提交
275
		}
276

M
Mr.doob 已提交
277
	};
278

M
Mr.doob 已提交
279 280
	// Start/stop
	GLTFAnimation.prototype.play = function () {
281

M
Mr.doob 已提交
282 283
		if ( this.running )
			return;
284

M
Mr.doob 已提交
285 286 287
		this.startTime = Date.now();
		this.running = true;
		GLTFLoader.Animations.add( this.uuid, this );
288

M
Mr.doob 已提交
289
	};
290

M
Mr.doob 已提交
291
	GLTFAnimation.prototype.stop = function () {
292

M
Mr.doob 已提交
293 294
		this.running = false;
		GLTFLoader.Animations.remove( this.uuid );
295

M
Mr.doob 已提交
296
	};
297

M
Mr.doob 已提交
298 299
	// Update - drive key frame evaluation
	GLTFAnimation.prototype.update = function () {
300

M
Mr.doob 已提交
301
		if ( ! this.running ) return;
302

M
Mr.doob 已提交
303 304 305 306
		var now = Date.now();
		var deltat = ( now - this.startTime ) / 1000;
		var t = deltat % this.duration;
		var nCycles = Math.floor( deltat / this.duration );
M
Mr.doob 已提交
307
		var interps = this.interps;
308

M
Mr.doob 已提交
309
		if ( nCycles >= 1 && ! this.loop ) {
310

M
Mr.doob 已提交
311
			this.running = false;
312

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

M
Mr.doob 已提交
315
				interps[ i ].interp( this.duration );
316

M
Mr.doob 已提交
317
			}
318

M
Mr.doob 已提交
319
			this.stop();
M
Mr.doob 已提交
320

M
Mr.doob 已提交
321
		} else {
M
Mr.doob 已提交
322

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

M
Mr.doob 已提交
325
				interps[ i ].interp( t );
326

M
Mr.doob 已提交
327
			}
328

M
Mr.doob 已提交
329
		}
330

M
Mr.doob 已提交
331
	};
332

M
Mr.doob 已提交
333
	/* GLTFINTERPOLATOR */
334

M
Mr.doob 已提交
335
	function GLTFInterpolator( param ) {
336

M
Mr.doob 已提交
337 338 339 340 341 342
		this.keys = param.keys;
		this.values = param.values;
		this.count = param.count;
		this.type = param.type;
		this.path = param.path;
		this.isRot = false;
343

M
Mr.doob 已提交
344 345 346 347
		var node = param.target;
		node.updateMatrix();
		node.matrixAutoUpdate = true;
		this.targetNode = node;
348

M
Mr.doob 已提交
349
		switch ( param.path ) {
350

M
Mr.doob 已提交
351
			case "translation" :
352

M
Mr.doob 已提交
353 354 355
				this.target = node.position;
				this.originalValue = node.position.clone();
				break;
356

M
Mr.doob 已提交
357
			case "rotation" :
358

M
Mr.doob 已提交
359 360 361 362
				this.target = node.quaternion;
				this.originalValue = node.quaternion.clone();
				this.isRot = true;
				break;
363

M
Mr.doob 已提交
364
			case "scale" :
365

M
Mr.doob 已提交
366 367 368
				this.target = node.scale;
				this.originalValue = node.scale.clone();
				break;
369

M
Mr.doob 已提交
370
		}
371

M
Mr.doob 已提交
372
		this.duration = this.keys[ this.count - 1 ];
373

M
Mr.doob 已提交
374 375 376 377 378 379
		this.vec1 = new THREE.Vector3();
		this.vec2 = new THREE.Vector3();
		this.vec3 = new THREE.Vector3();
		this.quat1 = new THREE.Quaternion();
		this.quat2 = new THREE.Quaternion();
		this.quat3 = new THREE.Quaternion();
380

M
Mr.doob 已提交
381
	}
382

M
Mr.doob 已提交
383 384
	//Interpolation and tweening methods
	GLTFInterpolator.prototype.interp = function ( t ) {
385

M
Mr.doob 已提交
386
		if ( t == this.keys[ 0 ] ) {
387

M
Mr.doob 已提交
388
			if ( this.isRot ) {
389

M
Mr.doob 已提交
390
				this.quat3.fromArray( this.values );
391

M
Mr.doob 已提交
392
			} else {
393

M
Mr.doob 已提交
394
				this.vec3.fromArray( this.values );
R
Rich Tibbett 已提交
395

M
Mr.doob 已提交
396
			}
R
Rich Tibbett 已提交
397

M
Mr.doob 已提交
398
		} else if ( t < this.keys[ 0 ] ) {
R
Rich Tibbett 已提交
399

M
Mr.doob 已提交
400
			if ( this.isRot ) {
401

M
Mr.doob 已提交
402 403 404
				this.quat1.copy( this.originalValue );
				this.quat2.fromArray( this.values );
				THREE.Quaternion.slerp( this.quat1, this.quat2, this.quat3, t / this.keys[ 0 ] );
R
Rich Tibbett 已提交
405

M
Mr.doob 已提交
406
			} else {
407

M
Mr.doob 已提交
408 409 410
				this.vec3.copy( this.originalValue );
				this.vec2.fromArray( this.values );
				this.vec3.lerp( this.vec2, t / this.keys[ 0 ] );
411

M
Mr.doob 已提交
412
			}
413

M
Mr.doob 已提交
414
		} else if ( t >= this.keys[ this.count - 1 ] ) {
415

M
Mr.doob 已提交
416
			if ( this.isRot ) {
417

M
Mr.doob 已提交
418
				this.quat3.fromArray( this.values, ( this.count - 1 ) * 4 );
419

M
Mr.doob 已提交
420
			} else {
421

M
Mr.doob 已提交
422
				this.vec3.fromArray( this.values, ( this.count - 1 ) * 3 );
423

M
Mr.doob 已提交
424
			}
425

M
Mr.doob 已提交
426
		} else {
427

M
Mr.doob 已提交
428
			for ( var i = 0; i < this.count - 1; i ++ ) {
429

M
Mr.doob 已提交
430 431
				var key1 = this.keys[ i ];
				var key2 = this.keys[ i + 1 ];
432

M
Mr.doob 已提交
433
				if ( t >= key1 && t <= key2 ) {
434

M
Mr.doob 已提交
435
					if ( this.isRot ) {
436

M
Mr.doob 已提交
437 438 439 440 441
						this.quat1.fromArray( this.values, i * 4 );
						this.quat2.fromArray( this.values, ( i + 1 ) * 4 );
						THREE.Quaternion.slerp( this.quat1, this.quat2, this.quat3, ( t - key1 ) / ( key2 - key1 ) );

					} else {
R
Rich Tibbett 已提交
442

M
Mr.doob 已提交
443 444 445 446 447
						this.vec3.fromArray( this.values, i * 3 );
						this.vec2.fromArray( this.values, ( i + 1 ) * 3 );
						this.vec3.lerp( this.vec2, ( t - key1 ) / ( key2 - key1 ) );

					}
R
Rich Tibbett 已提交
448 449

				}
450 451 452

			}

R
Rich Tibbett 已提交
453 454
		}

M
Mr.doob 已提交
455
		if ( this.target ) {
R
Rich Tibbett 已提交
456

M
Mr.doob 已提交
457
			if ( this.isRot ) {
458

M
Mr.doob 已提交
459
				this.target.copy( this.quat3 );
460

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

M
Mr.doob 已提交
463
				this.target.copy( this.vec3 );
R
Rich Tibbett 已提交
464

M
Mr.doob 已提交
465
			}
R
Rich Tibbett 已提交
466 467 468

		}

M
Mr.doob 已提交
469
	};
R
Rich Tibbett 已提交
470

471

M
Mr.doob 已提交
472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495
	/*********************************/
	/********** 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,
		UNSIGNED_BYTE: 5121,
		UNSIGNED_SHORT: 5123,

		VERTEX_SHADER: 35633,
		FRAGMENT_SHADER: 35632
	};
496

M
Mr.doob 已提交
497 498 499 500 501 502 503 504 505 506
	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
	};
507

M
Mr.doob 已提交
508 509 510 511 512 513 514 515
	var WEBGL_COMPONENT_TYPES = {
		5120: Int8Array,
		5121: Uint8Array,
		5122: Int16Array,
		5123: Uint16Array,
		5125: Uint32Array,
		5126: Float32Array
	};
516

M
Mr.doob 已提交
517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547
	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
	};

	/* UTILITY FUNCTIONS */

	function _each( object, callback, thisObj ) {

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

M
Mr.doob 已提交
550 551 552 553
		var results;
		var fns = [];

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

M
Mr.doob 已提交
555
			results = [];
R
Rich Tibbett 已提交
556

M
Mr.doob 已提交
557 558 559
			var length = object.length;
			for ( var idx = 0; idx < length; idx ++ ) {
				var value = callback.call( thisObj || this, object[ idx ], idx );
R
Rich Tibbett 已提交
560 561 562 563
				if ( value ) {
					fns.push( value );
					if ( value instanceof Promise ) {
						value.then( function( key, value ) {
M
Mr.doob 已提交
564
							results[ idx ] = value;
R
Rich Tibbett 已提交
565 566
						}.bind( this, key ));
					} else {
M
Mr.doob 已提交
567
						results[ idx ] = value;
R
Rich Tibbett 已提交
568 569
					}
				}
570
			}
R
Rich Tibbett 已提交
571

M
Mr.doob 已提交
572
		} else {
R
Rich Tibbett 已提交
573

M
Mr.doob 已提交
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590
			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 已提交
591

M
Mr.doob 已提交
592
		}
R
Rich Tibbett 已提交
593

M
Mr.doob 已提交
594 595 596
		return Promise.all( fns ).then( function() {
			return results;
		});
R
Rich Tibbett 已提交
597 598 599

	}

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

M
Mr.doob 已提交
602 603 604
		// Invalid URL
		if ( typeof url !== 'string' || url === '' )
			return '';
605

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

M
Mr.doob 已提交
609
			return url;
R
Rich Tibbett 已提交
610

M
Mr.doob 已提交
611
		}
R
Rich Tibbett 已提交
612

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

M
Mr.doob 已提交
616
			return url;
R
Rich Tibbett 已提交
617

M
Mr.doob 已提交
618
		}
R
Rich Tibbett 已提交
619

M
Mr.doob 已提交
620 621
		// Relative URL
		return ( path || '' ) + url;
R
Rich Tibbett 已提交
622

M
Mr.doob 已提交
623
	}
R
Rich Tibbett 已提交
624

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

M
Mr.doob 已提交
629 630
		// Expected technique attributes
		var attributes = {};
R
Rich Tibbett 已提交
631

M
Mr.doob 已提交
632 633 634
		for ( var attributeId in technique.attributes ) {

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

M
Mr.doob 已提交
636 637 638
			var param = technique.parameters[ pname ];
			var atype = param.type;
			var semantic = param.semantic;
R
Rich Tibbett 已提交
639

M
Mr.doob 已提交
640 641 642 643
			attributes[ attributeId ] = {
				type: atype,
				semantic: semantic
			};
644

M
Mr.doob 已提交
645
		}
646

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

M
Mr.doob 已提交
649 650 651
		var shaderParams = technique.parameters;
		var shaderAttributes = technique.attributes;
		var params = {};
652

M
Mr.doob 已提交
653
		for ( var attributeId in attributes ) {
654

M
Mr.doob 已提交
655 656 657 658
			var pname = shaderAttributes[ attributeId ];
			var shaderParam = shaderParams[ pname ];
			var semantic = shaderParam.semantic;
			if ( semantic ) {
659

M
Mr.doob 已提交
660
				params[ attributeId ] = shaderParam;
661

M
Mr.doob 已提交
662
			}
R
Rich Tibbett 已提交
663

M
Mr.doob 已提交
664
		}
R
Rich Tibbett 已提交
665

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

M
Mr.doob 已提交
668
			var param = params[ pname ];
M
Mr.doob 已提交
669
			var semantic = param.semantic;
R
Rich Tibbett 已提交
670

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

M
Mr.doob 已提交
673
			switch ( semantic ) {
R
Rich Tibbett 已提交
674

M
Mr.doob 已提交
675
				case "POSITION":
R
Rich Tibbett 已提交
676

M
Mr.doob 已提交
677 678
					shaderText = shaderText.replace( regEx, 'position' );
					break;
R
Rich Tibbett 已提交
679

M
Mr.doob 已提交
680
				case "NORMAL":
R
Rich Tibbett 已提交
681

M
Mr.doob 已提交
682 683
					shaderText = shaderText.replace( regEx, 'normal' );
					break;
684

M
Mr.doob 已提交
685 686 687
				case 'TEXCOORD_0':
				case 'TEXCOORD0':
				case 'TEXCOORD':
688

M
Mr.doob 已提交
689 690
					shaderText = shaderText.replace( regEx, 'uv' );
					break;
691

M
Mr.doob 已提交
692
				case "WEIGHT":
693

M
Mr.doob 已提交
694 695
					shaderText = shaderText.replace( regEx, 'skinWeight' );
					break;
696

M
Mr.doob 已提交
697
				case "JOINT":
698

M
Mr.doob 已提交
699 700
					shaderText = shaderText.replace( regEx, 'skinIndex' );
					break;
701

M
Mr.doob 已提交
702
			}
703

M
Mr.doob 已提交
704
		}
R
Rich Tibbett 已提交
705

M
Mr.doob 已提交
706
		return shaderText;
707

M
Mr.doob 已提交
708
	}
R
Rich Tibbett 已提交
709

M
Mr.doob 已提交
710 711
	// Deferred constructor for RawShaderMaterial types
	function DeferredShaderMaterial( params ) {
R
Rich Tibbett 已提交
712

M
Mr.doob 已提交
713
		this.isDeferredShaderMaterial = true;
R
Rich Tibbett 已提交
714

M
Mr.doob 已提交
715
		this.params = params;
716

M
Mr.doob 已提交
717
	}
718

M
Mr.doob 已提交
719
	DeferredShaderMaterial.prototype.create = function () {
720

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

M
Mr.doob 已提交
723 724 725
		for ( var uniformId in this.params.uniforms ) {

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

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

M
Mr.doob 已提交
729 730
				uniforms[ uniformId ].value = originalUniform.value;
				uniforms[ uniformId ].value.needsUpdate = true;
R
Rich Tibbett 已提交
731

M
Mr.doob 已提交
732
			}
R
Rich Tibbett 已提交
733

M
Mr.doob 已提交
734 735
			uniforms[ uniformId ].semantic = originalUniform.semantic;
			uniforms[ uniformId ].node = originalUniform.node;
R
Rich Tibbett 已提交
736

M
Mr.doob 已提交
737
		}
R
Rich Tibbett 已提交
738

M
Mr.doob 已提交
739
		this.params.uniforms = uniforms;
R
Rich Tibbett 已提交
740

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

M
Mr.doob 已提交
743
	};
R
Rich Tibbett 已提交
744

M
Mr.doob 已提交
745
	/* GLTF PARSER */
R
Rich Tibbett 已提交
746

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

M
Mr.doob 已提交
749 750
		this.json = json || {};
		this.options = options || {};
R
Rich Tibbett 已提交
751

M
Mr.doob 已提交
752 753
		// loader object cache
		this.cache = new GLTFRegistry();
R
Rich Tibbett 已提交
754

M
Mr.doob 已提交
755
	}
R
Rich Tibbett 已提交
756

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

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

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

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

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

M
Mr.doob 已提交
768
			if ( cached !== undefined ) {
769

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

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

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

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

M
Mr.doob 已提交
779
			}
R
Rich Tibbett 已提交
780

M
Mr.doob 已提交
781
		}
R
Rich Tibbett 已提交
782

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

M
Mr.doob 已提交
785
			return dependency;
R
Rich Tibbett 已提交
786

M
Mr.doob 已提交
787
		} );
R
Rich Tibbett 已提交
788

M
Mr.doob 已提交
789
	};
R
Rich Tibbett 已提交
790

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

M
Mr.doob 已提交
793 794
		// Clear the loader cache
		this.cache.removeAll();
R
Rich Tibbett 已提交
795

M
Mr.doob 已提交
796 797
		// Fire the callback on complete
		this._withDependencies( [
R
Rich Tibbett 已提交
798

M
Mr.doob 已提交
799 800 801
			"scenes",
			"cameras",
			"animations"
R
Rich Tibbett 已提交
802

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

M
Mr.doob 已提交
805
			var scene = dependencies.scenes[ this.json.scene ];
R
Rich Tibbett 已提交
806

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

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

M
Mr.doob 已提交
811
				var camera = dependencies.cameras[ name ];
M
Mr.doob 已提交
812
				cameras.push( camera );
R
Rich Tibbett 已提交
813

M
Mr.doob 已提交
814
			}
R
Rich Tibbett 已提交
815

M
Mr.doob 已提交
816
			var animations = [];
R
Rich Tibbett 已提交
817

M
Mr.doob 已提交
818
			for ( var name in dependencies.animations ) {
R
Rich Tibbett 已提交
819

M
Mr.doob 已提交
820
				var animation = dependencies.animations[ name ];
M
Mr.doob 已提交
821
				animations.push( animation );
R
Rich Tibbett 已提交
822

M
Mr.doob 已提交
823
			}
R
Rich Tibbett 已提交
824

M
Mr.doob 已提交
825
			callback( scene, cameras, animations );
R
Rich Tibbett 已提交
826

M
Mr.doob 已提交
827
		}.bind( this ) );
R
Rich Tibbett 已提交
828

M
Mr.doob 已提交
829
	};
R
Rich Tibbett 已提交
830

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

M
Mr.doob 已提交
833
		return _each( this.json.shaders, function ( shader ) {
R
Rich Tibbett 已提交
834

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

837
				var loader = new THREE.FileLoader();
M
Mr.doob 已提交
838 839
				loader.responseType = 'text';
				loader.load( resolveURL( shader.uri, this.options.path ), function ( shaderText ) {
R
Rich Tibbett 已提交
840

M
Mr.doob 已提交
841
					resolve( shaderText );
R
Rich Tibbett 已提交
842 843 844

				} );

M
Mr.doob 已提交
845
			}.bind( this ) );
R
Rich Tibbett 已提交
846

M
Mr.doob 已提交
847
		}.bind( this ) );
R
Rich Tibbett 已提交
848

M
Mr.doob 已提交
849
	};
R
Rich Tibbett 已提交
850

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

M
Mr.doob 已提交
853
		return _each( this.json.buffers, function ( buffer ) {
R
Rich Tibbett 已提交
854

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

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

M
Mr.doob 已提交
859 860 861
					var loader = new THREE.FileLoader();
					loader.responseType = 'arraybuffer';
					loader.load( resolveURL( buffer.uri, this.options.path ), function ( buffer ) {
R
Rich Tibbett 已提交
862

M
Mr.doob 已提交
863
						resolve( buffer );
R
Rich Tibbett 已提交
864

M
Mr.doob 已提交
865
					} );
R
Rich Tibbett 已提交
866

M
Mr.doob 已提交
867
				}.bind( this ) );
R
Rich Tibbett 已提交
868

M
Mr.doob 已提交
869
			}
R
Rich Tibbett 已提交
870

M
Mr.doob 已提交
871
		}.bind( this ) );
R
Rich Tibbett 已提交
872

M
Mr.doob 已提交
873
	};
R
Rich Tibbett 已提交
874

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

M
Mr.doob 已提交
877
		return this._withDependencies( [
R
Rich Tibbett 已提交
878

M
Mr.doob 已提交
879
			"buffers"
R
Rich Tibbett 已提交
880

M
Mr.doob 已提交
881
		] ).then( function ( dependencies ) {
882

M
Mr.doob 已提交
883
			return _each( this.json.bufferViews, function ( bufferView ) {
884

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

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

M
Mr.doob 已提交
889
			} );
890

M
Mr.doob 已提交
891
		}.bind( this ) );
892

M
Mr.doob 已提交
893
	};
894

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

M
Mr.doob 已提交
897 898 899 900 901
		return this._withDependencies( [

			"bufferViews"

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

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

M
Mr.doob 已提交
905 906 907
				var arraybuffer = dependencies.bufferViews[ accessor.bufferView ];
				var itemSize = WEBGL_TYPE_SIZES[ accessor.type ];
				var TypedArray = WEBGL_COMPONENT_TYPES[ accessor.componentType ];
R
Rich Tibbett 已提交
908

M
Mr.doob 已提交
909 910 911
				// For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.
				var elementBytes = TypedArray.BYTES_PER_ELEMENT;
				var itemBytes = elementBytes * itemSize;
R
Rich Tibbett 已提交
912

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

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

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

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

M
Mr.doob 已提交
924 925 926
				} else {

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

M
Mr.doob 已提交
928
					return new THREE.BufferAttribute( array, itemSize );
R
Rich Tibbett 已提交
929 930 931

				}

M
Mr.doob 已提交
932
			} );
R
Rich Tibbett 已提交
933

M
Mr.doob 已提交
934
		}.bind( this ) );
R
Rich Tibbett 已提交
935

M
Mr.doob 已提交
936
	};
R
Rich Tibbett 已提交
937

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

M
Mr.doob 已提交
940
		return _each( this.json.textures, function ( texture ) {
R
Rich Tibbett 已提交
941

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

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

M
Mr.doob 已提交
946
					var source = this.json.images[ texture.source ];
R
Rich Tibbett 已提交
947

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

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

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

M
Mr.doob 已提交
954
					}
R
Rich Tibbett 已提交
955

M
Mr.doob 已提交
956
					textureLoader.crossOrigin = this.options.crossOrigin || false;
R
Rich Tibbett 已提交
957

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

M
Mr.doob 已提交
960
						_texture.flipY = false;
R
Rich Tibbett 已提交
961

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

M
Mr.doob 已提交
964
							var sampler = this.json.samplers[ texture.sampler ];
R
Rich Tibbett 已提交
965

M
Mr.doob 已提交
966 967 968 969
							_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 已提交
970

M
Mr.doob 已提交
971 972 973
						}

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

M
Mr.doob 已提交
975
					}.bind( this ) );
R
Rich Tibbett 已提交
976

M
Mr.doob 已提交
977
				}.bind( this ) );
R
Rich Tibbett 已提交
978 979 980

			}

M
Mr.doob 已提交
981
		}.bind( this ) );
R
Rich Tibbett 已提交
982

M
Mr.doob 已提交
983
	};
R
Rich Tibbett 已提交
984

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

M
Mr.doob 已提交
987
		return this._withDependencies( [
R
Rich Tibbett 已提交
988

M
Mr.doob 已提交
989 990
			"shaders",
			"textures"
R
Rich Tibbett 已提交
991

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

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

M
Mr.doob 已提交
996 997 998
				var materialType;
				var materialValues = {};
				var materialParams = {};
R
Rich Tibbett 已提交
999

M
Mr.doob 已提交
1000
				var khr_material;
R
Rich Tibbett 已提交
1001

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

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

M
Mr.doob 已提交
1006 1007 1008
				} else if ( this.json.extensions && this.json.extensions.KHR_materials_common ) {

					khr_material = this.json.extensions.KHR_materials_common;
R
Rich Tibbett 已提交
1009 1010 1011

				}

M
Mr.doob 已提交
1012
				if ( khr_material ) {
R
Rich Tibbett 已提交
1013

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

M
Mr.doob 已提交
1016 1017 1018 1019
						case 'BLINN' :
						case 'PHONG' :
							materialType = THREE.MeshPhongMaterial;
							break;
R
Rich Tibbett 已提交
1020

M
Mr.doob 已提交
1021 1022 1023
						case 'LAMBERT' :
							materialType = THREE.MeshLambertMaterial;
							break;
R
Rich Tibbett 已提交
1024

M
Mr.doob 已提交
1025 1026 1027 1028
						case 'CONSTANT' :
						default :
							materialType = THREE.MeshBasicMaterial;
							break;
R
Rich Tibbett 已提交
1029

M
Mr.doob 已提交
1030
					}
R
Rich Tibbett 已提交
1031

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

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

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

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

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

M
Mr.doob 已提交
1042 1043
						materialParams.transparent = true;
						materialParams.opacity = ( materialValues.transparency !== undefined ) ? materialValues.transparency : 1;
R
Rich Tibbett 已提交
1044 1045 1046

					}

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

M
Mr.doob 已提交
1049
					materialType = THREE.MeshPhongMaterial;
R
Rich Tibbett 已提交
1050

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

M
Mr.doob 已提交
1053
				} else {
R
Rich Tibbett 已提交
1054

M
Mr.doob 已提交
1055
					materialType = DeferredShaderMaterial;
R
Rich Tibbett 已提交
1056

M
Mr.doob 已提交
1057
					var technique = this.json.techniques[ material.technique ];
R
Rich Tibbett 已提交
1058

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

M
Mr.doob 已提交
1061
					var program = this.json.programs[ technique.program ];
R
Rich Tibbett 已提交
1062

M
Mr.doob 已提交
1063
					if ( program ) {
R
Rich Tibbett 已提交
1064

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

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

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

M
Mr.doob 已提交
1072
						}
R
Rich Tibbett 已提交
1073

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

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

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

M
Mr.doob 已提交
1081
						}
R
Rich Tibbett 已提交
1082

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

M
Mr.doob 已提交
1086
						var uniforms = technique.uniforms;
R
Rich Tibbett 已提交
1087

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

M
Mr.doob 已提交
1090
							var pname = uniforms[ uniformId ];
M
Mr.doob 已提交
1091
							var shaderParam = technique.parameters[ pname ];
R
Rich Tibbett 已提交
1092

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

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

M
Mr.doob 已提交
1097 1098
								var pcount = shaderParam.count;
								var value = material.values[ pname ];
R
Rich Tibbett 已提交
1099

M
Mr.doob 已提交
1100 1101 1102
								var uvalue = new WEBGL_TYPE[ ptype ]();
								var usemantic = shaderParam.semantic;
								var unode = shaderParam.node;
R
Rich Tibbett 已提交
1103

M
Mr.doob 已提交
1104
								switch ( ptype ) {
R
Rich Tibbett 已提交
1105

M
Mr.doob 已提交
1106
									case WEBGL_CONSTANTS.FLOAT:
R
Rich Tibbett 已提交
1107

M
Mr.doob 已提交
1108
										uvalue = shaderParam.value;
R
Rich Tibbett 已提交
1109

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

M
Mr.doob 已提交
1112
											materialParams.transparent = true;
R
Rich Tibbett 已提交
1113

M
Mr.doob 已提交
1114
										}
R
Rich Tibbett 已提交
1115

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

M
Mr.doob 已提交
1118
											uvalue = value;
R
Rich Tibbett 已提交
1119

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

M
Mr.doob 已提交
1122
										break;
R
Rich Tibbett 已提交
1123

M
Mr.doob 已提交
1124 1125 1126 1127
									case WEBGL_CONSTANTS.FLOAT_VEC2:
									case WEBGL_CONSTANTS.FLOAT_VEC3:
									case WEBGL_CONSTANTS.FLOAT_VEC4:
									case WEBGL_CONSTANTS.FLOAT_MAT3:
R
Rich Tibbett 已提交
1128 1129 1130

										if ( shaderParam && shaderParam.value ) {

M
Mr.doob 已提交
1131
											uvalue.fromArray( shaderParam.value );
R
Rich Tibbett 已提交
1132 1133 1134 1135 1136 1137 1138 1139 1140

										}

										if ( value ) {

											uvalue.fromArray( value );

										}

M
Mr.doob 已提交
1141
										break;
R
Rich Tibbett 已提交
1142

M
Mr.doob 已提交
1143
									case WEBGL_CONSTANTS.FLOAT_MAT2:
R
Rich Tibbett 已提交
1144

M
Mr.doob 已提交
1145 1146 1147
										// what to do?
										console.warn( "FLOAT_MAT2 is not a supported uniform type" );
										break;
R
Rich Tibbett 已提交
1148

M
Mr.doob 已提交
1149
									case WEBGL_CONSTANTS.FLOAT_MAT4:
R
Rich Tibbett 已提交
1150

M
Mr.doob 已提交
1151
										if ( pcount ) {
R
Rich Tibbett 已提交
1152

M
Mr.doob 已提交
1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187
											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 已提交
1188 1189 1190

										}

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

M
Mr.doob 已提交
1193
									case WEBGL_CONSTANTS.SAMPLER_2D:
R
Rich Tibbett 已提交
1194

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

M
Mr.doob 已提交
1197
										break;
R
Rich Tibbett 已提交
1198

M
Mr.doob 已提交
1199
								}
R
Rich Tibbett 已提交
1200

M
Mr.doob 已提交
1201 1202 1203 1204 1205
								materialParams.uniforms[ uniformId ] = {
									value: uvalue,
									semantic: usemantic,
									node: unode
								};
R
Rich Tibbett 已提交
1206

M
Mr.doob 已提交
1207
							} else {
R
Rich Tibbett 已提交
1208

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

M
Mr.doob 已提交
1211
							}
R
Rich Tibbett 已提交
1212

M
Mr.doob 已提交
1213
						}
R
Rich Tibbett 已提交
1214

M
Mr.doob 已提交
1215
					}
R
Rich Tibbett 已提交
1216 1217 1218

				}

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

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

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

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

M
Mr.doob 已提交
1227
				}
R
Rich Tibbett 已提交
1228

M
Mr.doob 已提交
1229
				delete materialParams.diffuse;
R
Rich Tibbett 已提交
1230

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

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

M
Mr.doob 已提交
1235
				}
R
Rich Tibbett 已提交
1236

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

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

M
Mr.doob 已提交
1241
				}
R
Rich Tibbett 已提交
1242

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

M
Mr.doob 已提交
1245
					materialParams.emissive = new THREE.Color().fromArray( materialValues.emission );
R
Rich Tibbett 已提交
1246

M
Mr.doob 已提交
1247
				}
R
Rich Tibbett 已提交
1248

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

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

M
Mr.doob 已提交
1253
				}
R
Rich Tibbett 已提交
1254

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

M
Mr.doob 已提交
1257
					materialParams.shininess = materialValues.shininess;
R
Rich Tibbett 已提交
1258

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

M
Mr.doob 已提交
1261 1262
				var _material = new materialType( materialParams );
				_material.name = material.name;
R
Rich Tibbett 已提交
1263

M
Mr.doob 已提交
1264
				return _material;
R
Rich Tibbett 已提交
1265

M
Mr.doob 已提交
1266
			}.bind( this ) );
R
Rich Tibbett 已提交
1267

M
Mr.doob 已提交
1268
		}.bind( this ) );
R
Rich Tibbett 已提交
1269

M
Mr.doob 已提交
1270
	};
R
Rich Tibbett 已提交
1271

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

M
Mr.doob 已提交
1274
		return this._withDependencies( [
R
Rich Tibbett 已提交
1275

M
Mr.doob 已提交
1276 1277
			"accessors",
			"materials"
R
Rich Tibbett 已提交
1278

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

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

M
Mr.doob 已提交
1283 1284
				var group = new THREE.Object3D();
				group.name = mesh.name;
R
Rich Tibbett 已提交
1285

M
Mr.doob 已提交
1286
				var primitives = mesh.primitives;
R
Rich Tibbett 已提交
1287

M
Mr.doob 已提交
1288 1289 1290
				for ( var name in primitives ) {

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

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

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

M
Mr.doob 已提交
1296
						var attributes = primitive.attributes;
R
Rich Tibbett 已提交
1297

M
Mr.doob 已提交
1298 1299 1300
						for ( var attributeId in attributes ) {

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

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

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

M
Mr.doob 已提交
1306
							switch ( attributeId ) {
R
Rich Tibbett 已提交
1307

M
Mr.doob 已提交
1308 1309 1310
								case 'POSITION':
									geometry.addAttribute( 'position', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1311

M
Mr.doob 已提交
1312 1313 1314
								case 'NORMAL':
									geometry.addAttribute( 'normal', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1315

M
Mr.doob 已提交
1316 1317 1318 1319 1320
								case 'TEXCOORD_0':
								case 'TEXCOORD0':
								case 'TEXCOORD':
									geometry.addAttribute( 'uv', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1321

M
Mr.doob 已提交
1322 1323 1324
								case 'WEIGHT':
									geometry.addAttribute( 'skinWeight', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1325

M
Mr.doob 已提交
1326 1327 1328
								case 'JOINT':
									geometry.addAttribute( 'skinIndex', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1329

M
Mr.doob 已提交
1330
							}
R
Rich Tibbett 已提交
1331

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

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

M
Mr.doob 已提交
1336
							var indexArray = dependencies.accessors[ primitive.indices ];
R
Rich Tibbett 已提交
1337

M
Mr.doob 已提交
1338
							geometry.setIndex( indexArray );
R
Rich Tibbett 已提交
1339

M
Mr.doob 已提交
1340
							var offset = {
R
Rich Tibbett 已提交
1341 1342 1343 1344 1345
								start: 0,
								index: 0,
								count: indexArray.count
							};

M
Mr.doob 已提交
1346
							geometry.groups.push( offset );
R
Rich Tibbett 已提交
1347

M
Mr.doob 已提交
1348
							geometry.computeBoundingSphere();
R
Rich Tibbett 已提交
1349

M
Mr.doob 已提交
1350
						}
R
Rich Tibbett 已提交
1351 1352


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

M
Mr.doob 已提交
1355 1356
						var meshNode = new THREE.Mesh( geometry, material );
						meshNode.castShadow = true;
R
Rich Tibbett 已提交
1357

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

M
Mr.doob 已提交
1360
					} else {
R
Rich Tibbett 已提交
1361

M
Mr.doob 已提交
1362
						console.warn( "Non-triangular primitives are not supported" );
R
Rich Tibbett 已提交
1363

M
Mr.doob 已提交
1364
					}
R
Rich Tibbett 已提交
1365

M
Mr.doob 已提交
1366
				}
R
Rich Tibbett 已提交
1367

M
Mr.doob 已提交
1368
				return group;
R
Rich Tibbett 已提交
1369

M
Mr.doob 已提交
1370
			} );
R
Rich Tibbett 已提交
1371

M
Mr.doob 已提交
1372
		}.bind( this ) );
R
Rich Tibbett 已提交
1373

M
Mr.doob 已提交
1374
	};
R
Rich Tibbett 已提交
1375

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

M
Mr.doob 已提交
1378
		return _each( this.json.cameras, function ( camera ) {
R
Rich Tibbett 已提交
1379

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

M
Mr.doob 已提交
1382 1383 1384
				var yfov = camera.perspective.yfov;
				var xfov = camera.perspective.xfov;
				var aspect_ratio = camera.perspective.aspect_ratio || 1;
R
Rich Tibbett 已提交
1385

M
Mr.doob 已提交
1386 1387 1388
				// According to COLLADA spec...
				// aspect_ratio = xfov / yfov
				xfov = ( xfov === undefined && yfov ) ? yfov * aspect_ratio : xfov;
R
Rich Tibbett 已提交
1389

M
Mr.doob 已提交
1390 1391 1392
				// According to COLLADA spec...
				// aspect_ratio = xfov / yfov
				// yfov = ( yfov === undefined && xfov ) ? xfov / aspect_ratio : yfov;
R
Rich Tibbett 已提交
1393

M
Mr.doob 已提交
1394 1395
				var _camera = new THREE.PerspectiveCamera( THREE.Math.radToDeg( xfov ), aspect_ratio, camera.perspective.znear || 1, camera.perspective.zfar || 2e6 );
				_camera.name = camera.name;
R
Rich Tibbett 已提交
1396

M
Mr.doob 已提交
1397
				return _camera;
R
Rich Tibbett 已提交
1398

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

M
Mr.doob 已提交
1401 1402
				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;
R
Rich Tibbett 已提交
1403

M
Mr.doob 已提交
1404
				return _camera;
R
Rich Tibbett 已提交
1405

M
Mr.doob 已提交
1406
			}
R
Rich Tibbett 已提交
1407

M
Mr.doob 已提交
1408
		}.bind( this ) );
R
Rich Tibbett 已提交
1409

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

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

M
Mr.doob 已提交
1414
		var scope = this;
R
Rich Tibbett 已提交
1415

M
Mr.doob 已提交
1416
		return this._withDependencies( [
R
Rich Tibbett 已提交
1417

M
Mr.doob 已提交
1418
			"accessors"
R
Rich Tibbett 已提交
1419

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

M
Mr.doob 已提交
1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432
			return _each( scope.json.skins, function ( skin ) {

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

				return _skin;

			} );
R
Rich Tibbett 已提交
1433

M
Mr.doob 已提交
1434
		} );
R
Rich Tibbett 已提交
1435

M
Mr.doob 已提交
1436 1437 1438
	};

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

M
Mr.doob 已提交
1440
		var scope = this;
R
Rich Tibbett 已提交
1441

M
Mr.doob 已提交
1442
		return this._withDependencies( [
R
Rich Tibbett 已提交
1443

M
Mr.doob 已提交
1444 1445
			"accessors",
			"nodes"
R
Rich Tibbett 已提交
1446

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

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

M
Mr.doob 已提交
1451
				var interps = [];
R
Rich Tibbett 已提交
1452

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

M
Mr.doob 已提交
1455
					var channel = animation.channels[ channelId ];
M
Mr.doob 已提交
1456 1457 1458
					var sampler = animation.samplers[ channel.sampler ];

					if ( sampler && animation.parameters ) {
R
Rich Tibbett 已提交
1459 1460 1461

						var target = channel.target;
						var name = target.id;
M
Mr.doob 已提交
1462 1463
						var input = animation.parameters[ sampler.input ];
						var output = animation.parameters[ sampler.output ];
R
Rich Tibbett 已提交
1464 1465 1466 1467 1468 1469 1470 1471 1472

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

						var node = dependencies.nodes[ name ];

						if ( node ) {

							var interp = {
M
Mr.doob 已提交
1473 1474 1475 1476 1477 1478
								keys: inputAccessor.array,
								values: outputAccessor.array,
								count: inputAccessor.count,
								target: node,
								path: target.path,
								type: sampler.interpolation
R
Rich Tibbett 已提交
1479 1480 1481 1482 1483 1484
							};

							interps.push( interp );

						}

M
Mr.doob 已提交
1485
					}
R
Rich Tibbett 已提交
1486

M
Mr.doob 已提交
1487
				}
R
Rich Tibbett 已提交
1488

M
Mr.doob 已提交
1489 1490
				var _animation = new GLTFAnimation( interps );
				_animation.name = "animation_" + animationId;
R
Rich Tibbett 已提交
1491

M
Mr.doob 已提交
1492
				return _animation;
R
Rich Tibbett 已提交
1493

M
Mr.doob 已提交
1494
			} );
R
Rich Tibbett 已提交
1495

M
Mr.doob 已提交
1496
		} );
R
Rich Tibbett 已提交
1497

M
Mr.doob 已提交
1498
	};
R
Rich Tibbett 已提交
1499

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

M
Mr.doob 已提交
1502
		return _each( this.json.nodes, function ( node ) {
R
Rich Tibbett 已提交
1503

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

M
Mr.doob 已提交
1506
			var _node;
R
Rich Tibbett 已提交
1507

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

M
Mr.doob 已提交
1510 1511
				_node = new THREE.Bone();
				_node.jointName = node.jointName;
R
Rich Tibbett 已提交
1512

M
Mr.doob 已提交
1513
			} else {
R
Rich Tibbett 已提交
1514

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

M
Mr.doob 已提交
1517
			}
R
Rich Tibbett 已提交
1518

M
Mr.doob 已提交
1519
			_node.name = node.name;
R
Rich Tibbett 已提交
1520

M
Mr.doob 已提交
1521
			_node.matrixAutoUpdate = false;
R
Rich Tibbett 已提交
1522

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

M
Mr.doob 已提交
1525 1526
				matrix.fromArray( node.matrix );
				_node.applyMatrix( matrix );
R
Rich Tibbett 已提交
1527

M
Mr.doob 已提交
1528
			} else {
R
Rich Tibbett 已提交
1529

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

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

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

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

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

M
Mr.doob 已提交
1540 1541 1542
				}

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

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

M
Mr.doob 已提交
1546
				}
R
Rich Tibbett 已提交
1547 1548 1549

			}

M
Mr.doob 已提交
1550
			return _node;
R
Rich Tibbett 已提交
1551

M
Mr.doob 已提交
1552
		}.bind( this ) ).then( function ( __nodes ) {
R
Rich Tibbett 已提交
1553

M
Mr.doob 已提交
1554
			return this._withDependencies( [
R
Rich Tibbett 已提交
1555

M
Mr.doob 已提交
1556 1557 1558 1559
				"meshes",
				"skins",
				"cameras",
				"extensions"
R
Rich Tibbett 已提交
1560

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

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

M
Mr.doob 已提交
1565
					var node = this.json.nodes[ nodeId ];
R
Rich Tibbett 已提交
1566

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

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

M
Mr.doob 已提交
1571 1572
							var mesh = node.meshes[ meshId ];
							var group = dependencies.meshes[ mesh ];
R
Rich Tibbett 已提交
1573

M
Mr.doob 已提交
1574 1575 1576
							for ( var childrenId in group.children ) {

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

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

M
Mr.doob 已提交
1580 1581
								var originalMaterial = child.material;
								var originalGeometry = child.geometry;
R
Rich Tibbett 已提交
1582

M
Mr.doob 已提交
1583
								var material;
R
Rich Tibbett 已提交
1584

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

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

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

M
Mr.doob 已提交
1591
									material = originalMaterial;
R
Rich Tibbett 已提交
1592

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

M
Mr.doob 已提交
1595 1596
								child = new THREE.Mesh( originalGeometry, material );
								child.castShadow = true;
R
Rich Tibbett 已提交
1597

M
Mr.doob 已提交
1598
								var skinEntry;
M
Mr.doob 已提交
1599

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

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

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

M
Mr.doob 已提交
1606 1607
								// Replace Mesh with SkinnedMesh in library
								if ( skinEntry ) {
R
Rich Tibbett 已提交
1608

M
Mr.doob 已提交
1609 1610 1611
									var geometry = originalGeometry;
									var material = originalMaterial;
									material.skinning = true;
R
Rich Tibbett 已提交
1612

M
Mr.doob 已提交
1613 1614
									child = new THREE.SkinnedMesh( geometry, material, false );
									child.castShadow = true;
R
Rich Tibbett 已提交
1615

M
Mr.doob 已提交
1616 1617
									var bones = [];
									var boneInverses = [];
R
Rich Tibbett 已提交
1618

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

M
Mr.doob 已提交
1621
										var jointId = skinEntry.jointNames[ i ];
M
Mr.doob 已提交
1622
										var jointNode = __nodes[ jointId ];
R
Rich Tibbett 已提交
1623

M
Mr.doob 已提交
1624
										if ( jointNode ) {
R
Rich Tibbett 已提交
1625

M
Mr.doob 已提交
1626
											jointNode.skin = child;
M
Mr.doob 已提交
1627
											bones.push( jointNode );
R
Rich Tibbett 已提交
1628

M
Mr.doob 已提交
1629 1630 1631
											var m = skinEntry.inverseBindMatrices.array;
											var mat = new THREE.Matrix4().fromArray( m, i * 16 );
											boneInverses.push( mat );
R
Rich Tibbett 已提交
1632

M
Mr.doob 已提交
1633
										} else {
R
Rich Tibbett 已提交
1634

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

M
Mr.doob 已提交
1637
										}
R
Rich Tibbett 已提交
1638

M
Mr.doob 已提交
1639
									}
R
Rich Tibbett 已提交
1640

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

M
Mr.doob 已提交
1643
								}
R
Rich Tibbett 已提交
1644

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

M
Mr.doob 已提交
1647
							}
R
Rich Tibbett 已提交
1648

M
Mr.doob 已提交
1649
						}
R
Rich Tibbett 已提交
1650

M
Mr.doob 已提交
1651
					}
R
Rich Tibbett 已提交
1652

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

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

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

M
Mr.doob 已提交
1659
					}
R
Rich Tibbett 已提交
1660

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

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

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

M
Mr.doob 已提交
1667
					}
R
Rich Tibbett 已提交
1668

M
Mr.doob 已提交
1669
					return _node;
R
Rich Tibbett 已提交
1670

M
Mr.doob 已提交
1671
				}.bind( this ) );
R
Rich Tibbett 已提交
1672

M
Mr.doob 已提交
1673
			}.bind( this ) );
R
Rich Tibbett 已提交
1674

M
Mr.doob 已提交
1675
		}.bind( this ) );
R
Rich Tibbett 已提交
1676

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

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

M
Mr.doob 已提交
1681
		return _each( this.json.extensions, function ( extension, extensionId ) {
R
Rich Tibbett 已提交
1682

M
Mr.doob 已提交
1683
			switch ( extensionId ) {
R
Rich Tibbett 已提交
1684

M
Mr.doob 已提交
1685
				case "KHR_materials_common":
R
Rich Tibbett 已提交
1686

M
Mr.doob 已提交
1687 1688 1689
					var extensionNode = {
						lights: {}
					};
R
Rich Tibbett 已提交
1690

M
Mr.doob 已提交
1691
					var lights = extension.lights;
R
Rich Tibbett 已提交
1692

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

M
Mr.doob 已提交
1695
						var light = lights[ lightId ];
M
Mr.doob 已提交
1696
						var lightNode;
R
Rich Tibbett 已提交
1697

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

M
Mr.doob 已提交
1701 1702 1703 1704 1705 1706
						switch ( light.type ) {

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

M
Mr.doob 已提交
1708 1709 1710
							case "point":
								lightNode = new THREE.PointLight( color );
								break;
R
Rich Tibbett 已提交
1711

M
Mr.doob 已提交
1712 1713 1714 1715
							case "spot ":
								lightNode = new THREE.SpotLight( color );
								lightNode.position.set( 0, 0, 1 );
								break;
R
Rich Tibbett 已提交
1716

M
Mr.doob 已提交
1717 1718 1719
							case "ambient":
								lightNode = new THREE.AmbientLight( color );
								break;
R
Rich Tibbett 已提交
1720

M
Mr.doob 已提交
1721
						}
R
Rich Tibbett 已提交
1722

M
Mr.doob 已提交
1723
						if ( lightNode ) {
R
Rich Tibbett 已提交
1724

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

M
Mr.doob 已提交
1727
						}
R
Rich Tibbett 已提交
1728

M
Mr.doob 已提交
1729
					}
R
Rich Tibbett 已提交
1730

M
Mr.doob 已提交
1731
					return extensionNode;
R
Rich Tibbett 已提交
1732

M
Mr.doob 已提交
1733
					break;
R
Rich Tibbett 已提交
1734

M
Mr.doob 已提交
1735
			}
R
Rich Tibbett 已提交
1736

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

M
Mr.doob 已提交
1739
	};
R
Rich Tibbett 已提交
1740

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

M
Mr.doob 已提交
1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755
		var scope = this;

		// scene node hierachy builder

		function buildNodeHierachy( nodeId, parentObject, allNodes ) {

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

			var node = scope.json.nodes[ nodeId ];

			if ( node.children ) {

M
Mr.doob 已提交
1756 1757 1758
				var children = node.children;

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

M
Mr.doob 已提交
1760
					var child = children[ i ];
M
Mr.doob 已提交
1761 1762
					buildNodeHierachy( child, _node, allNodes );

M
Mr.doob 已提交
1763
				}
M
Mr.doob 已提交
1764 1765

			}
R
Rich Tibbett 已提交
1766 1767 1768

		}

M
Mr.doob 已提交
1769
		return this._withDependencies( [
R
Rich Tibbett 已提交
1770

M
Mr.doob 已提交
1771
			"nodes"
R
Rich Tibbett 已提交
1772

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

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

M
Mr.doob 已提交
1777 1778
				var _scene = new THREE.Scene();
				_scene.name = scene.name;
R
Rich Tibbett 已提交
1779

M
Mr.doob 已提交
1780
				var nodes = scene.nodes;
R
Rich Tibbett 已提交
1781

M
Mr.doob 已提交
1782 1783 1784
				for ( var i = 0, l = nodes.length; i < l; i ++ ) {

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

M
Mr.doob 已提交
1787
				}
R
Rich Tibbett 已提交
1788

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

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

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

M
Mr.doob 已提交
1797 1798 1799 1800 1801 1802 1803
					}

				} );

				return _scene;

			} );
R
Rich Tibbett 已提交
1804

M
Mr.doob 已提交
1805 1806 1807
		} );

	};
R
Rich Tibbett 已提交
1808

M
Mr.doob 已提交
1809
	return GLTFLoader;
R
Rich Tibbett 已提交
1810

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