GLTFLoader.js 44.8 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/
T
Takahiro 已提交
5
 * @author Takahiro / https://github.com/takahirox
6 7
 */

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

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

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

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

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

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

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

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

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

M
Mr.doob 已提交
26
			var loader = new THREE.FileLoader( scope.manager );
R
Rich Tibbett 已提交
27

28 29 30 31
			loader.setResponseType( 'arraybuffer' );

			loader.load( url, function ( data ) {

M
Mr.doob 已提交
32
				scope.parse( data, onLoad, path );
33

M
Mr.doob 已提交
34
			}, onProgress, onError );
35

M
Mr.doob 已提交
36
		},
37

M
Mr.doob 已提交
38
		setCrossOrigin: function ( value ) {
39

M
Mr.doob 已提交
40
			this.crossOrigin = value;
41

M
Mr.doob 已提交
42
		},
43

M
Mr.doob 已提交
44
		setPath: function ( value ) {
45

M
Mr.doob 已提交
46
			this.path = value;
47

M
Mr.doob 已提交
48
		},
49

50 51
		parse: function ( data, callback, path ) {

M
Mr.doob 已提交
52
			var content;
53 54 55 56 57 58 59
			var extensions = {};

			var magic = convertUint8ArrayToString( new Uint8Array( data, 0, 4 ) );

			if ( magic === BINARY_EXTENSION_HEADER_DEFAULTS.magic ) {

				extensions[ EXTENSIONS.KHR_BINARY_GLTF ] = new GLTFBinaryExtension( data );
M
Mr.doob 已提交
60
				content = extensions[ EXTENSIONS.KHR_BINARY_GLTF ].content;
61 62 63

			} else {

M
Mr.doob 已提交
64
				content = convertUint8ArrayToString( new Uint8Array( data ) );
65 66 67

			}

M
Mr.doob 已提交
68
			var json = JSON.parse( content );
69 70 71 72 73 74

			if ( json.extensionsUsed && json.extensionsUsed.indexOf( EXTENSIONS.KHR_MATERIALS_COMMON ) >= 0 ) {

				extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ] = new GLTFMaterialsCommonExtension( json );

			}
75

M
Mr.doob 已提交
76
			console.time( 'GLTFLoader' );
77

78
			var parser = new GLTFParser( json, extensions, {
79

M
Mr.doob 已提交
80
				path: path || this.path,
T
Takahiro 已提交
81
				crossOrigin: this.crossOrigin
82

M
Mr.doob 已提交
83
			} );
84

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

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

M
Mr.doob 已提交
89 90
				var glTF = {
					"scene": scene,
T
Takahiro 已提交
91
					"scenes": scenes,
M
Mr.doob 已提交
92
					"cameras": cameras,
93
					"animations": animations
M
Mr.doob 已提交
94
				};
R
Rich Tibbett 已提交
95

M
Mr.doob 已提交
96
				callback( glTF );
R
Rich Tibbett 已提交
97

M
Mr.doob 已提交
98
			} );
R
Rich Tibbett 已提交
99

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

M
Mr.doob 已提交
102
	};
R
Rich Tibbett 已提交
103

M
Mr.doob 已提交
104
	/* GLTFREGISTRY */
R
Rich Tibbett 已提交
105

M
Mr.doob 已提交
106
	function GLTFRegistry() {
107

M
Mr.doob 已提交
108
		var objects = {};
109

M
Mr.doob 已提交
110
		return	{
R
Rich Tibbett 已提交
111

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

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

M
Mr.doob 已提交
116
			},
R
Rich Tibbett 已提交
117

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

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

M
Mr.doob 已提交
122
			},
R
Rich Tibbett 已提交
123

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

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

M
Mr.doob 已提交
128
			},
R
Rich Tibbett 已提交
129

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

M
Mr.doob 已提交
132
				objects = {};
R
Rich Tibbett 已提交
133

M
Mr.doob 已提交
134
			},
R
Rich Tibbett 已提交
135

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

138 139 140 141 142 143 144 145 146
				// update scene graph

				scene.updateMatrixWorld();

				// update camera matrices and frustum

				camera.updateMatrixWorld();
				camera.matrixWorldInverse.getInverse( camera.matrixWorld );

M
Mr.doob 已提交
147 148 149
				for ( var name in objects ) {

					var object = objects[ name ];
150

M
Mr.doob 已提交
151
					if ( object.update ) {
152

M
Mr.doob 已提交
153
						object.update( scene, camera );
154

M
Mr.doob 已提交
155
					}
156

M
Mr.doob 已提交
157
				}
158

M
Mr.doob 已提交
159
			}
160

M
Mr.doob 已提交
161
		};
162

M
Mr.doob 已提交
163
	}
164

M
Mr.doob 已提交
165
	/* GLTFSHADERS */
166

M
Mr.doob 已提交
167 168 169 170 171
	GLTFLoader.Shaders = new GLTFRegistry();

	/* GLTFSHADER */

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

M
Mr.doob 已提交
173
		var boundUniforms = {};
M
Mr.doob 已提交
174 175

		// bind each uniform to its source node
M
Mr.doob 已提交
176 177 178 179 180 181

		var uniforms = targetNode.material.uniforms;

		for ( var uniformId in uniforms ) {

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

M
Mr.doob 已提交
183
			if ( uniform.semantic ) {
184

M
Mr.doob 已提交
185
				var sourceNodeRef = uniform.node;
186

M
Mr.doob 已提交
187
				var sourceNode = targetNode;
188

M
Mr.doob 已提交
189
				if ( sourceNodeRef ) {
190

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

M
Mr.doob 已提交
193
				}
R
Rich Tibbett 已提交
194

M
Mr.doob 已提交
195
				boundUniforms[ uniformId ] = {
M
Mr.doob 已提交
196 197 198 199 200
					semantic: uniform.semantic,
					sourceNode: sourceNode,
					targetNode: targetNode,
					uniform: uniform
				};
R
Rich Tibbett 已提交
201 202

			}
203

M
Mr.doob 已提交
204
		}
205

M
Mr.doob 已提交
206
		this.boundUniforms = boundUniforms;
M
Mr.doob 已提交
207
		this._m4 = new THREE.Matrix4();
208

M
Mr.doob 已提交
209
	}
210

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

M
Mr.doob 已提交
214 215 216 217 218
		var boundUniforms = this.boundUniforms;

		for ( var name in boundUniforms ) {

			var boundUniform = boundUniforms[ name ];
219

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

M
Mr.doob 已提交
222
				case "MODELVIEW":
R
Rich Tibbett 已提交
223

M
Mr.doob 已提交
224 225 226
					var m4 = boundUniform.uniform.value;
					m4.multiplyMatrices( camera.matrixWorldInverse, boundUniform.sourceNode.matrixWorld );
					break;
R
Rich Tibbett 已提交
227

M
Mr.doob 已提交
228
				case "MODELVIEWINVERSETRANSPOSE":
R
Rich Tibbett 已提交
229

M
Mr.doob 已提交
230 231 232 233
					var m3 = boundUniform.uniform.value;
					this._m4.multiplyMatrices( camera.matrixWorldInverse, boundUniform.sourceNode.matrixWorld );
					m3.getNormalMatrix( this._m4 );
					break;
R
Rich Tibbett 已提交
234

M
Mr.doob 已提交
235
				case "PROJECTION":
236

M
Mr.doob 已提交
237 238 239
					var m4 = boundUniform.uniform.value;
					m4.copy( camera.projectionMatrix );
					break;
R
Rich Tibbett 已提交
240

M
Mr.doob 已提交
241
				case "JOINTMATRIX":
R
Rich Tibbett 已提交
242

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

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

M
Mr.doob 已提交
247 248
						// So it goes like this:
						// SkinnedMesh world matrix is already baked into MODELVIEW;
T
Takahiro 已提交
249
						// transform joints to local space,
M
Mr.doob 已提交
250 251 252 253
						// then transform using joint's inverse
						m4v[ mi ]
							.getInverse( boundUniform.sourceNode.matrixWorld )
							.multiply( boundUniform.targetNode.skeleton.bones[ mi ].matrixWorld )
T
Takahiro 已提交
254 255
							.multiply( boundUniform.targetNode.skeleton.boneInverses[ mi ] )
							.multiply( boundUniform.targetNode.bindMatrix );
R
Rich Tibbett 已提交
256

M
Mr.doob 已提交
257
					}
