/** * @author alteredq / http://alteredqualia.com/ */ THREE.Loader = function ( showStatus ) { this.showStatus = showStatus; this.statusDomElement = showStatus ? THREE.Loader.prototype.addStatusElement() : null; this.imageLoader = new THREE.ImageLoader(); this.onLoadStart = function () {}; this.onLoadProgress = function () {}; this.onLoadComplete = function () {}; }; THREE.Loader.prototype = { constructor: THREE.Loader, crossOrigin: undefined, addStatusElement: function () { var e = document.createElement( 'div' ); e.style.position = 'absolute'; e.style.right = '0px'; e.style.top = '0px'; e.style.fontSize = '0.8em'; e.style.textAlign = 'left'; 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'; e.style.zIndex = 1000; e.innerHTML = 'Loading ...'; return e; }, updateProgress: function ( progress ) { var message = 'Loaded '; if ( progress.total ) { message += ( 100 * progress.loaded / progress.total ).toFixed( 0 ) + '%'; } else { message += ( progress.loaded / 1024 ).toFixed( 2 ) + ' KB'; } this.statusDomElement.innerHTML = message; }, extractUrlBase: function ( url ) { var parts = url.split( '/' ); if ( parts.length === 1 ) return './'; parts.pop(); return parts.join( '/' ) + '/'; }, initMaterials: function ( materials, texturePath ) { var array = []; for ( var i = 0; i < materials.length; ++ i ) { array[ i ] = this.createMaterial( materials[ i ], texturePath ); } return array; }, needsTangents: function ( materials ) { for ( var i = 0, il = materials.length; i < il; i ++ ) { var m = materials[ i ]; if ( m instanceof THREE.ShaderMaterial ) return true; } return false; }, createMaterial: function ( m, texturePath ) { var scope = this; function nearest_pow2( n ) { var l = Math.log( n ) / Math.LN2; return Math.pow( 2, Math.round( l ) ); } function create_texture( where, name, sourceFile, repeat, offset, wrap, anisotropy ) { var fullPath = texturePath + sourceFile; var texture; var loader = THREE.Loader.Handlers.get( fullPath ); if ( loader !== null ) { texture = loader.load( fullPath ); } else { texture = new THREE.Texture(); 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 ); var canvas = document.createElement( 'canvas' ); canvas.width = width; canvas.height = height; var context = canvas.getContext( '2d' ); context.drawImage( image, 0, 0, width, height ); texture.image = canvas; } else { texture.image = image; } texture.needsUpdate = true; } ); } texture.sourceFile = sourceFile; if ( repeat ) { texture.repeat.set( repeat[ 0 ], repeat[ 1 ] ); if ( repeat[ 0 ] !== 1 ) texture.wrapS = THREE.RepeatWrapping; if ( repeat[ 1 ] !== 1 ) texture.wrapT = THREE.RepeatWrapping; } if ( offset ) { texture.offset.set( offset[ 0 ], offset[ 1 ] ); } if ( wrap ) { var wrapMap = { 'repeat': THREE.RepeatWrapping, 'mirror': THREE.MirroredRepeatWrapping }; if ( wrapMap[ wrap[ 0 ] ] !== undefined ) texture.wrapS = wrapMap[ wrap[ 0 ] ]; if ( wrapMap[ wrap[ 1 ] ] !== undefined ) texture.wrapT = wrapMap[ wrap[ 1 ] ]; } if ( anisotropy ) { texture.anisotropy = anisotropy; } where[ name ] = texture; } function rgb2hex( rgb ) { return ( rgb[ 0 ] * 255 << 16 ) + ( rgb[ 1 ] * 255 << 8 ) + rgb[ 2 ] * 255; } // defaults var mtype = 'MeshLambertMaterial'; var mpars = { color: 0xeeeeee, opacity: 1.0, map: null, lightMap: null, normalMap: null, bumpMap: null, wireframe: false }; // parameters from model file if ( m.shading ) { var shading = m.shading.toLowerCase(); if ( shading === 'phong' ) mtype = 'MeshPhongMaterial'; else if ( shading === 'basic' ) mtype = 'MeshBasicMaterial'; } if ( m.blending !== undefined && THREE[ m.blending ] !== undefined ) { mpars.blending = THREE[ m.blending ]; } if ( m.transparent !== undefined ) { mpars.transparent = m.transparent; } if ( m.opacity !== undefined && m.opacity < 1.0 ) { mpars.transparent = true; } if ( m.depthTest !== undefined ) { mpars.depthTest = m.depthTest; } if ( m.depthWrite !== undefined ) { mpars.depthWrite = m.depthWrite; } if ( m.visible !== undefined ) { mpars.visible = m.visible; } if ( m.flipSided !== undefined ) { mpars.side = THREE.BackSide; } if ( m.doubleSided !== undefined ) { mpars.side = THREE.DoubleSide; } if ( m.wireframe !== undefined ) { mpars.wireframe = m.wireframe; } if ( m.vertexColors !== undefined ) { if ( m.vertexColors === 'face' ) { mpars.vertexColors = THREE.FaceColors; } else if ( m.vertexColors ) { mpars.vertexColors = THREE.VertexColors; } } // colors if ( m.colorDiffuse ) { mpars.color = rgb2hex( m.colorDiffuse ); } else if ( m.DbgColor ) { mpars.color = m.DbgColor; } if ( m.colorSpecular ) { mpars.specular = rgb2hex( m.colorSpecular ); } if ( m.colorEmissive ) { mpars.emissive = rgb2hex( m.colorEmissive ); } // modifiers if ( m.transparency !== undefined ) { console.warn( 'THREE.Loader: transparency has been renamed to opacity' ); m.opacity = m.transparency; } if ( m.opacity !== undefined ) { mpars.opacity = m.opacity; } if ( m.specularCoef ) { mpars.shininess = m.specularCoef; } // textures if ( m.mapDiffuse && texturePath ) { create_texture( mpars, 'map', m.mapDiffuse, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy ); } if ( m.mapLight && texturePath ) { create_texture( mpars, 'lightMap', m.mapLight, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy ); } if ( m.mapAO && texturePath ) { create_texture( mpars, 'aoMap', m.mapAO, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy ); } if ( m.mapBump && texturePath ) { create_texture( mpars, 'bumpMap', m.mapBump, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy ); } if ( m.mapNormal && texturePath ) { create_texture( mpars, 'normalMap', m.mapNormal, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy ); } if ( m.mapSpecular && texturePath ) { create_texture( mpars, 'specularMap', m.mapSpecular, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy ); } if ( m.mapAlpha && texturePath ) { create_texture( mpars, 'alphaMap', m.mapAlpha, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy ); } // if ( m.mapBumpScale ) { mpars.bumpScale = m.mapBumpScale; } if ( m.mapNormalFactor ) { mpars.normalScale = new THREE.Vector2( m.mapNormalFactor, m.mapNormalFactor ); } var material = new THREE[ mtype ]( mpars ); if ( m.DbgName !== undefined ) material.name = m.DbgName; return material; } }; 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; } };