GLTFLoader.js 46.0 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
	var WEBGL_TEXTURE_FORMATS = {
		6406: THREE.AlphaFormat,
		6407: THREE.RGBFormat,
		6408: THREE.RGBAFormat,
		6409: THREE.LuminanceFormat,
		6410: THREE.LuminanceAlphaFormat
	};

474
	var WEBGL_TEXTURE_DATATYPES = {
475 476 477 478 479 480
		5121: THREE.UnsignedByteType,
		32819: THREE.UnsignedShort4444Type,
		32820: THREE.UnsignedShort5551Type,
		33635: THREE.UnsignedShort565Type
	};

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 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
	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 已提交
523 524 525 526 527 528 529 530 531 532
	var WEBGL_TYPE_SIZES = {
		'SCALAR': 1,
		'VEC2': 2,
		'VEC3': 3,
		'VEC4': 4,
		'MAT2': 4,
		'MAT3': 9,
		'MAT4': 16
	};

533 534 535 536 537 538 539
	var PATH_PROPERTIES = {
		scale: 'scale',
		translation: 'position',
		rotation: 'quaternion'
	};

	var INTERPOLATION = {
540 541
		LINEAR: THREE.InterpolateLinear,
		STEP: THREE.InterpolateDiscrete
542 543
	};

544 545 546 547 548 549 550 551 552
	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 已提交
553 554 555 556 557 558
	/* UTILITY FUNCTIONS */

	function _each( object, callback, thisObj ) {

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

M
Mr.doob 已提交
561 562 563 564
		var results;
		var fns = [];

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

M
Mr.doob 已提交
566
			results = [];
R
Rich Tibbett 已提交
567

M
Mr.doob 已提交
568 569 570
			var length = object.length;
			for ( var idx = 0; idx < length; idx ++ ) {
				var value = callback.call( thisObj || this, object[ idx ], idx );
R
Rich Tibbett 已提交
571 572 573 574
				if ( value ) {
					fns.push( value );
					if ( value instanceof Promise ) {
						value.then( function( key, value ) {
M
Mr.doob 已提交
575
							results[ idx ] = value;
R
Rich Tibbett 已提交
576 577
						}.bind( this, key ));
					} else {
M
Mr.doob 已提交
578
						results[ idx ] = value;
R
Rich Tibbett 已提交
579 580
					}
				}
581
			}
R
Rich Tibbett 已提交
582

M
Mr.doob 已提交
583
		} else {
R
Rich Tibbett 已提交
584

M
Mr.doob 已提交
585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601
			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 已提交
602

M
Mr.doob 已提交
603
		}
R
Rich Tibbett 已提交
604

M
Mr.doob 已提交
605 606 607
		return Promise.all( fns ).then( function() {
			return results;
		});
R
Rich Tibbett 已提交
608 609 610

	}

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

M
Mr.doob 已提交
613 614 615
		// Invalid URL
		if ( typeof url !== 'string' || url === '' )
			return '';
616

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

M
Mr.doob 已提交
620
			return url;
R
Rich Tibbett 已提交
621

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

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

M
Mr.doob 已提交
627
			return url;
R
Rich Tibbett 已提交
628

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

M
Mr.doob 已提交
631 632
		// Relative URL
		return ( path || '' ) + url;
R
Rich Tibbett 已提交
633

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

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

640 641
		var s = '';

M
Mr.doob 已提交
642
		for ( var i = 0; i < array.length; i ++ ) {
643 644 645 646 647 648

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

		}

		return s;
M
Mr.doob 已提交
649

650 651
	}

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

M
Mr.doob 已提交
656 657
		// Expected technique attributes
		var attributes = {};
R
Rich Tibbett 已提交
658

M
Mr.doob 已提交
659 660 661
		for ( var attributeId in technique.attributes ) {

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

M
Mr.doob 已提交
663 664 665
			var param = technique.parameters[ pname ];
			var atype = param.type;
			var semantic = param.semantic;
R
Rich Tibbett 已提交
666

M
Mr.doob 已提交
667 668 669 670
			attributes[ attributeId ] = {
				type: atype,
				semantic: semantic
			};
671

M
Mr.doob 已提交
672
		}
673

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

M
Mr.doob 已提交
676 677 678
		var shaderParams = technique.parameters;
		var shaderAttributes = technique.attributes;
		var params = {};
679

M
Mr.doob 已提交
680
		for ( var attributeId in attributes ) {
681

M
Mr.doob 已提交
682 683 684 685
			var pname = shaderAttributes[ attributeId ];
			var shaderParam = shaderParams[ pname ];
			var semantic = shaderParam.semantic;
			if ( semantic ) {
686

M
Mr.doob 已提交
687
				params[ attributeId ] = shaderParam;
688

M
Mr.doob 已提交
689
			}
R
Rich Tibbett 已提交
690

M
Mr.doob 已提交
691
		}
R
Rich Tibbett 已提交
692

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

M
Mr.doob 已提交
695
			var param = params[ pname ];
M
Mr.doob 已提交
696
			var semantic = param.semantic;
R
Rich Tibbett 已提交
697

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

