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

5 6 7
THREE.ObjectLoader = function ( manager ) {

	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
M
mese79 已提交
8
	this.texturePath = '';
9 10

};
M
Mr.doob 已提交
11

12
THREE.ObjectLoader.prototype = {
M
Mr.doob 已提交
13

14
	constructor: THREE.ObjectLoader,
M
Mr.doob 已提交
15

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

M
Mr.doob 已提交
18
		if ( this.texturePath === '' ) {
M
Mr.doob 已提交
19

M
Mr.doob 已提交
20
			this.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 );
M
Mr.doob 已提交
21

M
Mr.doob 已提交
22
		}
M
Mr.doob 已提交
23

M
Mr.doob 已提交
24
		var scope = this;
M
Mr.doob 已提交
25

M
Mr.doob 已提交
26 27
		var loader = new THREE.XHRLoader( scope.manager );
		loader.load( url, function ( text ) {
E
elephantatwork 已提交
28

M
Mr.doob 已提交
29
			scope.parse( JSON.parse( text ), onLoad );
E
elephantatwork 已提交
30

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

	},
M
Mr.doob 已提交
34

M
Mr.doob 已提交
35
	setTexturePath: function ( value ) {
36

M
Mr.doob 已提交
37
		this.texturePath = value;
38 39 40

	},

41
	setCrossOrigin: function ( value ) {
M
Mr.doob 已提交
42

43
		this.crossOrigin = value;
M
Mr.doob 已提交
44 45 46

	},

47 48
	parse: function ( json, onLoad ) {

49
		var geometries = this.parseGeometries( json.geometries );
50

51 52 53 54 55
		var images = this.parseImages( json.images, function () {

			if ( onLoad !== undefined ) onLoad( object );

		} );
E
elephantatwork 已提交
56

57 58
		var textures  = this.parseTextures( json.textures, images );
		var materials = this.parseMaterials( json.materials, textures );
59

60
		var object = this.parseObject( json.object, geometries, materials );
61

M
Mr.doob 已提交
62
		if ( json.animations ) {
63

64
			object.animations = this.parseAnimations( json.animations );
65 66

		}
67

68 69 70 71 72
		if ( json.images === undefined || json.images.length === 0 ) {

			if ( onLoad !== undefined ) onLoad( object );

		}
M
Mr.doob 已提交
73

74
		return object;
75

76 77 78 79
	},

	parseGeometries: function ( json ) {

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

		if ( json !== undefined ) {
M
Mr.doob 已提交
83

84 85
			var geometryLoader = new THREE.JSONLoader();
			var bufferGeometryLoader = new THREE.BufferGeometryLoader();
M
Mr.doob 已提交
86

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

89
				var geometry;
M
Mr.doob 已提交
90
				var data = json[ i ];
91

92
				switch ( data.type ) {
93

94
					case 'PlaneGeometry':
95
					case 'PlaneBufferGeometry':
96

97
						geometry = new THREE[ data.type ](
98 99 100 101 102
							data.width,
							data.height,
							data.widthSegments,
							data.heightSegments
						);
103

104
						break;
105

M
Mr.doob 已提交
106
					case 'BoxGeometry':
M
Mugen87 已提交
107
					case 'BoxBufferGeometry':
108
					case 'CubeGeometry': // backwards compatible
109

M
Mugen87 已提交
110
						geometry = new THREE[ data.type ](
111 112 113 114 115 116 117
							data.width,
							data.height,
							data.depth,
							data.widthSegments,
							data.heightSegments,
							data.depthSegments
						);
118

119
						break;
120

M
Mr.doob 已提交
121
					case 'CircleGeometry':
M
Mugen87 已提交
122
					case 'CircleBufferGeometry':
M
Mr.doob 已提交
123

M
Mugen87 已提交
124
						geometry = new THREE[ data.type ](
M
Mr.doob 已提交
125
							data.radius,
D
dubejf 已提交
126 127 128
							data.segments,
							data.thetaStart,
							data.thetaLength
M
Mr.doob 已提交
129 130 131 132
						);

						break;

133
					case 'CylinderGeometry':
M
Mugen87 已提交
134
					case 'CylinderBufferGeometry':
135

M
Mugen87 已提交
136
						geometry = new THREE[ data.type ](
137 138 139
							data.radiusTop,
							data.radiusBottom,
							data.height,
140
							data.radialSegments,
141
							data.heightSegments,
D
dubejf 已提交
142 143 144
							data.openEnded,
							data.thetaStart,
							data.thetaLength
145
						);
146

147
						break;
148

149
					case 'SphereGeometry':
D
dubejf 已提交
150 151
					case 'SphereBufferGeometry':

M
Mugen87 已提交
152
						geometry = new THREE[ data.type ](
D
dubejf 已提交
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
							data.radius,
							data.widthSegments,
							data.heightSegments,
							data.phiStart,
							data.phiLength,
							data.thetaStart,
							data.thetaLength
						);

						break;

					case 'DodecahedronGeometry':

						geometry = new THREE.DodecahedronGeometry(
							data.radius,
							data.detail
						);

						break;

173
					case 'IcosahedronGeometry':
174

175 176 177 178
						geometry = new THREE.IcosahedronGeometry(
							data.radius,
							data.detail
						);
179

180
						break;
181

D
dubejf 已提交
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
					case 'OctahedronGeometry':

						geometry = new THREE.OctahedronGeometry(
							data.radius,
							data.detail
						);

						break;

					case 'TetrahedronGeometry':

						geometry = new THREE.TetrahedronGeometry(
							data.radius,
							data.detail
						);

						break;

					case 'RingGeometry':
M
Mugen87 已提交
201
					case 'RingBufferGeometry':
D
dubejf 已提交
202

M
Mugen87 已提交
203
						geometry = new THREE[ data.type ](
D
dubejf 已提交
204 205 206 207 208 209 210 211 212 213
							data.innerRadius,
							data.outerRadius,
							data.thetaSegments,
							data.phiSegments,
							data.thetaStart,
							data.thetaLength
						);

						break;

214
					case 'TorusGeometry':
M
Mugen87 已提交
215
					case 'TorusBufferGeometry':
216

M
Mugen87 已提交
217
						geometry = new THREE[ data.type ](
218 219 220 221 222 223
							data.radius,
							data.tube,
							data.radialSegments,
							data.tubularSegments,
							data.arc
						);
224

225
						break;
M
Mr.doob 已提交
226

227
					case 'TorusKnotGeometry':
M
Mr.doob 已提交
228

229 230 231 232 233 234 235 236 237
						geometry = new THREE.TorusKnotGeometry(
							data.radius,
							data.tube,
							data.radialSegments,
							data.tubularSegments,
							data.p,
							data.q,
							data.heightScale
						);
M
Mr.doob 已提交
238

239
						break;
240

241 242 243 244 245 246
					case 'LatheGeometry':

						geometry = new THREE.LatheGeometry(
							data.points,
							data.segments,
							data.phiStart,
M
Mr.doob 已提交
247
							data.phiLength
248 249 250 251
						);

						break;

M
Mr.doob 已提交
252
					case 'BufferGeometry':
253

M
Mr.doob 已提交
254
						geometry = bufferGeometryLoader.parse( data );
255

256
						break;
E
elephantatwork 已提交
257

M
Mr.doob 已提交
258
					case 'Geometry':
259

M
Mr.doob 已提交
260
						geometry = geometryLoader.parse( data.data, this.texturePath ).geometry;
261

262
						break;
263

264 265 266 267 268 269
					default:

						console.warn( 'THREE.ObjectLoader: Unsupported geometry type "' + data.type + '"' );

						continue;

270 271
				}

272 273
				geometry.uuid = data.uuid;

274
				if ( data.name !== undefined ) geometry.name = data.name;
M
Mr.doob 已提交
275

276
				geometries[ data.uuid ] = geometry;
277

278
			}
M
Mr.doob 已提交
279 280 281

		}

282 283 284
		return geometries;

	},
