ObjectLoader.js 13.1 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 28
		var loader = new THREE.XHRLoader( scope.manager );
		loader.setCrossOrigin( this.crossOrigin );
		loader.load( url, function ( text ) {
E
elephantatwork 已提交
29

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

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

	},
M
Mr.doob 已提交
35

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

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

	},

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

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

	},

48 49
	parse: function ( json, onLoad ) {

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

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

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

		} );
E
elephantatwork 已提交
57

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

61 62 63 64 65 66 67 68 69
		var tracks = [];

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

		if( tracks.length > 0 ) {

			object.animationClips = [ new THREE.AnimationClip( "default", -1, tracks ) ];

		}
70

71 72 73 74 75
		if ( json.images === undefined || json.images.length === 0 ) {

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

		}
M
Mr.doob 已提交
76

77
		return object;
78

79 80 81 82
	},

	parseGeometries: function ( json ) {

M
Mr.doob 已提交
83
		var geometries = {};
84 85

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

87 88
			var geometryLoader = new THREE.JSONLoader();
			var bufferGeometryLoader = new THREE.BufferGeometryLoader();
M
Mr.doob 已提交
89

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

92
				var geometry;
M
Mr.doob 已提交
93
				var data = json[ i ];
94

95
				switch ( data.type ) {
96

97
					case 'PlaneGeometry':
98
					case 'PlaneBufferGeometry':
99

100
						geometry = new THREE[ data.type ](
101 102 103 104 105
							data.width,
							data.height,
							data.widthSegments,
							data.heightSegments
						);
106

107
						break;
108

M
Mr.doob 已提交
109
					case 'BoxGeometry':
110
					case 'CubeGeometry': // backwards compatible
111

M
Mr.doob 已提交
112
						geometry = new THREE.BoxGeometry(
113 114 115 116 117 118 119
							data.width,
							data.height,
							data.depth,
							data.widthSegments,
							data.heightSegments,
							data.depthSegments
						);
120

121
						break;
122

D
dubejf 已提交
123 124 125 126 127 128 129 130 131 132 133
					case 'CircleBufferGeometry':

						geometry = new THREE.CircleBufferGeometry(
							data.radius,
							data.segments,
							data.thetaStart,
							data.thetaLength
						);

						break;

M
Mr.doob 已提交
134 135 136 137
					case 'CircleGeometry':

						geometry = new THREE.CircleGeometry(
							data.radius,
D
dubejf 已提交
138 139 140
							data.segments,
							data.thetaStart,
							data.thetaLength
M
Mr.doob 已提交
141 142 143 144
						);

						break;

145
					case 'CylinderGeometry':
146

147 148 149 150
						geometry = new THREE.CylinderGeometry(
							data.radiusTop,
							data.radiusBottom,
							data.height,
151
							data.radialSegments,
152
							data.heightSegments,
D
dubejf 已提交
153 154 155
							data.openEnded,
							data.thetaStart,
							data.thetaLength
156
						);
157

158
						break;
159

160
					case 'SphereGeometry':
161

162 163 164 165 166 167 168 169 170
						geometry = new THREE.SphereGeometry(
							data.radius,
							data.widthSegments,
							data.heightSegments,
							data.phiStart,
							data.phiLength,
							data.thetaStart,
							data.thetaLength
						);
171

172
						break;
173

D
dubejf 已提交
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
					case 'SphereBufferGeometry':

						geometry = new THREE.SphereBufferGeometry(
							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;

197
					case 'IcosahedronGeometry':
198

199 200 201 202
						geometry = new THREE.IcosahedronGeometry(
							data.radius,
							data.detail
						);
203

204
						break;
205

D
dubejf 已提交
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
					case 'OctahedronGeometry':

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

						break;

					case 'TetrahedronGeometry':

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

						break;

					case 'RingGeometry':

						geometry = new THREE.RingGeometry(
							data.innerRadius,
							data.outerRadius,
							data.thetaSegments,
							data.phiSegments,
							data.thetaStart,
							data.thetaLength
						);

						break;

237
					case 'TorusGeometry':
238

239 240 241 242 243 244 245
						geometry = new THREE.TorusGeometry(
							data.radius,
							data.tube,
							data.radialSegments,
							data.tubularSegments,
							data.arc
						);
246

247
						break;
M
Mr.doob 已提交
248

249
					case 'TorusKnotGeometry':
M
Mr.doob 已提交
250

251 252 253 254 255 256 257 258 259
						geometry = new THREE.TorusKnotGeometry(
							data.radius,
							data.tube,
							data.radialSegments,
							data.tubularSegments,
							data.p,
							data.q,
							data.heightScale
						);
M
Mr.doob 已提交
260

261
						break;
262

263 264
					case 'BufferGeometry':

M
makc 已提交
265
						geometry = bufferGeometryLoader.parse( data );
266 267 268

						break;

269
					case 'Geometry':
270

271
						geometry = geometryLoader.parse( data.data, this.texturePath ).geometry;
272

273
						break;
E
elephantatwork 已提交
274

275
					case 'TextGeometry':
276

277 278 279
						geometry = new THREE.TextGeometry(
							data.text,
							data.data
280 281
						);

282
						break;
283 284 285

				}

286 287
				geometry.uuid = data.uuid;

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

290
				geometries[ data.uuid ] = geometry;
291

292
			}
M
Mr.doob 已提交
293 294 295

		}