M
Mr.doob 已提交
700
			switch ( semantic ) {
R
Rich Tibbett 已提交
701

M
Mr.doob 已提交
702
				case "POSITION":
R
Rich Tibbett 已提交
703

M
Mr.doob 已提交
704 705
					shaderText = shaderText.replace( regEx, 'position' );
					break;
R
Rich Tibbett 已提交
706

M
Mr.doob 已提交
707
				case "NORMAL":
R
Rich Tibbett 已提交
708

M
Mr.doob 已提交
709 710
					shaderText = shaderText.replace( regEx, 'normal' );
					break;
711

M
Mr.doob 已提交
712 713 714
				case 'TEXCOORD_0':
				case 'TEXCOORD0':
				case 'TEXCOORD':
715

M
Mr.doob 已提交
716 717
					shaderText = shaderText.replace( regEx, 'uv' );
					break;
718

719 720 721 722 723 724 725
				case 'COLOR_0':
				case 'COLOR0':
				case 'COLOR':

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

M
Mr.doob 已提交
726
				case "WEIGHT":
727

M
Mr.doob 已提交
728 729
					shaderText = shaderText.replace( regEx, 'skinWeight' );
					break;
730

M
Mr.doob 已提交
731
				case "JOINT":
732

M
Mr.doob 已提交
733 734
					shaderText = shaderText.replace( regEx, 'skinIndex' );
					break;
735

M
Mr.doob 已提交
736
			}
737

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

M
Mr.doob 已提交
740
		return shaderText;
741

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

T
Takahiro 已提交
744 745 746 747 748 749 750 751 752 753 754 755
	function createDefaultMaterial() {

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

M
Mr.doob 已提交
756
	}
T
Takahiro 已提交
757

M
Mr.doob 已提交
758 759
	// Deferred constructor for RawShaderMaterial types
	function DeferredShaderMaterial( params ) {
R
Rich Tibbett 已提交
760

M
Mr.doob 已提交
761
		this.isDeferredShaderMaterial = true;
R
Rich Tibbett 已提交
762

M
Mr.doob 已提交
763
		this.params = params;
764

M
Mr.doob 已提交
765
	}
766

M
Mr.doob 已提交
767
	DeferredShaderMaterial.prototype.create = function () {
768

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

M
Mr.doob 已提交
771 772 773
		for ( var uniformId in this.params.uniforms ) {

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

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

M
Mr.doob 已提交
777 778
				uniforms[ uniformId ].value = originalUniform.value;
				uniforms[ uniformId ].value.needsUpdate = true;
R
Rich Tibbett 已提交
779

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

M
Mr.doob 已提交
782 783
			uniforms[ uniformId ].semantic = originalUniform.semantic;
			uniforms[ uniformId ].node = originalUniform.node;
R
Rich Tibbett 已提交
784

M
Mr.doob 已提交
785
		}
R
Rich Tibbett 已提交
786

M
Mr.doob 已提交
787
		this.params.uniforms = uniforms;
R
Rich Tibbett 已提交
788

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

M
Mr.doob 已提交
791
	};
R
Rich Tibbett 已提交
792

M
Mr.doob 已提交
793
	/* GLTF PARSER */
R
Rich Tibbett 已提交
794

795
	function GLTFParser( json, extensions, options ) {
R
Rich Tibbett 已提交
796

M
Mr.doob 已提交
797
		this.json = json || {};
798
		this.extensions = extensions || {};
M
Mr.doob 已提交
799
		this.options = options || {};
R
Rich Tibbett 已提交
800

M
Mr.doob 已提交
801 802
		// loader object cache
		this.cache = new GLTFRegistry();
R
Rich Tibbett 已提交
803

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

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

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

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

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

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

M
Mr.doob 已提交
817
			if ( cached !== undefined ) {
818

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

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

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

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

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

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

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

M
Mr.doob 已提交
834
			return dependency;
R
Rich Tibbett 已提交
835

M
Mr.doob 已提交
836
		} );
R
Rich Tibbett 已提交
837

M
Mr.doob 已提交
838
	};
R
Rich Tibbett 已提交
839

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

M
Mr.doob 已提交
842 843
		var json = this.json;

M
Mr.doob 已提交
844 845
		// Clear the loader cache
		this.cache.removeAll();
R
Rich Tibbett 已提交
846

M
Mr.doob 已提交
847 848
		// Fire the callback on complete
		this._withDependencies( [
R
Rich Tibbett 已提交
849

M
Mr.doob 已提交
850 851
			"scenes",
			"cameras",
852
			"animations"
R
Rich Tibbett 已提交
853

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

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

T
Takahiro 已提交
858 859 860 861 862 863 864 865
			var scenes = [];

			for ( var name in dependencies.scenes ) {

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

			}

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

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

M
Mr.doob 已提交
870
				var camera = dependencies.cameras[ name ];
M
Mr.doob 已提交
871
				cameras.push( camera );
R
Rich Tibbett 已提交
872

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

875
			var animations = [];
R
Rich Tibbett 已提交
876

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

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

M
Mr.doob 已提交
881
			}
R
Rich Tibbett 已提交
882

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

M
Mr.doob 已提交
885
		} );
R
Rich Tibbett 已提交
886

M
Mr.doob 已提交
887
	};
R
Rich Tibbett 已提交
888

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

M
Mr.doob 已提交
891
		var json = this.json;
892
		var extensions = this.extensions;
M
Mr.doob 已提交
893 894
		var options = this.options;

895 896 897 898 899 900 901 902 903 904 905 906 907 908 909
		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 已提交
910