M
Mr.doob 已提交
285

286
	parseMaterials: function ( json, textures ) {
287

M
Mr.doob 已提交
288
		var materials = {};
289 290

		if ( json !== undefined ) {
291 292

			var loader = new THREE.MaterialLoader();
293
			loader.setTextures( textures );
294

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

297 298
				var material = loader.parse( json[ i ] );
				materials[ material.uuid ] = material;
299 300

			}
301 302 303

		}

304
		return materials;
M
Mr.doob 已提交
305

306
	},
M
Mr.doob 已提交
307

308 309 310 311
	parseAnimations: function ( json ) {

		var animations = [];

M
Mr.doob 已提交
312
		for ( var i = 0; i < json.length; i ++ ) {
313

314
			var clip = THREE.AnimationClip.parse( json[ i ] );
315 316 317 318 319 320 321 322 323

			animations.push( clip );

		}

		return animations;

	},

M
Mr.doob 已提交
324
	parseImages: function ( json, onLoad ) {
325

M
Mr.doob 已提交
326
		var scope = this;
327 328
		var images = {};

M
Mr.doob 已提交
329
		function loadImage( url ) {
M
Mr.doob 已提交
330

M
Mr.doob 已提交
331
			scope.manager.itemStart( url );
332

M
Mr.doob 已提交
333
			return loader.load( url, function () {
334

M
Mr.doob 已提交
335
				scope.manager.itemEnd( url );
336

M
Mr.doob 已提交
337
			} );
338

M
Mr.doob 已提交
339
		}
340

M
Mr.doob 已提交
341
		if ( json !== undefined && json.length > 0 ) {
342

M
Mr.doob 已提交
343
			var manager = new THREE.LoadingManager( onLoad );
M
Mr.doob 已提交
344

M
Mr.doob 已提交
345 346
			var loader = new THREE.ImageLoader( manager );
			loader.setCrossOrigin( this.crossOrigin );
347

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

350
				var image = json[ i ];
351 352 353
				var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url;

				images[ image.uuid ] = loadImage( path );
354 355 356 357 358 359 360 361 362 363 364

			}

		}

		return images;

	},

	parseTextures: function ( json, images ) {

365 366 367 368 369 370 371 372 373 374
		function parseConstant( value ) {

			if ( typeof( value ) === 'number' ) return value;

			console.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );

			return THREE[ value ];

		}