296 297 298
		return geometries;

	},
M
Mr.doob 已提交
299

300
	parseMaterials: function ( json, textures ) {
301

M
Mr.doob 已提交
302
		var materials = {};
303 304

		if ( json !== undefined ) {
305

M
Mr.doob 已提交
306 307 308 309
			var getTexture = function ( name ) {

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

310
					console.warn( 'THREE.ObjectLoader: Undefined texture', name );
M
Mr.doob 已提交
311 312 313 314 315 316 317

				}

				return textures[ name ];

			};

318
			var loader = new THREE.MaterialLoader();
319

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

M
Mr.doob 已提交
322
				var data = json[ i ];
323
				var material = loader.parse( data );
324

325 326
				material.uuid = data.uuid;

E
elephantatwork 已提交
327 328 329
				if ( data.depthTest !== undefined ) material.depthTest = data.depthTest;
				if ( data.depthWrite !== undefined ) material.depthWrite = data.depthWrite;

330
				if ( data.name !== undefined ) material.name = data.name;
331

E
elephantatwork 已提交
332
				if ( data.map !== undefined ) material.map = getTexture( data.map );
333

E
elephantatwork 已提交
334
				if ( data.alphaMap !== undefined ) {
M
Mr.doob 已提交
335

E
elephantatwork 已提交
336 337 338
					material.alphaMap = getTexture( data.alphaMap );
					material.transparent = true;

339
				}
M
Mr.doob 已提交
340

341 342
				if ( data.bumpMap !== undefined ) material.bumpMap = getTexture( data.bumpMap );
				if ( data.bumpScale !== undefined ) material.bumpScale = data.bumpScale;
M
Mr.doob 已提交
343

344 345
				if ( data.normalMap !== undefined ) material.normalMap = getTexture( data.normalMap );
				if ( data.normalScale )	material.normalScale = new THREE.Vector2( data.normalScale, data.normalScale );
M
Mr.doob 已提交
346

E
elephantatwork 已提交
347 348
				if ( data.specularMap !== undefined ) material.specularMap = getTexture( data.specularMap );

M
Mr.doob 已提交
349 350 351
				if ( data.envMap !== undefined ) {

					material.envMap = getTexture( data.envMap );
E
elephantatwork 已提交
352
					material.combine = THREE.MultiplyOperation;
M
Mr.doob 已提交
353

354
				}
M
Mr.doob 已提交
355

356
				if ( data.reflectivity ) material.reflectivity = data.reflectivity;
M
Mr.doob 已提交
357

358 359
				if ( data.lightMap !== undefined ) material.lightMap = getTexture( data.lightMap );
				if ( data.lightMapIntensity !== undefined ) material.lightMapIntensity = data.lightMapIntensity;
360

361 362
				if ( data.aoMap !== undefined ) material.aoMap = getTexture( data.aoMap );
				if ( data.aoMapIntensity !== undefined ) material.aoMapIntensity = data.aoMapIntensity;
B
Ben Houston 已提交
363

364
				materials[ data.uuid ] = material;
365 366

			}