911 912 913
					var loader = new THREE.FileLoader();
					loader.setResponseType( 'text' );
					loader.load( resolveURL( shader.uri, options.path ), function ( shaderText ) {
R
Rich Tibbett 已提交
914

915
						resolve( shaderText );
R
Rich Tibbett 已提交
916

917
					} );
R
Rich Tibbett 已提交
918 919 920

				} );

M
Mr.doob 已提交
921
			} );
R
Rich Tibbett 已提交
922

M
Mr.doob 已提交
923
		} );
R
Rich Tibbett 已提交
924

M
Mr.doob 已提交
925
	};
R
Rich Tibbett 已提交
926

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

M
Mr.doob 已提交
929
		var json = this.json;
930
		var extensions = this.extensions;
M
Mr.doob 已提交
931 932
		var options = this.options;

933 934 935 936 937 938 939
		return _each( json.buffers, function ( buffer, name ) {

			if ( name === BINARY_EXTENSION_BUFFER_NAME ) {

				return extensions[ EXTENSIONS.KHR_BINARY_GLTF ].body;

			}
R
Rich Tibbett 已提交
940

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

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

M
Mr.doob 已提交
945
					var loader = new THREE.FileLoader();
946
					loader.setResponseType( 'arraybuffer' );
M
Mr.doob 已提交
947
					loader.load( resolveURL( buffer.uri, options.path ), function ( buffer ) {
R
Rich Tibbett 已提交
948

M
Mr.doob 已提交
949
						resolve( buffer );
R
Rich Tibbett 已提交
950

M
Mr.doob 已提交
951
					} );
R
Rich Tibbett 已提交
952

M
Mr.doob 已提交
953
				} );
R
Rich Tibbett 已提交
954

T
Takahiro 已提交
955 956 957 958
			} else {

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

M
Mr.doob 已提交
959
			}
R
Rich Tibbett 已提交
960

M
Mr.doob 已提交
961
		} );
R
Rich Tibbett 已提交
962

M
Mr.doob 已提交
963
	};
R
Rich Tibbett 已提交
964

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

M
Mr.doob 已提交
967 968
		var json = this.json;

M
Mr.doob 已提交
969
		return this._withDependencies( [
R
Rich Tibbett 已提交
970

M
Mr.doob 已提交
971
			"buffers"
R
Rich Tibbett 已提交
972

M
Mr.doob 已提交
973
		] ).then( function ( dependencies ) {
974

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

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

979 980 981
				var byteLength = bufferView.byteLength !== undefined ? bufferView.byteLength : 0;

				return arraybuffer.slice( bufferView.byteOffset, bufferView.byteOffset + byteLength );
982

M
Mr.doob 已提交
983
			} );
984

M
Mr.doob 已提交
985
		} );
986

M
Mr.doob 已提交
987
	};
988

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

M
Mr.doob 已提交
991 992
		var json = this.json;

M
Mr.doob 已提交
993 994 995 996 997
		return this._withDependencies( [

			"bufferViews"

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

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

M
Mr.doob 已提交
1001 1002 1003
				var arraybuffer = dependencies.bufferViews[ accessor.bufferView ];
				var itemSize = WEBGL_TYPE_SIZES[ accessor.type ];
				var TypedArray = WEBGL_COMPONENT_TYPES[ accessor.componentType ];
R
Rich Tibbett 已提交
1004

M
Mr.doob 已提交
1005 1006 1007
				// For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.
				var elementBytes = TypedArray.BYTES_PER_ELEMENT;
				var itemBytes = elementBytes * itemSize;
R
Rich Tibbett 已提交
1008

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

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

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

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

M
Mr.doob 已提交
1020 1021 1022
				} else {

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

M
Mr.doob 已提交
1024
					return new THREE.BufferAttribute( array, itemSize );
R
Rich Tibbett 已提交
1025 1026 1027

				}

M
Mr.doob 已提交
1028
			} );
R
Rich Tibbett 已提交
1029

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

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

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

M
Mr.doob 已提交
1036
		var json = this.json;
1037
		var extensions = this.extensions;
M
Mr.doob 已提交
1038 1039
		var options = this.options;

1040
		return this._withDependencies( [
R
Rich Tibbett 已提交
1041

1042
			"bufferViews"
R
Rich Tibbett 已提交
1043

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

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

1048
				if ( texture.source ) {
R
Rich Tibbett 已提交
1049

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

1052 1053
						var source = json.images[ texture.source ];
						var sourceUri = source.uri;
R
Rich Tibbett 已提交
1054

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

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

1059
						}
R
Rich Tibbett 已提交
1060

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

1063
						if ( textureLoader === null ) {
R
Rich Tibbett 已提交
1064

1065
							textureLoader = new THREE.TextureLoader();
R
Rich Tibbett 已提交
1066

M
Mr.doob 已提交
1067 1068
						}

1069 1070 1071 1072 1073 1074
						textureLoader.setCrossOrigin( options.crossOrigin );

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

							_texture.flipY = false;

T
Takahiro 已提交
1075 1076
							if ( texture.name !== undefined ) _texture.name = texture.name;

T
Takahiro 已提交
1077 1078 1079 1080 1081 1082 1083 1084 1085
							_texture.format = texture.format !== undefined ? WEBGL_TEXTURE_FORMATS[ texture.format ] : THREE.RGBAFormat;

							if ( texture.internalFormat !== undefined && _texture.format !== WEBGL_TEXTURE_FORMATS[ texture.internalFormat ] ) {

								console.warn( 'THREE.GLTFLoader: Three.js doesn\'t support texture internalFormat which is different from texture format. ' +
								              'internalFormat will be forced to be the same value as format.' );

							}

1086
							_texture.type = texture.type !== undefined ? WEBGL_TEXTURE_DATATYPES[ texture.type ] : THREE.UnsignedByteType;
1087

1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101
							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 已提交
1102

1103
							resolve();
1104

1105
						} );