375 376 377 378 379 380 381 382
		var textures = {};

		if ( json !== undefined ) {

			for ( var i = 0, l = json.length; i < l; i ++ ) {

				var data = json[ i ];

M
Mr.doob 已提交
383 384
				if ( data.image === undefined ) {

D
dubejf 已提交
385
					console.warn( 'THREE.ObjectLoader: No "image" specified for', data.uuid );
M
Mr.doob 已提交
386

387 388
				}

M
Mr.doob 已提交
389 390
				if ( images[ data.image ] === undefined ) {

391
					console.warn( 'THREE.ObjectLoader: Undefined image', data.image );
M
Mr.doob 已提交
392

393 394
				}

M
Mr.doob 已提交
395
				var texture = new THREE.Texture( images[ data.image ] );
396 397 398 399 400
				texture.needsUpdate = true;

				texture.uuid = data.uuid;

				if ( data.name !== undefined ) texture.name = data.name;
401
				if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping );
402
				if ( data.offset !== undefined ) texture.offset = new THREE.Vector2( data.offset[ 0 ], data.offset[ 1 ] );
M
Mr.doob 已提交
403
				if ( data.repeat !== undefined ) texture.repeat = new THREE.Vector2( data.repeat[ 0 ], data.repeat[ 1 ] );
404 405
				if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter );
				if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter );
406
				if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;
407
				if ( Array.isArray( data.wrap ) ) {
408

409 410
					texture.wrapS = parseConstant( data.wrap[ 0 ] );
					texture.wrapT = parseConstant( data.wrap[ 1 ] );
411 412 413 414 415 416 417 418 419 420 421 422 423

				}

				textures[ data.uuid ] = texture;

			}

		}

		return textures;

	},

