ObjectLoader.js 10.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 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
		var object = this.parseObject( json.object, geometries, materials );
61

62 63 64 65 66
		if ( json.images === undefined || json.images.length === 0 ) {

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

		}
M
Mr.doob 已提交
67

68
		return object;
69

70 71 72 73
	},

	parseGeometries: function ( json ) {

M
Mr.doob 已提交
74
		var geometries = {};
75 76

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

78 79
			var geometryLoader = new THREE.JSONLoader();
			var bufferGeometryLoader = new THREE.BufferGeometryLoader();
M
Mr.doob 已提交
80

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

83
				var geometry;
M
Mr.doob 已提交
84
				var data = json[ i ];
85

86
				switch ( data.type ) {
87

88
					case 'PlaneGeometry':
89
					case 'PlaneBufferGeometry':
90

91
						geometry = new THREE[ data.type ](
92 93 94 95 96
							data.width,
							data.height,
							data.widthSegments,
							data.heightSegments
						);
97

98
						break;
99

M
Mr.doob 已提交
100
					case 'BoxGeometry':
101
					case 'CubeGeometry': // backwards compatible
102

M
Mr.doob 已提交
103
						geometry = new THREE.BoxGeometry(
104 105 106 107 108 109 110
							data.width,
							data.height,
							data.depth,
							data.widthSegments,
							data.heightSegments,
							data.depthSegments
						);
111

112
						break;
113

M
Mr.doob 已提交
114 115 116 117 118 119 120 121 122
					case 'CircleGeometry':

						geometry = new THREE.CircleGeometry(
							data.radius,
							data.segments
						);

						break;

123
					case 'CylinderGeometry':
124

125 126 127 128
						geometry = new THREE.CylinderGeometry(
							data.radiusTop,
							data.radiusBottom,
							data.height,
129
							data.radialSegments,
130 131 132
							data.heightSegments,
							data.openEnded
						);
133

134
						break;
135

136
					case 'SphereGeometry':
137

138 139 140 141 142 143 144 145 146
						geometry = new THREE.SphereGeometry(
							data.radius,
							data.widthSegments,
							data.heightSegments,
							data.phiStart,
							data.phiLength,
							data.thetaStart,
							data.thetaLength
						);
147

148
						break;
149

150
					case 'IcosahedronGeometry':
151

152 153 154 155
						geometry = new THREE.IcosahedronGeometry(
							data.radius,
							data.detail
						);
156

157
						break;
158

159
					case 'TorusGeometry':
160

161 162 163 164 165 166 167
						geometry = new THREE.TorusGeometry(
							data.radius,
							data.tube,
							data.radialSegments,
							data.tubularSegments,
							data.arc
						);
168

169
						break;
M
Mr.doob 已提交
170

171
					case 'TorusKnotGeometry':
M
Mr.doob 已提交
172

173 174 175 176 177 178 179 180 181
						geometry = new THREE.TorusKnotGeometry(
							data.radius,
							data.tube,
							data.radialSegments,
							data.tubularSegments,
							data.p,
							data.q,
							data.heightScale
						);
M
Mr.doob 已提交
182

183
						break;
184

185 186
					case 'BufferGeometry':

M
makc 已提交
187
						geometry = bufferGeometryLoader.parse( data );
188 189 190

						break;

191
					case 'Geometry':
192

193
						geometry = geometryLoader.parse( data.data ).geometry;
194

195
						break;
E
elephantatwork 已提交
196

197
					case 'TextGeometry':
198

199 200 201
						geometry = new THREE.TextGeometry(
							data.text,
							data.data
202 203
						);

204
						break;
205 206 207

				}

208 209
				geometry.uuid = data.uuid;

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

212
				geometries[ data.uuid ] = geometry;
213

214
			}
M
Mr.doob 已提交
215 216 217

		}

218 219 220
		return geometries;

	},
M
Mr.doob 已提交
221