1106 1107

					} );
R
Rich Tibbett 已提交
1108

1109
				}
R
Rich Tibbett 已提交
1110

1111
			} );
R
Rich Tibbett 已提交
1112

M
Mr.doob 已提交
1113
		} );
R
Rich Tibbett 已提交
1114

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

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

M
Mr.doob 已提交
1119 1120
		var json = this.json;

M
Mr.doob 已提交
1121
		return this._withDependencies( [
R
Rich Tibbett 已提交
1122

M
Mr.doob 已提交
1123 1124
			"shaders",
			"textures"
R
Rich Tibbett 已提交
1125

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

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

M
Mr.doob 已提交
1130 1131 1132
				var materialType;
				var materialValues = {};
				var materialParams = {};
R
Rich Tibbett 已提交
1133

M
Mr.doob 已提交
1134
				var khr_material;
R
Rich Tibbett 已提交
1135

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

1138
					khr_material = material.extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ];
R
Rich Tibbett 已提交
1139 1140 1141

				}

M
Mr.doob 已提交
1142
				if ( khr_material ) {
R
Rich Tibbett 已提交
1143

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

M
Mr.doob 已提交
1146 1147 1148 1149
						case 'BLINN' :
						case 'PHONG' :
							materialType = THREE.MeshPhongMaterial;
							break;
R
Rich Tibbett 已提交
1150

M
Mr.doob 已提交
1151 1152 1153
						case 'LAMBERT' :
							materialType = THREE.MeshLambertMaterial;
							break;
R
Rich Tibbett 已提交
1154

M
Mr.doob 已提交
1155 1156 1157 1158
						case 'CONSTANT' :
						default :
							materialType = THREE.MeshBasicMaterial;
							break;
R
Rich Tibbett 已提交
1159

M
Mr.doob 已提交
1160
					}
R
Rich Tibbett 已提交
1161

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

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

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

M
Mr.doob 已提交
1168
					}
R
Rich Tibbett 已提交
1169

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

M
Mr.doob 已提交
1172 1173
						materialParams.transparent = true;
						materialParams.opacity = ( materialValues.transparency !== undefined ) ? materialValues.transparency : 1;
R
Rich Tibbett 已提交
1174 1175 1176

					}

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

M
Mr.doob 已提交
1179
					materialType = THREE.MeshPhongMaterial;
R
Rich Tibbett 已提交
1180

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

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

M
Mr.doob 已提交
1185
					materialType = DeferredShaderMaterial;
R
Rich Tibbett 已提交
1186

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

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

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

M
Mr.doob 已提交
1193
					if ( program ) {
R
Rich Tibbett 已提交
1194

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

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

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

M
Mr.doob 已提交
1202
						}
R
Rich Tibbett 已提交
1203

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

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

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

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

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

M
Mr.doob 已提交
1216
						var uniforms = technique.uniforms;
R
Rich Tibbett 已提交
1217

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

M
Mr.doob 已提交
1220
							var pname = uniforms[ uniformId ];
M
Mr.doob 已提交
1221
							var shaderParam = technique.parameters[ pname ];
R
Rich Tibbett 已提交
1222

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

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

M
Mr.doob 已提交
1227
								var pcount = shaderParam.count;
1228 1229 1230
								var value;

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

M
Mr.doob 已提交
1232 1233 1234
								var uvalue = new WEBGL_TYPE[ ptype ]();
								var usemantic = shaderParam.semantic;
								var unode = shaderParam.node;
R
Rich Tibbett 已提交
1235