258

M
Mr.doob 已提交
259 260 261
					break;

				default :
262

M
Mr.doob 已提交
263 264 265 266 267
					console.warn( "Unhandled shader semantic: " + boundUniform.semantic );
					break;

			}

M
Mr.doob 已提交
268
		}
M
Mr.doob 已提交
269 270

	};
271 272


273
	/* ANIMATION */
274

M
Mr.doob 已提交
275 276 277 278 279 280 281 282 283 284
	GLTFLoader.Animations = {

		update: function () {

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

		}

	};

285 286 287 288 289 290 291 292 293 294 295
	/*********************************/
	/********** EXTENSIONS ***********/
	/*********************************/

	var EXTENSIONS = {
		KHR_BINARY_GLTF: 'KHR_binary_glTF',
		KHR_MATERIALS_COMMON: 'KHR_materials_common'
	};

	/* MATERIALS COMMON EXTENSION */

M
Mr.doob 已提交
296
	function GLTFMaterialsCommonExtension( json ) {
297 298 299 300 301 302 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 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351

		this.name = EXTENSIONS.KHR_MATERIALS_COMMON;

		this.lights = {};

		var lights = json.extensions && json.extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ].lights;

		for ( var lightId in lights ) {

			var light = lights[ lightId ];
			var lightNode;

			var lightParams = light[ light.type ];
			var color = new THREE.Color().fromArray( lightParams.color );

			switch ( light.type ) {

				case "directional":
					lightNode = new THREE.DirectionalLight( color );
					lightNode.position.set( 0, 0, 1 );
					break;

				case "point":
					lightNode = new THREE.PointLight( color );
					break;

				case "spot":
					lightNode = new THREE.SpotLight( color );
					lightNode.position.set( 0, 0, 1 );
					break;

				case "ambient":
					lightNode = new THREE.AmbientLight( color );
					break;

			}

			if ( lightNode ) {

				this.lights[ lightId ] = lightNode;

			}

		}

	}

	/* BINARY EXTENSION */

	var BINARY_EXTENSION_BUFFER_NAME = 'binary_glTF';

	var BINARY_EXTENSION_HEADER_DEFAULTS = { magic: 'glTF', version: 1, contentFormat: 0 };

	var BINARY_EXTENSION_HEADER_LENGTH = 20;

M
Mr.doob 已提交
352
	function GLTFBinaryExtension( data ) {
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404

		this.name = EXTENSIONS.KHR_BINARY_GLTF;

		var headerView = new DataView( data, 0, BINARY_EXTENSION_HEADER_LENGTH );

		var header = {
			magic: convertUint8ArrayToString( new Uint8Array( data.slice( 0, 4 ) ) ),
			version: headerView.getUint32( 4, true ),
			length: headerView.getUint32( 8, true ),
			contentLength: headerView.getUint32( 12, true ),
			contentFormat: headerView.getUint32( 16, true )
		};

		for ( var key in BINARY_EXTENSION_HEADER_DEFAULTS ) {

			var value = BINARY_EXTENSION_HEADER_DEFAULTS[ key ];

			if ( header[ key ] !== value ) {

				throw new Error( 'Unsupported glTF-Binary header: Expected "%s" to be "%s".', key, value );

			}

		}

		var contentArray = new Uint8Array( data, BINARY_EXTENSION_HEADER_LENGTH, header.contentLength );

		this.header = header;
		this.content = convertUint8ArrayToString( contentArray );
		this.body = data.slice( BINARY_EXTENSION_HEADER_LENGTH + header.contentLength, header.length );

	}

	GLTFBinaryExtension.prototype.loadShader = function ( shader, bufferViews ) {

		var bufferView = bufferViews[ shader.extensions[ EXTENSIONS.KHR_BINARY_GLTF ].bufferView ];
		var array = new Uint8Array( bufferView );

		return convertUint8ArrayToString( array );

	};

	GLTFBinaryExtension.prototype.loadTextureSourceUri = function ( source, bufferViews ) {

		var metadata = source.extensions[ EXTENSIONS.KHR_BINARY_GLTF ];
		var bufferView = bufferViews[ metadata.bufferView ];
		var stringData = convertUint8ArrayToString( new Uint8Array( bufferView ) );

		return 'data:' + metadata.mimeType + ';base64,' + btoa( stringData );

	};

M
Mr.doob 已提交
405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422
	/*********************************/
	/********** 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,
423
		LINES: 1,
M
Mr.doob 已提交
424 425 426 427 428 429
		UNSIGNED_BYTE: 5121,
		UNSIGNED_SHORT: 5123,

		VERTEX_SHADER: 35633,
		FRAGMENT_SHADER: 35632
	};
430

M
Mr.doob 已提交
431 432 433 434 435 436 437 438 439 440
	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
	};
441

M
Mr.doob 已提交
442 443 444 445 446 447 448 449
	var WEBGL_COMPONENT_TYPES = {
		5120: Int8Array,
		5121: Uint8Array,
		5122: Int16Array,
		5123: Uint16Array,
		5125: Uint32Array,
		5126: Float32Array
	};
450

M
Mr.doob 已提交
451 452 453 454 455 456 457 458 459 460 461 462 463 464 465
	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
	};

466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507
	var WEBGL_SIDES = {
		1028: THREE.BackSide,  // Culling front
		1029: THREE.FrontSide  // Culling back
		//1032: THREE.NoSide   // Culling front and back, what to do?
	};

	var WEBGL_DEPTH_FUNCS = {
		512: THREE.NeverDepth,
		513: THREE.LessDepth,
		514: THREE.EqualDepth,
		515: THREE.LessEqualDepth,
		516: THREE.GreaterEqualDepth,
		517: THREE.NotEqualDepth,
		518: THREE.GreaterEqualDepth,
		519: THREE.AlwaysDepth
	};

	var WEBGL_BLEND_EQUATIONS = {
		32774: THREE.AddEquation,
		32778: THREE.SubtractEquation,
		32779: THREE.ReverseSubtractEquation
	};

	var WEBGL_BLEND_FUNCS = {
		0: THREE.ZeroFactor,
		1: THREE.OneFactor,
		768: THREE.SrcColorFactor,
		769: THREE.OneMinusSrcColorFactor,
		770: THREE.SrcAlphaFactor,
		771: THREE.OneMinusSrcAlphaFactor,
		772: THREE.DstAlphaFactor,
		773: THREE.OneMinusDstAlphaFactor,
		774: THREE.DstColorFactor,
		775: THREE.OneMinusDstColorFactor,
		776: THREE.SrcAlphaSaturateFactor
		// The followings are not supported by Three.js yet
		//32769: CONSTANT_COLOR,
		//32770: ONE_MINUS_CONSTANT_COLOR,
		//32771: CONSTANT_ALPHA,
		//32772: ONE_MINUS_CONSTANT_COLOR
	};

M
Mr.doob 已提交
508 509 510 511 512 513 514 515 516 517
	var WEBGL_TYPE_SIZES = {
		'SCALAR': 1,
		'VEC2': 2,
		'VEC3': 3,
		'VEC4': 4,
		'MAT2': 4,
		'MAT3': 9,
		'MAT4': 16
	};

518 519 520 521 522 523 524
	var PATH_PROPERTIES = {
		scale: 'scale',
		translation: 'position',
		rotation: 'quaternion'
	};

	var INTERPOLATION = {
525 526
		LINEAR: THREE.InterpolateLinear,
		STEP: THREE.InterpolateDiscrete
527 528
	};

529 530 531 532 533 534 535 536 537
	var STATES_ENABLES = {
		2884: 'CULL_FACE',
		2929: 'DEPTH_TEST',
		3042: 'BLEND',
		3089: 'SCISSOR_TEST',
		32823: 'POLYGON_OFFSET_FILL',
		32926: 'SAMPLE_ALPHA_TO_COVERAGE'
	};

M
Mr.doob 已提交
538 539 540 541 542 543
	/* UTILITY FUNCTIONS */

	function _each( object, callback, thisObj ) {

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

M
Mr.doob 已提交
546 547 548 549
		var results;
		var fns = [];

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

M
Mr.doob 已提交
551
			results = [];
R
Rich Tibbett 已提交
552

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

M
Mr.doob 已提交
568
		} else {
R
Rich Tibbett 已提交
569

M
Mr.doob 已提交
570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586
			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 已提交
587

M
Mr.doob 已提交
588
		}
