ObjectLoader.js 11.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
		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 ];
T
tschw 已提交
323
				images[ image.uuid ] = loadImage( image.url );
324 325 326 327 328 329 330 331 332 333 334

			}

		}

		return images;

	},

	parseTextures: function ( json, images ) {

335 336 337 338 339 340 341 342 343 344
		function parseConstant( value ) {

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

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

			return THREE[ value ];

		}

345 346 347 348 349 350 351 352
		var textures = {};

		if ( json !== undefined ) {

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

				var data = json[ i ];

M
Mr.doob 已提交
353 354
				if ( data.image === undefined ) {

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

357 358
				}

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

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

363 364
				}

M
Mr.doob 已提交
365
				var texture = new THREE.Texture( images[ data.image ] );
366 367 368 369 370
				texture.needsUpdate = true;

				texture.uuid = data.uuid;

				if ( data.name !== undefined ) texture.name = data.name;
371
				if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping );
M
Mr.doob 已提交
372
				if ( data.repeat !== undefined ) texture.repeat = new THREE.Vector2( data.repeat[ 0 ], data.repeat[ 1 ] );
373 374
				if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter );
				if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter );
375
				if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;
376
				if ( Array.isArray( data.wrap ) ) {
377

378 379
					texture.wrapS = parseConstant( data.wrap[ 0 ] );
					texture.wrapT = parseConstant( data.wrap[ 1 ] );
380 381 382 383 384 385 386 387 388 389 390 391 392

				}

				textures[ data.uuid ] = texture;

			}

		}

		return textures;

	},

393
	parseObject: function () {
M
Mr.doob 已提交
394

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

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

399
			var object;
M
Mr.doob 已提交
400

M
Mr.doob 已提交
401 402 403 404
			var getGeometry = function ( name ) {

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

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

				}

				return geometries[ name ];

			};

			var getMaterial = function ( name ) {

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

417
					console.warn( 'THREE.ObjectLoader: Undefined material', name );
M
Mr.doob 已提交
418 419 420 421 422 423 424

				}

				return materials[ name ];

			};

425
			switch ( data.type ) {
M
Mr.doob 已提交
426

427
				case 'Scene':
M
Mr.doob 已提交
428

429
					object = new THREE.Scene();
M
Mr.doob 已提交
430

431
					break;
M
Mr.doob 已提交
432

433
				case 'PerspectiveCamera':
M
Mr.doob 已提交
434

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

437
					break;
438

439
				case 'OrthographicCamera':
M
Mr.doob 已提交
440

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

443
					break;
M
Mr.doob 已提交
444

445
				case 'AmbientLight':
M
Mr.doob 已提交
446

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

449
					break;
M
Mr.doob 已提交
450

451
				case 'DirectionalLight':
M
Mr.doob 已提交
452

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

455
					break;
M
Mr.doob 已提交
456

457
				case 'PointLight':
M
Mr.doob 已提交
458

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

461
					break;
M
Mr.doob 已提交
462

463
				case 'SpotLight':
M
Mr.doob 已提交
464

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

467
					break;
M
Mr.doob 已提交
468

469
				case 'HemisphereLight':
M
Mr.doob 已提交
470

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

473
					break;
M
Mr.doob 已提交
474

475
				case 'Mesh':
M
Mr.doob 已提交
476

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

479
					break;
M
Mr.doob 已提交
480

M
Mr.doob 已提交
481 482
				case 'Line':

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

					break;
486

M
Mr.doob 已提交
487
				case 'PointCloud':
488

M
Mr.doob 已提交
489
					object = new THREE.PointCloud( getGeometry( data.geometry ), getMaterial( data.material ) );
490 491

					break;
M
Mr.doob 已提交
492

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

M
Mr.doob 已提交
495
					object = new THREE.Sprite( getMaterial( data.material ) );
M
Mr.doob 已提交
496 497 498

					break;

499 500 501 502 503 504
				case 'Group':

					object = new THREE.Group();

					break;

505 506 507 508 509 510
				default:

					object = new THREE.Object3D();

			}

511 512 513
			object.uuid = data.uuid;

			if ( data.name !== undefined ) object.name = data.name;
514
			if ( data.matrix !== undefined ) {
515

516 517 518 519 520 521 522 523 524 525
				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 );

			}
526

527 528 529
			if ( data.castShadow !== undefined ) object.castShadow = data.castShadow;
			if ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;

530 531
			if ( data.visible !== undefined ) object.visible = data.visible;
			if ( data.userData !== undefined ) object.userData = data.userData;
532

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

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

537 538 539
					object.add( this.parseObject( data.children[ child ], geometries, materials ) );

				}
M
Mr.doob 已提交
540 541 542

			}

543
			return object;
M
Mr.doob 已提交
544

545
		}
M
Mr.doob 已提交
546

547
	}()
M
Mr.doob 已提交
548

549
};