367 368 369

		}

370
		return materials;
M
Mr.doob 已提交
371

372
	},
M
Mr.doob 已提交
373

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

M
Mr.doob 已提交
376
		var scope = this;
377 378
		var images = {};

M
Mr.doob 已提交
379 380 381
		if ( json !== undefined && json.length > 0 ) {

			var manager = new THREE.LoadingManager( onLoad );
382 383 384 385

			var loader = new THREE.ImageLoader( manager );
			loader.setCrossOrigin( this.crossOrigin );

386
			var loadImage = function ( url ) {
387

388 389
				url = scope.texturePath + url;

M
Mr.doob 已提交
390
				scope.manager.itemStart( url );
391

392
				return loader.load( url, function () {
393

M
Mr.doob 已提交
394
					scope.manager.itemEnd( url );
395

M
Mr.doob 已提交
396 397 398
				} );

			};
399

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

402
				var image = json[ i ];
T
tschw 已提交
403
				images[ image.uuid ] = loadImage( image.url );
404 405 406 407 408 409 410 411 412 413 414

			}

		}

		return images;

	},

	parseTextures: function ( json, images ) {

415 416 417 418 419 420 421 422 423 424
		function parseConstant( value ) {

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

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

			return THREE[ value ];

		}

425 426 427 428 429 430 431 432
		var textures = {};

		if ( json !== undefined ) {

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

				var data = json[ i ];

M
Mr.doob 已提交
433 434
				if ( data.image === undefined ) {

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

437 438
				}

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

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

443 444
				}

M
Mr.doob 已提交
445
				var texture = new THREE.Texture( images[ data.image ] );
446 447 448 449 450
				texture.needsUpdate = true;

				texture.uuid = data.uuid;

				if ( data.name !== undefined ) texture.name = data.name;
451
				if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping );
M
Mr.doob 已提交
452
				if ( data.repeat !== undefined ) texture.repeat = new THREE.Vector2( data.repeat[ 0 ], data.repeat[ 1 ] );
453 454
				if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter );
				if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter );
455
				if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;
456
				if ( Array.isArray( data.wrap ) ) {
457

458 459
					texture.wrapS = parseConstant( data.wrap[ 0 ] );
					texture.wrapT = parseConstant( data.wrap[ 1 ] );
460 461 462 463 464 465 466 467 468 469 470 471 472

				}

				textures[ data.uuid ] = texture;

			}

		}

		return textures;

	},

473
	parseObject: function () {
M
Mr.doob 已提交
474

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

477
		return function ( data, geometries, materials, tracks ) {
M
Mr.doob 已提交
478

479
			var object;
M
Mr.doob 已提交
480

M
Mr.doob 已提交
481 482 483 484
			var getGeometry = function ( name ) {

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

485
					console.warn( 'THREE.ObjectLoader: Undefined geometry', name );
M
Mr.doob 已提交
486 487 488 489 490 491 492 493 494 495 496

				}

				return geometries[ name ];

			};

			var getMaterial = function ( name ) {

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

497
					console.warn( 'THREE.ObjectLoader: Undefined material', name );
M
Mr.doob 已提交
498 499 500 501 502 503 504

				}

				return materials[ name ];

			};

