Loader.js 12.6 KB
Newer Older
M
Mr.doob 已提交
1 2 3 4
/**
 * @author mrdoob / http://mrdoob.com/
 */

5
var Loader = function ( editor ) {
6

7
	var scope = this;
8

9 10
	this.texturePath = '';

11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
	this.loadFiles = function ( files ) {

		if ( files.length > 0 ) {

			var filesMap = createFileMap( files );

			var manager = new THREE.LoadingManager();
			manager.setURLModifier( function ( url ) {

				var file = filesMap[ url ];

				if ( file ) {

					console.log( 'Loading', url );

					return URL.createObjectURL( file );

				}

				return url;

			} );

			for ( var i = 0; i < files.length; i ++ ) {

T
Temdog007 已提交
36
				scope.loadFile( files[ i ], manager );
37 38 39 40 41 42 43 44

			}

		}

	};

	this.loadFile = function ( file, manager ) {
45 46 47

		var filename = file.name;
		var extension = filename.split( '.' ).pop().toLowerCase();
48

M
Mr.doob 已提交
49 50 51 52
		var reader = new FileReader();
		reader.addEventListener( 'progress', function ( event ) {

			var size = '(' + Math.floor( event.total / 1000 ).format() + ' KB)';
M
Mr.doob 已提交
53
			var progress = Math.floor( ( event.loaded / event.total ) * 100 ) + '%';
54

M
Mr.doob 已提交
55 56 57 58
			console.log( 'Loading', filename, size, progress );

		} );

M
Mr.doob 已提交
59
		switch ( extension ) {
60

M
Mr.doob 已提交
61 62 63 64 65 66 67
			case '3ds':

				reader.addEventListener( 'load', function ( event ) {

					var loader = new THREE.TDSLoader();
					var object = loader.parse( event.target.result );

68
					editor.execute( new AddObjectCommand( editor, object ) );
M
Mr.doob 已提交
69 70 71 72 73 74

				}, false );
				reader.readAsArrayBuffer( file );

				break;

E
Elijah Snyder 已提交
75 76 77 78 79 80 81
			case 'amf':

				reader.addEventListener( 'load', function ( event ) {

					var loader = new THREE.AMFLoader();
					var amfobject = loader.parse( event.target.result );

82
					editor.execute( new AddObjectCommand( editor, amfobject ) );
E
Elijah Snyder 已提交
83 84 85 86 87 88

				}, false );
				reader.readAsArrayBuffer( file );

				break;

M
Mr.doob 已提交
89
			case 'dae':
90

M
Mr.doob 已提交
91
				reader.addEventListener( 'load', function ( event ) {
92

M
Mr.doob 已提交
93
					var contents = event.target.result;
94

95
					var loader = new THREE.ColladaLoader( manager );
M
Mr.doob 已提交
96
					var collada = loader.parse( contents );
97

M
Mr.doob 已提交
98
					collada.scene.name = filename;
99

100
					editor.addAnimation( collada.scene, collada.animations );
101
					editor.execute( new AddObjectCommand( editor, collada.scene ) );
102

M
Mr.doob 已提交
103 104
				}, false );
				reader.readAsText( file );
105

M
Mr.doob 已提交
106
				break;
107

M
Mr.doob 已提交
108 109 110 111 112 113
			case 'fbx':

				reader.addEventListener( 'load', function ( event ) {

					var contents = event.target.result;

114
					var loader = new THREE.FBXLoader( manager );
M
Mr.doob 已提交
115 116
					var object = loader.parse( contents );

117
					editor.addAnimation( object, object.animations );
118
					editor.execute( new AddObjectCommand( editor, object ) );
M
Mr.doob 已提交
119 120

				}, false );
M
Mr.doob 已提交
121
				reader.readAsArrayBuffer( file );
M
Mr.doob 已提交
122 123 124

				break;

M
Mr.doob 已提交
125
			case 'glb':
M
Mr.doob 已提交
126 127 128 129 130

				reader.addEventListener( 'load', function ( event ) {

					var contents = event.target.result;

131 132
					var dracoLoader = new THREE.DRACOLoader();
					dracoLoader.setDecoderPath( '../examples/js/libs/draco/gltf/' );
133

M
Mr.doob 已提交
134
					var loader = new THREE.GLTFLoader();
135
					loader.setDRACOLoader( dracoLoader );
M
Mr.doob 已提交
136 137
					loader.parse( contents, '', function ( result ) {

T
Temdog007 已提交
138 139
						var scene = result.scene;
						scene.name = filename;
M
Mr.doob 已提交
140

T
Temdog007 已提交
141
						editor.addAnimation( scene, result.animations );
142
						editor.execute( new AddObjectCommand( editor, scene ) );
M
Mr.doob 已提交
143 144 145 146 147 148 149 150

					} );

				}, false );
				reader.readAsArrayBuffer( file );

				break;

M
Mr.doob 已提交
151
			case 'gltf':
152

M
Mr.doob 已提交
153
				reader.addEventListener( 'load', function ( event ) {
154

M
Mr.doob 已提交
155
					var contents = event.target.result;
M
Mr.doob 已提交
156

157 158
					var loader;

M
Mr.doob 已提交
159
					if ( isGLTF1( contents ) ) {
160

M
Mr.doob 已提交
161
						loader = new THREE.LegacyGLTFLoader( manager );
162 163 164

					} else {

165
						loader = new THREE.GLTFLoader( manager );
166 167

					}
168

169
					loader.parse( contents, '', function ( result ) {
170

T
Temdog007 已提交
171 172
						var scene = result.scene;
						scene.name = filename;
M
Mr.doob 已提交
173

T
Temdog007 已提交
174
						editor.addAnimation( scene, result.animations );
175
						editor.execute( new AddObjectCommand( editor, scene ) );
176

M
Mr.doob 已提交
177
					} );
178

M
Mr.doob 已提交
179
				}, false );
M
Mr.doob 已提交
180
				reader.readAsArrayBuffer( file );
181

M
Mr.doob 已提交
182
				break;
183

M
Mr.doob 已提交
184 185
			case 'js':
			case 'json':
M
Mr.doob 已提交
186

187 188 189
			case '3geo':
			case '3mat':
			case '3obj':
M
Mr.doob 已提交
190
			case '3scn':
191

M
Mr.doob 已提交
192
				reader.addEventListener( 'load', function ( event ) {
193

M
Mr.doob 已提交
194
					var contents = event.target.result;
195

M
Mr.doob 已提交
196
					// 2.0
197

M
Mr.doob 已提交
198
					if ( contents.indexOf( 'postMessage' ) !== - 1 ) {
199

M
Mr.doob 已提交
200 201
						var blob = new Blob( [ contents ], { type: 'text/javascript' } );
						var url = URL.createObjectURL( blob );
202

M
Mr.doob 已提交
203
						var worker = new Worker( url );
204

M
Mr.doob 已提交
205
						worker.onmessage = function ( event ) {
206

M
Mr.doob 已提交
207
							event.data.metadata = { version: 2 };
M
Mr.doob 已提交
208
							handleJSON( event.data, file, filename );
209

M
Mr.doob 已提交
210
						};
211

M
Mr.doob 已提交
212
						worker.postMessage( Date.now() );
213

M
Mr.doob 已提交
214
						return;
215

M
Mr.doob 已提交
216
					}
217

M
Mr.doob 已提交
218
					// >= 3.0
219

M
Mr.doob 已提交
220
					var data;
221

M
Mr.doob 已提交
222
					try {
223

M
Mr.doob 已提交
224
						data = JSON.parse( contents );
225

M
Mr.doob 已提交
226
					} catch ( error ) {
227

M
Mr.doob 已提交
228 229
						alert( error );
						return;
230

M
Mr.doob 已提交
231
					}
232

M
Mr.doob 已提交
233
					handleJSON( data, file, filename );
234

M
Mr.doob 已提交
235 236
				}, false );
				reader.readAsText( file );
237

M
Mr.doob 已提交
238
				break;
239

M
Mr.doob 已提交
240

M
Mr.doob 已提交
241
			case 'kmz':
M
Mr.doob 已提交
242

M
Mr.doob 已提交
243
				reader.addEventListener( 'load', function ( event ) {
M
Mr.doob 已提交
244

M
Mr.doob 已提交
245 246
					var loader = new THREE.KMZLoader();
					var collada = loader.parse( event.target.result );
M
Mr.doob 已提交
247

M
Mr.doob 已提交
248
					collada.scene.name = filename;
M
Mr.doob 已提交
249

250
					editor.execute( new AddObjectCommand( editor, collada.scene ) );
M
Mr.doob 已提交
251

M
Mr.doob 已提交
252 253
				}, false );
				reader.readAsArrayBuffer( file );
M
Mr.doob 已提交
254

M
Mr.doob 已提交
255
				break;
M
Mr.doob 已提交
256

M
Mr.doob 已提交
257
			case 'md2':
M
Mr.doob 已提交
258

M
Mr.doob 已提交
259
				reader.addEventListener( 'load', function ( event ) {
M
Mr.doob 已提交
260

M
Mr.doob 已提交
261
					var contents = event.target.result;
M
Mr.doob 已提交
262

M
Mr.doob 已提交
263 264 265 266 267
					var geometry = new THREE.MD2Loader().parse( contents );
					var material = new THREE.MeshStandardMaterial( {
						morphTargets: true,
						morphNormals: true
					} );
M
Mr.doob 已提交
268

M
Mr.doob 已提交
269 270 271
					var mesh = new THREE.Mesh( geometry, material );
					mesh.mixer = new THREE.AnimationMixer( mesh );
					mesh.name = filename;
M
Mr.doob 已提交
272

M
Mr.doob 已提交
273
					editor.addAnimation( mesh, geometry.animations );
274
					editor.execute( new AddObjectCommand( editor, mesh ) );
M
Mr.doob 已提交
275

M
Mr.doob 已提交
276 277
				}, false );
				reader.readAsArrayBuffer( file );
M
Mr.doob 已提交
278

M
Mr.doob 已提交
279
				break;
M
Mr.doob 已提交
280

M
Mr.doob 已提交
281
			case 'obj':
282

M
Mr.doob 已提交
283
				reader.addEventListener( 'load', function ( event ) {
284

M
Mr.doob 已提交
285
					var contents = event.target.result;
286

M
Mr.doob 已提交
287 288
					var object = new THREE.OBJLoader().parse( contents );
					object.name = filename;
289

290
					editor.execute( new AddObjectCommand( editor, object ) );
291

M
Mr.doob 已提交
292 293
				}, false );
				reader.readAsText( file );
294

M
Mr.doob 已提交
295
				break;
296

M
Mr.doob 已提交
297
			case 'ply':
298

M
Mr.doob 已提交
299
				reader.addEventListener( 'load', function ( event ) {
300

M
Mr.doob 已提交
301
					var contents = event.target.result;
302

M
Mr.doob 已提交
303 304 305
					var geometry = new THREE.PLYLoader().parse( contents );
					geometry.sourceType = "ply";
					geometry.sourceFile = file.name;
306

M
Mr.doob 已提交
307
					var material = new THREE.MeshStandardMaterial();
308

M
Mr.doob 已提交
309 310
					var mesh = new THREE.Mesh( geometry, material );
					mesh.name = filename;
311

312
					editor.execute( new AddObjectCommand( editor, mesh ) );
313

M
Mr.doob 已提交
314
				}, false );
M
Mr.doob 已提交
315
				reader.readAsArrayBuffer( file );
316

M
Mr.doob 已提交
317
				break;
318

M
Mr.doob 已提交
319
			case 'stl':
320

M
Mr.doob 已提交
321
				reader.addEventListener( 'load', function ( event ) {
322

M
Mr.doob 已提交
323
					var contents = event.target.result;
324

M
Mr.doob 已提交
325 326 327
					var geometry = new THREE.STLLoader().parse( contents );
					geometry.sourceType = "stl";
					geometry.sourceFile = file.name;
328

M
Mr.doob 已提交
329
					var material = new THREE.MeshStandardMaterial();
330

M
Mr.doob 已提交
331 332
					var mesh = new THREE.Mesh( geometry, material );
					mesh.name = filename;
333

334
					editor.execute( new AddObjectCommand( editor, mesh ) );
335

M
Mr.doob 已提交
336
				}, false );
337

M
Mr.doob 已提交
338
				if ( reader.readAsBinaryString !== undefined ) {
339

M
Mr.doob 已提交
340
					reader.readAsBinaryString( file );
341

M
Mr.doob 已提交
342
				} else {
343

M
Mr.doob 已提交
344
					reader.readAsArrayBuffer( file );
345

M
Mr.doob 已提交
346
				}
347

M
Mr.doob 已提交
348
				break;
349

M
Mr.doob 已提交
350 351 352 353 354 355 356
			case 'svg':

				reader.addEventListener( 'load', function ( event ) {

					var contents = event.target.result;

					var loader = new THREE.SVGLoader();
M
Mr.doob 已提交
357
					var paths = loader.parse( contents ).paths;
M
Mr.doob 已提交
358 359 360 361 362

					//

					var group = new THREE.Group();
					group.scale.multiplyScalar( 0.1 );
T
Temdog007 已提交
363
					group.scale.y *= - 1;
M
Mr.doob 已提交
364 365 366 367 368 369

					for ( var i = 0; i < paths.length; i ++ ) {

						var path = paths[ i ];

						var material = new THREE.MeshBasicMaterial( {
M
Mr.doob 已提交
370
							color: path.color,
M
Mr.doob 已提交
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388
							depthWrite: false
						} );

						var shapes = path.toShapes( true );

						for ( var j = 0; j < shapes.length; j ++ ) {

							var shape = shapes[ j ];

							var geometry = new THREE.ShapeBufferGeometry( shape );
							var mesh = new THREE.Mesh( geometry, material );

							group.add( mesh );

						}

					}

389
					editor.execute( new AddObjectCommand( editor, group ) );
M
Mr.doob 已提交
390 391 392 393 394 395

				}, false );
				reader.readAsText( file );

				break;

M
Mr.doob 已提交
396
			case 'vtk':
397

M
Mr.doob 已提交
398
				reader.addEventListener( 'load', function ( event ) {
399

M
Mr.doob 已提交
400
					var contents = event.target.result;
401

M
Mr.doob 已提交
402 403 404
					var geometry = new THREE.VTKLoader().parse( contents );
					geometry.sourceType = "vtk";
					geometry.sourceFile = file.name;
405

M
Mr.doob 已提交
406
					var material = new THREE.MeshStandardMaterial();
407

M
Mr.doob 已提交
408 409
					var mesh = new THREE.Mesh( geometry, material );
					mesh.name = filename;
410

411
					editor.execute( new AddObjectCommand( editor, mesh ) );
M
Mr.doob 已提交
412 413 414 415 416 417 418 419 420 421 422 423 424 425

				}, false );
				reader.readAsText( file );

				break;

			case 'wrl':

				reader.addEventListener( 'load', function ( event ) {

					var contents = event.target.result;

					var result = new THREE.VRMLLoader().parse( contents );

426
					editor.execute( new SetSceneCommand( editor, result ) );
427

M
Mr.doob 已提交
428 429 430 431 432
				}, false );
				reader.readAsText( file );

				break;

M
Mr.doob 已提交
433 434 435 436
			case 'zip':

				reader.addEventListener( 'load', function ( event ) {

M
Mr.doob 已提交
437
					handleZIP( event.target.result );
M
Mr.doob 已提交
438

M
Mr.doob 已提交
439 440 441 442 443
				}, false );
				reader.readAsBinaryString( file );

				break;

444 445
			default:

446
				// alert( 'Unsupported file format (' + extension +  ').' );
447 448 449

				break;

M
Mr.doob 已提交
450 451
		}

452
	};
M
Mr.doob 已提交
453

M
Mr.doob 已提交
454
	function handleJSON( data, file, filename ) {
M
Mr.doob 已提交
455 456 457

		if ( data.metadata === undefined ) { // 2.0

458
			data.metadata = { type: 'Geometry' };
M
Mr.doob 已提交
459 460 461 462 463

		}

		if ( data.metadata.type === undefined ) { // 3.0

464
			data.metadata.type = 'Geometry';
M
Mr.doob 已提交
465 466 467

		}

M
Mr.doob 已提交
468
		if ( data.metadata.formatVersion !== undefined ) {
M
Mr.doob 已提交
469 470 471 472 473

			data.metadata.version = data.metadata.formatVersion;

		}

M
Mr.doob 已提交
474
		switch ( data.metadata.type.toLowerCase() ) {
475

M
Mr.doob 已提交
476
			case 'buffergeometry':
477

M
Mr.doob 已提交
478 479
				var loader = new THREE.BufferGeometryLoader();
				var result = loader.parse( data );
480

M
Mr.doob 已提交
481
				var mesh = new THREE.Mesh( result );
482

483
				editor.execute( new AddObjectCommand( editor, mesh ) );
M
Mr.doob 已提交
484

M
Mr.doob 已提交
485 486
				break;

487 488
			case 'geometry':

M
Mugen87 已提交
489
				console.error( 'Loader: "Geometry" is no longer supported.' );
490 491 492

				break;

M
Mr.doob 已提交
493
			case 'object':
M
Mr.doob 已提交
494

M
Mr.doob 已提交
495
				var loader = new THREE.ObjectLoader();
496
				loader.setResourcePath( scope.texturePath );
M
Mr.doob 已提交
497

M
Mr.doob 已提交
498
				var result = loader.parse( data );
M
Mr.doob 已提交
499

M
Mr.doob 已提交
500
				if ( result.isScene ) {
501

502
					editor.execute( new SetSceneCommand( editor, result ) );
M
Mr.doob 已提交
503

M
Mr.doob 已提交
504
				} else {
M
Mr.doob 已提交
505

506
					editor.execute( new AddObjectCommand( editor, result ) );
M
Mr.doob 已提交
507

M
Mr.doob 已提交
508
				}
M
Mr.doob 已提交
509

M
Mr.doob 已提交
510
				break;
M
Mr.doob 已提交
511

M
Mr.doob 已提交
512 513
			case 'app':

M
Mr.doob 已提交
514
				editor.fromJSON( data );
M
Mr.doob 已提交
515 516 517

				break;

M
Mr.doob 已提交
518 519
		}

M
Mr.doob 已提交
520
	}
M
Mr.doob 已提交
521

522 523 524 525 526 527 528 529 530 531 532 533 534 535 536
	function createFileMap( files ) {

		var map = {};

		for ( var i = 0; i < files.length; i ++ ) {

			var file = files[ i ];
			map[ file.name ] = file;

		}

		return map;

	}

M
Mr.doob 已提交
537 538 539 540 541 542 543 544 545 546
	function handleZIP( contents ) {

		var zip = new JSZip( contents );

		// Poly

		if ( zip.files[ 'model.obj' ] && zip.files[ 'materials.mtl' ] ) {

			var materials = new THREE.MTLLoader().parse( zip.file( 'materials.mtl' ).asText() );
			var object = new THREE.OBJLoader().setMaterials( materials ).parse( zip.file( 'model.obj' ).asText() );
547
			editor.execute( new AddObjectCommand( editor, object ) );
M
Mr.doob 已提交
548 549 550 551 552 553 554

		}

		//

		zip.filter( function ( path, file ) {

M
Mr.doob 已提交
555 556
			var manager = new THREE.LoadingManager();
			manager.setURLModifier( function ( url ) {
M
Mr.doob 已提交
557

M
Mr.doob 已提交
558
				var file = zip.files[ url ];
M
Mr.doob 已提交
559

M
Mr.doob 已提交
560
				if ( file ) {
M
Mr.doob 已提交
561

562 563
					console.log( 'Loading', url );

M
Mr.doob 已提交
564 565
					var blob = new Blob( [ file.asArrayBuffer() ], { type: 'application/octet-stream' } );
					return URL.createObjectURL( blob );
M
Mr.doob 已提交
566

M
Mr.doob 已提交
567
				}
M
Mr.doob 已提交
568

569 570
				return url;

M
Mr.doob 已提交
571
			} );
M
Mr.doob 已提交
572

M
Mr.doob 已提交
573
			var extension = file.name.split( '.' ).pop().toLowerCase();
M
Mr.doob 已提交
574

M
Mr.doob 已提交
575
			switch ( extension ) {
M
Mr.doob 已提交
576

M
Mr.doob 已提交
577
				case 'fbx':
M
Mr.doob 已提交
578 579 580 581

					var loader = new THREE.FBXLoader( manager );
					var object = loader.parse( file.asArrayBuffer() );

582
					editor.execute( new AddObjectCommand( editor, object ) );
M
Mr.doob 已提交
583 584 585 586 587 588 589 590

					break;

				case 'glb':

					var loader = new THREE.GLTFLoader();
					loader.parse( file.asArrayBuffer(), '', function ( result ) {

T
Temdog007 已提交
591
						var scene = result.scene;
M
Mr.doob 已提交
592

T
Temdog007 已提交
593
						editor.addAnimation( scene, result.animations );
594
						editor.execute( new AddObjectCommand( editor, scene ) );
M
Mr.doob 已提交
595 596 597 598 599 600 601 602 603 604

					} );

					break;

				case 'gltf':

					var loader = new THREE.GLTFLoader( manager );
					loader.parse( file.asText(), '', function ( result ) {

T
Temdog007 已提交
605
						var scene = result.scene;
M
Mr.doob 已提交
606

T
Temdog007 已提交
607 608
						editor.addAnimation( scene, result.animations );
						editor.execute( new AddObjectCommand( scene ) );
M
Mr.doob 已提交
609 610 611 612 613 614 615 616 617 618 619

					} );

					break;

			}

		} );

	}

M
Mr.doob 已提交
620
	function isGLTF1( contents ) {
621 622 623 624 625

		var resultContent;

		if ( typeof contents === 'string' ) {

626
			// contents is a JSON string
627 628 629 630 631 632 633 634
			resultContent = contents;

		} else {

			var magic = THREE.LoaderUtils.decodeText( new Uint8Array( contents, 0, 4 ) );

			if ( magic === 'glTF' ) {

635
				// contents is a .glb file; extract the version
A
Alan Millman 已提交
636
				var version = new DataView( contents ).getUint32( 4, true );
637

A
Alan Millman 已提交
638
				return version < 2;
639 640 641

			} else {

642
				// contents is a .gltf file
643 644 645 646 647 648 649 650 651 652 653 654
				resultContent = THREE.LoaderUtils.decodeText( new Uint8Array( contents ) );

			}

		}

		var json = JSON.parse( resultContent );

		return ( json.asset != undefined && json.asset.version[ 0 ] < 2 );

	}

M
Mr.doob 已提交
655
};