M
Mr.doob 已提交
1236
								switch ( ptype ) {
R
Rich Tibbett 已提交
1237

M
Mr.doob 已提交
1238
									case WEBGL_CONSTANTS.FLOAT:
R
Rich Tibbett 已提交
1239

M
Mr.doob 已提交
1240
										uvalue = shaderParam.value;
R
Rich Tibbett 已提交
1241

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

M
Mr.doob 已提交
1244
											materialParams.transparent = true;
R
Rich Tibbett 已提交
1245

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

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

M
Mr.doob 已提交
1250
											uvalue = value;
R
Rich Tibbett 已提交
1251

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

M
Mr.doob 已提交
1254
										break;
R
Rich Tibbett 已提交
1255

M
Mr.doob 已提交
1256 1257 1258 1259
									case WEBGL_CONSTANTS.FLOAT_VEC2:
									case WEBGL_CONSTANTS.FLOAT_VEC3:
									case WEBGL_CONSTANTS.FLOAT_VEC4:
									case WEBGL_CONSTANTS.FLOAT_MAT3:
R
Rich Tibbett 已提交
1260 1261 1262

										if ( shaderParam && shaderParam.value ) {

M
Mr.doob 已提交
1263
											uvalue.fromArray( shaderParam.value );
R
Rich Tibbett 已提交
1264 1265 1266 1267 1268 1269 1270 1271 1272

										}

										if ( value ) {

											uvalue.fromArray( value );

										}

M
Mr.doob 已提交
1273
										break;
R
Rich Tibbett 已提交
1274

M
Mr.doob 已提交
1275
									case WEBGL_CONSTANTS.FLOAT_MAT2:
R
Rich Tibbett 已提交
1276

M
Mr.doob 已提交
1277 1278 1279
										// what to do?
										console.warn( "FLOAT_MAT2 is not a supported uniform type" );
										break;
R
Rich Tibbett 已提交
1280

M
Mr.doob 已提交
1281
									case WEBGL_CONSTANTS.FLOAT_MAT4:
R
Rich Tibbett 已提交
1282

M
Mr.doob 已提交
1283
										if ( pcount ) {
R
Rich Tibbett 已提交
1284

M
Mr.doob 已提交
1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305
											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 已提交
1306
										} else {
M
Mr.doob 已提交
1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319

											if ( shaderParam && shaderParam.value ) {

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

											}

											if ( value ) {

												uvalue.fromArray( value );

											}
R
Rich Tibbett 已提交
1320 1321 1322

										}

M
Mr.doob 已提交
1323
										break;
R
Rich Tibbett 已提交
1324

M
Mr.doob 已提交
1325
									case WEBGL_CONSTANTS.SAMPLER_2D:
R
Rich Tibbett 已提交
1326

1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339
										if ( value !== undefined ) {

											uvalue = dependencies.textures[ value ];

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

											uvalue = dependencies.textures[ shaderParam.value ];

										} else {

											uvalue = null;

										}
R
Rich Tibbett 已提交
1340

M
Mr.doob 已提交
1341
										break;
R
Rich Tibbett 已提交
1342

M
Mr.doob 已提交
1343
								}
R
Rich Tibbett 已提交
1344

M
Mr.doob 已提交
1345 1346 1347 1348 1349
								materialParams.uniforms[ uniformId ] = {
									value: uvalue,
									semantic: usemantic,
									node: unode
								};
R
Rich Tibbett 已提交
1350

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

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

M
Mr.doob 已提交
1355
							}
R
Rich Tibbett 已提交
1356

M
Mr.doob 已提交
1357
						}
R
Rich Tibbett 已提交
1358

1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370
						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 已提交
1371
							switch ( STATES_ENABLES[ enable ] ) {
1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 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

								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;
1418
						materialParams.depthWrite = functions.depthMask !== undefined ? functions.depthMask[ 0 ] : true;
1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454

						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 已提交
1455
					}
R
Rich Tibbett 已提交
1456 1457 1458

				}

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

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

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

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

M
Mr.doob 已提交
1467
				}
R
Rich Tibbett 已提交
1468

M
Mr.doob 已提交
1469
				delete materialParams.diffuse;
R
Rich Tibbett 已提交
1470

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

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

M
Mr.doob 已提交
1475
				}
R
Rich Tibbett 已提交
1476

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

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

M
Mr.doob 已提交
1481
				}
R
Rich Tibbett 已提交
1482

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

1485 1486 1487 1488 1489 1490 1491 1492 1493
					if ( materialType === THREE.MeshBasicMaterial ) {

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

					} else {

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

					}
R
Rich Tibbett 已提交
1494

1495 1496
				} else if ( typeof( materialValues.emission ) === 'string' ) {

1497
					if ( materialType === THREE.MeshBasicMaterial ) {
1498

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

1501 1502 1503 1504 1505 1506 1507
					} else {

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

					}

				}
1508

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

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

1513 1514 1515 1516
				} else if ( typeof( materialValues.specular ) === 'string' ) {

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

1517
				}
1518

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

M
Mr.doob 已提交
1521
					materialParams.shininess = materialValues.shininess;
R
Rich Tibbett 已提交
1522

M
Mr.doob 已提交
1523
				}
R
Rich Tibbett 已提交
1524

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

M
Mr.doob 已提交
1528
				return _material;
R
Rich Tibbett 已提交
1529

M
Mr.doob 已提交
1530
			} );
R
Rich Tibbett 已提交
1531

M
Mr.doob 已提交
1532
		} );
R
Rich Tibbett 已提交
1533

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

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

M
Mr.doob 已提交
1538 1539
		var json = this.json;