505
			switch ( data.type ) {
M
Mr.doob 已提交
506

507
				case 'Scene':
M
Mr.doob 已提交
508

509
					object = new THREE.Scene();
M
Mr.doob 已提交
510

511
					break;
M
Mr.doob 已提交
512

513
				case 'PerspectiveCamera':
M
Mr.doob 已提交
514

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

517
					break;
518

519
				case 'OrthographicCamera':
M
Mr.doob 已提交
520

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

523
					break;
M
Mr.doob 已提交
524

525
				case 'AmbientLight':
M
Mr.doob 已提交
526

527
					object = new THREE.AmbientLight( data.color );
M
Mr.doob 已提交
528

529
					break;
M
Mr.doob 已提交
530

D
dubejf 已提交
531 532 533 534 535 536 537

				case 'AreaLight':

					object = new THREE.AreaLight( data.color, data.intensity );

					break;

538
				case 'DirectionalLight':
M
Mr.doob 已提交
539

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

542
					break;
M
Mr.doob 已提交
543

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

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

548
					break;
M
Mr.doob 已提交
549

550
				case 'SpotLight':
M
Mr.doob 已提交
551

M
Mr.doob 已提交
552
					object = new THREE.SpotLight( data.color, data.intensity, data.distance, data.angle, data.exponent, data.decay );
M
Mr.doob 已提交
553

554
					break;
M
Mr.doob 已提交
555

556
				case 'HemisphereLight':
M
Mr.doob 已提交
557

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

560
					break;
M
Mr.doob 已提交
561

562
				case 'Mesh':
M
Mr.doob 已提交
563

M
Mr.doob 已提交
564
					object = new THREE.Mesh( getGeometry( data.geometry ), getMaterial( data.material ) );
M
Mr.doob 已提交
565

566
					break;
M
Mr.doob 已提交
567

M
Mr.doob 已提交
568 569
				case 'Line':

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

					break;
573

M
Mr.doob 已提交
574
				case 'PointCloud':
575

M
Mr.doob 已提交
576
					object = new THREE.PointCloud( getGeometry( data.geometry ), getMaterial( data.material ) );
577 578

					break;
M
Mr.doob 已提交
579

M
Mr.doob 已提交
580 581
				case 'Sprite':

M
Mr.doob 已提交
582
					object = new THREE.Sprite( getMaterial( data.material ) );
M
Mr.doob 已提交
583 584 585

					break;

586 587 588 589 590 591
				case 'Group':

					object = new THREE.Group();

					break;

592 593 594 595 596 597
				default:

					object = new THREE.Object3D();

			}

598 599 600
			object.uuid = data.uuid;

			if ( data.name !== undefined ) object.name = data.name;
601
			if ( data.matrix !== undefined ) {
602

603 604 605 606 607 608 609 610 611 612
				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 );

			}
613

614 615 616
			if ( data.castShadow !== undefined ) object.castShadow = data.castShadow;
			if ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;

617 618
			if ( data.visible !== undefined ) object.visible = data.visible;
			if ( data.userData !== undefined ) object.userData = data.userData;
619

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

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

B
Ben Houston 已提交
624
					object.add( this.parseObject( data.children[ child ], geometries, materials, tracks ) );
625 626

				}
M
Mr.doob 已提交
627 628 629

			}

B
Ben Houston 已提交
630
			if( data.animations && data.animations.tracks ) {
631 632 633

				var dataTracks = data.animations.tracks;

634 635
				var fpsToSeconds = ( data.animations.fps !== undefined ) ? ( 1.0 / data.animations.fps ) : 1.0;

636
				for( var i = 0; i < data.animations.tracks.length; i ++ ) {
637

638 639 640 641
					var track = THREE.KeyframeTrack.parse( data.animations.tracks[i] );
					track.name = object.uuid + '.' + track.name;
					track.scale( fpsToSeconds );
					tracks.push( track );
642
					
643 644 645 646
				}

			}

647
			return object;
M
Mr.doob 已提交
648

649
		}
M
Mr.doob 已提交
650

651
	}()
M
Mr.doob 已提交
652

653
};