R
Rich Tibbett 已提交
589

M
Mr.doob 已提交
590 591 592
		return Promise.all( fns ).then( function() {
			return results;
		});
R
Rich Tibbett 已提交
593 594 595

	}

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

M
Mr.doob 已提交
598 599 600
		// Invalid URL
		if ( typeof url !== 'string' || url === '' )
			return '';
601

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

M
Mr.doob 已提交
605
			return url;
R
Rich Tibbett 已提交
606

M
Mr.doob 已提交
607
		}
R
Rich Tibbett 已提交
608

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

M
Mr.doob 已提交
612
			return url;
R
Rich Tibbett 已提交
613

M
Mr.doob 已提交
614
		}
R
Rich Tibbett 已提交
615

M
Mr.doob 已提交
616 617
		// Relative URL
		return ( path || '' ) + url;
R
Rich Tibbett 已提交
618

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

621 622
	// Avoid the String.fromCharCode.apply(null, array) shortcut, which
	// throws a "maximum call stack size exceeded" error for large arrays.
M
Mr.doob 已提交
623 624
	function convertUint8ArrayToString( array ) {

625 626
		var s = '';

M
Mr.doob 已提交
627
		for ( var i = 0; i < array.length; i ++ ) {
628 629 630 631 632 633

			s += String.fromCharCode( array[ i ] );

		}

		return s;
M
Mr.doob 已提交
634

635 636
	}

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

M
Mr.doob 已提交
641 642
		// Expected technique attributes
		var attributes = {};
R
Rich Tibbett 已提交
643

M
Mr.doob 已提交
644 645 646
		for ( var attributeId in technique.attributes ) {

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

M
Mr.doob 已提交
648 649 650
			var param = technique.parameters[ pname ];
			var atype = param.type;
			var semantic = param.semantic;
R
Rich Tibbett 已提交
651

M
Mr.doob 已提交
652 653 654 655
			attributes[ attributeId ] = {
				type: atype,
				semantic: semantic
			};
656

M
Mr.doob 已提交
657
		}
658

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

M
Mr.doob 已提交
661 662 663
		var shaderParams = technique.parameters;
		var shaderAttributes = technique.attributes;
		var params = {};
664

M
Mr.doob 已提交
665
		for ( var attributeId in attributes ) {
666

M
Mr.doob 已提交
667 668 669 670
			var pname = shaderAttributes[ attributeId ];
			var shaderParam = shaderParams[ pname ];
			var semantic = shaderParam.semantic;
			if ( semantic ) {
671

M
Mr.doob 已提交
672
				params[ attributeId ] = shaderParam;
673

M
Mr.doob 已提交
674
			}
R
Rich Tibbett 已提交
675

M
Mr.doob 已提交
676
		}
R
Rich Tibbett 已提交
677

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

M
Mr.doob 已提交
680
			var param = params[ pname ];
M
Mr.doob 已提交
681
			var semantic = param.semantic;
R
Rich Tibbett 已提交
682

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

M
Mr.doob 已提交
685
			switch ( semantic ) {
R
Rich Tibbett 已提交
686

M
Mr.doob 已提交
687
				case "POSITION":
R
Rich Tibbett 已提交
688

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

M
Mr.doob 已提交
692
				case "NORMAL":
R
Rich Tibbett 已提交
693

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

M
Mr.doob 已提交
697 698 699
				case 'TEXCOORD_0':
				case 'TEXCOORD0':
				case 'TEXCOORD':
700

M
Mr.doob 已提交
701 702
					shaderText = shaderText.replace( regEx, 'uv' );
					break;
703

704 705 706 707 708 709 710
				case 'COLOR_0':
				case 'COLOR0':
				case 'COLOR':

					shaderText = shaderText.replace( regEx, 'color' );
					break;

M
Mr.doob 已提交
711
				case "WEIGHT":
712

M
Mr.doob 已提交
713 714
					shaderText = shaderText.replace( regEx, 'skinWeight' );
					break;
715

M
Mr.doob 已提交
716
				case "JOINT":
717

M
Mr.doob 已提交
718 719
					shaderText = shaderText.replace( regEx, 'skinIndex' );
					break;
720

M
Mr.doob 已提交
721
			}
722

M
Mr.doob 已提交
723
		}
R
Rich Tibbett 已提交
724

M
Mr.doob 已提交
725
		return shaderText;
726

M
Mr.doob 已提交
727
	}
R
Rich Tibbett 已提交
728

T
Takahiro 已提交
729 730 731 732 733 734 735 736 737 738 739 740
	function createDefaultMaterial() {

		return new THREE.MeshPhongMaterial( {
			color: 0x00000,
			emissive: 0x888888,
			specular: 0x000000,
			shininess: 0,
			transparent: false,
			depthTest: true,
			side: THREE.FrontSide
		} );

M
Mr.doob 已提交
741
	}
T
Takahiro 已提交
742

M
Mr.doob 已提交
743 744
	// Deferred constructor for RawShaderMaterial types
	function DeferredShaderMaterial( params ) {
R
Rich Tibbett 已提交
745

M
Mr.doob 已提交
746
		this.isDeferredShaderMaterial = true;
R
Rich Tibbett 已提交
747

M
Mr.doob 已提交
748
		this.params = params;
749

M
Mr.doob 已提交
750
	}
751

M
Mr.doob 已提交
752
	DeferredShaderMaterial.prototype.create = function () {
753

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

M
Mr.doob 已提交
756 757 758
		for ( var uniformId in this.params.uniforms ) {

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

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

M
Mr.doob 已提交
762 763
				uniforms[ uniformId ].value = originalUniform.value;
				uniforms[ uniformId ].value.needsUpdate = true;
R
Rich Tibbett 已提交
764

M
Mr.doob 已提交
765
			}
R
Rich Tibbett 已提交
766

M
Mr.doob 已提交
767 768
			uniforms[ uniformId ].semantic = originalUniform.semantic;
			uniforms[ uniformId ].node = originalUniform.node;
R
Rich Tibbett 已提交
769

M
Mr.doob 已提交
770
		}
R
Rich Tibbett 已提交
771

M
Mr.doob 已提交
772
		this.params.uniforms = uniforms;
R
Rich Tibbett 已提交
773

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

M
Mr.doob 已提交
776
	};
R
Rich Tibbett 已提交
777

M
Mr.doob 已提交
778
	/* GLTF PARSER */
R
Rich Tibbett 已提交
779

780
	function GLTFParser( json, extensions, options ) {
R
Rich Tibbett 已提交
781

M
Mr.doob 已提交
782
		this.json = json || {};
783
		this.extensions = extensions || {};
M
Mr.doob 已提交
784
		this.options = options || {};
R
Rich Tibbett 已提交
785

M
Mr.doob 已提交
786 787
		// loader object cache
		this.cache = new GLTFRegistry();
R
Rich Tibbett 已提交
788

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

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

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

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

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

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

M
Mr.doob 已提交
802
			if ( cached !== undefined ) {
803

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

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

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

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

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

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

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

M
Mr.doob 已提交
819
			return dependency;
R
Rich Tibbett 已提交
820

M
Mr.doob 已提交
821
		} );
R
Rich Tibbett 已提交
822

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

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

M
Mr.doob 已提交
827 828
		var json = this.json;

