Loader.js 8.8 KB
Newer Older
1 2 3 4
/**
 * @author alteredq / http://alteredqualia.com/
 */

5
THREE.Loader = function ( showStatus ) {
6

7
	this.showStatus = showStatus;
A
alteredq 已提交
8
	this.statusDomElement = showStatus ? THREE.Loader.prototype.addStatusElement() : null;
9

10 11
	this.imageLoader = new THREE.ImageLoader();

12
	this.onLoadStart = function () {};
M
Mr.doob 已提交
13
	this.onLoadProgress = function () {};
14 15
	this.onLoadComplete = function () {};

16
};
17 18 19

THREE.Loader.prototype = {

M
Mr.doob 已提交
20 21
	constructor: THREE.Loader,

22
	crossOrigin: undefined,
23

24 25
	addStatusElement: function () {

26
		var e = document.createElement( "div" );
27

M
Mr.doob 已提交
28 29 30 31
		e.style.position = "absolute";
		e.style.right = "0px";
		e.style.top = "0px";
		e.style.fontSize = "0.8em";
32
		e.style.textAlign = "left";
M
Mr.doob 已提交
33 34 35 36
		e.style.background = "rgba(0,0,0,0.25)";
		e.style.color = "#fff";
		e.style.width = "120px";
		e.style.padding = "0.5em 0.5em 0.5em 0.5em";
37
		e.style.zIndex = 1000;
38

39
		e.innerHTML = "Loading ...";
40

41
		return e;
42

43
	},
44

45 46 47 48 49 50 51 52 53 54 55
	updateProgress: function ( progress ) {

		var message = "Loaded ";

		if ( progress.total ) {

			message += ( 100 * progress.loaded / progress.total ).toFixed(0) + "%";


		} else {

S
srifqi 已提交
56
			message += ( progress.loaded / 1024 ).toFixed(2) + " KB";
57 58 59 60 61 62

		}

		this.statusDomElement.innerHTML = message;

	},
63

M
Mr.doob 已提交
64
	extractUrlBase: function ( url ) {
65

M
Mr.doob 已提交
66
		var parts = url.split( '/' );
M
Mr.doob 已提交
67 68 69

		if ( parts.length === 1 ) return './';

M
Mr.doob 已提交
70
		parts.pop();
M
Mr.doob 已提交
71 72

		return parts.join( '/' ) + '/';
73

74 75
	},

76
	initMaterials: function ( materials, texturePath ) {
77

78
		var array = [];
79

80
		for ( var i = 0; i < materials.length; ++ i ) {
81

82
			array[ i ] = this.createMaterial( materials[ i ], texturePath );
83 84 85

		}

86 87
		return array;

88 89
	},

90
	needsTangents: function ( materials ) {
M
Mr.doob 已提交
91

92
		for( var i = 0, il = materials.length; i < il; i ++ ) {
M
Mr.doob 已提交
93

94
			var m = materials[ i ];
M
Mr.doob 已提交
95

96
			if ( m instanceof THREE.ShaderMaterial ) return true;
M
Mr.doob 已提交
97 98 99 100 101 102 103

		}

		return false;

	},

104
	createMaterial: function ( m, texturePath ) {
105

106
		var scope = this;
107

108 109 110 111 112 113 114
		function nearest_pow2( n ) {

			var l = Math.log( n ) / Math.LN2;
			return Math.pow( 2, Math.round(  l ) );

		}

115
		function create_texture( where, name, sourceFile, repeat, offset, wrap, anisotropy ) {
M
Mr.doob 已提交
116

M
Mr.doob 已提交
117
			var fullPath = texturePath + sourceFile;
118

M
Mr.doob 已提交
119 120 121 122 123 124 125 126 127 128
			var texture;

			var loader = THREE.Loader.Handlers.get( fullPath );

			if ( loader !== null ) {

				texture = loader.load( fullPath );

			} else {

129
				texture = new THREE.Texture();
M
Mr.doob 已提交
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157

				loader = scope.imageLoader;
				loader.crossOrigin = scope.crossOrigin;
				loader.load( fullPath, function ( image ) {

					if ( THREE.Math.isPowerOfTwo( image.width ) === false ||
						 THREE.Math.isPowerOfTwo( image.height ) === false ) {

						var width = nearest_pow2( image.width );
						var height = nearest_pow2( image.height );

						texture.image.width = width;
						texture.image.height = height;
						texture.image.getContext( '2d' ).drawImage( image, 0, 0, width, height );

					} else {

						texture.image = image;

					}

					texture.needsUpdate = true;

				} );

			}

			texture.sourceFile = sourceFile;
M
Mr.doob 已提交
158

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

M
Mr.doob 已提交
161
				texture.repeat.set( repeat[ 0 ], repeat[ 1 ] );
M
Mr.doob 已提交
162

M
Mr.doob 已提交
163 164
				if ( repeat[ 0 ] !== 1 ) texture.wrapS = THREE.RepeatWrapping;
				if ( repeat[ 1 ] !== 1 ) texture.wrapT = THREE.RepeatWrapping;
M
Mr.doob 已提交
165 166 167

			}

168
			if ( offset ) {
M
Mr.doob 已提交
169

M
Mr.doob 已提交
170
				texture.offset.set( offset[ 0 ], offset[ 1 ] );
M
Mr.doob 已提交
171 172 173

			}

174
			if ( wrap ) {
M
Mr.doob 已提交
175 176

				var wrapMap = {
177 178
					"repeat": THREE.RepeatWrapping,
					"mirror": THREE.MirroredRepeatWrapping
M
Mr.doob 已提交
179 180
				}

M
Mr.doob 已提交
181 182
				if ( wrapMap[ wrap[ 0 ] ] !== undefined ) texture.wrapS = wrapMap[ wrap[ 0 ] ];
				if ( wrapMap[ wrap[ 1 ] ] !== undefined ) texture.wrapT = wrapMap[ wrap[ 1 ] ];
M
Mr.doob 已提交
183 184 185

			}

186 187
			if ( anisotropy ) {

M
Mr.doob 已提交
188
				texture.anisotropy = anisotropy;
189 190 191

			}

M
Mr.doob 已提交
192
			where[ name ] = texture;
M
Mr.doob 已提交
193 194 195

		}

196
		function rgb2hex( rgb ) {
M
Mr.doob 已提交
197 198 199 200 201

			return ( rgb[ 0 ] * 255 << 16 ) + ( rgb[ 1 ] * 255 << 8 ) + rgb[ 2 ] * 255;

		}

202
		// defaults
203

204
		var mtype = "MeshLambertMaterial";
205
		var mpars = { color: 0xeeeeee, opacity: 1.0, map: null, lightMap: null, normalMap: null, bumpMap: null, wireframe: false };
M
Mr.doob 已提交
206

207
		// parameters from model file
208

209
		if ( m.shading ) {
210

211 212 213 214
			var shading = m.shading.toLowerCase();

			if ( shading === "phong" ) mtype = "MeshPhongMaterial";
			else if ( shading === "basic" ) mtype = "MeshBasicMaterial";
215

216
		}
M
Mr.doob 已提交
217

218
		if ( m.blending !== undefined && THREE[ m.blending ] !== undefined ) {
M
Mr.doob 已提交
219

220
			mpars.blending = THREE[ m.blending ];
221

222
		}
M
Mr.doob 已提交
223

224
		if ( m.transparent !== undefined || m.opacity < 1.0 ) {
M
Mr.doob 已提交
225

226 227 228 229 230
			mpars.transparent = m.transparent;

		}

		if ( m.depthTest !== undefined ) {
M
Mr.doob 已提交
231

232 233 234
			mpars.depthTest = m.depthTest;

		}
M
Mr.doob 已提交
235

236 237 238 239 240 241
		if ( m.depthWrite !== undefined ) {

			mpars.depthWrite = m.depthWrite;

		}

242 243 244 245 246 247
		if ( m.visible !== undefined ) {

			mpars.visible = m.visible;

		}

248
		if ( m.flipSided !== undefined ) {
249

250
			mpars.side = THREE.BackSide;
251 252 253

		}

254
		if ( m.doubleSided !== undefined ) {
255

256
			mpars.side = THREE.DoubleSide;
257 258 259

		}

260 261 262 263 264 265
		if ( m.wireframe !== undefined ) {

			mpars.wireframe = m.wireframe;

		}

M
Mr.doob 已提交
266
		if ( m.vertexColors !== undefined ) {
M
Mr.doob 已提交
267

268
			if ( m.vertexColors === "face" ) {
M
Mr.doob 已提交
269

M
Mr.doob 已提交
270 271 272
				mpars.vertexColors = THREE.FaceColors;

			} else if ( m.vertexColors ) {
M
Mr.doob 已提交
273

M
Mr.doob 已提交
274 275 276 277 278
				mpars.vertexColors = THREE.VertexColors;

			}

		}
M
Mr.doob 已提交
279

M
Mr.doob 已提交
280
		// colors
281

M
Mr.doob 已提交
282
		if ( m.colorDiffuse ) {
283

M
Mr.doob 已提交
284
			mpars.color = rgb2hex( m.colorDiffuse );
285

M
Mr.doob 已提交
286
		} else if ( m.DbgColor ) {
287

M
Mr.doob 已提交
288
			mpars.color = m.DbgColor;
289

M
Mr.doob 已提交
290
		}
291

M
Mr.doob 已提交
292
		if ( m.colorSpecular ) {
293

M
Mr.doob 已提交
294
			mpars.specular = rgb2hex( m.colorSpecular );
295

M
Mr.doob 已提交
296
		}
297

M
Mr.doob 已提交
298
		if ( m.colorAmbient ) {
299

M
Mr.doob 已提交
300
			mpars.ambient = rgb2hex( m.colorAmbient );
301

M
Mr.doob 已提交
302
		}
303

A
Alessandro Piva 已提交
304 305 306 307 308 309
		if ( m.colorEmissive ) {

			mpars.emissive = rgb2hex( m.colorEmissive );

		}

M
Mr.doob 已提交
310
		// modifiers
311

M
Mr.doob 已提交
312 313 314 315 316 317 318 319 320 321 322 323 324 325
		if ( m.transparency ) {

			mpars.opacity = m.transparency;

		}

		if ( m.specularCoef ) {

			mpars.shininess = m.specularCoef;

		}

		// textures

326
		if ( m.mapDiffuse && texturePath ) {
M
Mr.doob 已提交
327

328
			create_texture( mpars, "map", m.mapDiffuse, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );
329 330 331

		}

332
		if ( m.mapLight && texturePath ) {
333

334
			create_texture( mpars, "lightMap", m.mapLight, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );
M
Mr.doob 已提交
335 336

		}
337

338 339
		if ( m.mapBump && texturePath ) {

340
			create_texture( mpars, "bumpMap", m.mapBump, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );
341 342 343

		}

344
		if ( m.mapNormal && texturePath ) {
345

346
			create_texture( mpars, "normalMap", m.mapNormal, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );
M
Mr.doob 已提交
347 348

		}
349

350
		if ( m.mapSpecular && texturePath ) {
351

352
			create_texture( mpars, "specularMap", m.mapSpecular, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );
353 354 355

		}

356 357 358 359 360 361 362 363
		//

		if ( m.mapBumpScale ) {

			mpars.bumpScale = m.mapBumpScale;

		}

M
Mr.doob 已提交
364 365 366 367
		// special case for normal mapped material

		if ( m.mapNormal ) {

368
			var shader = THREE.ShaderLib[ "normalmap" ];
M
Mr.doob 已提交
369 370
			var uniforms = THREE.UniformsUtils.clone( shader.uniforms );

371
			uniforms[ "tNormal" ].value = mpars.normalMap;
M
Mr.doob 已提交
372 373 374

			if ( m.mapNormalFactor ) {

375
				uniforms[ "uNormalScale" ].value.set( m.mapNormalFactor, m.mapNormalFactor );
376 377 378

			}

M
Mr.doob 已提交
379
			if ( mpars.map ) {
380

381
				uniforms[ "tDiffuse" ].value = mpars.map;
M
Mr.doob 已提交
382
				uniforms[ "enableDiffuse" ].value = true;
383 384 385

			}

386 387
			if ( mpars.specularMap ) {

388
				uniforms[ "tSpecular" ].value = mpars.specularMap;
389 390 391 392 393 394
				uniforms[ "enableSpecular" ].value = true;

			}

			if ( mpars.lightMap ) {

395
				uniforms[ "tAO" ].value = mpars.lightMap;
396 397 398
				uniforms[ "enableAO" ].value = true;

			}
399

400
			// for the moment don't handle displacement texture
M
Mr.doob 已提交
401

B
Ben Houston 已提交
402 403 404
			uniforms[ "diffuse" ].value.setHex( mpars.color );
			uniforms[ "specular" ].value.setHex( mpars.specular );
			uniforms[ "ambient" ].value.setHex( mpars.ambient );
M
Mr.doob 已提交
405

B
Ben Houston 已提交
406
			uniforms[ "shininess" ].value = mpars.shininess;
M
Mr.doob 已提交
407

408
			if ( mpars.opacity !== undefined ) {
409

B
Ben Houston 已提交
410
				uniforms[ "opacity" ].value = mpars.opacity;
M
Mr.doob 已提交
411 412 413

			}

A
alteredq 已提交
414
			var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true, fog: true };
415
			var material = new THREE.ShaderMaterial( parameters );
M
Mr.doob 已提交
416

417 418 419 420 421 422
			if ( mpars.transparent ) {

				material.transparent = true;

			}

M
Mr.doob 已提交
423 424
		} else {

425
			var material = new THREE[ mtype ]( mpars );
M
Mr.doob 已提交
426 427

		}
428

A
alteredq 已提交
429 430
		if ( m.DbgName !== undefined ) material.name = m.DbgName;

431 432
		return material;

M
Mr.doob 已提交
433
	}
434

435
};
M
Mr.doob 已提交
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466

THREE.Loader.Handlers = {

	handlers: [],

	add: function ( regex, loader ) {

		this.handlers.push( regex, loader );

	},

	get: function ( file ) {

		for ( var i = 0, l = this.handlers.length; i < l; i += 2 ) {

			var regex = this.handlers[ i ];
			var loader  = this.handlers[ i + 1 ];

			if ( regex.test( file ) ) {

				return loader;

			}

		}

		return null;

	}

};