M
Mr.doob 已提交
1540
		return this._withDependencies( [
R
Rich Tibbett 已提交
1541

M
Mr.doob 已提交
1542 1543
			"accessors",
			"materials"
R
Rich Tibbett 已提交
1544

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

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

M
Mr.doob 已提交
1549
				var group = new THREE.Object3D();
1550
				if ( mesh.name !== undefined ) group.name = mesh.name;
1551 1552

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

1554
				var primitives = mesh.primitives || [];
R
Rich Tibbett 已提交
1555

M
Mr.doob 已提交
1556 1557 1558
				for ( var name in primitives ) {

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

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

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

M
Mr.doob 已提交
1564
						var attributes = primitive.attributes;
R
Rich Tibbett 已提交
1565

M
Mr.doob 已提交
1566 1567 1568
						for ( var attributeId in attributes ) {

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

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

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

M
Mr.doob 已提交
1574
							switch ( attributeId ) {
R
Rich Tibbett 已提交
1575

M
Mr.doob 已提交
1576 1577 1578
								case 'POSITION':
									geometry.addAttribute( 'position', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1579

M
Mr.doob 已提交
1580 1581 1582
								case 'NORMAL':
									geometry.addAttribute( 'normal', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1583

M
Mr.doob 已提交
1584 1585 1586 1587 1588
								case 'TEXCOORD_0':
								case 'TEXCOORD0':
								case 'TEXCOORD':
									geometry.addAttribute( 'uv', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1589

1590 1591 1592 1593 1594
								case 'COLOR_0':
								case 'COLOR0':
								case 'COLOR':
									geometry.addAttribute( 'color', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1595

M
Mr.doob 已提交
1596 1597 1598
								case 'WEIGHT':
									geometry.addAttribute( 'skinWeight', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1599

M
Mr.doob 已提交
1600 1601 1602
								case 'JOINT':
									geometry.addAttribute( 'skinIndex', bufferAttribute );
									break;
R
Rich Tibbett 已提交
1603

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

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

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

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

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

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

M
Mr.doob 已提交
1616 1617
						var meshNode = new THREE.Mesh( geometry, material );
						meshNode.castShadow = true;
A
Al McElrath 已提交
1618
						meshNode.name = ( name === "0" ? group.name : group.name + name );
M
Mr.doob 已提交
1619

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

1622 1623
						group.add( meshNode );

M
Mr.doob 已提交
1624
					} else if ( primitive.mode === WEBGL_CONSTANTS.LINES ) {
1625 1626 1627 1628 1629

						var geometry = new THREE.BufferGeometry();

						var attributes = primitive.attributes;

B
bdysvik 已提交
1630

1631 1632 1633
						for ( var attributeId in attributes ) {

							var attributeEntry = attributes[ attributeId ];
1634

M
Mr.doob 已提交
1635
							if ( ! attributeEntry ) return;
1636 1637 1638 1639 1640 1641 1642 1643

							var bufferAttribute = dependencies.accessors[ attributeEntry ];

							switch ( attributeId ) {

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

1645 1646
								case 'COLOR_0':
								case 'COLOR0':
1647
								case 'COLOR':
M
Mr.doob 已提交
1648 1649 1650
									geometry.addAttribute( 'color', bufferAttribute );
									break;

1651
							}
M
Mr.doob 已提交
1652 1653

						}
M
Mr.doob 已提交
1654 1655 1656 1657

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

						var meshNode;
1658 1659 1660

						if ( primitive.indices ) {

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

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

M
Mr.doob 已提交
1665
						} else {
1666

M
Mr.doob 已提交
1667
							meshNode = new THREE.Line( geometry, material );
1668 1669 1670

						}

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

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

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

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

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

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

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

M
Mr.doob 已提交
1685
				return group;
R
Rich Tibbett 已提交
1686

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

M
Mr.doob 已提交
1689
		} );
R
Rich Tibbett 已提交
1690

M
Mr.doob 已提交
1691
	};
R
Rich Tibbett 已提交
1692

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

M
Mr.doob 已提交
1695 1696 1697
		var json = this.json;

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

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

M
Mr.doob 已提交
1701 1702 1703
				var yfov = camera.perspective.yfov;
				var xfov = camera.perspective.xfov;
				var aspect_ratio = camera.perspective.aspect_ratio || 1;
R
Rich Tibbett 已提交
1704

M
Mr.doob 已提交
1705 1706 1707
				// According to COLLADA spec...
				// aspect_ratio = xfov / yfov
				xfov = ( xfov === undefined && yfov ) ? yfov * aspect_ratio : xfov;
R
Rich Tibbett 已提交
1708

M
Mr.doob 已提交
1709 1710 1711
				// According to COLLADA spec...
				// aspect_ratio = xfov / yfov
				// yfov = ( yfov === undefined && xfov ) ? xfov / aspect_ratio : yfov;
R
Rich Tibbett 已提交
1712

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

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

M
Mr.doob 已提交
1718
				return _camera;
R
Rich Tibbett 已提交
1719

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

M
Mr.doob 已提交
1722
				var _camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, camera.orthographic.znear, camera.orthographic.zfar );
1723
				if ( camera.name !== undefined ) _camera.name = camera.name;
1724 1725

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

M
Mr.doob 已提交
1727
				return _camera;
R
Rich Tibbett 已提交
1728

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

M
Mr.doob 已提交
1731
		} );
R
Rich Tibbett 已提交
1732

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

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

M
Mr.doob 已提交
1737
		var json = this.json;
R
Rich Tibbett 已提交
1738

M
Mr.doob 已提交
1739
		return this._withDependencies( [
R
Rich Tibbett 已提交
1740

M
Mr.doob 已提交
1741
			"accessors"
R
Rich Tibbett 已提交
1742

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

M
Mr.doob 已提交
1745
			return _each( json.skins, function ( skin ) {
M
Mr.doob 已提交
1746 1747 1748 1749 1750 1751 1752 1753 1754 1755

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

				return _skin;

			} );
R
Rich Tibbett 已提交
1756

M
Mr.doob 已提交
1757
		} );
R
Rich Tibbett 已提交
1758

M
Mr.doob 已提交
1759 1760
	};

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

M
Mr.doob 已提交
1763
		var json = this.json;
R
Rich Tibbett 已提交
1764

M
Mr.doob 已提交
1765
		return this._withDependencies( [
R
Rich Tibbett 已提交
1766

M
Mr.doob 已提交
1767 1768
			"accessors",
			"nodes"
R
Rich Tibbett 已提交
1769

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

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

D
Don McCurdy 已提交
1774
				var tracks = [];
R
Rich Tibbett 已提交
1775

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

M
Mr.doob 已提交
1778
					var channel = animation.channels[ channelId ];
M
Mr.doob 已提交
1779 1780
					var sampler = animation.samplers[ channel.sampler ];

1781
					if ( sampler ) {
R
Rich Tibbett 已提交
1782 1783 1784

						var target = channel.target;
						var name = target.id;
1785 1786
						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 已提交
1787 1788 1789 1790 1791 1792 1793 1794

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

						var node = dependencies.nodes[ name ];

						if ( node ) {

D
Don McCurdy 已提交
1795 1796 1797 1798 1799 1800
							node.updateMatrix();
							node.matrixAutoUpdate = true;

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

1802
							var targetName = node.name ? node.name : node.uuid;
1803
							var interpolation = sampler.interpolation !== undefined ? INTERPOLATION[ sampler.interpolation ] : THREE.InterpolateLinear;
R
Rich Tibbett 已提交
1804

D
Don McCurdy 已提交
1805 1806 1807 1808
							// 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(
1809
								targetName + '.' + PATH_PROPERTIES[ target.path ],
D
Don McCurdy 已提交
1810 1811
								THREE.AnimationUtils.arraySlice( inputAccessor.array, 0 ),
								THREE.AnimationUtils.arraySlice( outputAccessor.array, 0 ),
1812
								interpolation
D
Don McCurdy 已提交
1813
							) );
R
Rich Tibbett 已提交
1814 1815 1816

						}

M
Mr.doob 已提交
1817
					}
R
Rich Tibbett 已提交
1818

M
Mr.doob 已提交
1819
				}
R
Rich Tibbett 已提交
1820

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

M
Mr.doob 已提交
1823
			} );