M
Mr.doob 已提交
829 830
		// Clear the loader cache
		this.cache.removeAll();
R
Rich Tibbett 已提交
831

M
Mr.doob 已提交
832 833
		// Fire the callback on complete
		this._withDependencies( [
R
Rich Tibbett 已提交
834

M
Mr.doob 已提交
835 836
			"scenes",
			"cameras",
837
			"animations"
R
Rich Tibbett 已提交
838

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

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

T
Takahiro 已提交
843 844 845 846 847 848 849 850
			var scenes = [];

			for ( var name in dependencies.scenes ) {

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

			}

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

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

M
Mr.doob 已提交
855
				var camera = dependencies.cameras[ name ];
M
Mr.doob 已提交
856
				cameras.push( camera );
R
Rich Tibbett 已提交
857

M
Mr.doob 已提交
858
			}
R
Rich Tibbett 已提交
859

860
			var animations = [];
R
Rich Tibbett 已提交
861

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

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

M
Mr.doob 已提交
866
			}
R
Rich Tibbett 已提交
867

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

M
Mr.doob 已提交
870
		} );
R
Rich Tibbett 已提交
871

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

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

M
Mr.doob 已提交
876
		var json = this.json;
877
		var extensions = this.extensions;
M
Mr.doob 已提交
878 879
		var options = this.options;

880 881 882 883 884 885 886 887 888 889 890 891 892 893 894
		return this._withDependencies( [

			"bufferViews"

		] ).then( function ( dependencies ) {

			return _each( json.shaders, function ( shader ) {

				if ( shader.extensions && shader.extensions[ EXTENSIONS.KHR_BINARY_GLTF ] ) {

					return extensions[ EXTENSIONS.KHR_BINARY_GLTF ].loadShader( shader, dependencies.bufferViews );

				}

				return new Promise( function ( resolve ) {
R
Rich Tibbett 已提交
895

896 897 898
					var loader = new THREE.FileLoader();
					loader.setResponseType( 'text' );
					loader.load( resolveURL( shader.uri, options.path ), function ( shaderText ) {
R
Rich Tibbett 已提交
899

900
						resolve( shaderText );
R
Rich Tibbett 已提交
901

902
					} );
R
Rich Tibbett 已提交
903 904 905

				} );

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

M
Mr.doob 已提交
908
		} );
R
Rich Tibbett 已提交
909

M
Mr.doob 已提交
910
	};
R
Rich Tibbett 已提交
911

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

M
Mr.doob 已提交
914
		var json = this.json;
915
		var extensions = this.extensions;
M
Mr.doob 已提交
916 917
		var options = this.options;

918 919 920 921 922 923 924
		return _each( json.buffers, function ( buffer, name ) {

			if ( name === BINARY_EXTENSION_BUFFER_NAME ) {

				return extensions[ EXTENSIONS.KHR_BINARY_GLTF ].body;

			}
R
Rich Tibbett 已提交
925

T
Takahiro 已提交
926
			if ( buffer.type === 'arraybuffer' || buffer.type === undefined ) {
R
Rich Tibbett 已提交
927

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

M
Mr.doob 已提交
930
					var loader = new THREE.FileLoader();
931
					loader.setResponseType( 'arraybuffer' );
M
Mr.doob 已提交
932
					loader.load( resolveURL( buffer.uri, options.path ), function ( buffer ) {
R
Rich Tibbett 已提交
933

M
Mr.doob 已提交
934
						resolve( buffer );
R
Rich Tibbett 已提交
935

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

M
Mr.doob 已提交
938
				} );
R
Rich Tibbett 已提交
939

T
Takahiro 已提交
940 941 942 943
			} else {

				console.warn( 'THREE.GLTFLoader: ' + buffer.type + ' buffer type is not supported' );

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

M
Mr.doob 已提交
946
		} );
R
Rich Tibbett 已提交
947

M
Mr.doob 已提交
948
	};
R
Rich Tibbett 已提交
949

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

M
Mr.doob 已提交
952 953
		var json = this.json;

M
Mr.doob 已提交
954
		return this._withDependencies( [
R
Rich Tibbett 已提交
955

M
Mr.doob 已提交
956
			"buffers"
R
Rich Tibbett 已提交
957

M
Mr.doob 已提交
958
		] ).then( function ( dependencies ) {
959

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

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

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

M
Mr.doob 已提交
966
			} );
967

M
Mr.doob 已提交
968
		} );
969

M
Mr.doob 已提交
970
	};
971

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

M
Mr.doob 已提交
974 975
		var json = this.json;

M
Mr.doob 已提交
976 977 978 979 980
		return this._withDependencies( [

			"bufferViews"

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

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

M
Mr.doob 已提交
984 985 986
				var arraybuffer = dependencies.bufferViews[ accessor.bufferView ];
				var itemSize = WEBGL_TYPE_SIZES[ accessor.type ];
				var TypedArray = WEBGL_COMPONENT_TYPES[ accessor.componentType ];
R
Rich Tibbett 已提交
987

M
Mr.doob 已提交
988 989 990
				// For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.
				var elementBytes = TypedArray.BYTES_PER_ELEMENT;
				var itemBytes = elementBytes * itemSize;
R
Rich Tibbett 已提交
991

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

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

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

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

M
Mr.doob 已提交
1003 1004 1005
				} else {

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

M
Mr.doob 已提交
1007
					return new THREE.BufferAttribute( array, itemSize );
R
Rich Tibbett 已提交
1008 1009 1010

				}

M
Mr.doob 已提交
1011
			} );
R
Rich Tibbett 已提交
1012

M
Mr.doob 已提交
1013
		} );
R
Rich Tibbett 已提交
1014

M
Mr.doob 已提交
1015
	};
R
Rich Tibbett 已提交
1016

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

M
Mr.doob 已提交
1019
		var json = this.json;
1020
		var extensions = this.extensions;
M
Mr.doob 已提交
1021 1022
		var options = this.options;

1023
		return this._withDependencies( [
R
Rich Tibbett 已提交
1024

1025
			"bufferViews"
R
Rich Tibbett 已提交
1026

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

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

1031
				if ( texture.source ) {
R
Rich Tibbett 已提交
1032

1033
					return new Promise( function ( resolve ) {
R
Rich Tibbett 已提交
1034

1035 1036
						var source = json.images[ texture.source ];
						var sourceUri = source.uri;
R
Rich Tibbett 已提交
1037

M
Mr.doob 已提交
1038
						if ( source.extensions && source.extensions[ EXTENSIONS.KHR_BINARY_GLTF ] ) {
R
Rich Tibbett 已提交
1039

1040
							sourceUri = extensions[ EXTENSIONS.KHR_BINARY_GLTF ].loadTextureSourceUri( source, dependencies.bufferViews );
R
Rich Tibbett 已提交
1041

1042
						}
R
Rich Tibbett 已提交
1043

1044
						var textureLoader = THREE.Loader.Handlers.get( sourceUri );
R
Rich Tibbett 已提交
1045

1046
						if ( textureLoader === null ) {
R
Rich Tibbett 已提交
1047

1048
							textureLoader = new THREE.TextureLoader();
R
Rich Tibbett 已提交
1049

M
Mr.doob 已提交
1050 1051
						}

1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071
						textureLoader.setCrossOrigin( options.crossOrigin );

						textureLoader.load( resolveURL( sourceUri, options.path ), function ( _texture ) {

							_texture.flipY = false;

							if ( texture.sampler ) {

								var sampler = json.samplers[ texture.sampler ];

								_texture.magFilter = WEBGL_FILTERS[ sampler.magFilter ];
								_texture.minFilter = WEBGL_FILTERS[ sampler.minFilter ];
								_texture.wrapS = WEBGL_WRAPPINGS[ sampler.wrapS ];
								_texture.wrapT = WEBGL_WRAPPINGS[ sampler.wrapT ];

							}

							resolve( _texture );

						}, undefined, function () {
R
Rich Tibbett 已提交
1072

1073
							resolve();
1074

1075
						} );
1076 1077

					} );
R
Rich Tibbett 已提交
1078

1079
				}
R
Rich Tibbett 已提交
1080

1081
			} );