222
	parseMaterials: function ( json, textures ) {
223

M
Mr.doob 已提交
224
		var materials = {};
225 226

		if ( json !== undefined ) {
227

M
Mr.doob 已提交
228 229 230 231
			var getTexture = function ( name ) {

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

232
					console.warn( 'THREE.ObjectLoader: Undefined texture', name );
M
Mr.doob 已提交
233 234 235 236 237 238 239

				}

				return textures[ name ];

			};

240
			var loader = new THREE.MaterialLoader();
241

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

M
Mr.doob 已提交
244
				var data = json[ i ];
245
				var material = loader.parse( data );
246

247 248
				material.uuid = data.uuid;

E
elephantatwork 已提交
249 250 251
				if ( data.depthTest !== undefined ) material.depthTest = data.depthTest;
				if ( data.depthWrite !== undefined ) material.depthWrite = data.depthWrite;

252
				if ( data.name !== undefined ) material.name = data.name;
253

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

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

E
elephantatwork 已提交
258 259 260
					material.alphaMap = getTexture( data.alphaMap );
					material.transparent = true;

261
				}
M
Mr.doob 已提交
262

263 264
				if ( data.bumpMap !== undefined ) material.bumpMap = getTexture( data.bumpMap );
				if ( data.bumpScale !== undefined ) material.bumpScale = data.bumpScale;
M
Mr.doob 已提交
265

266 267
				if ( data.normalMap !== undefined ) material.normalMap = getTexture( data.normalMap );
				if ( data.normalScale )	material.normalScale = new THREE.Vector2( data.normalScale, data.normalScale );
M
Mr.doob 已提交
268

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

M
Mr.doob 已提交
271 272 273
				if ( data.envMap !== undefined ) {

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

276
				}
M
Mr.doob 已提交
277

278
				if ( data.reflectivity ) material.reflectivity = data.reflectivity;
M
Mr.doob 已提交
279

280 281
				if ( data.lightMap !== undefined ) material.lightMap = getTexture( data.lightMap );
				if ( data.lightMapIntensity !== undefined ) material.lightMapIntensity = data.lightMapIntensity;
282

283 284
				if ( data.aoMap !== undefined ) material.aoMap = getTexture( data.aoMap );
				if ( data.aoMapIntensity !== undefined ) material.aoMapIntensity = data.aoMapIntensity;
B
Ben Houston 已提交
285

286
				materials[ data.uuid ] = material;
287 288

			}
289 290 291

		}

292
		return materials;
M
Mr.doob 已提交
293

294
	},
M
Mr.doob 已提交
295

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

M
Mr.doob 已提交
298
		var scope = this;
299 300
		var images = {};

M
Mr.doob 已提交
301 302 303
		if ( json !== undefined && json.length > 0 ) {

			var manager = new THREE.LoadingManager( onLoad );
304 305 306 307

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

308
			var loadImage = function ( url ) {
309

M
Mr.doob 已提交
310
				scope.manager.itemStart( url );
311

312
				return loader.load( url, function () {
313

M
Mr.doob 已提交
314
					scope.manager.itemEnd( url );
315

M
Mr.doob 已提交
316 317 318
				} );

			};
319

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

322
				var image = json[ i ];
323
				images[ image.uuid ] = loadImage( image.src );
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342

			}

		}

		return images;

	},

	parseTextures: function ( json, images ) {

		var textures = {};

		if ( json !== undefined ) {

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

				var data = json[ i ];

M
Mr.doob 已提交
343 344
				if ( data.image === undefined ) {

345
					console.warn( 'THREE.ObjectLoader: No "image" speficied for', data.uuid );
M
Mr.doob 已提交
346

347 348
				}

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

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

353 354
				}

M
Mr.doob 已提交
355
				var texture = new THREE.Texture( images[ data.image ] );
356 357 358 359 360
				texture.needsUpdate = true;

				texture.uuid = data.uuid;

				if ( data.name !== undefined ) texture.name = data.name;
361
				if ( data.mapping !== undefined ) texture.mapping = data.mapping;
M
Mr.doob 已提交
362 363 364
				if ( data.repeat !== undefined ) texture.repeat = new THREE.Vector2( data.repeat[ 0 ], data.repeat[ 1 ] );
				if ( data.minFilter !== undefined ) texture.minFilter = THREE[ data.minFilter ];
				if ( data.magFilter !== undefined ) texture.magFilter = THREE[ data.magFilter ];
365 366 367
				if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;
				if ( data.wrap instanceof Array ) {

M
Mr.doob 已提交
368 369
					texture.wrapS = THREE[ data.wrap[ 0 ] ];
					texture.wrapT = THREE[ data.wrap[ 1 ] ];
370 371 372 373 374 375 376 377 378 379 380 381 382

				}

				textures[ data.uuid ] = texture;

			}

		}

		return textures;

	},