R
Rich Tibbett 已提交
1824

M
Mr.doob 已提交
1825
		} );
R
Rich Tibbett 已提交
1826

M
Mr.doob 已提交
1827
	};
R
Rich Tibbett 已提交
1828

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

M
Mr.doob 已提交
1831
		var json = this.json;
1832
		var extensions = this.extensions;
M
Mr.doob 已提交
1833 1834 1835
		var scope = this;

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

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

M
Mr.doob 已提交
1839
			var _node;
R
Rich Tibbett 已提交
1840

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

M
Mr.doob 已提交
1843
				_node = new THREE.Bone();
1844
				_node.name = node.name !== undefined ? node.name : node.jointName;
M
Mr.doob 已提交
1845
				_node.jointName = node.jointName;
R
Rich Tibbett 已提交
1846

M
Mr.doob 已提交
1847
			} else {
R
Rich Tibbett 已提交
1848

M
Mr.doob 已提交
1849
				_node = new THREE.Object3D();
1850
				if ( node.name !== undefined ) _node.name = node.name;
R
Rich Tibbett 已提交
1851

M
Mr.doob 已提交
1852
			}
R
Rich Tibbett 已提交
1853

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

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

M
Mr.doob 已提交
1858 1859
				matrix.fromArray( node.matrix );
				_node.applyMatrix( matrix );
R
Rich Tibbett 已提交
1860

M
Mr.doob 已提交
1861
			} else {
R
Rich Tibbett 已提交
1862

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

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

M
Mr.doob 已提交
1867
				}
R
Rich Tibbett 已提交
1868

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

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

M
Mr.doob 已提交
1873 1874 1875
				}

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

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

M
Mr.doob 已提交
1879
				}
R
Rich Tibbett 已提交
1880 1881 1882

			}

M
Mr.doob 已提交
1883
			return _node;
R
Rich Tibbett 已提交
1884

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

M
Mr.doob 已提交
1887
			return scope._withDependencies( [
R
Rich Tibbett 已提交
1888

M
Mr.doob 已提交
1889 1890
				"meshes",
				"skins",
1891
				"cameras"
R
Rich Tibbett 已提交
1892

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

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

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

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

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

M
Mr.doob 已提交
1903 1904
							var mesh = node.meshes[ meshId ];
							var group = dependencies.meshes[ mesh ];
R
Rich Tibbett 已提交
1905

1906 1907 1908 1909 1910 1911 1912
							if ( group === undefined ) {

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

							}

M
Mr.doob 已提交
1913 1914 1915
							for ( var childrenId in group.children ) {

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

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

M
Mr.doob 已提交
1919 1920
								var originalMaterial = child.material;
								var originalGeometry = child.geometry;
1921
								var originalUserData = child.userData;
A
Al McElrath 已提交
1922
								var originalName = child.name;
R
Rich Tibbett 已提交
1923

M
Mr.doob 已提交
1924
								var material;
R
Rich Tibbett 已提交
1925

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

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

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

M
Mr.doob 已提交
1932
									material = originalMaterial;
R
Rich Tibbett 已提交
1933

M
Mr.doob 已提交
1934
								}
M
Mr.doob 已提交
1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948

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

1949
								}
M
Mr.doob 已提交
1950

M
Mr.doob 已提交
1951
								child.castShadow = true;
1952
								child.userData = originalUserData;
A
Al McElrath 已提交
1953
								child.name = originalName;
R
Rich Tibbett 已提交
1954

M
Mr.doob 已提交
1955
								var skinEntry;
M
Mr.doob 已提交
1956

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

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

M
Mr.doob 已提交
1961
								}