R
Rich Tibbett 已提交
1082

M
Mr.doob 已提交
1083
		} );
R
Rich Tibbett 已提交
1084

M
Mr.doob 已提交
1085
	};
R
Rich Tibbett 已提交
1086

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

M
Mr.doob 已提交
1089 1090
		var json = this.json;

M
Mr.doob 已提交
1091
		return this._withDependencies( [
R
Rich Tibbett 已提交
1092

M
Mr.doob 已提交
1093 1094
			"shaders",
			"textures"
R
Rich Tibbett 已提交
1095

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

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

M
Mr.doob 已提交
1100 1101 1102
				var materialType;
				var materialValues = {};
				var materialParams = {};
R
Rich Tibbett 已提交
1103

M
Mr.doob 已提交
1104
				var khr_material;
R
Rich Tibbett 已提交
1105

1106
				if ( material.extensions && material.extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ] ) {
R
Rich Tibbett 已提交
1107

1108
					khr_material = material.extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ];
R
Rich Tibbett 已提交
1109 1110 1111

				}

M
Mr.doob 已提交
1112
				if ( khr_material ) {
R
Rich Tibbett 已提交
1113

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

M
Mr.doob 已提交
1116 1117 1118 1119
						case 'BLINN' :
						case 'PHONG' :
							materialType = THREE.MeshPhongMaterial;
							break;
R
Rich Tibbett 已提交
1120

M
Mr.doob 已提交
1121 1122 1123
						case 'LAMBERT' :
							materialType = THREE.MeshLambertMaterial;
							break;
R
Rich Tibbett 已提交
1124

M
Mr.doob 已提交
1125 1126 1127 1128
						case 'CONSTANT' :
						default :
							materialType = THREE.MeshBasicMaterial;
							break;
R
Rich Tibbett 已提交
1129

M
Mr.doob 已提交
1130
					}
R
Rich Tibbett 已提交
1131

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

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

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

M
Mr.doob 已提交
1138
					}
R
Rich Tibbett 已提交
1139

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

M
Mr.doob 已提交
1142 1143
						materialParams.transparent = true;
						materialParams.opacity = ( materialValues.transparency !== undefined ) ? materialValues.transparency : 1;
R
Rich Tibbett 已提交
1144 1145 1146

					}

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

M
Mr.doob 已提交
1149
					materialType = THREE.MeshPhongMaterial;
R
Rich Tibbett 已提交
1150

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

M
Mr.doob 已提交
1153
				} else {
R
Rich Tibbett 已提交
1154

M
Mr.doob 已提交
1155
					materialType = DeferredShaderMaterial;
R
Rich Tibbett 已提交
1156

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

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

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

M
Mr.doob 已提交
1163
					if ( program ) {
R
Rich Tibbett 已提交
1164

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

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

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

M
Mr.doob 已提交
1172
						}
R
Rich Tibbett 已提交
1173

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

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

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

M
Mr.doob 已提交
1181
						}
R
Rich Tibbett 已提交
1182

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

M
Mr.doob 已提交
1186
						var uniforms = technique.uniforms;
R
Rich Tibbett 已提交
1187

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

M
Mr.doob 已提交
1190
							var pname = uniforms[ uniformId ];
M
Mr.doob 已提交
1191
							var shaderParam = technique.parameters[ pname ];
R
Rich Tibbett 已提交
1192

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

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

M
Mr.doob 已提交
1197
								var pcount = shaderParam.count;
1198 1199 1200
								var value;

								if ( material.values !== undefined ) value = material.values[ pname ];
R
Rich Tibbett 已提交
1201

M
Mr.doob 已提交
1202 1203 1204
								var uvalue = new WEBGL_TYPE[ ptype ]();
								var usemantic = shaderParam.semantic;
								var unode = shaderParam.node;
R
Rich Tibbett 已提交
1205

M
Mr.doob 已提交
1206
								switch ( ptype ) {
R
Rich Tibbett 已提交
1207

M
Mr.doob 已提交
1208
									case WEBGL_CONSTANTS.FLOAT:
R
Rich Tibbett 已提交
1209

M
Mr.doob 已提交
1210
										uvalue = shaderParam.value;
R
Rich Tibbett 已提交
1211

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

M
Mr.doob 已提交
1214
											materialParams.transparent = true;
R
Rich Tibbett 已提交
1215

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

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

M
Mr.doob 已提交
1220
											uvalue = value;
R
Rich Tibbett 已提交
1221

M
Mr.doob 已提交
1222
										}
R
Rich Tibbett 已提交
1223

M
Mr.doob 已提交
1224
										break;
R
Rich Tibbett 已提交
1225

M
Mr.doob 已提交
1226 1227 1228 1229
									case WEBGL_CONSTANTS.FLOAT_VEC2:
									case WEBGL_CONSTANTS.FLOAT_VEC3:
									case WEBGL_CONSTANTS.FLOAT_VEC4:
									case WEBGL_CONSTANTS.FLOAT_MAT3:
R
Rich Tibbett 已提交
1230 1231 1232

										if ( shaderParam && shaderParam.value ) {

M
Mr.doob 已提交
1233
											uvalue.fromArray( shaderParam.value );
R
Rich Tibbett 已提交
1234 1235 1236 1237 1238 1239 1240 1241 1242

										}

										if ( value ) {

											uvalue.fromArray( value );

										}

M
Mr.doob 已提交
1243
										break;
R
Rich Tibbett 已提交
1244

M
Mr.doob 已提交
1245
									case WEBGL_CONSTANTS.FLOAT_MAT2:
R
Rich Tibbett 已提交
1246

M
Mr.doob 已提交
1247 1248 1249
										// what to do?
										console.warn( "FLOAT_MAT2 is not a supported uniform type" );
										break;
R
Rich Tibbett 已提交
1250

M
Mr.doob 已提交
1251
									case WEBGL_CONSTANTS.FLOAT_MAT4:
R
Rich Tibbett 已提交
1252

M
Mr.doob 已提交
1253
										if ( pcount ) {
R
Rich Tibbett 已提交
1254

M
Mr.doob 已提交
1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275
											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 );

											}

T
Takahiro 已提交
1276
										} else {
M
Mr.doob 已提交
1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289

											if ( shaderParam && shaderParam.value ) {

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

											}

											if ( value ) {

												uvalue.fromArray( value );

											}
R
Rich Tibbett 已提交
1290 1291 1292

										}

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

M
Mr.doob 已提交
1295
									case WEBGL_CONSTANTS.SAMPLER_2D:
R
Rich Tibbett 已提交
1296

1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309
										if ( value !== undefined ) {

											uvalue = dependencies.textures[ value ];

										} else if ( shaderParam.value !== undefined ) {

											uvalue = dependencies.textures[ shaderParam.value ];

										} else {

											uvalue = null;

										}
R
Rich Tibbett 已提交
1310

M
Mr.doob 已提交
1311
										break;
R
Rich Tibbett 已提交
1312

M
Mr.doob 已提交
1313
								}
R
Rich Tibbett 已提交
1314

M
Mr.doob 已提交
1315 1316 1317 1318 1319
								materialParams.uniforms[ uniformId ] = {
									value: uvalue,
									semantic: usemantic,
									node: unode
								};
R
Rich Tibbett 已提交
1320

M
Mr.doob 已提交
1321
							} else {
R
Rich Tibbett 已提交
1322

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

M
Mr.doob 已提交
1325
							}
R
Rich Tibbett 已提交
1326

M
Mr.doob 已提交
1327
						}
R
Rich Tibbett 已提交
1328