424
	parseObject: function () {
M
Mr.doob 已提交
425

426
		var matrix = new THREE.Matrix4();
M
Mr.doob 已提交
427

428
		return function ( data, geometries, materials ) {
M
Mr.doob 已提交
429

430
			var object;
M
Mr.doob 已提交
431

M
Mr.doob 已提交
432
			function getGeometry( name ) {
M
Mr.doob 已提交
433 434 435

				if ( geometries[ name ] === undefined ) {

436
					console.warn( 'THREE.ObjectLoader: Undefined geometry', name );
M
Mr.doob 已提交
437 438 439 440 441

				}

				return geometries[ name ];

M
Mr.doob 已提交
442
			}
M
Mr.doob 已提交
443

M
Mr.doob 已提交
444
			function getMaterial( name ) {
M
Mr.doob 已提交
445

446 447
				if ( name === undefined ) return undefined;

M
Mr.doob 已提交
448 449
				if ( materials[ name ] === undefined ) {

450
					console.warn( 'THREE.ObjectLoader: Undefined material', name );
M
Mr.doob 已提交
451 452 453 454 455

				}

				return materials[ name ];

M
Mr.doob 已提交
456
			}
M
Mr.doob 已提交
457

458
			switch ( data.type ) {
M
Mr.doob 已提交
459

460
				case 'Scene':
M
Mr.doob 已提交
461

462
					object = new THREE.Scene();
M
Mr.doob 已提交
463

464
					break;
M
Mr.doob 已提交
465

466
				case 'PerspectiveCamera':
M
Mr.doob 已提交
467

468
					object = new THREE.PerspectiveCamera( data.fov, data.aspect, data.near, data.far );
M
Mr.doob 已提交
469

470
					break;
471

472
				case 'OrthographicCamera':
M
Mr.doob 已提交
473

474
					object = new THREE.OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );
475

476
					break;
M
Mr.doob 已提交
477

478
				case 'AmbientLight':
M
Mr.doob 已提交
479

480
					object = new THREE.AmbientLight( data.color, data.intensity );
M
Mr.doob 已提交
481

482
					break;
M
Mr.doob 已提交
483

484
				case 'DirectionalLight':
M
Mr.doob 已提交
485

486
					object = new THREE.DirectionalLight( data.color, data.intensity );
M
Mr.doob 已提交
487

488
					break;
M
Mr.doob 已提交
489

490
				case 'PointLight':
M
Mr.doob 已提交
491

M
Mr.doob 已提交
492
					object = new THREE.PointLight( data.color, data.intensity, data.distance, data.decay );
M
Mr.doob 已提交
493

494
					break;
M
Mr.doob 已提交
495

496
				case 'SpotLight':
M
Mr.doob 已提交
497

498
					object = new THREE.SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );
M
Mr.doob 已提交
499

500
					break;
M
Mr.doob 已提交
501

502
				case 'HemisphereLight':
M
Mr.doob 已提交
503

504
					object = new THREE.HemisphereLight( data.color, data.groundColor, data.intensity );
M
Mr.doob 已提交
505

506
					break;
M
Mr.doob 已提交
507

M
Mr.doob 已提交
508
				case 'Mesh':
M
Mr.doob 已提交
509

M
Mr.doob 已提交
510 511
					var geometry = getGeometry( data.geometry );
					var material = getMaterial( data.material );
512

M
Mr.doob 已提交
513
					if ( geometry.bones && geometry.bones.length > 0 ) {
514

M
Mr.doob 已提交
515
						object = new THREE.SkinnedMesh( geometry, material );
516

M
Mr.doob 已提交
517
					} else {
518

519
						object = new THREE.Mesh( geometry, material );
520 521

					}
M
Mr.doob 已提交
522

523
					break;
M
Mr.doob 已提交
524

525 526 527 528 529 530
				case 'LOD':

					object = new THREE.LOD();

					break;

M
Mr.doob 已提交
531 532
				case 'Line':

B
bGute 已提交
533
					object = new THREE.Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );
M
Mr.doob 已提交
534 535

					break;
536

M
Mr.doob 已提交
537
				case 'PointCloud':
538
				case 'Points':
539

540
					object = new THREE.Points( getGeometry( data.geometry ), getMaterial( data.material ) );
541 542

					break;
M
Mr.doob 已提交
543

M
Mr.doob 已提交
544 545
				case 'Sprite':

M
Mr.doob 已提交
546
					object = new THREE.Sprite( getMaterial( data.material ) );
M
Mr.doob 已提交
547 548 549

					break;

550 551 552 553 554 555
				case 'Group':

					object = new THREE.Group();

					break;

556 557 558 559 560 561
				default:

					object = new THREE.Object3D();

			}

562 563 564
			object.uuid = data.uuid;

			if ( data.name !== undefined ) object.name = data.name;
565
			if ( data.matrix !== undefined ) {
566

567 568 569 570 571 572 573 574 575 576
				matrix.fromArray( data.matrix );
				matrix.decompose( object.position, object.quaternion, object.scale );

			} else {

				if ( data.position !== undefined ) object.position.fromArray( data.position );
				if ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );
				if ( data.scale !== undefined ) object.scale.fromArray( data.scale );

			}
577

578 579 580
			if ( data.castShadow !== undefined ) object.castShadow = data.castShadow;
			if ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;

581 582
			if ( data.visible !== undefined ) object.visible = data.visible;
			if ( data.userData !== undefined ) object.userData = data.userData;
583

584
			if ( data.children !== undefined ) {
M
Mr.doob 已提交
585

586
				for ( var child in data.children ) {
M
Mr.doob 已提交
587

588 589 590
					object.add( this.parseObject( data.children[ child ], geometries, materials ) );

				}
M
Mr.doob 已提交
591 592 593

			}

594 595
			if ( data.type === 'LOD' ) {

M
Mr.doob 已提交
596
				var levels = data.levels;
597

M
Mr.doob 已提交
598
				for ( var l = 0; l < levels.length; l ++ ) {
599

M
Mr.doob 已提交
600 601
					var level = levels[ l ];
					var child = object.getObjectByProperty( 'uuid', level.object );
602

M
Mr.doob 已提交
603
					if ( child !== undefined ) {
604

M
Mr.doob 已提交
605
						object.addLevel( child, level.distance );
606 607 608 609 610 611 612

					}

				}

			}

613
			return object;
M
Mr.doob 已提交
614

M
Mugen87 已提交
615
		};
M
Mr.doob 已提交
616

617
	}()
M
Mr.doob 已提交
618

619
};