R
Rich Tibbett 已提交
1962

M
Mr.doob 已提交
1963 1964
								// Replace Mesh with SkinnedMesh in library
								if ( skinEntry ) {
R
Rich Tibbett 已提交
1965

1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979
									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 已提交
1980
									};
1981

M
Mr.doob 已提交
1982 1983 1984
									var geometry = originalGeometry;
									var material = originalMaterial;
									material.skinning = true;
R
Rich Tibbett 已提交
1985

M
Mr.doob 已提交
1986 1987
									child = new THREE.SkinnedMesh( geometry, material, false );
									child.castShadow = true;
1988
									child.userData = originalUserData;
A
Al McElrath 已提交
1989
									child.name = originalName;
R
Rich Tibbett 已提交
1990

M
Mr.doob 已提交
1991 1992
									var bones = [];
									var boneInverses = [];
R
Rich Tibbett 已提交
1993

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

M
Mr.doob 已提交
1996
										var jointId = skinEntry.jointNames[ i ];
1997
										var jointNode = getJointNode( jointId );
R
Rich Tibbett 已提交
1998

M
Mr.doob 已提交
1999
										if ( jointNode ) {
R
Rich Tibbett 已提交
2000

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

M
Mr.doob 已提交
2003 2004 2005
											var m = skinEntry.inverseBindMatrices.array;
											var mat = new THREE.Matrix4().fromArray( m, i * 16 );
											boneInverses.push( mat );
R
Rich Tibbett 已提交
2006

M
Mr.doob 已提交
2007
										} else {
R
Rich Tibbett 已提交
2008

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

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

M
Mr.doob 已提交
2013
									}
R
Rich Tibbett 已提交
2014

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

T
Takahiro 已提交
2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037
									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 已提交
2038
									};
T
Takahiro 已提交
2039 2040 2041

									buildBoneGraph( node, child, 'skeletons' );

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

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

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

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

M
Mr.doob 已提交
2050
					}
R
Rich Tibbett 已提交
2051

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

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

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

M
Mr.doob 已提交
2058
					}
R
Rich Tibbett 已提交
2059

2060 2061 2062
					if ( node.extensions
							 && node.extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ]
							 && node.extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ].light ) {
R
Rich Tibbett 已提交
2063

2064 2065
						var extensionLights = extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ].lights;
						var light = extensionLights[ node.extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ].light ];
R
Rich Tibbett 已提交
2066

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

M
Mr.doob 已提交
2069
					}
R
Rich Tibbett 已提交
2070

M
Mr.doob 已提交
2071
					return _node;
R
Rich Tibbett 已提交
2072

M
Mr.doob 已提交
2073
				} );
R
Rich Tibbett 已提交
2074

M
Mr.doob 已提交
2075
			} );
R
Rich Tibbett 已提交
2076

M
Mr.doob 已提交
2077
		} );
R
Rich Tibbett 已提交
2078

M
Mr.doob 已提交
2079
	};
R
Rich Tibbett 已提交
2080

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

M
Mr.doob 已提交
2083
		var json = this.json;
M
Mr.doob 已提交
2084 2085 2086 2087 2088 2089 2090 2091

		// scene node hierachy builder

		function buildNodeHierachy( nodeId, parentObject, allNodes ) {

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

M
Mr.doob 已提交
2092
			var node = json.nodes[ nodeId ];
M
Mr.doob 已提交
2093 2094 2095

			if ( node.children ) {

M
Mr.doob 已提交
2096 2097 2098
				var children = node.children;

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

M
Mr.doob 已提交
2100
					var child = children[ i ];
M
Mr.doob 已提交
2101 2102
					buildNodeHierachy( child, _node, allNodes );

M
Mr.doob 已提交
2103
				}
M
Mr.doob 已提交
2104 2105

			}
R
Rich Tibbett 已提交
2106 2107 2108

		}

M
Mr.doob 已提交
2109
		return this._withDependencies( [
R
Rich Tibbett 已提交
2110

M
Mr.doob 已提交
2111
			"nodes"
R
Rich Tibbett 已提交
2112

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

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

M
Mr.doob 已提交
2117
				var _scene = new THREE.Scene();
2118
				if ( scene.name !== undefined ) _scene.name = scene.name;
2119 2120

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

T
Takahiro 已提交
2122
				var nodes = scene.nodes || [];
R
Rich Tibbett 已提交
2123

M
Mr.doob 已提交
2124 2125 2126
				for ( var i = 0, l = nodes.length; i < l; i ++ ) {

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

M
Mr.doob 已提交
2129
				}
R
Rich Tibbett 已提交
2130

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

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

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

M
Mr.doob 已提交
2139 2140 2141 2142 2143 2144 2145
					}

				} );

				return _scene;

			} );
R
Rich Tibbett 已提交
2146

M
Mr.doob 已提交
2147 2148 2149
		} );

	};
R
Rich Tibbett 已提交
2150

M
Mr.doob 已提交
2151
	return GLTFLoader;
R
Rich Tibbett 已提交
2152

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