1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340
						var states = technique.states || {};
						var enables = states.enable || [];
						var functions = states.functions || {};

						var enableCullFace = false;
						var enableDepthTest = false;
						var enableBlend = false;

						for ( var i = 0, il = enables.length; i < il; i ++ ) {

							var enable = enables[ i ];

M
Mr.doob 已提交
1341
							switch ( STATES_ENABLES[ enable ] ) {
1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387

								case 'CULL_FACE':

									enableCullFace = true;

									break;

								case 'DEPTH_TEST':

									enableDepthTest = true;

									break;

								case 'BLEND':

									enableBlend = true;

									break;

								// TODO: implement
								case 'SCISSOR_TEST':
								case 'POLYGON_OFFSET_FILL':
								case 'SAMPLE_ALPHA_TO_COVERAGE':

									break;

								default:

									throw new Error( "Unknown technique.states.enable: " + enable );

							}

						}

						if ( enableCullFace ) {

							materialParams.side = functions.cullFace !== undefined ? WEBGL_SIDES[ functions.cullFace ] : THREE.FrontSide;

						} else {

							materialParams.side = THREE.DoubleSide;

						}

						materialParams.depthTest = enableDepthTest;
						materialParams.depthFunc = functions.depthFunc !== undefined ? WEBGL_DEPTH_FUNCS[ functions.depthFunc ] : THREE.LessDepth;
1388
						materialParams.depthWrite = functions.depthMask !== undefined ? functions.depthMask[ 0 ] : true;
1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424

						materialParams.blending = enableBlend ? THREE.CustomBlending : THREE.NoBlending;
						materialParams.transparent = enableBlend;

						var blendEquationSeparate = functions.blendEquationSeparate;

						if ( blendEquationSeparate !== undefined ) {

							materialParams.blendEquation = WEBGL_BLEND_EQUATIONS[ blendEquationSeparate[ 0 ] ];
							materialParams.blendEquationAlpha = WEBGL_BLEND_EQUATIONS[ blendEquationSeparate[ 1 ] ];

						} else {

							materialParams.blendEquation = THREE.AddEquation;
							materialParams.blendEquationAlpha = THREE.AddEquation;

						}

						var blendFuncSeparate = functions.blendFuncSeparate;

						if ( blendFuncSeparate !== undefined ) {

							materialParams.blendSrc = WEBGL_BLEND_FUNCS[ blendFuncSeparate[ 0 ] ];
							materialParams.blendDst = WEBGL_BLEND_FUNCS[ blendFuncSeparate[ 1 ] ];
							materialParams.blendSrcAlpha = WEBGL_BLEND_FUNCS[ blendFuncSeparate[ 2 ] ];
							materialParams.blendDstAlpha = WEBGL_BLEND_FUNCS[ blendFuncSeparate[ 3 ] ];

						} else {

							materialParams.blendSrc = THREE.OneFactor;
							materialParams.blendDst = THREE.ZeroFactor;
							materialParams.blendSrcAlpha = THREE.OneFactor;
							materialParams.blendDstAlpha = THREE.ZeroFactor;

						}

M
Mr.doob 已提交
1425
					}
R
Rich Tibbett 已提交
1426 1427 1428

				}

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

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

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

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

M
Mr.doob 已提交
1437
				}
R
Rich Tibbett 已提交
1438

M
Mr.doob 已提交
1439
				delete materialParams.diffuse;
R
Rich Tibbett 已提交
1440

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

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

M
Mr.doob 已提交
1445
				}
R
Rich Tibbett 已提交
1446

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

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

M
Mr.doob 已提交
1451
				}
R
Rich Tibbett 已提交
1452

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

1455 1456 1457 1458 1459 1460 1461 1462 1463
					if ( materialType === THREE.MeshBasicMaterial ) {

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

					} else {

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

					}
R
Rich Tibbett 已提交
1464

1465 1466
				} else if ( typeof( materialValues.emission ) === 'string' ) {

1467
					if ( materialType === THREE.MeshBasicMaterial ) {
1468

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

1471 1472 1473 1474 1475 1476 1477
					} else {

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

					}

				}
1478

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

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

1483 1484 1485 1486
				} else if ( typeof( materialValues.specular ) === 'string' ) {

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

1487
				}
1488

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

M
Mr.doob 已提交
1491
					materialParams.shininess = materialValues.shininess;
R
Rich Tibbett 已提交
1492

M
Mr.doob 已提交
1493
				}
R
Rich Tibbett 已提交
1494

M
Mr.doob 已提交
1495
				var _material = new materialType( materialParams );
1496
				if ( material.name !== undefined ) _material.name = material.name;
R
Rich Tibbett 已提交
1497

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

M
Mr.doob 已提交
1500
			} );
R
Rich Tibbett 已提交
1501

M
Mr.doob 已提交
1502
		} );
R
Rich Tibbett 已提交
1503

M
Mr.doob 已提交
1504
	};
R
Rich Tibbett 已提交
1505

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

M
Mr.doob 已提交
1508 1509
		var json = this.json;

M
Mr.doob 已提交
1510
		return this._withDependencies( [
R
Rich Tibbett 已提交
1511

M
Mr.doob 已提交
1512 1513
			"accessors",
			"materials"
R
Rich Tibbett 已提交
1514

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

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

M
Mr.doob 已提交
1519
				var group = new THREE.Object3D();
1520
				if ( mesh.name !== undefined ) group.name = mesh.name;
1521 1522

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

M
Mr.doob 已提交
1524
				var primitives = mesh.primitives;
R
Rich Tibbett 已提交
1525

M
Mr.doob 已提交
1526 1527 1528
				for ( var name in primitives ) {

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

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

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

M
Mr.doob 已提交
1534
						var attributes = primitive.attributes;
R
Rich Tibbett 已提交
1535

M
Mr.doob 已提交
1536 1537 1538
						for ( var attributeId in attributes ) {

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

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

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

M
Mr.doob 已提交
1544
							switch ( attributeId ) {
R
Rich Tibbett 已提交
1545

M
Mr.doob 已提交
1546 1547 1548
								case 'POSITION':
									geometry.addAttribute( 'position', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1549

M
Mr.doob 已提交
1550 1551 1552
								case 'NORMAL':
									geometry.addAttribute( 'normal', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1553

M
Mr.doob 已提交
1554 1555 1556 1557 1558
								case 'TEXCOORD_0':
								case 'TEXCOORD0':
								case 'TEXCOORD':
									geometry.addAttribute( 'uv', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1559

1560 1561 1562 1563 1564
								case 'COLOR_0':
								case 'COLOR0':
								case 'COLOR':
									geometry.addAttribute( 'color', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1565

M
Mr.doob 已提交
1566 1567 1568
								case 'WEIGHT':
									geometry.addAttribute( 'skinWeight', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1569

M
Mr.doob 已提交
1570 1571 1572
								case 'JOINT':
									geometry.addAttribute( 'skinIndex', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1573

M
Mr.doob 已提交
1574
							}
R
Rich Tibbett 已提交
1575

M
Mr.doob 已提交
1576
						}
R
Rich Tibbett 已提交
1577

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

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

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

1584
						var material = dependencies.materials !== undefined ? dependencies.materials[ primitive.material ] : createDefaultMaterial();
R
Rich Tibbett 已提交
1585

M
Mr.doob 已提交
1586 1587
						var meshNode = new THREE.Mesh( geometry, material );
						meshNode.castShadow = true;
A
Al McElrath 已提交
1588
						meshNode.name = ( name === "0" ? group.name : group.name + name );
M
Mr.doob 已提交
1589

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

1592 1593
						group.add( meshNode );

M
Mr.doob 已提交
1594
					} else if ( primitive.mode === WEBGL_CONSTANTS.LINES ) {
1595 1596 1597 1598 1599

						var geometry = new THREE.BufferGeometry();

						var attributes = primitive.attributes;

B
bdysvik 已提交
1600

1601 1602 1603
						for ( var attributeId in attributes ) {

							var attributeEntry = attributes[ attributeId ];
1604

M
Mr.doob 已提交
1605
							if ( ! attributeEntry ) return;
1606 1607 1608 1609 1610 1611 1612 1613

							var bufferAttribute = dependencies.accessors[ attributeEntry ];

							switch ( attributeId ) {

								case 'POSITION':
									geometry.addAttribute( 'position', bufferAttribute );
									break;
1614

1615 1616
								case 'COLOR_0':
								case 'COLOR0':
1617
								case 'COLOR':
M
Mr.doob 已提交
1618 1619 1620
									geometry.addAttribute( 'color', bufferAttribute );
									break;

1621
							}
M
Mr.doob 已提交
1622 1623

						}
M
Mr.doob 已提交
1624 1625 1626 1627

						var material = dependencies.materials[ primitive.material ];

						var meshNode;
1628 1629 1630

						if ( primitive.indices ) {

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

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

M
Mr.doob 已提交
1635
						} else {
1636

M
Mr.doob 已提交
1637
							meshNode = new THREE.Line( geometry, material );
1638 1639 1640

						}

A
Al McElrath 已提交
1641 1642
						meshNode.name = ( name === "0" ? group.name : group.name + name );

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

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

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

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

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

M
Mr.doob 已提交
1653
				}
R
Rich Tibbett 已提交
1654

M
Mr.doob 已提交
1655
				return group;
R
Rich Tibbett 已提交
1656

M
Mr.doob 已提交
1657
			} );
R
Rich Tibbett 已提交
1658

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

M
Mr.doob 已提交
1661
	};
R
Rich Tibbett 已提交
1662

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

M
Mr.doob 已提交
1665 1666 1667
		var json = this.json;

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

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

M
Mr.doob 已提交
1671 1672 1673
				var yfov = camera.perspective.yfov;
				var xfov = camera.perspective.xfov;
				var aspect_ratio = camera.perspective.aspect_ratio || 1;
R
Rich Tibbett 已提交
1674

M
Mr.doob 已提交
1675 1676 1677
				// According to COLLADA spec...
				// aspect_ratio = xfov / yfov
				xfov = ( xfov === undefined && yfov ) ? yfov * aspect_ratio : xfov;
R
Rich Tibbett 已提交
1678

M
Mr.doob 已提交
1679 1680 1681
				// According to COLLADA spec...
				// aspect_ratio = xfov / yfov
				// yfov = ( yfov === undefined && xfov ) ? xfov / aspect_ratio : yfov;
R
Rich Tibbett 已提交
1682

M
Mr.doob 已提交
1683
				var _camera = new THREE.PerspectiveCamera( THREE.Math.radToDeg( xfov ), aspect_ratio, camera.perspective.znear || 1, camera.perspective.zfar || 2e6 );
1684
				if ( camera.name !== undefined ) _camera.name = camera.name;
1685 1686

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

M
Mr.doob 已提交
1688
				return _camera;
R
Rich Tibbett 已提交
1689

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

M
Mr.doob 已提交
1692
				var _camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, camera.orthographic.znear, camera.orthographic.zfar );
1693
				if ( camera.name !== undefined ) _camera.name = camera.name;
1694 1695

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

M
Mr.doob 已提交
1697
				return _camera;
R
Rich Tibbett 已提交
1698

M
Mr.doob 已提交
1699
			}
R
Rich Tibbett 已提交
1700

M
Mr.doob 已提交
1701
		} );
R
Rich Tibbett 已提交
1702

M
Mr.doob 已提交
1703
	};