383
	parseObject: function () {
M
Mr.doob 已提交
384

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

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

389
			var object;
M
Mr.doob 已提交
390

M
Mr.doob 已提交
391 392 393 394
			var getGeometry = function ( name ) {

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

395
					console.warn( 'THREE.ObjectLoader: Undefined geometry', name );
M
Mr.doob 已提交
396 397 398 399 400 401 402 403 404 405 406

				}

				return geometries[ name ];

			};

			var getMaterial = function ( name ) {

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

407
					console.warn( 'THREE.ObjectLoader: Undefined material', name );
M
Mr.doob 已提交
408 409 410 411 412 413 414

				}

				return materials[ name ];

			};

415
			switch ( data.type ) {
M
Mr.doob 已提交
416

417
				case 'Scene':
M
Mr.doob 已提交
418

419
					object = new THREE.Scene();
M
Mr.doob 已提交
420

421
					break;
M
Mr.doob 已提交
422

423
				case 'PerspectiveCamera':
M
Mr.doob 已提交
424

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

427
					break;
428

429
				case 'OrthographicCamera':
M
Mr.doob 已提交
430

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

433
					break;
M
Mr.doob 已提交
434

435
				case 'AmbientLight':
M
Mr.doob 已提交
436

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

439
					break;
M
Mr.doob 已提交
440

441
				case 'DirectionalLight':
M
Mr.doob 已提交
442

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

445
					break;
M
Mr.doob 已提交
446

447
				case 'PointLight':
M
Mr.doob 已提交
448

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

451
					break;
M
Mr.doob 已提交
452

453
				case 'SpotLight':
M
Mr.doob 已提交
454

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

457
					break;
M
Mr.doob 已提交
458

459
				case 'HemisphereLight':
M
Mr.doob 已提交
460

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

463
					break;
M
Mr.doob 已提交
464

465
				case 'Mesh':
M
Mr.doob 已提交
466

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

469
					break;
M
Mr.doob 已提交
470

M
Mr.doob 已提交
471 472
				case 'Line':

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

					break;
476

M
Mr.doob 已提交
477
				case 'PointCloud':
478

M
Mr.doob 已提交
479
					object = new THREE.PointCloud( getGeometry( data.geometry ), getMaterial( data.material ) );
480 481

					break;
M
Mr.doob 已提交
482

M
Mr.doob 已提交
483 484
				case 'Sprite':

M
Mr.doob 已提交
485
					object = new THREE.Sprite( getMaterial( data.material ) );
M
Mr.doob 已提交
486 487 488

					break;

489 490 491 492 493 494
				case 'Group':

					object = new THREE.Group();

					break;

495 496 497 498 499 500
				default:

					object = new THREE.Object3D();

			}

501 502 503
			object.uuid = data.uuid;

			if ( data.name !== undefined ) object.name = data.name;
504
			if ( data.matrix !== undefined ) {
505

506 507 508 509 510 511 512 513 514 515
				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 );

			}
516

517 518
			if ( data.visible !== undefined ) object.visible = data.visible;
			if ( data.userData !== undefined ) object.userData = data.userData;
519

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

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

524 525 526
					object.add( this.parseObject( data.children[ child ], geometries, materials ) );

				}
M
Mr.doob 已提交
527 528 529

			}

530
			return object;
M
Mr.doob 已提交
531

532
		}
M
Mr.doob 已提交
533

534
	}()
M
Mr.doob 已提交
535

536
};