427 lines
7.9 KiB
JavaScript
427 lines
7.9 KiB
JavaScript
/**
|
|
* @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.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;
|
|
|
|
}
|
|
|
|
};
|