R
Rich Tibbett 已提交
1704

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

M
Mr.doob 已提交
1707
		var json = this.json;
R
Rich Tibbett 已提交
1708

M
Mr.doob 已提交
1709
		return this._withDependencies( [
R
Rich Tibbett 已提交
1710

M
Mr.doob 已提交
1711
			"accessors"
R
Rich Tibbett 已提交
1712

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

M
Mr.doob 已提交
1715
			return _each( json.skins, function ( skin ) {
M
Mr.doob 已提交
1716 1717 1718 1719 1720 1721 1722 1723 1724 1725

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

				return _skin;

			} );
R
Rich Tibbett 已提交
1726

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

M
Mr.doob 已提交
1729 1730
	};

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

M
Mr.doob 已提交
1733
		var json = this.json;
R
Rich Tibbett 已提交
1734

M
Mr.doob 已提交
1735
		return this._withDependencies( [
R
Rich Tibbett 已提交
1736

M
Mr.doob 已提交
1737 1738
			"accessors",
			"nodes"
R
Rich Tibbett 已提交
1739

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

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

D
Don McCurdy 已提交
1744
				var tracks = [];
R
Rich Tibbett 已提交
1745

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

M
Mr.doob 已提交
1748
					var channel = animation.channels[ channelId ];
M
Mr.doob 已提交
1749 1750
					var sampler = animation.samplers[ channel.sampler ];

1751
					if ( sampler ) {
R
Rich Tibbett 已提交
1752 1753 1754

						var target = channel.target;
						var name = target.id;
1755 1756
						var input = animation.parameters !== undefined ? animation.parameters[ sampler.input ] : sampler.input;
						var output = animation.parameters !== undefined ? animation.parameters[ sampler.output ] : sampler.output;
R
Rich Tibbett 已提交
1757 1758 1759 1760 1761 1762 1763 1764

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

						var node = dependencies.nodes[ name ];

						if ( node ) {

D
Don McCurdy 已提交
1765 1766 1767 1768 1769 1770
							node.updateMatrix();
							node.matrixAutoUpdate = true;

							var TypedKeyframeTrack = PATH_PROPERTIES[ target.path ] === PATH_PROPERTIES.rotation
								? THREE.QuaternionKeyframeTrack
								: THREE.VectorKeyframeTrack;
1771

1772
							var targetName = node.name ? node.name : node.uuid;
R
Rich Tibbett 已提交
1773

D
Don McCurdy 已提交
1774 1775 1776 1777
							// 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(
1778
								targetName + '.' + PATH_PROPERTIES[ target.path ],
D
Don McCurdy 已提交
1779 1780 1781 1782
								THREE.AnimationUtils.arraySlice( inputAccessor.array, 0 ),
								THREE.AnimationUtils.arraySlice( outputAccessor.array, 0 ),
								INTERPOLATION[ sampler.interpolation ]
							) );
R
Rich Tibbett 已提交
1783 1784 1785

						}

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

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

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

M
Mr.doob 已提交
1792
			} );
R
Rich Tibbett 已提交
1793

M
Mr.doob 已提交
1794
		} );
R
Rich Tibbett 已提交
1795

M
Mr.doob 已提交
1796
	};
R
Rich Tibbett 已提交
1797

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

M
Mr.doob 已提交
1800
		var json = this.json;
1801
		var extensions = this.extensions;
M
Mr.doob 已提交
1802 1803 1804
		var scope = this;

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

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

M
Mr.doob 已提交
1808
			var _node;
R
Rich Tibbett 已提交
1809

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

M
Mr.doob 已提交
1812
				_node = new THREE.Bone();
1813
				_node.name = node.name !== undefined ? node.name : node.jointName;
M
Mr.doob 已提交
1814
				_node.jointName = node.jointName;
R
Rich Tibbett 已提交
1815

M
Mr.doob 已提交
1816
			} else {
R
Rich Tibbett 已提交
1817

M
Mr.doob 已提交
1818
				_node = new THREE.Object3D();
1819
				if ( node.name !== undefined ) _node.name = node.name;
R
Rich Tibbett 已提交
1820

M
Mr.doob 已提交
1821
			}
R
Rich Tibbett 已提交
1822

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

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

M
Mr.doob 已提交
1827 1828
				matrix.fromArray( node.matrix );
				_node.applyMatrix( matrix );
R
Rich Tibbett 已提交
1829

M
Mr.doob 已提交
1830
			} else {
R
Rich Tibbett 已提交
1831

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

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

M
Mr.doob 已提交
1836
				}
R
Rich Tibbett 已提交
1837

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

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

M
Mr.doob 已提交
1842 1843 1844
				}

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

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

M
Mr.doob 已提交
1848
				}
R
Rich Tibbett 已提交
1849 1850 1851

			}

M
Mr.doob 已提交
1852
			return _node;
R
Rich Tibbett 已提交
1853

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

M
Mr.doob 已提交
1856
			return scope._withDependencies( [
R
Rich Tibbett 已提交
1857

M
Mr.doob 已提交
1858 1859
				"meshes",
				"skins",
1860
				"cameras"
R
Rich Tibbett 已提交
1861

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

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

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

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

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

M
Mr.doob 已提交
1872 1873
							var mesh = node.meshes[ meshId ];
							var group = dependencies.meshes[ mesh ];
R
Rich Tibbett 已提交
1874

1875 1876 1877 1878 1879 1880 1881
							if ( group === undefined ) {

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

							}

M
Mr.doob 已提交
1882 1883 1884
							for ( var childrenId in group.children ) {

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

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

M
Mr.doob 已提交
1888 1889
								var originalMaterial = child.material;
								var originalGeometry = child.geometry;
1890
								var originalUserData = child.userData;
A
Al McElrath 已提交
1891
								var originalName = child.name;
R
Rich Tibbett 已提交
1892

M
Mr.doob 已提交
1893
								var material;
R
Rich Tibbett 已提交
1894

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

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

M
Mr.doob 已提交
1899
								} else {
R
Rich Tibbett 已提交
1900

M
Mr.doob 已提交
1901
									material = originalMaterial;
R
Rich Tibbett 已提交
1902

M
Mr.doob 已提交
1903
								}
M
Mr.doob 已提交
1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917

								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 );

1918
								}
M
Mr.doob 已提交
1919

M
Mr.doob 已提交
1920
								child.castShadow = true;
1921
								child.userData = originalUserData;
A
Al McElrath 已提交
1922
								child.name = originalName;
R
Rich Tibbett 已提交
1923

M
Mr.doob 已提交
1924
								var skinEntry;
M
Mr.doob 已提交
1925

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

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

M
Mr.doob 已提交
1930
								}
R
Rich Tibbett 已提交
1931

M
Mr.doob 已提交
1932 1933
								// Replace Mesh with SkinnedMesh in library
								if ( skinEntry ) {
R
Rich Tibbett 已提交
1934

1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948
									var getJointNode = function ( jointId ) {

										var keys = Object.keys( __nodes );

										for ( var i = 0, il = keys.length; i < il; i ++ ) {

											var n = __nodes[ keys[ i ] ];

											if ( n.jointName === jointId ) return n;

										}

										return null;

M
Mr.doob 已提交
1949
									};
1950

M
Mr.doob 已提交
1951 1952 1953
									var geometry = originalGeometry;
									var material = originalMaterial;
									material.skinning = true;
R
Rich Tibbett 已提交
1954

M
Mr.doob 已提交
1955 1956
									child = new THREE.SkinnedMesh( geometry, material, false );
									child.castShadow = true;
1957
									child.userData = originalUserData;
A
Al McElrath 已提交
1958
									child.name = originalName;
R
Rich Tibbett 已提交
1959

M
Mr.doob 已提交
1960 1961
									var bones = [];
									var boneInverses = [];
R
Rich Tibbett 已提交
1962

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

M
Mr.doob 已提交
1965
										var jointId = skinEntry.jointNames[ i ];
1966
										var jointNode = getJointNode( jointId );
R
Rich Tibbett 已提交
1967

M
Mr.doob 已提交
1968
										if ( jointNode ) {
R
Rich Tibbett 已提交
1969

M
Mr.doob 已提交
1970
											bones.push( jointNode );
R
Rich Tibbett 已提交
1971

M
Mr.doob 已提交
1972 1973 1974
											var m = skinEntry.inverseBindMatrices.array;
											var mat = new THREE.Matrix4().fromArray( m, i * 16 );
											boneInverses.push( mat );
R
Rich Tibbett 已提交
1975

M
Mr.doob 已提交
1976
										} else {
R
Rich Tibbett 已提交
1977

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

M
Mr.doob 已提交
1980
										}
R
Rich Tibbett 已提交
1981

M
Mr.doob 已提交
1982
									}
R
Rich Tibbett 已提交
1983

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

T
Takahiro 已提交
1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006
									var buildBoneGraph = function ( parentJson, parentObject, property ) {

										var children = parentJson[ property ];

										if ( children === undefined ) return;

										for ( var i = 0, il = children.length; i < il; i ++ ) {

											var nodeId = children[ i ];
											var bone = __nodes[ nodeId ];
											var boneJson = json.nodes[ nodeId ];

											if ( bone !== undefined && bone.isBone === true && boneJson !== undefined ) {

												parentObject.add( bone );
												buildBoneGraph( boneJson, bone, 'children' );

											}

										}

M
Mr.doob 已提交
2007
									};
T
Takahiro 已提交
2008 2009 2010

									buildBoneGraph( node, child, 'skeletons' );

M
Mr.doob 已提交
2011
								}
R
Rich Tibbett 已提交
2012

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

M
Mr.doob 已提交
2015
							}
R
Rich Tibbett 已提交
2016

M
Mr.doob 已提交
2017
						}
R
Rich Tibbett 已提交
2018

M
Mr.doob 已提交
2019
					}
R
Rich Tibbett 已提交
2020

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

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

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

M
Mr.doob 已提交
2027
					}
R
Rich Tibbett 已提交
2028

2029 2030 2031
					if ( node.extensions
							 && node.extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ]
							 && node.extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ].light ) {
R
Rich Tibbett 已提交
2032

2033 2034
						var extensionLights = extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ].lights;
						var light = extensionLights[ node.extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ].light ];
R
Rich Tibbett 已提交
2035

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

M
Mr.doob 已提交
2038
					}
R
Rich Tibbett 已提交
2039

M
Mr.doob 已提交
2040
					return _node;
R
Rich Tibbett 已提交
2041

M
Mr.doob 已提交
2042
				} );
R
Rich Tibbett 已提交
2043

M
Mr.doob 已提交
2044
			} );
R
Rich Tibbett 已提交
2045

M
Mr.doob 已提交
2046
		} );
R
Rich Tibbett 已提交
2047

M
Mr.doob 已提交
2048
	};
R
Rich Tibbett 已提交
2049

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

M
Mr.doob 已提交
2052
		var json = this.json;
M
Mr.doob 已提交
2053 2054 2055 2056 2057 2058 2059 2060

		// scene node hierachy builder

		function buildNodeHierachy( nodeId, parentObject, allNodes ) {

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

M
Mr.doob 已提交
2061
			var node = json.nodes[ nodeId ];
M
Mr.doob 已提交
2062 2063 2064

			if ( node.children ) {

M
Mr.doob 已提交
2065 2066 2067
				var children = node.children;

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

M
Mr.doob 已提交
2069
					var child = children[ i ];
M
Mr.doob 已提交
2070 2071
					buildNodeHierachy( child, _node, allNodes );

M
Mr.doob 已提交
2072
				}
M
Mr.doob 已提交
2073 2074

			}
R
Rich Tibbett 已提交
2075 2076 2077

		}

M
Mr.doob 已提交
2078
		return this._withDependencies( [
R
Rich Tibbett 已提交
2079

M
Mr.doob 已提交
2080
			"nodes"
R
Rich Tibbett 已提交
2081

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

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

M
Mr.doob 已提交
2086
				var _scene = new THREE.Scene();
2087
				if ( scene.name !== undefined ) _scene.name = scene.name;
2088 2089

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

M
Mr.doob 已提交
2091
				var nodes = scene.nodes;
R
Rich Tibbett 已提交
2092

M
Mr.doob 已提交
2093 2094 2095
				for ( var i = 0, l = nodes.length; i < l; i ++ ) {

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

M
Mr.doob 已提交
2098
				}
R
Rich Tibbett 已提交
2099

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

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

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

M
Mr.doob 已提交
2108 2109 2110 2111 2112 2113 2114
					}

				} );

				return _scene;

			} );
R
Rich Tibbett 已提交
2115

M
Mr.doob 已提交
2116 2117 2118
		} );

	};
R
Rich Tibbett 已提交
2119

M
Mr.doob 已提交
2120
	return GLTFLoader;
R
Rich Tibbett 已提交
2121

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