Explorar el Código

attempty to unify all loaders and plumb manager & crossOrigin
adds an onStart event to the loading manager
i tried to "mrdoob style" as i went along

James Kiefer hace 10 años
padre
commit
a82e43d7f8

+ 951 - 1059
examples/js/loaders/AWDLoader.js

@@ -3,1224 +3,1116 @@
  * Date: 09/12/2013 17:21
  */
 
-THREE.AWDLoader = (function (){
+(function (){
 
+	var UNCOMPRESSED  = 0,
+			DEFLATE       = 1,
+			LZMA          = 2,
 
+			AWD_FIELD_INT8      = 1,
+			AWD_FIELD_INT16     = 2,
+			AWD_FIELD_INT32     = 3,
+			AWD_FIELD_UINT8     = 4,
+			AWD_FIELD_UINT16    = 5,
+			AWD_FIELD_UINT32    = 6,
+			AWD_FIELD_FLOAT32   = 7,
+			AWD_FIELD_FLOAT64   = 8,
+			AWD_FIELD_BOOL      = 21,
+			AWD_FIELD_COLOR     = 22,
+			AWD_FIELD_BADDR     = 23,
+			AWD_FIELD_STRING    = 31,
+			AWD_FIELD_BYTEARRAY = 32,
+			AWD_FIELD_VECTOR2x1 = 41,
+			AWD_FIELD_VECTOR3x1 = 42,
+			AWD_FIELD_VECTOR4x1 = 43,
+			AWD_FIELD_MTX3x2    = 44,
+			AWD_FIELD_MTX3x3    = 45,
+			AWD_FIELD_MTX4x3    = 46,
+			AWD_FIELD_MTX4x4    = 47,
 
-  var UNCOMPRESSED  = 0,
-      DEFLATE       = 1,
-      LZMA          = 2,
+			BOOL       = 21,
+			COLOR      = 22,
+			BADDR      = 23,
 
-      AWD_FIELD_INT8      = 1,
-      AWD_FIELD_INT16     = 2,
-      AWD_FIELD_INT32     = 3,
-      AWD_FIELD_UINT8     = 4,
-      AWD_FIELD_UINT16    = 5,
-      AWD_FIELD_UINT32    = 6,
-      AWD_FIELD_FLOAT32   = 7,
-      AWD_FIELD_FLOAT64   = 8,
-      AWD_FIELD_BOOL      = 21,
-      AWD_FIELD_COLOR     = 22,
-      AWD_FIELD_BADDR     = 23,
-      AWD_FIELD_STRING    = 31,
-      AWD_FIELD_BYTEARRAY = 32,
-      AWD_FIELD_VECTOR2x1 = 41,
-      AWD_FIELD_VECTOR3x1 = 42,
-      AWD_FIELD_VECTOR4x1 = 43,
-      AWD_FIELD_MTX3x2    = 44,
-      AWD_FIELD_MTX3x3    = 45,
-      AWD_FIELD_MTX4x3    = 46,
-      AWD_FIELD_MTX4x4    = 47,
+			INT8    = 1,
+			INT16   = 2,
+			INT32   = 3,
+			UINT8   = 4,
+			UINT16  = 5,
+			UINT32  = 6,
+			FLOAT32 = 7,
+			FLOAT64 = 8;
 
-      BOOL       = 21,
-      COLOR      = 22,
-      BADDR      = 23,
+	var littleEndian = true;
 
-      INT8    = 1,
-      INT16   = 2,
-      INT32   = 3,
-      UINT8   = 4,
-      UINT16  = 5,
-      UINT32  = 6,
-      FLOAT32 = 7,
-      FLOAT64 = 8;
+	function Block(){
+		this.id = 0;
+		this.data = null;
+	}
 
+	AWDProperties = function(){}
 
-  var littleEndian = true;
+	AWDProperties.prototype = {
+		set : function(key, value)
+		{
+			this[key] = value;
+		},
 
-  // ResourcesLoader
-  // =============
-  // handle loading for external resources
-  function ResourcesLoader( awdUrl ){
+		get : function(key, fallback)
+		{
+			if ( this.hasOwnProperty(key) )
+				return this[key];
+			else return fallback;
+		}
+	}
 
-    this._baseDir = awdUrl.substr( 0, awdUrl.lastIndexOf( '/' )+1 );
+	THREE.AWDLoader = function ( manager ) {
 
-    this._loadingManager = new THREE.LoadingManager();
+		this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
 
-  }
+		//--
 
-  ResourcesLoader.prototype = {
+		this.trunk = new THREE.Object3D();
 
-    loadTexture : function( path ){
-      var tex = new THREE.Texture();
+		this.materialFactory = undefined;
 
-      var loader = new THREE.ImageLoader( this._loadingManager );
+		this._url     = '';
+		this._baseDir = '';
 
-      loader.load( this._baseDir+path, function( image ) {
-        tex.image = image;
-        tex.needsUpdate = true;
-      });
+		this._data;
+		this._ptr = 0;
 
-      return tex;
+		this._version =  [];
+		this._streaming = false;
+		this._optimized_for_accuracy = false;
+		this._compression = 0;
+		this._bodylen = 0xFFFFFFFF;
 
-    }
-  }
+		this._blocks = [ new Block() ];
 
+		this._accuracyMatrix  = false;
+		this._accuracyGeo     = false;
+		this._accuracyProps   = false;
+
+	};
+
+	THREE.AWDLoader.prototype = {
+
+		constructor: THREE.AWDLoader,
+
+		load: function ( url, onLoad, onProgress, onError ) {
+
+			var scope = this;
+
+			this._url = url;
+			this._baseDir = url.substr( 0, url.lastIndexOf( '/' )+1 );
+
+			var loader = new THREE.XHRLoader( this.manager );
+			loader.setCrossOrigin( this.crossOrigin );
+			loader.setResponseType('arraybuffer');
+			loader.load( url, function ( text ) {
+
+				onLoad( scope.parse(text) );
+
+			}, onProgress, onError );
+
+		},
 
+		setCrossOrigin: function ( value ) {
 
-  function Block(){
-    this.id = 0;
-    this.data = null;
-  }
+			this.crossOrigin = value;
 
+		},
 
+		parse: function ( data ) {
 
-  function AWDLoader( showStatus ) {
+			var blen = data.byteLength;
 
-    THREE.Loader.call( this, showStatus );
+			this._ptr = 0;
+			this._data = new DataView( data );
 
-    this.trunk = new THREE.Object3D();
+			this._parseHeader( );
 
-    this.materialFactory = undefined;
+			if( this._compression != 0  ) {
+				console.error( 'compressed AWD not supported' );
+			}
 
-    this._resourceLoader = null;
-    this._url = '';
+			if (!this._streaming && this._bodylen != data.byteLength - this._ptr ) {
+				console.error('AWDLoader: body len does not match file length', this._bodylen ,  blen - this._ptr);
+			}
 
-    this._data;
-    this._ptr = 0;
+			while ( this._ptr < blen ) {
+				this.parseNextBlock();
+			}
 
-    this._version =  [];
-    this._streaming = false;
-    this._optimized_for_accuracy = false;
-    this._compression = 0;
-    this._bodylen = 0xFFFFFFFF;
+			return this.trunk;
 
+		},
 
-    this._blocks = [ new Block() ];
+		parseNextBlock: function() {
 
-    this._accuracyMatrix  = false;
-    this._accuracyGeo     = false;
-    this._accuracyProps   = false;
+			var assetData,
+					ns, type, len, block,
+					blockId = this.readU32(),
+					ns      = this.readU8(),
+					type    = this.readU8(),
+					flags   = this.readU8(),
+					len     = this.readU32();
 
 
-  };
+			switch (type) {
+				case 1:
+					assetData = this.parseMeshData(len);
+					break;
+				case 22:
+					assetData = this.parseContainer(len);
+					break;
+				case 23:
+					assetData = this.parseMeshInstance(len);
+					break;
+				case 81:
+					assetData = this.parseMaterial(len);
+					break;
+				case 82:
+					assetData = this.parseTexture(len);
+					break;
+				case 101:
+					assetData = this.parseSkeleton(len);
+					break;
 
+	//      case 111:
+	//        assetData = this.parseMeshPoseAnimation(len, true);
+	//        break;
+				case 112:
+					assetData = this.parseMeshPoseAnimation(len, false);
+					break;
+				case 113:
+					assetData = this.parseVertexAnimationSet(len);
+					break;
+				case 102:
+					assetData = this.parseSkeletonPose(len);
+					break;
+				case 103:
+					assetData = this.parseSkeletonAnimation(len);
+					break;
+				case 122:
+					assetData = this.parseAnimatorSet(len);
+					break;
+				// case 121:
+				//  assetData = parseUVAnimation(len);
+				//  break;
+				default:
+					//debug('Ignoring block!',type, len);
+					this._ptr += len;
+					break;
+			}
+
+
+			// Store block reference for later use
+			this._blocks[blockId] = block = new Block();
+			block.data = assetData;
+			block.id = blockId;
+
+
+		},
+
+		_parseHeader: function () {
+
+			var version = this._version,
+					awdmagic =
+							( this.readU8()<<16)
+					|   ( this.readU8()<<8 )
+					|     this.readU8();
+
+			if( awdmagic != 4282180 )
+				throw new Error( "AWDLoader - bad magic" );
+
+			version[0] = this.readU8();
+			version[1] = this.readU8();
+
+			var flags = this.readU16();
+
+			this._streaming = (flags & 0x1) == 0x1;
+
+			if ((version[0] === 2) && (version[1] === 1)) {
+				this._accuracyMatrix =  (flags & 0x2) === 0x2;
+				this._accuracyGeo =     (flags & 0x4) === 0x4;
+				this._accuracyProps =   (flags & 0x8) === 0x8;
+			}
+
+			this._geoNrType     = this._accuracyGeo     ? FLOAT64 : FLOAT32;
+			this._matrixNrType  = this._accuracyMatrix  ? FLOAT64 : FLOAT32;
+			this._propsNrType   = this._accuracyProps   ? FLOAT64 : FLOAT32;
+
+			this._optimized_for_accuracy  = (flags & 0x2) === 0x2;
+
+			this._compression = this.readU8();
+			this._bodylen = this.readU32();
+
+		},
+
+		parseContainer: function ( len ) {
+			var parent,
+					ctr     = new THREE.Object3D(),
+					par_id  = this.readU32(),
+					mtx     = this.parseMatrix4();
+
+			ctr.name = this.readUTF();
+			ctr.applyMatrix( mtx );
+
+			parent = this._blocks[par_id].data || this.trunk;
+			parent.add(ctr);
+
+			this.parseProperties({
+				1:this._matrixNrType,
+				2:this._matrixNrType,
+				3:this._matrixNrType,
+				4:UINT8
+			});
+
+			ctr.extra = this.parseUserAttributes();
+
+			return ctr;
+		},
+
+		parseMeshInstance: function ( len ) {
+			var name,
+					mesh, geometries, meshLen, meshes,
+					par_id, data_id,
+					mtx,
+					materials, mat, mat_id,
+					num_materials,
+					materials_parsed,
+					parent,
+					i;
+
+			par_id        = this.readU32();
+			mtx           = this.parseMatrix4();
+			name          = this.readUTF();
+			data_id       = this.readU32();
+			num_materials = this.readU16();
+
+			geometries = this.getBlock( data_id );
+
+			materials = [];
+			materials_parsed = 0;
+
+			for ( i = 0; i < num_materials; i++) {
+				mat_id = this.readU32();
+				mat = this.getBlock( mat_id );
+				materials.push( mat );
+			}
 
-  AWDLoader.prototype = Object.create( THREE.Loader.prototype );
-  AWDLoader.prototype.constructor = AWDLoader;
+			meshLen = geometries.length
+			meshes = [];
 
-  AWDLoader.prototype.load = function ( url, callback ) {
+			// TODO : BufferGeometry don't support "geometryGroups" for now.
+			// so we create sub meshes for each groups
+			if( meshLen  > 1 ) {
+				mesh = new THREE.Object3D()
+				for ( i = 0; i < meshLen; i++) {
+					var sm = new THREE.Mesh( geometries[i] );
+					meshes.push( sm );
+					mesh.add( sm );
+				}
+			}
+			else {
+				mesh = new THREE.Mesh( geometries[0] );
+				meshes.push( mesh );
+			}
+
+			mesh.applyMatrix( mtx );
+			mesh.name = name;
+
+
+			parent = this.getBlock( par_id ) || this.trunk;
+			parent.add( mesh );
+
+
+			var matLen = materials.length;
+			var maxLen = Math.max( meshLen, matLen);
+			for( i = 0; i< maxLen; i++ )
+				meshes[ i%meshLen ].material = materials[ i % matLen ];
+
+
+			// Ignore for now
+			this.parseProperties( null );
+			mesh.extra = this.parseUserAttributes();
+
+			return mesh;
+		},
+
+		parseMaterial: function ( len ) {
+			var name,
+					type,
+					props,
+					mat,
+					attributes,
+					finalize,
+					num_methods,
+					methods_parsed;
+
+			name        = this.readUTF();
+			type        = this.readU8();
+			num_methods = this.readU8();
+
+			//log( "AWDLoader parseMaterial ",name )
+
+			// Read material numerical properties
+			// (1=color, 2=bitmap url, 11=alpha_blending, 12=alpha_threshold, 13=repeat)
+			props = this.parseProperties({
+				1:  AWD_FIELD_INT32,
+				2:  AWD_FIELD_BADDR,
+				11: AWD_FIELD_BOOL,
+				12: AWD_FIELD_FLOAT32,
+				13: AWD_FIELD_BOOL
+			});
+
+			methods_parsed = 0;
+
+			while( methods_parsed < num_methods ) {
+				var method_type = this.readU16();
+				this.parseProperties( null );
+				this.parseUserAttributes();
+			}
+
+			attributes = this.parseUserAttributes();
+
+			if( this.materialFactory !== undefined ) {
+				mat = this.materialFactory( name );
+				if( mat ) return mat;
+			}
 
-    var that = this;
-    this._url = url;
-    var xhr = new XMLHttpRequest();
-    xhr.open( "GET", url, true );
-    xhr.responseType = 'arraybuffer';
+			mat = new THREE.MeshPhongMaterial();
 
-    xhr.onreadystatechange = function () {
+			if (type === 1) { // Color material
+				mat.color.setHex( props.get(1, 0xcccccc) );
+			}
+			else if (type === 2) { // Bitmap material
+				var tex_addr = props.get(2, 0);
+				mat.map = this.getBlock( tex_addr );
+			}
 
-      if ( xhr.readyState == 4 ) {
+			mat.extra = attributes;
+			mat.alphaThreshold = props.get(12, 0.0);
+			mat.repeat = props.get(13, false);
 
-        if ( xhr.status == 200 || xhr.status == 0 ) {
-          that.parse( xhr.response );
-          callback( that.trunk );
 
-        } else {
+			return mat;
+		},
 
-          console.error( 'AWDLoader: Couldn\'t load ' + url + ' (' + xhr.status + ')' );
+		parseTexture: function( len ) {
+			var name = this.readUTF(),
+					type = this.readU8(),
+					asset,
+					data_len;
 
-        }
+			// External
+			if (type === 0) {
+				data_len = this.readU32();
+				var url = this.readUTFBytes(data_len);
+				console.log( url );
 
-      }
+				asset = this.loadTexture( url );
+			} else {
+				// embed texture not supported
+			}
+			// Ignore for now
+			this.parseProperties( null );
 
-    };
+			this.parseUserAttributes();
+			return asset;
+		},
 
-    xhr.send( null );
+		loadTexture: function( url ) {
+			var tex = new THREE.Texture();
 
-  };
+			var loader = new THREE.ImageLoader( this.manager );
 
-  AWDLoader.prototype.parse = function ( data ) {
+			loader.load( this._baseDir+url, function( image ) {
+				tex.image = image;
+				tex.needsUpdate = true;
+			});
 
-    var blen = data.byteLength;
+			return tex;
+		},
 
-    this._ptr = 0;
-    this._data = new DataView( data );
+		parseSkeleton: function( len ) { // Array<Bone>
+			var name          = this.readUTF(),
+					num_joints    = this.readU16(),
+					skeleton      = [],
+					joints_parsed = 0;
 
-    this._parseHeader( );
+			this.parseProperties( null );
 
-    if( this._compression != 0  ) {
-      console.error( 'compressed AWD not supported' );
-    }
+			while (joints_parsed < num_joints) {
+				var joint, ibp;
 
-    if (!this._streaming && this._bodylen != data.byteLength - this._ptr ) {
-      console.error('AWDLoader: body len does not match file length', this._bodylen ,  blen - this._ptr);
-    }
+				// Ignore joint id
+				this.readU16();
 
-    while ( this._ptr < blen ) {
-      this.parseNextBlock();
-    }
+				joint = new THREE.Bone();
+				joint.parent = this.readU16() - 1; // 0=null in AWD
+				joint.name = this.readUTF();
 
-    return this.trunk;
+				ibp = this.parseMatrix4();
+				joint.skinMatrix = ibp;
 
-  }
+				// Ignore joint props/attributes for now
+				this.parseProperties(null);
+				this.parseUserAttributes();
 
+				skeleton.push(joint);
+				joints_parsed++;
+			}
 
+			// Discard attributes for now
+			this.parseUserAttributes();
 
-  AWDLoader.prototype.parseNextBlock = function ( ) {
 
-    var assetData,
-        ns, type, len, block,
-        blockId = this.readU32(),
-        ns      = this.readU8(),
-        type    = this.readU8(),
-        flags   = this.readU8(),
-        len     = this.readU32();
+			return skeleton;
+		},
 
+		parseSkeletonPose: function( blockID ) {
+			var name = this.readUTF();
 
-    switch (type) {
-      case 1:
-        assetData = this.parseMeshData(len);
-        break;
-      case 22:
-        assetData = this.parseContainer(len);
-        break;
-      case 23:
-        assetData = this.parseMeshInstance(len);
-        break;
-      case 81:
-        assetData = this.parseMaterial(len);
-        break;
-      case 82:
-        assetData = this.parseTexture(len);
-        break;
-      case 101:
-        assetData = this.parseSkeleton(len);
-        break;
+			var num_joints = this.readU16();
+			this.parseProperties(null);
 
-//      case 111:
-//        assetData = this.parseMeshPoseAnimation(len, true);
-//        break;
-      case 112:
-        assetData = this.parseMeshPoseAnimation(len, false);
-        break;
-      case 113:
-        assetData = this.parseVertexAnimationSet(len);
-        break;
-      case 102:
-      	assetData = this.parseSkeletonPose(len);
-      	break;
-      case 103:
-      	assetData = this.parseSkeletonAnimation(len);
-      	break;
-      case 122:
-        assetData = this.parseAnimatorSet(len);
-        break;
-      // case 121:
-      // 	assetData = parseUVAnimation(len);
-      // 	break;
-      default:
-        //debug('Ignoring block!',type, len);
-        this._ptr += len;
-        break;
-    }
+			// debug( 'parse Skeleton Pose. joints : ' + num_joints);
 
+			var pose = [];
 
-    // Store block reference for later use
-    this._blocks[blockId] = block = new Block();
-    block.data = assetData;
-    block.id = blockId;
+			var joints_parsed = 0;
 
-  }
+			while (joints_parsed < num_joints) {
 
+				var joint_pose;
 
-  AWDLoader.prototype._parseHeader = function () {
+				var has_transform; //:uint;
+				var mtx_data;
 
-    var version = this._version,
-        awdmagic =
-            ( this.readU8()<<16)
-        |   ( this.readU8()<<8 )
-        |     this.readU8();
-
-    if( awdmagic != 4282180 )
-      throw new Error( "AWDLoader - bad magic" );
-
-    version[0] = this.readU8();
-    version[1] = this.readU8();
-
-    var flags = this.readU16();
-
-    this._streaming = (flags & 0x1) == 0x1;
-
-    if ((version[0] === 2) && (version[1] === 1)) {
-      this._accuracyMatrix =  (flags & 0x2) === 0x2;
-      this._accuracyGeo =     (flags & 0x4) === 0x4;
-      this._accuracyProps =   (flags & 0x8) === 0x8;
-    }
-
-    this._geoNrType     = this._accuracyGeo     ? FLOAT64 : FLOAT32;
-    this._matrixNrType  = this._accuracyMatrix  ? FLOAT64 : FLOAT32;
-    this._propsNrType   = this._accuracyProps   ? FLOAT64 : FLOAT32;
-
-    this._optimized_for_accuracy 	= (flags & 0x2) === 0x2;
-
-    this._compression = this.readU8();
-    this._bodylen = this.readU32();
-
-
-  }
-
-
-  AWDLoader.prototype.parseContainer = function ( len ) {
-    var parent,
-        ctr     = new THREE.Object3D(),
-        par_id  = this.readU32(),
-        mtx     = this.parseMatrix4();
-
-    ctr.name = this.readUTF();
-    ctr.applyMatrix( mtx );
-
-    parent = this._blocks[par_id].data || this.trunk;
-    parent.add(ctr);
-
-    this.parseProperties({
-      1:this._matrixNrType,
-      2:this._matrixNrType,
-      3:this._matrixNrType,
-      4:UINT8
-    });
-
-    ctr.extra = this.parseUserAttributes();
-
-    return ctr;
-  }
+				has_transform = this.readU8();
 
+				if (has_transform === 1) {
+					mtx_data = this.parseMatrix4();
+				} else
+				{
+					mtx_data = new THREE.Matrix4();
+				}
+				pose[joints_parsed] = mtx_data;
+				joints_parsed++;
+			}
 
+			// Skip attributes for now
+			this.parseUserAttributes();
 
-  AWDLoader.prototype.parseMeshInstance = function ( len ) {
-    var name,
-        mesh, geometries, meshLen, meshes,
-        par_id, data_id,
-        mtx,
-        materials, mat, mat_id,
-        num_materials,
-        materials_parsed,
-        parent,
-        i;
+			return pose;
 
-    par_id        = this.readU32();
-    mtx           = this.parseMatrix4();
-    name          = this.readUTF();
-    data_id       = this.readU32();
-    num_materials = this.readU16();
+		},
 
-    geometries = this.getBlock( data_id );
+		parseSkeletonAnimation: function( blockID ) {
 
-    materials = [];
-    materials_parsed = 0;
+			var frame_dur;
+			var pose_addr;
+			var pose;
 
-    for ( i = 0; i < num_materials; i++) {
-      mat_id = this.readU32();
-      mat = this.getBlock( mat_id );
-      materials.push( mat );
-    }
+			var name = this.readUTF();
 
+			var clip = [];
 
+			var num_frames = this.readU16();
+			this.parseProperties( null );
 
-    meshLen = geometries.length
-    meshes = [];
+			var frames_parsed = 0;
+			var returnedArray;
 
-    // TODO : BufferGeometry don't support "geometryGroups" for now.
-    // so we create sub meshes for each groups
-    if( meshLen  > 1 ) {
-      mesh = new THREE.Object3D()
-      for ( i = 0; i < meshLen; i++) {
-        var sm = new THREE.Mesh( geometries[i] );
-        meshes.push( sm );
-        mesh.add( sm );
-      }
-    }
-    else {
-      mesh = new THREE.Mesh( geometries[0] );
-      meshes.push( mesh );
-    }
+			// debug( 'parse Skeleton Animation. frames : ' + num_frames);
 
-    mesh.applyMatrix( mtx );
-    mesh.name = name;
+			while ( frames_parsed < num_frames ) {
+				pose_addr = this.readU32();
+				frame_dur = this.readU16();
 
+				pose = this._blocks[pose_addr].data
+				// debug( 'pose address ',pose[2].elements[12],pose[2].elements[13],pose[2].elements[14] );
+				clip.push( {
+					pose : pose,
+					duration : frame_dur
+				} );
 
-    parent = this.getBlock( par_id ) || this.trunk;
-    parent.add( mesh );
+				frames_parsed++;
+			}
 
+			if ( clip.length === 0 ) {
+				// debug("Could not this SkeletonClipNode, because no Frames where set.");
+				return;
+			}
+			// Ignore attributes for now
+			this.parseUserAttributes();
+			return clip;
 
-    var matLen = materials.length;
-    var maxLen = Math.max( meshLen, matLen);
-    for( i = 0; i< maxLen; i++ )
-      meshes[ i%meshLen ].material = materials[ i % matLen ];
+		},
 
+		parseVertexAnimationSet: function( len ) {
 
-    // Ignore for now
-    this.parseProperties( null );
-    mesh.extra = this.parseUserAttributes();
+			var poseBlockAdress,
+					name           = this.readUTF(),
+					num_frames     = this.readU16(),
+					props          = this.parseProperties( { 1:UINT16 } ),
+					frames_parsed  = 0,
+					skeletonFrames = [];
 
-    return mesh;
-  }
+			while ( frames_parsed < num_frames ) {
+				poseBlockAdress = this.readU32();
+				skeletonFrames.push( this._blocks[poseBlockAdress].data );
+				frames_parsed++;
+			}
 
+			this.parseUserAttributes();
 
 
-  AWDLoader.prototype.parseMaterial = function ( len ) {
-    var name,
-        type,
-        props,
-        mat,
-        attributes,
-        finalize,
-        num_methods,
-        methods_parsed;
+			return skeletonFrames;
 
-    name        = this.readUTF();
-    type        = this.readU8();
-    num_methods = this.readU8();
+		},
 
-    //log( "AWDLoader parseMaterial ",name )
+		parseAnimatorSet: function( len ) {
+			var targetMesh;
 
-    // Read material numerical properties
-    // (1=color, 2=bitmap url, 11=alpha_blending, 12=alpha_threshold, 13=repeat)
-    props = this.parseProperties({
-      1:  AWD_FIELD_INT32,
-      2:  AWD_FIELD_BADDR,
-      11: AWD_FIELD_BOOL,
-      12: AWD_FIELD_FLOAT32,
-      13: AWD_FIELD_BOOL
-    });
+			var animSetBlockAdress; //:int
 
-    methods_parsed = 0;
+			var targetAnimationSet; //:AnimationSetBase;
+			var outputString = ""; //:String = "";
+			var name = this.readUTF();
+			var type = this.readU16();
 
-    while( methods_parsed < num_methods ) {
-      var method_type = this.readU16();
-      this.parseProperties( null );
-      this.parseUserAttributes();
-    }
+			var props = this.parseProperties( { 1:BADDR } );
 
-    attributes = this.parseUserAttributes();
+			animSetBlockAdress = this.readU32();
+			var targetMeshLength = this.readU16();
 
-    if( this.materialFactory !== undefined ) {
-      mat = this.materialFactory( name );
-      if( mat ) return mat;
-    }
+			var meshAdresses = []; //:Vector.<uint> = new Vector.<uint>;
 
-    mat = new THREE.MeshPhongMaterial();
+			for (var i = 0; i < targetMeshLength; i++)
+				meshAdresses.push( this.readU32() );
 
-    if (type === 1) { // Color material
-      mat.color.setHex( props.get(1, 0xcccccc) );
-    }
-    else if (type === 2) { // Bitmap material
-      var tex_addr = props.get(2, 0);
-      mat.map = this.getBlock( tex_addr );
-    }
+			var activeState = this.readU16();
+			var autoplay = Boolean( this.readU8() );
+			this.parseUserAttributes();
+			this.parseUserAttributes();
 
-    mat.extra = attributes;
-    mat.alphaThreshold = props.get(12, 0.0);
-    mat.repeat = props.get(13, false);
+			var returnedArray;
+			var targetMeshes = []; //:Vector.<Mesh> = new Vector.<Mesh>;
 
+			for ( i = 0; i < meshAdresses.length; i++ ) {
+	//      returnedArray = getAssetByID(meshAdresses[i], [AssetType.MESH]);
+	//      if (returnedArray[0])
+					targetMeshes.push( this._blocks[meshAdresses[i]].data );
+			}
 
-    return mat;
-  }
+			targetAnimationSet = this._blocks[animSetBlockAdress].data
+			var thisAnimator;
 
+			if (type == 1) {
 
 
+				thisAnimator = {
+					animationSet : targetAnimationSet,
+					skeleton : this._blocks[props.get(1, 0)].data
+				};
 
-  AWDLoader.prototype.parseTexture = function( len ) {
+			} else if (type == 2) {
+				// debug( "vertex Anim???");
+			}
 
 
-    var name = this.readUTF(),
-        type = this.readU8(),
-        asset,
-        data_len;
+			for ( i = 0; i < targetMeshes.length; i++ ) {
+					targetMeshes[i].animator = thisAnimator;
+			}
+			// debug("Parsed a Animator: Name = " + name);
 
-    // External
-    if (type === 0) {
-      data_len = this.readU32();
-      var url = this.readUTFBytes(data_len);
-      console.log( url );
+			return thisAnimator;
 
-      asset = this.loadTexture( url );
-    } else {
-      // embed texture not supported
-    }
-    // Ignore for now
-    this.parseProperties( null );
+		},
 
-    this.parseUserAttributes();
-    return asset;
-  }
+		parseMeshData: function ( len ) {
+			var name      = this.readUTF(),
+				num_subs  = this.readU16(),
+				geom,
+				subs_parsed = 0,
+				props,
+				buffer,
+				skinW, skinI,
+				geometries = [];
 
-  AWDLoader.prototype.loadTexture = function( url ) {
+			props = this.parseProperties({
+				1: this._geoNrType,
+				2: this._geoNrType
+			});
 
-    if( null === this._resourceLoader )
-      this._resourceLoader = new ResourcesLoader( this._url );
+			// Loop through sub meshes
+			while ( subs_parsed < num_subs ) {
 
-    return this._resourceLoader.loadTexture( url );
-  }
+				var sm_len, sm_end, attrib;
 
-  // broken : skeleton pose format is different than threejs one
-  AWDLoader.prototype.parseSkeleton = function(len) // Array<Bone>
-  {
-    var name          = this.readUTF(),
-        num_joints    = this.readU16(),
-        skeleton      = [],
-        joints_parsed = 0;
+				geom = new THREE.BufferGeometry();
+				geom.name = name;
+				geometries.push( geom );
 
-    this.parseProperties( null );
 
-    while (joints_parsed < num_joints) {
-      var joint, ibp;
+				sm_len = this.readU32();
+				sm_end = this._ptr + sm_len;
 
-      // Ignore joint id
-      this.readU16();
 
-      joint = new THREE.Bone();
-      joint.parent = this.readU16() - 1; // 0=null in AWD
-      joint.name = this.readUTF();
+				// Ignore for now
+				this.parseProperties( { 1:this._geoNrType, 2:this._geoNrType } );
 
-      ibp = this.parseMatrix4();
-      joint.skinMatrix = ibp;
+				// Loop through data streams
+				while ( this._ptr < sm_end ) {
 
-      // Ignore joint props/attributes for now
-      this.parseProperties(null);
-      this.parseUserAttributes();
+					var idx = 0,
+							str_type  = this.readU8(),
+							str_ftype = this.readU8(),
+							str_len   = this.readU32(),
+							str_end   = str_len + this._ptr;
 
-      skeleton.push(joint);
-      joints_parsed++;
-    }
+					// VERTICES
+					// ------------------
+					if ( str_type === 1 ) {
 
-    // Discard attributes for now
-    this.parseUserAttributes();
+						buffer = new Float32Array( ( str_len / 12 ) * 3 );
+						attrib = new THREE.BufferAttribute( buffer, 3 );
 
+						geom.addAttribute( 'position', attrib );
+						idx = 0;
 
-    return skeleton;
-  }
+						while (this._ptr < str_end) {
+							buffer[idx]   = -this.readF32();
+							buffer[idx+1] = this.readF32();
+							buffer[idx+2] = this.readF32();
+							idx+=3;
+						}
+					}
 
+					// INDICES
+					// -----------------
+					else if (str_type === 2) {
 
+						buffer = new Uint16Array( str_len / 2 );
+						attrib = new THREE.BufferAttribute( buffer, 1 );
+						geom.addAttribute( 'index', attrib );
 
-  AWDLoader.prototype.parseSkeletonPose = function(blockID)
-  {
-    var name = this.readUTF();
+						geom.offsets.push({
+							start: 0,
+							index: 0,
+							count: str_len/2
+						});
 
+						idx = 0;
 
-    var num_joints = this.readU16();
-    this.parseProperties(null);
+						while (this._ptr < str_end) {
+							buffer[idx+1]   = this.readU16();
+							buffer[idx]     = this.readU16();
+							buffer[idx+2]   = this.readU16();
+							idx+=3;
+						}
+					}
+
+					// UVS
+					// -------------------
+					else if (str_type === 3) {
+
+						buffer = new Float32Array( ( str_len / 8 ) * 2 );
+						attrib = new THREE.BufferAttribute( buffer, 2 );
+
+						geom.addAttribute( 'uv', attrib );
+						idx = 0;
+
+						while (this._ptr < str_end) {
+							buffer[idx]   = this.readF32();
+							buffer[idx+1] = 1.0-this.readF32();
+							idx+=2;
+						}
+					}
+
+					// NORMALS
+					else if (str_type === 4) {
+
+						buffer = new Float32Array( ( str_len / 12 ) * 3 );
+						attrib = new THREE.BufferAttribute( buffer, 3 );
+						geom.addAttribute( 'normal', attrib );
+						idx = 0;
+
+						while (this._ptr < str_end) {
+							buffer[idx]   = -this.readF32();
+							buffer[idx+1] = this.readF32();
+							buffer[idx+2] = this.readF32();
+							idx+=3;
+						}
 
-    // debug( 'parse Skeleton Pose. joints : ' + num_joints);
+					}
 
-    var pose = [];
+					// else if (str_type == 6) {
+					//   skinI = new Float32Array( str_len>>1 );
+					//   idx = 0
 
-    var joints_parsed = 0;
+					//   while (this._ptr < str_end) {
+					//     skinI[idx]   = this.readU16();
+					//     idx++;
+					//   }
+
+					// }
+					// else if (str_type == 7) {
+					//   skinW = new Float32Array( str_len>>2 );
+					//   idx = 0;
+
+					//   while (this._ptr < str_end) {
+					//     skinW[idx]   = this.readF32();
+					//     idx++;
+					//   }
+					// }
+					else {
+						this._ptr = str_end;
+					}
+
+				}
+
+				this.parseUserAttributes();
+
+				geom.computeBoundingSphere();
+				subs_parsed++;
+			}
+
+			//geom.computeFaceNormals();
+
+			this.parseUserAttributes();
+			//finalizeAsset(geom, name);
+
+			return geometries;
+
+		},
 
-    while (joints_parsed < num_joints) {
+		parseMeshPoseAnimation: function( len, poseOnly ) {
+			var num_frames = 1,
+					num_submeshes,
+					frames_parsed,
+					subMeshParsed,
+					frame_dur,
+					x, y, z,
 
-      var joint_pose;
+					str_len,
+					str_end,
+					geom,
+					subGeom,
+					idx = 0,
+					clip = {},
+					indices,
+					verts,
+					num_Streams,
+					streamsParsed,
+					streamtypes = [],
 
-      var has_transform; //:uint;
-      var mtx_data;
+					props,
+					thisGeo,
+					name = this.readUTF(),
+					geoAdress = this.readU32();
 
-      has_transform = this.readU8();
+			var mesh = this.getBlock( geoAdress );
 
-      if (has_transform === 1) {
-        mtx_data = this.parseMatrix4();
-      } else
-      {
-        mtx_data = new THREE.Matrix4();
-      }
-      pose[joints_parsed] = mtx_data;
-      joints_parsed++;
-    }
-    // Skip attributes for now
-    this.parseUserAttributes();
+			if (mesh === null) {
+				console.log( "parseMeshPoseAnimation target mesh not found at:", geoAdress );
+				return;
+			}
 
-    return pose
-  }
+			geom = mesh.geometry;
+			geom.morphTargets = [];
 
-  AWDLoader.prototype.parseSkeletonAnimation = function(blockID)
-  {
-    var frame_dur;
-    var pose_addr;
-    var pose;
+			if (!poseOnly)
+				num_frames = this.readU16();
 
-    var name = this.readUTF();
+			num_submeshes = this.readU16();
+			num_Streams = this.readU16();
 
-    var clip = [];
+			// debug("VA num_frames : ", num_frames );
+			// debug("VA num_submeshes : ", num_submeshes );
+			// debug("VA numstreams : ", num_Streams );
 
-    var num_frames = this.readU16();
-    this.parseProperties(null);
+			streamsParsed = 0;
+			while ( streamsParsed < num_Streams ) {
+				streamtypes.push(this.readU16());
+				streamsParsed++;
+			}
+			props = this.parseProperties( { 1:BOOL, 2:BOOL } );
 
-    var frames_parsed = 0;
-    var returnedArray;
+			clip.looping = props.get( 1, true );
+			clip.stitchFinalFrame = props.get( 2, false );
 
+			frames_parsed = 0;
 
-    // debug( 'parse Skeleton Animation. frames : ' + num_frames);
+			while ( frames_parsed < num_frames ) {
 
-    while (frames_parsed < num_frames) {
-      pose_addr = this.readU32();
-      frame_dur = this.readU16();
+				frame_dur = this.readU16();
+				subMeshParsed = 0;
 
-      pose = this._blocks[pose_addr].data
-      // debug( 'pose address ',pose[2].elements[12],pose[2].elements[13],pose[2].elements[14] );
-      clip.push( {
-        pose : pose,
-        duration : frame_dur
-      } );
+				while ( subMeshParsed < num_submeshes ) {
 
-      frames_parsed++;
-    }
-    if (clip.length == 0) {
-      // debug("Could not this SkeletonClipNode, because no Frames where set.");
-      return;
-    }
-    // Ignore attributes for now
-    this.parseUserAttributes();
-    return clip;
-  }
+					streamsParsed = 0;
+					str_len = this.readU32();
+					str_end = this._ptr + str_len;
 
+					while ( streamsParsed < num_Streams ) {
 
+						if ( streamtypes[streamsParsed] === 1 ) {
 
-  AWDLoader.prototype.parseVertexAnimationSet = function(len)
-  {
-    var poseBlockAdress,
-        name           = this.readUTF(),
-        num_frames     = this.readU16(),
-        props          = this.parseProperties({1:UINT16}),
-        frames_parsed  = 0,
-        skeletonFrames = [];
+							//geom.addAttribute( 'morphTarget'+frames_parsed, Float32Array, str_len/12, 3 );
+							var buffer = new Float32Array(str_len/4);
+							geom.morphTargets.push( {
+								array : buffer
+							});
 
-    while (frames_parsed < num_frames) {
-      poseBlockAdress = this.readU32();
-      skeletonFrames.push(this._blocks[poseBlockAdress].data);
-      frames_parsed++;
-    }
+							//buffer = geom.attributes['morphTarget'+frames_parsed].array
+							idx = 0;
 
-    this.parseUserAttributes();
+							while ( this._ptr < str_end ) {
+								buffer[idx]     = this.readF32();
+								buffer[idx+1]   = this.readF32();
+								buffer[idx+2]   = this.readF32();
+								idx += 3;
+							}
 
 
-    return skeletonFrames;
-  }
+							subMeshParsed++;
+						} else
+							this._ptr = str_end;
+						streamsParsed++;
+					}
+				}
 
-
-  AWDLoader.prototype.parseAnimatorSet = function(len)
-  {
-    var targetMesh;
-
-    var animSetBlockAdress; //:int
-
-    var targetAnimationSet; //:AnimationSetBase;
-    var outputString = ""; //:String = "";
-    var name = this.readUTF();
-    var type = this.readU16();
-
-    var props = this.parseProperties({1:BADDR});
-
-    animSetBlockAdress = this.readU32();
-    var targetMeshLength = this.readU16();
-
-    var meshAdresses = []; //:Vector.<uint> = new Vector.<uint>;
-
-    for (var i = 0; i < targetMeshLength; i++)
-      meshAdresses.push( this.readU32() );
-
-    var activeState = this.readU16();
-    var autoplay = Boolean(this.readU8());
-    this.parseUserAttributes();
-    this.parseUserAttributes();
-
-    var returnedArray;
-    var targetMeshes = []; //:Vector.<Mesh> = new Vector.<Mesh>;
-
-    for (i = 0; i < meshAdresses.length; i++) {
-//      returnedArray = getAssetByID(meshAdresses[i], [AssetType.MESH]);
-//      if (returnedArray[0])
-        targetMeshes.push(this._blocks[meshAdresses[i]].data);
-    }
-
-    targetAnimationSet = this._blocks[animSetBlockAdress].data
-    var thisAnimator;
-
-    if (type == 1) {
-
-
-      thisAnimator = {
-        animationSet : targetAnimationSet,
-        skeleton : this._blocks[props.get(1, 0)].data
-      };
-
-    } else if (type == 2) {
-      // debug( "vertex Anim???");
-    }
-
-
-    for (i = 0; i < targetMeshes.length; i++) {
-        targetMeshes[i].animator = thisAnimator;
-    }
-    // debug("Parsed a Animator: Name = " + name);
-
-    return thisAnimator;
-  }
-
-
-
-
-
-
-
-  AWDLoader.prototype.parseMeshData = function ( len ) {
-
-    var name      = this.readUTF(),
-        num_subs  = this.readU16(),
-        geom,
-        subs_parsed = 0,
-        props,
-        buffer,
-        skinW, skinI,
-        geometries = [];
-
-
-
-
-    props = this.parseProperties({
-      1: this._geoNrType,
-      2: this._geoNrType
-    });
-
-
-
-    // Loop through sub meshes
-    while (subs_parsed < num_subs) {
-
-      var sm_len, sm_end, attrib;
-
-      geom = new THREE.BufferGeometry();
-      geom.name = name;
-      geometries.push( geom );
-
-
-      sm_len = this.readU32();
-      sm_end = this._ptr + sm_len;
-
-
-      // Ignore for now
-      this.parseProperties({1:this._geoNrType, 2:this._geoNrType});
-
-      // Loop through data streams
-      while ( this._ptr < sm_end ) {
-
-
-        var idx = 0,
-            str_type  = this.readU8(),
-            str_ftype = this.readU8(),
-            str_len   = this.readU32(),
-            str_end   = str_len + this._ptr;
-
-
-
-
-
-        // VERTICES
-        // ------------------
-        if ( str_type === 1 ) {
-
-          buffer = new Float32Array( ( str_len / 12 ) * 3 );
-          attrib = new THREE.BufferAttribute( buffer, 3 );
-
-          geom.addAttribute( 'position', attrib );
-          idx = 0;
-
-          while (this._ptr < str_end) {
-            buffer[idx]   = -this.readF32();
-            buffer[idx+1] = this.readF32();
-            buffer[idx+2] = this.readF32();
-            idx+=3;
-          }
-        }
-
-
-        // INDICES
-        // -----------------
-        else if (str_type === 2) {
-
-          buffer = new Uint16Array( str_len / 2 );
-          attrib = new THREE.BufferAttribute( buffer, 1 );
-          geom.addAttribute( 'index', attrib );
-
-          geom.offsets.push({
-            start: 0,
-            index: 0,
-            count: str_len/2
-          });
-
-          idx = 0;
-
-          while (this._ptr < str_end) {
-            buffer[idx+1]   = this.readU16();
-            buffer[idx]     = this.readU16();
-            buffer[idx+2]   = this.readU16();
-            idx+=3;
-          }
-        }
-
-        // UVS
-        // -------------------
-        else if (str_type === 3) {
-
-          buffer = new Float32Array( ( str_len / 8 ) * 2 );
-          attrib = new THREE.BufferAttribute( buffer, 2 );
-
-          geom.addAttribute( 'uv', attrib );
-          idx = 0;
-
-          while (this._ptr < str_end) {
-            buffer[idx]   = this.readF32();
-            buffer[idx+1] = 1.0-this.readF32();
-            idx+=2;
-          }
-        }
-
-        // NORMALS
-        else if (str_type === 4) {
-
-          buffer = new Float32Array( ( str_len / 12 ) * 3 );
-          attrib = new THREE.BufferAttribute( buffer, 3 );
-          geom.addAttribute( 'normal', attrib );
-          idx = 0;
-
-          while (this._ptr < str_end) {
-            buffer[idx]   = -this.readF32();
-            buffer[idx+1] = this.readF32();
-            buffer[idx+2] = this.readF32();
-            idx+=3;
-          }
-
-        }
-
-        // else if (str_type == 6) {
-        //   skinI = new Float32Array( str_len>>1 );
-        //   idx = 0
-
-        //   while (this._ptr < str_end) {
-        //     skinI[idx]   = this.readU16();
-        //     idx++;
-        //   }
-
-        // }
-        // else if (str_type == 7) {
-        //   skinW = new Float32Array( str_len>>2 );
-        //   idx = 0;
-
-        //   while (this._ptr < str_end) {
-        //     skinW[idx]   = this.readF32();
-        //     idx++;
-        //   }
-        // }
-        else {
-          this._ptr = str_end;
-        }
-
-
-
-      }
-
-      this.parseUserAttributes();
-
-
-      geom.computeBoundingSphere();
-      subs_parsed++;
-    }
-
-
-    //geom.computeFaceNormals();
-
-
-    this.parseUserAttributes();
-    //finalizeAsset(geom, name);
-
-    return geometries;
-  }
-
-  AWDLoader.prototype.parseMeshPoseAnimation = function(len, poseOnly)
-  {
-    var num_frames = 1,
-        num_submeshes,
-        frames_parsed,
-        subMeshParsed,
-        frame_dur,
-        x, y, z,
-
-        str_len,
-        str_end,
-        geom,
-        subGeom,
-        idx = 0,
-        clip = {},
-        indices,
-        verts,
-        num_Streams,
-        streamsParsed,
-        streamtypes = [],
-
-        props,
-        thisGeo,
-        name = this.readUTF(),
-        geoAdress = this.readU32();
-
-
-    var mesh = this.getBlock( geoAdress );
-
-    if (mesh == null) {
-      console.log( "parseMeshPoseAnimation target mesh not found at:", geoAdress );
-      return;
-    }
-
-    geom = mesh.geometry;
-    geom.morphTargets = [];
-
-    if (!poseOnly)
-      num_frames = this.readU16();
-
-    num_submeshes = this.readU16();
-    num_Streams = this.readU16();
-
-    // debug("VA num_frames : ", num_frames );
-    // debug("VA num_submeshes : ", num_submeshes );
-    // debug("VA numstreams : ", num_Streams );
-
-    streamsParsed = 0;
-    while (streamsParsed < num_Streams) {
-      streamtypes.push(this.readU16());
-      streamsParsed++;
-    }
-    props = this.parseProperties({1:BOOL, 2:BOOL});
-
-    clip.looping = props.get(1, true);
-    clip.stitchFinalFrame = props.get(2, false);
-
-    frames_parsed = 0;
-
-    while (frames_parsed < num_frames) {
-
-      frame_dur = this.readU16();
-      subMeshParsed = 0;
-
-      while (subMeshParsed < num_submeshes) {
-
-        streamsParsed = 0;
-        str_len = this.readU32();
-        str_end = this._ptr + str_len;
-
-        while (streamsParsed < num_Streams) {
-
-          if (streamtypes[streamsParsed] == 1) {
-
-            //geom.addAttribute( 'morphTarget'+frames_parsed, Float32Array, str_len/12, 3 );
-            var buffer = new Float32Array(str_len/4);
-            geom.morphTargets.push( {
-              array : buffer
-            });
-
-            //buffer = geom.attributes['morphTarget'+frames_parsed].array
-            idx = 0;
-
-            while ( this._ptr < str_end ) {
-              buffer[idx]     = this.readF32();
-              buffer[idx+1]   = this.readF32();
-              buffer[idx+2]   = this.readF32();
-              idx += 3;
-            }
-
-
-            subMeshParsed++;
-          } else
-            this._ptr = str_end;
-          streamsParsed++;
-        }
-      }
-
-
-      frames_parsed++;
-    }
-    this.parseUserAttributes();
-
-    return null;
-  }
-
-
-
-
-
-
-
-
-
-  AWDLoader.prototype.getBlock = function ( id ) {
-    return this._blocks[id].data;
-  },
-
-
-  AWDLoader.prototype.parseMatrix4 = function ( ) {
-    var mtx = new THREE.Matrix4();
-    var e = mtx.elements;
-
-    e[0] = this.readF32();
-    e[1] = this.readF32();
-    e[2] = this.readF32();
-    e[3] = 0.0;
-    //e[3] = 0.0;
-
-    e[4] = this.readF32();
-    e[5] = this.readF32();
-    e[6] = this.readF32();
-    //e[7] = this.readF32();
-    e[7] = 0.0;
-
-    e[8] = this.readF32();
-    e[9] = this.readF32();
-    e[10] = this.readF32();
-    //e[11] = this.readF32();
-    e[11] = 0.0;
-
-    e[12] = -this.readF32();
-    e[13] = this.readF32();
-    e[14] = this.readF32();
-    //e[15] = this.readF32();
-    e[15] = 1.0;
-    return mtx;
-  }
-
-
-  AWDLoader.prototype.parseProperties = function ( expected ) {
-    var list_len = this.readU32();
-    var list_end = this._ptr + list_len;
-
-    var props = new AWDProperties();
-
-    if( expected ) {
-
-      while( this._ptr < list_end ) {
-
-        var key = this.readU16();
-        var len = this.readU32();
-        var type;
-
-        if( expected.hasOwnProperty( key ) ) {
-          type = expected[ key ];
-          props.set( key, this.parseAttrValue( type, len ) );
-        } else {
-          this._ptr += len;
-        }
-      }
-
-    }
-
-    return props;
-
-  };
-
-
-  AWDLoader.prototype.parseUserAttributes = function ( ) {
-    // skip for now
-    this._ptr = this.readU32() + this._ptr;
-    return null;
-  };
-
-
-  AWDLoader.prototype.parseAttrValue = function ( type, len ) {
-
-    var elem_len;
-    var read_func;
-
-    switch (type) {
-      case AWD_FIELD_INT8:
-        elem_len = 1;
-        read_func = this.readI8;
-        break;
-      case AWD_FIELD_INT16:
-        elem_len = 2;
-        read_func = this.readI16;
-        break;
-      case AWD_FIELD_INT32:
-        elem_len = 4;
-        read_func = this.readI32;
-        break;
-      case AWD_FIELD_BOOL:
-      case AWD_FIELD_UINT8:
-        elem_len = 1;
-        read_func = this.readU8;
-        break;
-      case AWD_FIELD_UINT16:
-        elem_len = 2;
-        read_func = this.readU16;
-        break;
-      case AWD_FIELD_UINT32:
-      case AWD_FIELD_BADDR:
-        elem_len = 4;
-        read_func = this.readU32;
-        break;
-      case AWD_FIELD_FLOAT32:
-        elem_len = 4;
-        read_func = this.readF32;
-        break;
-      case AWD_FIELD_FLOAT64:
-        elem_len = 8;
-        read_func = this.readF64;
-        break;
-      case AWD_FIELD_VECTOR2x1:
-      case AWD_FIELD_VECTOR3x1:
-      case AWD_FIELD_VECTOR4x1:
-      case AWD_FIELD_MTX3x2:
-      case AWD_FIELD_MTX3x3:
-      case AWD_FIELD_MTX4x3:
-      case AWD_FIELD_MTX4x4:
-        elem_len = 8;
-        read_func = this.readF64;
-        break;
-    }
-
-    if (elem_len < len) {
-      var list;
-      var num_read;
-      var num_elems;
-
-      list = [];
-      num_read = 0;
-      num_elems = len / elem_len;
-
-      while (num_read < num_elems) {
-        list.push(read_func.call( this ) );
-        num_read++;
-      }
-
-      return list;
-    }
-    else {
-      return read_func.call( this );
-    }
-
-  }
-
-
-  AWDLoader.prototype.readU8 = function () {
-    return this._data.getUint8( this._ptr++ );
-  }
-  AWDLoader.prototype.readI8 = function () {
-    return this._data.getInt8( this._ptr++ );
-  }
-
-  AWDLoader.prototype.readU16 = function () {
-    var a = this._data.getUint16( this._ptr, littleEndian );
-    this._ptr += 2;
-    return a;
-  }
-  AWDLoader.prototype.readI16 = function () {
-    var a = this._data.getInt16( this._ptr, littleEndian );
-    this._ptr += 2;
-    return a;
-  }
-
-  AWDLoader.prototype.readU32 = function () {
-    var a = this._data.getUint32( this._ptr, littleEndian );
-    this._ptr += 4;
-    return a;
-  }
-  AWDLoader.prototype.readI32 = function () {
-    var a = this._data.getInt32( this._ptr, littleEndian );
-    this._ptr += 4;
-    return a;
-  }
-  AWDLoader.prototype.readF32 = function () {
-    var a = this._data.getFloat32( this._ptr, littleEndian );
-    this._ptr += 4;
-    return a;
-  }
-  AWDLoader.prototype.readF64 = function () {
-    var a = this._data.getFloat64( this._ptr, littleEndian );
-    this._ptr += 8;
-    return a;
-  }
-
-
-  /**
-   * Converts a UTF-8 byte array to JavaScript's 16-bit Unicode.
-   * @param {Array.<number>} bytes UTF-8 byte array.
-   * @return {string} 16-bit Unicode string.
-   */
-  AWDLoader.prototype.readUTF = function () {
-    var len = this.readU16();
-
-    return this.readUTFBytes( len );
-  };
-
-  /**
-   * Converts a UTF-8 byte array to JavaScript's 16-bit Unicode.
-   * @param {Array.<number>} bytes UTF-8 byte array.
-   * @return {string} 16-bit Unicode string.
-   */
-  AWDLoader.prototype.readUTFBytes = function ( len ) {
-
-
-    // TODO(user): Use native implementations if/when available
-
-    var out = [], c = 0;
-
-    while ( out.length < len ) {
-      var c1 = this._data.getUint8( this._ptr++, littleEndian );
-      if (c1 < 128) {
-        out[c++] = String.fromCharCode(c1);
-      } else if (c1 > 191 && c1 < 224) {
-        var c2 = this._data.getUint8( this._ptr++, littleEndian );
-        out[c++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63);
-      } else {
-        var c2 = this._data.getUint8( this._ptr++, littleEndian );
-        var c3 = this._data.getUint8( this._ptr++, littleEndian );
-        out[c++] = String.fromCharCode(
-            (c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63
-        );
-      }
-    }
-    return out.join('');
-  };
-
-
-
-
-
-
-
-
-
-  AWDProperties = function(){}
-
-  AWDProperties.prototype = {
-
-
-    set : function(key, value)
-    {
-      this[key] = value;
-    },
-
-    get : function(key, fallback)
-    {
-      if ( this.hasOwnProperty(key) )
-        return this[key];
-      else return fallback;
-    }
-  }
-
-  return AWDLoader;
+
+				frames_parsed++;
+			}
+
+			this.parseUserAttributes();
+
+			return null;
+		},
+
+		getBlock: function ( id ) {
+
+			return this._blocks[id].data;
+
+		},
+
+		parseMatrix4: function () {
+
+			var mtx = new THREE.Matrix4();
+			var e = mtx.elements;
+
+			e[0] = this.readF32();
+			e[1] = this.readF32();
+			e[2] = this.readF32();
+			e[3] = 0.0;
+			//e[3] = 0.0;
+
+			e[4] = this.readF32();
+			e[5] = this.readF32();
+			e[6] = this.readF32();
+			//e[7] = this.readF32();
+			e[7] = 0.0;
+
+			e[8] = this.readF32();
+			e[9] = this.readF32();
+			e[10] = this.readF32();
+			//e[11] = this.readF32();
+			e[11] = 0.0;
+
+			e[12] = -this.readF32();
+			e[13] = this.readF32();
+			e[14] = this.readF32();
+			//e[15] = this.readF32();
+			e[15] = 1.0;
+			return mtx;
+
+		},
+
+		parseProperties: function ( expected ) {
+			var list_len = this.readU32();
+			var list_end = this._ptr + list_len;
+
+			var props = new AWDProperties();
+
+			if( expected ) {
+
+				while( this._ptr < list_end ) {
+
+					var key = this.readU16();
+					var len = this.readU32();
+					var type;
+
+					if( expected.hasOwnProperty( key ) ) {
+						type = expected[ key ];
+						props.set( key, this.parseAttrValue( type, len ) );
+					} else {
+						this._ptr += len;
+					}
+				}
+
+			}
+
+			return props;
+		},
+
+		parseUserAttributes: function ( ) {
+			// skip for now
+			this._ptr = this.readU32() + this._ptr;
+			return null;
+		},
+
+		parseAttrValue: function ( type, len ) {
+			var elem_len;
+			var read_func;
+
+			switch (type) {
+				case AWD_FIELD_INT8:
+					elem_len = 1;
+					read_func = this.readI8;
+					break;
+				case AWD_FIELD_INT16:
+					elem_len = 2;
+					read_func = this.readI16;
+					break;
+				case AWD_FIELD_INT32:
+					elem_len = 4;
+					read_func = this.readI32;
+					break;
+				case AWD_FIELD_BOOL:
+				case AWD_FIELD_UINT8:
+					elem_len = 1;
+					read_func = this.readU8;
+					break;
+				case AWD_FIELD_UINT16:
+					elem_len = 2;
+					read_func = this.readU16;
+					break;
+				case AWD_FIELD_UINT32:
+				case AWD_FIELD_BADDR:
+					elem_len = 4;
+					read_func = this.readU32;
+					break;
+				case AWD_FIELD_FLOAT32:
+					elem_len = 4;
+					read_func = this.readF32;
+					break;
+				case AWD_FIELD_FLOAT64:
+					elem_len = 8;
+					read_func = this.readF64;
+					break;
+				case AWD_FIELD_VECTOR2x1:
+				case AWD_FIELD_VECTOR3x1:
+				case AWD_FIELD_VECTOR4x1:
+				case AWD_FIELD_MTX3x2:
+				case AWD_FIELD_MTX3x3:
+				case AWD_FIELD_MTX4x3:
+				case AWD_FIELD_MTX4x4:
+					elem_len = 8;
+					read_func = this.readF64;
+					break;
+			}
+
+			if (elem_len < len) {
+				var list;
+				var num_read;
+				var num_elems;
+
+				list = [];
+				num_read = 0;
+				num_elems = len / elem_len;
+
+				while (num_read < num_elems) {
+					list.push(read_func.call( this ) );
+					num_read++;
+				}
+
+				return list;
+			}
+			else {
+				return read_func.call( this );
+			}
+		},
+
+		readU8: function () {
+			return this._data.getUint8( this._ptr++ );
+		},
+		readI8: function () {
+			return this._data.getInt8( this._ptr++ );
+		},
+		readU16: function () {
+			var a = this._data.getUint16( this._ptr, littleEndian );
+			this._ptr += 2;
+			return a;
+		},
+		readI16: function () {
+			var a = this._data.getInt16( this._ptr, littleEndian );
+			this._ptr += 2;
+			return a;
+		},
+		readU32: function () {
+			var a = this._data.getUint32( this._ptr, littleEndian );
+			this._ptr += 4;
+			return a;
+		},
+		readI32: function () {
+			var a = this._data.getInt32( this._ptr, littleEndian );
+			this._ptr += 4;
+			return a;
+		},
+		readF32: function () {
+			var a = this._data.getFloat32( this._ptr, littleEndian );
+			this._ptr += 4;
+			return a;
+		},
+		readF64: function () {
+			var a = this._data.getFloat64( this._ptr, littleEndian );
+			this._ptr += 8;
+			return a;
+		},
+
+		/**
+	 * Converts a UTF-8 byte array to JavaScript's 16-bit Unicode.
+	 * @param {Array.<number>} bytes UTF-8 byte array.
+	 * @return {string} 16-bit Unicode string.
+	 */
+		readUTF: function () {
+			var len = this.readU16();
+			return this.readUTFBytes( len );
+		},
+
+		/**
+		 * Converts a UTF-8 byte array to JavaScript's 16-bit Unicode.
+		 * @param {Array.<number>} bytes UTF-8 byte array.
+		 * @return {string} 16-bit Unicode string.
+		 */
+		readUTFBytes: function ( len ) {
+			// TODO(user): Use native implementations if/when available
+			var out = [], c = 0;
+
+			while ( out.length < len ) {
+				var c1 = this._data.getUint8( this._ptr++, littleEndian );
+				if (c1 < 128) {
+					out[c++] = String.fromCharCode(c1);
+				} else if (c1 > 191 && c1 < 224) {
+					var c2 = this._data.getUint8( this._ptr++, littleEndian );
+					out[c++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63);
+				} else {
+					var c2 = this._data.getUint8( this._ptr++, littleEndian );
+					var c3 = this._data.getUint8( this._ptr++, littleEndian );
+					out[c++] = String.fromCharCode(
+							(c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63
+					);
+				}
+			}
+			return out.join('');
+		}
+
+	};
 
 })();

+ 8 - 6
examples/js/loaders/AssimpJSONLoader.js

@@ -20,13 +20,11 @@ THREE.AssimpJSONLoader.prototype = {
 
 	constructor: THREE.AssimpJSONLoader,
 
-	texturePath : '',
-
-	load: function ( url, onLoad, onProgress, onError, texturePath ) {
+	load: function ( url, onLoad, onProgress, onError ) {
 
 		var scope = this;
 
-		this.texturePath = texturePath && ( typeof texturePath === "string" ) ? texturePath : this.extractUrlBase( url );
+		this.texturePath = this.texturePath && ( typeof this.texturePath === "string" ) ? this.texturePath : this.extractUrlBase( url );
 
 		var loader = new THREE.XHRLoader( this.manager );
 		loader.setCrossOrigin( this.crossOrigin );
@@ -60,6 +58,10 @@ THREE.AssimpJSONLoader.prototype = {
 		this.crossOrigin = value;
 	},
 
+	setTexturePath: function ( value ) {
+		this.texturePath = value;
+	}
+
 	extractUrlBase: function ( url ) { // from three/src/loaders/Loader.js
 		var parts = url.split( '/' );
 		parts.pop();
@@ -189,7 +191,7 @@ THREE.AssimpJSONLoader.prototype = {
 	},
 
 	parseMaterial : function(json) {
-		var mat = null, 
+		var mat = null,
 		scope = this, i, prop, has_textures = [],
 
 		init_props = {
@@ -293,7 +295,7 @@ THREE.AssimpJSONLoader.prototype = {
 				init_props[has_textures[i]] = defaultTexture();
 			}
 		}
-		
+
 		mat = new THREE.MeshPhongMaterial( init_props );
 		return mat;
 	},

+ 1 - 1
examples/js/loaders/BabylonLoader.js

@@ -16,7 +16,7 @@ THREE.BabylonLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.XHRLoader( this.manager );
 		loader.setCrossOrigin( this.crossOrigin );
 		loader.load( url, function ( text ) {
 

+ 449 - 506
examples/js/loaders/BinaryLoader.js

@@ -2,751 +2,694 @@
  * @author alteredq / http://alteredqualia.com/
  */
 
-THREE.BinaryLoader = function ( showStatus ) {
+THREE.BinaryLoader = function ( manager ) {
 
-	THREE.Loader.call( this, showStatus );
+	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
 
 };
 
-THREE.BinaryLoader.prototype = Object.create( THREE.Loader.prototype );
-THREE.BinaryLoader.prototype.constructor = THREE.BinaryLoader;
+THREE.BinaryLoader.prototype = {
 
-// Load models generated by slim OBJ converter with BINARY option (converter_obj_three_slim.py -t binary)
-//  - binary models consist of two files: JS and BIN
-//  - parameters
-//		- url (required)
-//		- callback (required)
-//		- texturePath (optional: if not specified, textures will be assumed to be in the same folder as JS model file)
-//		- binaryPath (optional: if not specified, binary file will be assumed to be in the same folder as JS model file)
+	constructor: THREE.BinaryLoader,
 
-THREE.BinaryLoader.prototype.load = function ( url, callback, texturePath, binaryPath ) {
+	// Load models generated by slim OBJ converter with BINARY option (converter_obj_three_slim.py -t binary)
+	//  - binary models consist of two files: JS and BIN
+	//  - parameters
+	//		- url (required)
+	//		- callback (required)
+	//		- texturePath (optional: if not specified, textures will be assumed to be in the same folder as JS model file)
+	//		- binaryPath (optional: if not specified, binary file will be assumed to be in the same folder as JS model file)
+	load: function ( url, onLoad, onProgress, onError ) {
 
-	// todo: unify load API to for easier SceneLoader use
+		// todo: unify load API to for easier SceneLoader use
 
-	texturePath = texturePath || this.extractUrlBase( url );
-	binaryPath = binaryPath || this.extractUrlBase( url );
+		var texturePath = this.texturePath || THREE.Loader.prototype.extractUrlBase( url );
+		var binaryPath  = this.binaryPath || THREE.Loader.prototype.extractUrlBase( url );
 
-	var callbackProgress = this.showProgress ? THREE.Loader.prototype.updateProgress : undefined;
+		// #1 load JS part via web worker
 
-	this.onLoadStart();
+		var scope = this;
 
-	// #1 load JS part via web worker
+		var jsonloader = new THREE.XHRLoader( this.manager );
+		jsonloader.setCrossOrigin( this.crossOrigin );
+		jsonloader.load( url, function ( data ) {
 
-	this.loadAjaxJSON( this, url, callback, texturePath, binaryPath, callbackProgress );
+			var json = JSON.parse( data );
 
-};
-
-THREE.BinaryLoader.prototype.loadAjaxJSON = function ( context, url, callback, texturePath, binaryPath, callbackProgress ) {
-
-	var xhr = new XMLHttpRequest();
-
-	texturePath = texturePath && ( typeof texturePath === "string" ) ? texturePath : this.extractUrlBase( url );
-	binaryPath = binaryPath && ( typeof binaryPath === "string" ) ? binaryPath : this.extractUrlBase( url );
-
-	xhr.onreadystatechange = function () {
-
-		if ( xhr.readyState == 4 ) {
-
-			if ( xhr.status == 200 || xhr.status == 0 ) {
-
-				var json = JSON.parse( xhr.responseText );
-				context.loadAjaxBuffers( json, callback, binaryPath, texturePath, callbackProgress );
-
-			} else {
-
-				console.error( "THREE.BinaryLoader: Couldn't load [" + url + "] [" + xhr.status + "]" );
-
-			}
-
-		}
-
-	};
-
-	xhr.open( "GET", url, true );
-	xhr.send( null );
-
-};
-
-THREE.BinaryLoader.prototype.loadAjaxBuffers = function ( json, callback, binaryPath, texturePath, callbackProgress ) {
-
-	var scope = this;
-
-	var xhr = new XMLHttpRequest(),
-		url = binaryPath + json.buffers;
-
-	xhr.addEventListener( 'load', function ( event ) {
-
-		var buffer = xhr.response;
-
-		if ( buffer === undefined ) {
-
-			// IEWEBGL needs this
-			buffer = ( new Uint8Array( xhr.responseBody ) ).buffer;
-
-		}
-
-		if ( buffer.byteLength == 0 ) {  // iOS and other XMLHttpRequest level 1
-
-			var buffer = new ArrayBuffer( xhr.responseText.length );
-
-			var bufView = new Uint8Array( buffer );
-
-			for ( var i = 0, l = xhr.responseText.length; i < l; i ++ ) {
+			var bufferUrl = binaryPath + json.buffers;
 
-				bufView[ i ] = xhr.responseText.charCodeAt( i ) & 0xff;
+			var bufferLoader = new THREE.XHRLoader( scope.manager );
+			bufferLoader.setCrossOrigin( scope.crossOrigin );
+			bufferLoader.setResponseType( 'arraybuffer' );
+			bufferLoader.load( bufferUrl, function ( bufData ) {
 
-			}
+				// IEWEBGL needs this ???
+				//buffer = ( new Uint8Array( xhr.responseBody ) ).buffer;
 
-		}
+				//// iOS and other XMLHttpRequest level 1 ???
 
-		scope.createBinModel( buffer, callback, texturePath, json.materials );
+				scope.parse( bufData, onLoad, texturePath, json.materials );
 
-	}, false );
+			}, onProgress, onError);
 
-	if ( callbackProgress !== undefined ) {
+		}, onProgress, onError );
 
-		xhr.addEventListener( 'progress', function ( event ) {
+	},
 
-			if ( event.lengthComputable ) {
+	setBinaryPath: function ( value ) {
 
-				callbackProgress( event );
+		this.binaryPath = value;
 
-			}
+	},
 
-		}, false );
+	setCrossOrigin: function ( value ) {
 
-	}
-
-	xhr.addEventListener( 'error', function ( event ) {
+		this.crossOrigin = value;
 
-		console.error( "THREE.BinaryLoader: Couldn't load [" + url + "] [" + xhr.status + "]" );
+	},
 
-	}, false );
+	setTexturePath: function ( value ) {
 
+		this.texturePath = value;
 
-	xhr.open( "GET", url, true );
-	xhr.responseType = "arraybuffer";
-	if ( xhr.overrideMimeType ) xhr.overrideMimeType( "text/plain; charset=x-user-defined" );
-	xhr.send( null );
-
-};
+	},
 
-// Binary AJAX parser
+	parse: function ( data, callback, texturePath, jsonMaterials ) {
 
-THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texturePath, jsonMaterials ) {
+		var Model = function ( texturePath ) {
 
-	var Model = function ( texturePath ) {
+			var scope = this,
+				currentOffset = 0,
+				md,
+				normals = [],
+				uvs = [],
+				start_tri_flat, start_tri_smooth, start_tri_flat_uv, start_tri_smooth_uv,
+				start_quad_flat, start_quad_smooth, start_quad_flat_uv, start_quad_smooth_uv,
+				tri_size, quad_size,
+				len_tri_flat, len_tri_smooth, len_tri_flat_uv, len_tri_smooth_uv,
+				len_quad_flat, len_quad_smooth, len_quad_flat_uv, len_quad_smooth_uv;
 
-		var scope = this,
-			currentOffset = 0,
-			md,
-			normals = [],
-			uvs = [],
-			start_tri_flat, start_tri_smooth, start_tri_flat_uv, start_tri_smooth_uv,
-			start_quad_flat, start_quad_smooth, start_quad_flat_uv, start_quad_smooth_uv,
-			tri_size, quad_size,
-			len_tri_flat, len_tri_smooth, len_tri_flat_uv, len_tri_smooth_uv,
-			len_quad_flat, len_quad_smooth, len_quad_flat_uv, len_quad_smooth_uv;
 
+			THREE.Geometry.call( this );
 
-		THREE.Geometry.call( this );
+			md = parseMetaData( data, currentOffset );
 
-		md = parseMetaData( data, currentOffset );
+			currentOffset += md.header_bytes;
+	/*
+			md.vertex_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
+			md.material_index_bytes = Uint16Array.BYTES_PER_ELEMENT;
+			md.normal_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
+			md.uv_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
+	*/
+			// buffers sizes
 
-		currentOffset += md.header_bytes;
-/*
-		md.vertex_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
-		md.material_index_bytes = Uint16Array.BYTES_PER_ELEMENT;
-		md.normal_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
-		md.uv_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
-*/
-		// buffers sizes
+			tri_size =  md.vertex_index_bytes * 3 + md.material_index_bytes;
+			quad_size = md.vertex_index_bytes * 4 + md.material_index_bytes;
 
-		tri_size =  md.vertex_index_bytes * 3 + md.material_index_bytes;
-		quad_size = md.vertex_index_bytes * 4 + md.material_index_bytes;
+			len_tri_flat      = md.ntri_flat      * ( tri_size );
+			len_tri_smooth    = md.ntri_smooth    * ( tri_size + md.normal_index_bytes * 3 );
+			len_tri_flat_uv   = md.ntri_flat_uv   * ( tri_size + md.uv_index_bytes * 3 );
+			len_tri_smooth_uv = md.ntri_smooth_uv * ( tri_size + md.normal_index_bytes * 3 + md.uv_index_bytes * 3 );
 
-		len_tri_flat      = md.ntri_flat      * ( tri_size );
-		len_tri_smooth    = md.ntri_smooth    * ( tri_size + md.normal_index_bytes * 3 );
-		len_tri_flat_uv   = md.ntri_flat_uv   * ( tri_size + md.uv_index_bytes * 3 );
-		len_tri_smooth_uv = md.ntri_smooth_uv * ( tri_size + md.normal_index_bytes * 3 + md.uv_index_bytes * 3 );
+			len_quad_flat      = md.nquad_flat      * ( quad_size );
+			len_quad_smooth    = md.nquad_smooth    * ( quad_size + md.normal_index_bytes * 4 );
+			len_quad_flat_uv   = md.nquad_flat_uv   * ( quad_size + md.uv_index_bytes * 4 );
+			len_quad_smooth_uv = md.nquad_smooth_uv * ( quad_size + md.normal_index_bytes * 4 + md.uv_index_bytes * 4 );
 
-		len_quad_flat      = md.nquad_flat      * ( quad_size );
-		len_quad_smooth    = md.nquad_smooth    * ( quad_size + md.normal_index_bytes * 4 );
-		len_quad_flat_uv   = md.nquad_flat_uv   * ( quad_size + md.uv_index_bytes * 4 );
-		len_quad_smooth_uv = md.nquad_smooth_uv * ( quad_size + md.normal_index_bytes * 4 + md.uv_index_bytes * 4 );
+			// read buffers
 
-		// read buffers
+			currentOffset += init_vertices( currentOffset );
 
-		currentOffset += init_vertices( currentOffset );
+			currentOffset += init_normals( currentOffset );
+			currentOffset += handlePadding( md.nnormals * 3 );
 
-		currentOffset += init_normals( currentOffset );
-		currentOffset += handlePadding( md.nnormals * 3 );
+			currentOffset += init_uvs( currentOffset );
 
-		currentOffset += init_uvs( currentOffset );
+			start_tri_flat 		= currentOffset;
+			start_tri_smooth    = start_tri_flat    + len_tri_flat    + handlePadding( md.ntri_flat * 2 );
+			start_tri_flat_uv   = start_tri_smooth  + len_tri_smooth  + handlePadding( md.ntri_smooth * 2 );
+			start_tri_smooth_uv = start_tri_flat_uv + len_tri_flat_uv + handlePadding( md.ntri_flat_uv * 2 );
 
-		start_tri_flat 		= currentOffset;
-		start_tri_smooth    = start_tri_flat    + len_tri_flat    + handlePadding( md.ntri_flat * 2 );
-		start_tri_flat_uv   = start_tri_smooth  + len_tri_smooth  + handlePadding( md.ntri_smooth * 2 );
-		start_tri_smooth_uv = start_tri_flat_uv + len_tri_flat_uv + handlePadding( md.ntri_flat_uv * 2 );
+			start_quad_flat     = start_tri_smooth_uv + len_tri_smooth_uv  + handlePadding( md.ntri_smooth_uv * 2 );
+			start_quad_smooth   = start_quad_flat     + len_quad_flat	   + handlePadding( md.nquad_flat * 2 );
+			start_quad_flat_uv  = start_quad_smooth   + len_quad_smooth    + handlePadding( md.nquad_smooth * 2 );
+			start_quad_smooth_uv= start_quad_flat_uv  + len_quad_flat_uv   + handlePadding( md.nquad_flat_uv * 2 );
 
-		start_quad_flat     = start_tri_smooth_uv + len_tri_smooth_uv  + handlePadding( md.ntri_smooth_uv * 2 );
-		start_quad_smooth   = start_quad_flat     + len_quad_flat	   + handlePadding( md.nquad_flat * 2 );
-		start_quad_flat_uv  = start_quad_smooth   + len_quad_smooth    + handlePadding( md.nquad_smooth * 2 );
-		start_quad_smooth_uv= start_quad_flat_uv  + len_quad_flat_uv   + handlePadding( md.nquad_flat_uv * 2 );
+			// have to first process faces with uvs
+			// so that face and uv indices match
 
-		// have to first process faces with uvs
-		// so that face and uv indices match
+			init_triangles_flat_uv( start_tri_flat_uv );
+			init_triangles_smooth_uv( start_tri_smooth_uv );
 
-		init_triangles_flat_uv( start_tri_flat_uv );
-		init_triangles_smooth_uv( start_tri_smooth_uv );
+			init_quads_flat_uv( start_quad_flat_uv );
+			init_quads_smooth_uv( start_quad_smooth_uv );
 
-		init_quads_flat_uv( start_quad_flat_uv );
-		init_quads_smooth_uv( start_quad_smooth_uv );
+			// now we can process untextured faces
 
-		// now we can process untextured faces
+			init_triangles_flat( start_tri_flat );
+			init_triangles_smooth( start_tri_smooth );
 
-		init_triangles_flat( start_tri_flat );
-		init_triangles_smooth( start_tri_smooth );
+			init_quads_flat( start_quad_flat );
+			init_quads_smooth( start_quad_smooth );
 
-		init_quads_flat( start_quad_flat );
-		init_quads_smooth( start_quad_smooth );
+			this.computeFaceNormals();
 
-		this.computeFaceNormals();
+			function handlePadding( n ) {
 
-		function handlePadding( n ) {
+				return ( n % 4 ) ? ( 4 - n % 4 ) : 0;
 
-			return ( n % 4 ) ? ( 4 - n % 4 ) : 0;
+			};
 
-		};
+			function parseMetaData( data, offset ) {
+
+				var metaData = {
+
+					'signature'               :parseString( data, offset,  12 ),
+					'header_bytes'            :parseUChar8( data, offset + 12 ),
+
+					'vertex_coordinate_bytes' :parseUChar8( data, offset + 13 ),
+					'normal_coordinate_bytes' :parseUChar8( data, offset + 14 ),
+					'uv_coordinate_bytes'     :parseUChar8( data, offset + 15 ),
+
+					'vertex_index_bytes'      :parseUChar8( data, offset + 16 ),
+					'normal_index_bytes'      :parseUChar8( data, offset + 17 ),
+					'uv_index_bytes'          :parseUChar8( data, offset + 18 ),
+					'material_index_bytes'    :parseUChar8( data, offset + 19 ),
+
+					'nvertices'    :parseUInt32( data, offset + 20 ),
+					'nnormals'     :parseUInt32( data, offset + 20 + 4*1 ),
+					'nuvs'         :parseUInt32( data, offset + 20 + 4*2 ),
+
+					'ntri_flat'      :parseUInt32( data, offset + 20 + 4*3 ),
+					'ntri_smooth'    :parseUInt32( data, offset + 20 + 4*4 ),
+					'ntri_flat_uv'   :parseUInt32( data, offset + 20 + 4*5 ),
+					'ntri_smooth_uv' :parseUInt32( data, offset + 20 + 4*6 ),
+
+					'nquad_flat'      :parseUInt32( data, offset + 20 + 4*7 ),
+					'nquad_smooth'    :parseUInt32( data, offset + 20 + 4*8 ),
+					'nquad_flat_uv'   :parseUInt32( data, offset + 20 + 4*9 ),
+					'nquad_smooth_uv' :parseUInt32( data, offset + 20 + 4*10 )
+
+				};
+	/*
+				console.log( "signature: " + metaData.signature );
+
+				console.log( "header_bytes: " + metaData.header_bytes );
+				console.log( "vertex_coordinate_bytes: " + metaData.vertex_coordinate_bytes );
+				console.log( "normal_coordinate_bytes: " + metaData.normal_coordinate_bytes );
+				console.log( "uv_coordinate_bytes: " + metaData.uv_coordinate_bytes );
+
+				console.log( "vertex_index_bytes: " + metaData.vertex_index_bytes );
+				console.log( "normal_index_bytes: " + metaData.normal_index_bytes );
+				console.log( "uv_index_bytes: " + metaData.uv_index_bytes );
+				console.log( "material_index_bytes: " + metaData.material_index_bytes );
+
+				console.log( "nvertices: " + metaData.nvertices );
+				console.log( "nnormals: " + metaData.nnormals );
+				console.log( "nuvs: " + metaData.nuvs );
+
+				console.log( "ntri_flat: " + metaData.ntri_flat );
+				console.log( "ntri_smooth: " + metaData.ntri_smooth );
+				console.log( "ntri_flat_uv: " + metaData.ntri_flat_uv );
+				console.log( "ntri_smooth_uv: " + metaData.ntri_smooth_uv );
+
+				console.log( "nquad_flat: " + metaData.nquad_flat );
+				console.log( "nquad_smooth: " + metaData.nquad_smooth );
+				console.log( "nquad_flat_uv: " + metaData.nquad_flat_uv );
+				console.log( "nquad_smooth_uv: " + metaData.nquad_smooth_uv );
+
+				var total = metaData.header_bytes
+						  + metaData.nvertices * metaData.vertex_coordinate_bytes * 3
+						  + metaData.nnormals * metaData.normal_coordinate_bytes * 3
+						  + metaData.nuvs * metaData.uv_coordinate_bytes * 2
+						  + metaData.ntri_flat * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes )
+						  + metaData.ntri_smooth * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.normal_index_bytes*3 )
+						  + metaData.ntri_flat_uv * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.uv_index_bytes*3 )
+						  + metaData.ntri_smooth_uv * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.normal_index_bytes*3 + metaData.uv_index_bytes*3 )
+						  + metaData.nquad_flat * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes )
+						  + metaData.nquad_smooth * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.normal_index_bytes*4 )
+						  + metaData.nquad_flat_uv * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.uv_index_bytes*4 )
+						  + metaData.nquad_smooth_uv * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.normal_index_bytes*4 + metaData.uv_index_bytes*4 );
+				console.log( "total bytes: " + total );
+	*/
+
+				return metaData;
 
-		function parseMetaData( data, offset ) {
+			};
 
-			var metaData = {
+			function parseString( data, offset, length ) {
 
-				'signature'               :parseString( data, offset,  12 ),
-				'header_bytes'            :parseUChar8( data, offset + 12 ),
+				var charArray = new Uint8Array( data, offset, length );
 
-				'vertex_coordinate_bytes' :parseUChar8( data, offset + 13 ),
-				'normal_coordinate_bytes' :parseUChar8( data, offset + 14 ),
-				'uv_coordinate_bytes'     :parseUChar8( data, offset + 15 ),
+				var text = "";
 
-				'vertex_index_bytes'      :parseUChar8( data, offset + 16 ),
-				'normal_index_bytes'      :parseUChar8( data, offset + 17 ),
-				'uv_index_bytes'          :parseUChar8( data, offset + 18 ),
-				'material_index_bytes'    :parseUChar8( data, offset + 19 ),
+				for ( var i = 0; i < length; i ++ ) {
 
-				'nvertices'    :parseUInt32( data, offset + 20 ),
-				'nnormals'     :parseUInt32( data, offset + 20 + 4*1 ),
-				'nuvs'         :parseUInt32( data, offset + 20 + 4*2 ),
+					text += String.fromCharCode( charArray[ offset + i ] );
 
-				'ntri_flat'      :parseUInt32( data, offset + 20 + 4*3 ),
-				'ntri_smooth'    :parseUInt32( data, offset + 20 + 4*4 ),
-				'ntri_flat_uv'   :parseUInt32( data, offset + 20 + 4*5 ),
-				'ntri_smooth_uv' :parseUInt32( data, offset + 20 + 4*6 ),
+				}
 
-				'nquad_flat'      :parseUInt32( data, offset + 20 + 4*7 ),
-				'nquad_smooth'    :parseUInt32( data, offset + 20 + 4*8 ),
-				'nquad_flat_uv'   :parseUInt32( data, offset + 20 + 4*9 ),
-				'nquad_smooth_uv' :parseUInt32( data, offset + 20 + 4*10 )
+				return text;
 
 			};
-/*
-			console.log( "signature: " + metaData.signature );
-
-			console.log( "header_bytes: " + metaData.header_bytes );
-			console.log( "vertex_coordinate_bytes: " + metaData.vertex_coordinate_bytes );
-			console.log( "normal_coordinate_bytes: " + metaData.normal_coordinate_bytes );
-			console.log( "uv_coordinate_bytes: " + metaData.uv_coordinate_bytes );
-
-			console.log( "vertex_index_bytes: " + metaData.vertex_index_bytes );
-			console.log( "normal_index_bytes: " + metaData.normal_index_bytes );
-			console.log( "uv_index_bytes: " + metaData.uv_index_bytes );
-			console.log( "material_index_bytes: " + metaData.material_index_bytes );
-
-			console.log( "nvertices: " + metaData.nvertices );
-			console.log( "nnormals: " + metaData.nnormals );
-			console.log( "nuvs: " + metaData.nuvs );
-
-			console.log( "ntri_flat: " + metaData.ntri_flat );
-			console.log( "ntri_smooth: " + metaData.ntri_smooth );
-			console.log( "ntri_flat_uv: " + metaData.ntri_flat_uv );
-			console.log( "ntri_smooth_uv: " + metaData.ntri_smooth_uv );
-
-			console.log( "nquad_flat: " + metaData.nquad_flat );
-			console.log( "nquad_smooth: " + metaData.nquad_smooth );
-			console.log( "nquad_flat_uv: " + metaData.nquad_flat_uv );
-			console.log( "nquad_smooth_uv: " + metaData.nquad_smooth_uv );
-
-			var total = metaData.header_bytes
-					  + metaData.nvertices * metaData.vertex_coordinate_bytes * 3
-					  + metaData.nnormals * metaData.normal_coordinate_bytes * 3
-					  + metaData.nuvs * metaData.uv_coordinate_bytes * 2
-					  + metaData.ntri_flat * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes )
-					  + metaData.ntri_smooth * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.normal_index_bytes*3 )
-					  + metaData.ntri_flat_uv * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.uv_index_bytes*3 )
-					  + metaData.ntri_smooth_uv * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.normal_index_bytes*3 + metaData.uv_index_bytes*3 )
-					  + metaData.nquad_flat * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes )
-					  + metaData.nquad_smooth * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.normal_index_bytes*4 )
-					  + metaData.nquad_flat_uv * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.uv_index_bytes*4 )
-					  + metaData.nquad_smooth_uv * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.normal_index_bytes*4 + metaData.uv_index_bytes*4 );
-			console.log( "total bytes: " + total );
-*/
-
-			return metaData;
-
-		};
-
-		function parseString( data, offset, length ) {
-
-			var charArray = new Uint8Array( data, offset, length );
-
-			var text = "";
-
-			for ( var i = 0; i < length; i ++ ) {
 
-				text += String.fromCharCode( charArray[ offset + i ] );
+			function parseUChar8( data, offset ) {
 
-			}
+				var charArray = new Uint8Array( data, offset, 1 );
 
-			return text;
+				return charArray[ 0 ];
 
-		};
-
-		function parseUChar8( data, offset ) {
+			};
 
-			var charArray = new Uint8Array( data, offset, 1 );
+			function parseUInt32( data, offset ) {
 
-			return charArray[ 0 ];
+				var intArray = new Uint32Array( data, offset, 1 );
 
-		};
+				return intArray[ 0 ];
 
-		function parseUInt32( data, offset ) {
-
-			var intArray = new Uint32Array( data, offset, 1 );
+			};
 
-			return intArray[ 0 ];
+			function init_vertices( start ) {
 
-		};
+				var nElements = md.nvertices;
 
-		function init_vertices( start ) {
+				var coordArray = new Float32Array( data, start, nElements * 3 );
 
-			var nElements = md.nvertices;
+				var i, x, y, z;
 
-			var coordArray = new Float32Array( data, start, nElements * 3 );
+				for( i = 0; i < nElements; i ++ ) {
 
-			var i, x, y, z;
+					x = coordArray[ i * 3 ];
+					y = coordArray[ i * 3 + 1 ];
+					z = coordArray[ i * 3 + 2 ];
 
-			for( i = 0; i < nElements; i ++ ) {
+					scope.vertices.push( new THREE.Vector3( x, y, z ) );
 
-				x = coordArray[ i * 3 ];
-				y = coordArray[ i * 3 + 1 ];
-				z = coordArray[ i * 3 + 2 ];
+				}
 
-				scope.vertices.push( new THREE.Vector3( x, y, z ) );
+				return nElements * 3 * Float32Array.BYTES_PER_ELEMENT;
 
-			}
+			};
 
-			return nElements * 3 * Float32Array.BYTES_PER_ELEMENT;
+			function init_normals( start ) {
 
-		};
+				var nElements = md.nnormals;
 
-		function init_normals( start ) {
+				if ( nElements ) {
 
-			var nElements = md.nnormals;
+					var normalArray = new Int8Array( data, start, nElements * 3 );
 
-			if ( nElements ) {
+					var i, x, y, z;
 
-				var normalArray = new Int8Array( data, start, nElements * 3 );
+					for( i = 0; i < nElements; i ++ ) {
 
-				var i, x, y, z;
+						x = normalArray[ i * 3 ];
+						y = normalArray[ i * 3 + 1 ];
+						z = normalArray[ i * 3 + 2 ];
 
-				for( i = 0; i < nElements; i ++ ) {
+						normals.push( x/127, y/127, z/127 );
 
-					x = normalArray[ i * 3 ];
-					y = normalArray[ i * 3 + 1 ];
-					z = normalArray[ i * 3 + 2 ];
-
-					normals.push( x/127, y/127, z/127 );
+					}
 
 				}
 
-			}
+				return nElements * 3 * Int8Array.BYTES_PER_ELEMENT;
 
-			return nElements * 3 * Int8Array.BYTES_PER_ELEMENT;
+			};
 
-		};
+			function init_uvs( start ) {
 
-		function init_uvs( start ) {
+				var nElements = md.nuvs;
 
-			var nElements = md.nuvs;
+				if ( nElements ) {
 
-			if ( nElements ) {
+					var uvArray = new Float32Array( data, start, nElements * 2 );
 
-				var uvArray = new Float32Array( data, start, nElements * 2 );
+					var i, u, v;
 
-				var i, u, v;
+					for( i = 0; i < nElements; i ++ ) {
 
-				for( i = 0; i < nElements; i ++ ) {
+						u = uvArray[ i * 2 ];
+						v = uvArray[ i * 2 + 1 ];
 
-					u = uvArray[ i * 2 ];
-					v = uvArray[ i * 2 + 1 ];
+						uvs.push( u, v );
 
-					uvs.push( u, v );
+					}
 
 				}
 
-			}
+				return nElements * 2 * Float32Array.BYTES_PER_ELEMENT;
 
-			return nElements * 2 * Float32Array.BYTES_PER_ELEMENT;
+			};
 
-		};
+			function init_uvs3( nElements, offset ) {
 
-		function init_uvs3( nElements, offset ) {
+				var i, uva, uvb, uvc, u1, u2, u3, v1, v2, v3;
 
-			var i, uva, uvb, uvc, u1, u2, u3, v1, v2, v3;
+				var uvIndexBuffer = new Uint32Array( data, offset, 3 * nElements );
 
-			var uvIndexBuffer = new Uint32Array( data, offset, 3 * nElements );
+				for( i = 0; i < nElements; i ++ ) {
 
-			for( i = 0; i < nElements; i ++ ) {
+					uva = uvIndexBuffer[ i * 3 ];
+					uvb = uvIndexBuffer[ i * 3 + 1 ];
+					uvc = uvIndexBuffer[ i * 3 + 2 ];
 
-				uva = uvIndexBuffer[ i * 3 ];
-				uvb = uvIndexBuffer[ i * 3 + 1 ];
-				uvc = uvIndexBuffer[ i * 3 + 2 ];
+					u1 = uvs[ uva*2 ];
+					v1 = uvs[ uva*2 + 1 ];
 
-				u1 = uvs[ uva*2 ];
-				v1 = uvs[ uva*2 + 1 ];
+					u2 = uvs[ uvb*2 ];
+					v2 = uvs[ uvb*2 + 1 ];
 
-				u2 = uvs[ uvb*2 ];
-				v2 = uvs[ uvb*2 + 1 ];
+					u3 = uvs[ uvc*2 ];
+					v3 = uvs[ uvc*2 + 1 ];
 
-				u3 = uvs[ uvc*2 ];
-				v3 = uvs[ uvc*2 + 1 ];
+					scope.faceVertexUvs[ 0 ].push( [
+						new THREE.Vector2( u1, v1 ),
+						new THREE.Vector2( u2, v2 ),
+						new THREE.Vector2( u3, v3 )
+					] );
 
-				scope.faceVertexUvs[ 0 ].push( [
-					new THREE.Vector2( u1, v1 ),
-					new THREE.Vector2( u2, v2 ),
-					new THREE.Vector2( u3, v3 )
-				] );
+				}
 
-			}
+			};
 
-		};
+			function init_uvs4( nElements, offset ) {
 
-		function init_uvs4( nElements, offset ) {
+				var i, uva, uvb, uvc, uvd, u1, u2, u3, u4, v1, v2, v3, v4;
 
-			var i, uva, uvb, uvc, uvd, u1, u2, u3, u4, v1, v2, v3, v4;
+				var uvIndexBuffer = new Uint32Array( data, offset, 4 * nElements );
 
-			var uvIndexBuffer = new Uint32Array( data, offset, 4 * nElements );
+				for( i = 0; i < nElements; i ++ ) {
 
-			for( i = 0; i < nElements; i ++ ) {
+					uva = uvIndexBuffer[ i * 4 ];
+					uvb = uvIndexBuffer[ i * 4 + 1 ];
+					uvc = uvIndexBuffer[ i * 4 + 2 ];
+					uvd = uvIndexBuffer[ i * 4 + 3 ];
 
-				uva = uvIndexBuffer[ i * 4 ];
-				uvb = uvIndexBuffer[ i * 4 + 1 ];
-				uvc = uvIndexBuffer[ i * 4 + 2 ];
-				uvd = uvIndexBuffer[ i * 4 + 3 ];
+					u1 = uvs[ uva*2 ];
+					v1 = uvs[ uva*2 + 1 ];
 
-				u1 = uvs[ uva*2 ];
-				v1 = uvs[ uva*2 + 1 ];
+					u2 = uvs[ uvb*2 ];
+					v2 = uvs[ uvb*2 + 1 ];
 
-				u2 = uvs[ uvb*2 ];
-				v2 = uvs[ uvb*2 + 1 ];
+					u3 = uvs[ uvc*2 ];
+					v3 = uvs[ uvc*2 + 1 ];
 
-				u3 = uvs[ uvc*2 ];
-				v3 = uvs[ uvc*2 + 1 ];
+					u4 = uvs[ uvd*2 ];
+					v4 = uvs[ uvd*2 + 1 ];
 
-				u4 = uvs[ uvd*2 ];
-				v4 = uvs[ uvd*2 + 1 ];
+					scope.faceVertexUvs[ 0 ].push( [
+						new THREE.Vector2( u1, v1 ),
+						new THREE.Vector2( u2, v2 ),
+						new THREE.Vector2( u4, v4 )
+					] );
 
-				scope.faceVertexUvs[ 0 ].push( [
-					new THREE.Vector2( u1, v1 ),
-					new THREE.Vector2( u2, v2 ),
-					new THREE.Vector2( u4, v4 )
-				] );
+					scope.faceVertexUvs[ 0 ].push( [
+						new THREE.Vector2( u2, v2 ),
+						new THREE.Vector2( u3, v3 ),
+						new THREE.Vector2( u4, v4 )
+					] );
 
-				scope.faceVertexUvs[ 0 ].push( [
-					new THREE.Vector2( u2, v2 ),
-					new THREE.Vector2( u3, v3 ),
-					new THREE.Vector2( u4, v4 )
-				] );
+				}
 
-			}
+			};
 
-		};
+			function init_faces3_flat( nElements, offsetVertices, offsetMaterials ) {
 
-		function init_faces3_flat( nElements, offsetVertices, offsetMaterials ) {
+				var i, a, b, c, m;
 
-			var i, a, b, c, m;
+				var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 3 * nElements );
+				var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
 
-			var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 3 * nElements );
-			var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
+				for( i = 0; i < nElements; i ++ ) {
 
-			for( i = 0; i < nElements; i ++ ) {
+					a = vertexIndexBuffer[ i * 3 ];
+					b = vertexIndexBuffer[ i * 3 + 1 ];
+					c = vertexIndexBuffer[ i * 3 + 2 ];
 
-				a = vertexIndexBuffer[ i * 3 ];
-				b = vertexIndexBuffer[ i * 3 + 1 ];
-				c = vertexIndexBuffer[ i * 3 + 2 ];
+					m = materialIndexBuffer[ i ];
 
-				m = materialIndexBuffer[ i ];
+					scope.faces.push( new THREE.Face3( a, b, c, null, null, m ) );
 
-				scope.faces.push( new THREE.Face3( a, b, c, null, null, m ) );
+				}
 
-			}
+			};
 
-		};
+			function init_faces4_flat( nElements, offsetVertices, offsetMaterials ) {
 
-		function init_faces4_flat( nElements, offsetVertices, offsetMaterials ) {
+				var i, a, b, c, d, m;
 
-			var i, a, b, c, d, m;
+				var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 4 * nElements );
+				var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
 
-			var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 4 * nElements );
-			var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
+				for( i = 0; i < nElements; i ++ ) {
 
-			for( i = 0; i < nElements; i ++ ) {
+					a = vertexIndexBuffer[ i * 4 ];
+					b = vertexIndexBuffer[ i * 4 + 1 ];
+					c = vertexIndexBuffer[ i * 4 + 2 ];
+					d = vertexIndexBuffer[ i * 4 + 3 ];
 
-				a = vertexIndexBuffer[ i * 4 ];
-				b = vertexIndexBuffer[ i * 4 + 1 ];
-				c = vertexIndexBuffer[ i * 4 + 2 ];
-				d = vertexIndexBuffer[ i * 4 + 3 ];
+					m = materialIndexBuffer[ i ];
 
-				m = materialIndexBuffer[ i ];
+					scope.faces.push( new THREE.Face3( a, b, d, null, null, m ) );
+					scope.faces.push( new THREE.Face3( b, c, d, null, null, m ) );
 
-				scope.faces.push( new THREE.Face3( a, b, d, null, null, m ) );
-				scope.faces.push( new THREE.Face3( b, c, d, null, null, m ) );
+				}
 
-			}
+			};
 
-		};
+			function init_faces3_smooth( nElements, offsetVertices, offsetNormals, offsetMaterials ) {
 
-		function init_faces3_smooth( nElements, offsetVertices, offsetNormals, offsetMaterials ) {
+				var i, a, b, c, m;
+				var na, nb, nc;
 
-			var i, a, b, c, m;
-			var na, nb, nc;
+				var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 3 * nElements );
+				var normalIndexBuffer = new Uint32Array( data, offsetNormals, 3 * nElements );
+				var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
 
-			var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 3 * nElements );
-			var normalIndexBuffer = new Uint32Array( data, offsetNormals, 3 * nElements );
-			var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
+				for( i = 0; i < nElements; i ++ ) {
 
-			for( i = 0; i < nElements; i ++ ) {
+					a = vertexIndexBuffer[ i * 3 ];
+					b = vertexIndexBuffer[ i * 3 + 1 ];
+					c = vertexIndexBuffer[ i * 3 + 2 ];
 
-				a = vertexIndexBuffer[ i * 3 ];
-				b = vertexIndexBuffer[ i * 3 + 1 ];
-				c = vertexIndexBuffer[ i * 3 + 2 ];
+					na = normalIndexBuffer[ i * 3 ];
+					nb = normalIndexBuffer[ i * 3 + 1 ];
+					nc = normalIndexBuffer[ i * 3 + 2 ];
 
-				na = normalIndexBuffer[ i * 3 ];
-				nb = normalIndexBuffer[ i * 3 + 1 ];
-				nc = normalIndexBuffer[ i * 3 + 2 ];
+					m = materialIndexBuffer[ i ];
 
-				m = materialIndexBuffer[ i ];
+					var nax = normals[ na*3     ],
+						nay = normals[ na*3 + 1 ],
+						naz = normals[ na*3 + 2 ],
 
-				var nax = normals[ na*3     ],
-					nay = normals[ na*3 + 1 ],
-					naz = normals[ na*3 + 2 ],
+						nbx = normals[ nb*3     ],
+						nby = normals[ nb*3 + 1 ],
+						nbz = normals[ nb*3 + 2 ],
 
-					nbx = normals[ nb*3     ],
-					nby = normals[ nb*3 + 1 ],
-					nbz = normals[ nb*3 + 2 ],
+						ncx = normals[ nc*3     ],
+						ncy = normals[ nc*3 + 1 ],
+						ncz = normals[ nc*3 + 2 ];
 
-					ncx = normals[ nc*3     ],
-					ncy = normals[ nc*3 + 1 ],
-					ncz = normals[ nc*3 + 2 ];
+					scope.faces.push( new THREE.Face3( a, b, c, [
+						new THREE.Vector3( nax, nay, naz ),
+						new THREE.Vector3( nbx, nby, nbz ),
+						new THREE.Vector3( ncx, ncy, ncz )
+					], null, m ) );
 
-				scope.faces.push( new THREE.Face3( a, b, c, [
-					new THREE.Vector3( nax, nay, naz ),
-					new THREE.Vector3( nbx, nby, nbz ),
-					new THREE.Vector3( ncx, ncy, ncz )
-				], null, m ) );
+				}
 
-			}
+			};
 
-		};
+			function init_faces4_smooth( nElements, offsetVertices, offsetNormals, offsetMaterials ) {
 
-		function init_faces4_smooth( nElements, offsetVertices, offsetNormals, offsetMaterials ) {
+				var i, a, b, c, d, m;
+				var na, nb, nc, nd;
 
-			var i, a, b, c, d, m;
-			var na, nb, nc, nd;
+				var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 4 * nElements );
+				var normalIndexBuffer = new Uint32Array( data, offsetNormals, 4 * nElements );
+				var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
 
-			var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 4 * nElements );
-			var normalIndexBuffer = new Uint32Array( data, offsetNormals, 4 * nElements );
-			var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
+				for( i = 0; i < nElements; i ++ ) {
 
-			for( i = 0; i < nElements; i ++ ) {
+					a = vertexIndexBuffer[ i * 4 ];
+					b = vertexIndexBuffer[ i * 4 + 1 ];
+					c = vertexIndexBuffer[ i * 4 + 2 ];
+					d = vertexIndexBuffer[ i * 4 + 3 ];
 
-				a = vertexIndexBuffer[ i * 4 ];
-				b = vertexIndexBuffer[ i * 4 + 1 ];
-				c = vertexIndexBuffer[ i * 4 + 2 ];
-				d = vertexIndexBuffer[ i * 4 + 3 ];
+					na = normalIndexBuffer[ i * 4 ];
+					nb = normalIndexBuffer[ i * 4 + 1 ];
+					nc = normalIndexBuffer[ i * 4 + 2 ];
+					nd = normalIndexBuffer[ i * 4 + 3 ];
 
-				na = normalIndexBuffer[ i * 4 ];
-				nb = normalIndexBuffer[ i * 4 + 1 ];
-				nc = normalIndexBuffer[ i * 4 + 2 ];
-				nd = normalIndexBuffer[ i * 4 + 3 ];
+					m = materialIndexBuffer[ i ];
 
-				m = materialIndexBuffer[ i ];
+					var nax = normals[ na*3     ],
+						nay = normals[ na*3 + 1 ],
+						naz = normals[ na*3 + 2 ],
 
-				var nax = normals[ na*3     ],
-					nay = normals[ na*3 + 1 ],
-					naz = normals[ na*3 + 2 ],
+						nbx = normals[ nb*3     ],
+						nby = normals[ nb*3 + 1 ],
+						nbz = normals[ nb*3 + 2 ],
 
-					nbx = normals[ nb*3     ],
-					nby = normals[ nb*3 + 1 ],
-					nbz = normals[ nb*3 + 2 ],
+						ncx = normals[ nc*3     ],
+						ncy = normals[ nc*3 + 1 ],
+						ncz = normals[ nc*3 + 2 ],
 
-					ncx = normals[ nc*3     ],
-					ncy = normals[ nc*3 + 1 ],
-					ncz = normals[ nc*3 + 2 ],
+						ndx = normals[ nd*3     ],
+						ndy = normals[ nd*3 + 1 ],
+						ndz = normals[ nd*3 + 2 ];
 
-					ndx = normals[ nd*3     ],
-					ndy = normals[ nd*3 + 1 ],
-					ndz = normals[ nd*3 + 2 ];
+					scope.faces.push( new THREE.Face3( a, b, d, [
+						new THREE.Vector3( nax, nay, naz ),
+						new THREE.Vector3( nbx, nby, nbz ),
+						new THREE.Vector3( ndx, ndy, ndz )
+					], null, m ) );
 
-				scope.faces.push( new THREE.Face3( a, b, d, [
-					new THREE.Vector3( nax, nay, naz ),
-					new THREE.Vector3( nbx, nby, nbz ),
-					new THREE.Vector3( ndx, ndy, ndz )
-				], null, m ) );
+					scope.faces.push( new THREE.Face3( b, c, d, [
+						new THREE.Vector3( nbx, nby, nbz ),
+						new THREE.Vector3( ncx, ncy, ncz ),
+						new THREE.Vector3( ndx, ndy, ndz )
+					], null, m ) );
 
-				scope.faces.push( new THREE.Face3( b, c, d, [
-					new THREE.Vector3( nbx, nby, nbz ),
-					new THREE.Vector3( ncx, ncy, ncz ),
-					new THREE.Vector3( ndx, ndy, ndz )
-				], null, m ) );
+				}
 
-			}
+			};
 
-		};
+			function init_triangles_flat( start ) {
 
-		function init_triangles_flat( start ) {
+				var nElements = md.ntri_flat;
 
-			var nElements = md.ntri_flat;
+				if ( nElements ) {
 
-			if ( nElements ) {
+					var offsetMaterials = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
+					init_faces3_flat( nElements, start, offsetMaterials );
 
-				var offsetMaterials = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
-				init_faces3_flat( nElements, start, offsetMaterials );
+				}
 
-			}
+			};
 
-		};
+			function init_triangles_flat_uv( start ) {
 
-		function init_triangles_flat_uv( start ) {
+				var nElements = md.ntri_flat_uv;
 
-			var nElements = md.ntri_flat_uv;
+				if ( nElements ) {
 
-			if ( nElements ) {
+					var offsetUvs = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
+					var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
 
-				var offsetUvs = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
-				var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
+					init_faces3_flat( nElements, start, offsetMaterials );
+					init_uvs3( nElements, offsetUvs );
 
-				init_faces3_flat( nElements, start, offsetMaterials );
-				init_uvs3( nElements, offsetUvs );
+				}
 
-			}
+			};
 
-		};
+			function init_triangles_smooth( start ) {
 
-		function init_triangles_smooth( start ) {
+				var nElements = md.ntri_smooth;
 
-			var nElements = md.ntri_smooth;
+				if ( nElements ) {
 
-			if ( nElements ) {
+					var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
+					var offsetMaterials = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
 
-				var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
-				var offsetMaterials = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
+					init_faces3_smooth( nElements, start, offsetNormals, offsetMaterials );
 
-				init_faces3_smooth( nElements, start, offsetNormals, offsetMaterials );
+				}
 
-			}
+			};
 
-		};
+			function init_triangles_smooth_uv( start ) {
 
-		function init_triangles_smooth_uv( start ) {
+				var nElements = md.ntri_smooth_uv;
 
-			var nElements = md.ntri_smooth_uv;
+				if ( nElements ) {
 
-			if ( nElements ) {
+					var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
+					var offsetUvs = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
+					var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
 
-				var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
-				var offsetUvs = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
-				var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
+					init_faces3_smooth( nElements, start, offsetNormals, offsetMaterials );
+					init_uvs3( nElements, offsetUvs );
 
-				init_faces3_smooth( nElements, start, offsetNormals, offsetMaterials );
-				init_uvs3( nElements, offsetUvs );
+				}
 
-			}
+			};
 
-		};
+			function init_quads_flat( start ) {
 
-		function init_quads_flat( start ) {
+				var nElements = md.nquad_flat;
 
-			var nElements = md.nquad_flat;
+				if ( nElements ) {
 
-			if ( nElements ) {
+					var offsetMaterials = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
+					init_faces4_flat( nElements, start, offsetMaterials );
 
-				var offsetMaterials = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
-				init_faces4_flat( nElements, start, offsetMaterials );
+				}
 
-			}
+			};
 
-		};
+			function init_quads_flat_uv( start ) {
 
-		function init_quads_flat_uv( start ) {
+				var nElements = md.nquad_flat_uv;
 
-			var nElements = md.nquad_flat_uv;
+				if ( nElements ) {
 
-			if ( nElements ) {
+					var offsetUvs = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
+					var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
 
-				var offsetUvs = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
-				var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
+					init_faces4_flat( nElements, start, offsetMaterials );
+					init_uvs4( nElements, offsetUvs );
 
-				init_faces4_flat( nElements, start, offsetMaterials );
-				init_uvs4( nElements, offsetUvs );
+				}
 
-			}
+			};
 
-		};
+			function init_quads_smooth( start ) {
 
-		function init_quads_smooth( start ) {
+				var nElements = md.nquad_smooth;
 
-			var nElements = md.nquad_smooth;
+				if ( nElements ) {
 
-			if ( nElements ) {
+					var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
+					var offsetMaterials = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
 
-				var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
-				var offsetMaterials = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
+					init_faces4_smooth( nElements, start, offsetNormals, offsetMaterials );
 
-				init_faces4_smooth( nElements, start, offsetNormals, offsetMaterials );
+				}
 
-			}
+			};
 
-		};
+			function init_quads_smooth_uv( start ) {
 
-		function init_quads_smooth_uv( start ) {
+				var nElements = md.nquad_smooth_uv;
 
-			var nElements = md.nquad_smooth_uv;
+				if ( nElements ) {
 
-			if ( nElements ) {
+					var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
+					var offsetUvs = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
+					var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
 
-				var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
-				var offsetUvs = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
-				var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
+					init_faces4_smooth( nElements, start, offsetNormals, offsetMaterials );
+					init_uvs4( nElements, offsetUvs );
 
-				init_faces4_smooth( nElements, start, offsetNormals, offsetMaterials );
-				init_uvs4( nElements, offsetUvs );
+				}
 
-			}
+			};
 
 		};
 
-	};
+		Model.prototype = Object.create( THREE.Geometry.prototype );
+		Model.prototype.constructor = Model;
 
-	Model.prototype = Object.create( THREE.Geometry.prototype );
-	Model.prototype.constructor = Model;
+		var geometry = new Model( texturePath );
+		var materials = THREE.Loader.prototype.initMaterials( jsonMaterials, texturePath );
 
-	var geometry = new Model( texturePath );
-	var materials = this.initMaterials( jsonMaterials, texturePath );
+		if ( THREE.Loader.prototype.needsTangents( materials ) ) geometry.computeTangents();
 
-	if ( this.needsTangents( materials ) ) geometry.computeTangents();
+		callback( geometry, materials );
 
-	callback( geometry, materials );
+	}
 
-};
+};

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 624 - 635
examples/js/loaders/ColladaLoader.js


+ 41 - 10
examples/js/loaders/MTLLoader.js

@@ -4,11 +4,9 @@
  * @author angelxuanchang
  */
 
-THREE.MTLLoader = function( baseUrl, options, crossOrigin ) {
+THREE.MTLLoader = function( manager ) {
 
-	this.baseUrl = baseUrl;
-	this.options = options;
-	this.crossOrigin = crossOrigin;
+	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
 
 };
 
@@ -20,7 +18,7 @@ THREE.MTLLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader();
+		var loader = new THREE.XHRLoader( this.manager );
 		loader.setCrossOrigin( this.crossOrigin );
 		loader.load( url, function ( text ) {
 
@@ -30,6 +28,24 @@ THREE.MTLLoader.prototype = {
 
 	},
 
+	setBaseUrl: function( value ) {
+
+		this.baseUrl = value;
+
+	},
+
+	setCrossOrigin: function ( value ) {
+
+		this.crossOrigin = value;
+
+	},
+
+	setMaterialOptions: function ( value ) {
+
+		this.materialOptions = value;
+
+	},
+
 	/**
 	 * Parses loaded MTL file
 	 * @param text - Content of MTL file
@@ -86,7 +102,9 @@ THREE.MTLLoader.prototype = {
 
 		}
 
-		var materialCreator = new THREE.MTLLoader.MaterialCreator( this.baseUrl, this.options );
+		var materialCreator = new THREE.MTLLoader.MaterialCreator( this.baseUrl, this.materialOptions );
+		materialCreator.setCrossOrigin( this.crossOrigin );
+		materialCreator.setManager( this.manager );
 		materialCreator.setMaterials( materialsInfo );
 		return materialCreator;
 
@@ -129,6 +147,18 @@ THREE.MTLLoader.MaterialCreator.prototype = {
 
 	constructor: THREE.MTLLoader.MaterialCreator,
 
+	setCrossOrigin: function ( value ) {
+
+		this.crossOrigin = value;
+
+	},
+
+	setManager: function ( value ) {
+
+		this.manager = value;
+
+	},
+
 	setMaterials: function( materialsInfo ) {
 
 		this.materialsInfo = this.convert( materialsInfo );
@@ -361,10 +391,11 @@ THREE.MTLLoader.MaterialCreator.prototype = {
 	},
 
 
-	loadTexture: function ( url, mapping, onLoad, onError ) {
+	loadTexture: function ( url, mapping, onLoad, onProgress, onError ) {
 
 		var texture;
 		var loader = THREE.Loader.Handlers.get( url );
+		var manager = ( this.manager !== undefined ) ? this.manager : THREE.DefaultLoadingManager;
 
 		if ( loader !== null ) {
 
@@ -374,8 +405,8 @@ THREE.MTLLoader.MaterialCreator.prototype = {
 
 			texture = new THREE.Texture();
 
-			loader = new THREE.ImageLoader();
-			loader.crossOrigin = this.crossOrigin;
+			loader = new THREE.ImageLoader( manager );
+			loader.setCrossOrigin( this.crossOrigin );
 			loader.load( url, function ( image ) {
 
 				texture.image = THREE.MTLLoader.ensurePowerOfTwo_( image );
@@ -383,7 +414,7 @@ THREE.MTLLoader.MaterialCreator.prototype = {
 
 				if ( onLoad ) onLoad( texture );
 
-			} );
+			}, onProgress, onError );
 
 		}
 

+ 9 - 3
examples/js/loaders/OBJLoader.js

@@ -16,7 +16,7 @@ THREE.OBJLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.XHRLoader( this.manager );
 		loader.setCrossOrigin( this.crossOrigin );
 		loader.load( url, function ( text ) {
 
@@ -26,6 +26,12 @@ THREE.OBJLoader.prototype = {
 
 	},
 
+	setCrossOrigin: function ( value ) {
+
+		this.crossOrigin = value;
+
+	},
+
 	parse: function ( text ) {
 
 		console.time( 'OBJLoader' );
@@ -202,7 +208,7 @@ THREE.OBJLoader.prototype = {
 
 		var face_pattern3 = /f( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))?/;
 
-		// f vertex//normal vertex//normal vertex//normal ... 
+		// f vertex//normal vertex//normal vertex//normal ...
 
 		var face_pattern4 = /f( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))?/
 
@@ -261,7 +267,7 @@ THREE.OBJLoader.prototype = {
 			} else if ( ( result = face_pattern2.exec( line ) ) !== null ) {
 
 				// ["f 1/1 2/2 3/3", " 1/1", "1", "1", " 2/2", "2", "2", " 3/3", "3", "3", undefined, undefined, undefined]
-				
+
 				addFace(
 					result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ],
 					result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ]

+ 10 - 2
examples/js/loaders/OBJMTLLoader.js

@@ -19,14 +19,16 @@ THREE.OBJMTLLoader.prototype = {
 
 		var scope = this;
 
-		var mtlLoader = new THREE.MTLLoader( url.substr( 0, url.lastIndexOf( "/" ) + 1 ) );
+		var mtlLoader = new THREE.MTLLoader( this.manager );
+		mtlLoader.setBaseUrl( url.substr( 0, url.lastIndexOf( "/" ) + 1 ) );
+		mtlLoader.setCrossOrigin( this.crossOrigin );
 		mtlLoader.load( mtlurl, function ( materials ) {
 
 			var materialsCreator = materials;
 			materialsCreator.preload();
 
 			var loader = new THREE.XHRLoader( scope.manager );
-			loader.setCrossOrigin( this.crossOrigin );
+			loader.setCrossOrigin( scope.crossOrigin );
 			loader.load( url, function ( text ) {
 
 				var object = scope.parse( text );
@@ -55,6 +57,12 @@ THREE.OBJMTLLoader.prototype = {
 
 	},
 
+	setCrossOrigin: function ( value ) {
+
+		this.crossOrigin = value;
+
+	},
+
 	/**
 	 * Parses loaded .obj file
 	 * @param data - content of .obj file

+ 7 - 1
examples/js/loaders/PDBLoader.js

@@ -16,7 +16,7 @@ THREE.PDBLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.XHRLoader( this.manager );
 		loader.setCrossOrigin( this.crossOrigin );
 		loader.load( url, function ( text ) {
 
@@ -27,6 +27,12 @@ THREE.PDBLoader.prototype = {
 
 	},
 
+	setCrossOrigin: function ( value ) {
+
+		this.crossOrigin = value;
+
+	},
+
 	// Based on CanvasMol PDB parser
 
 	parsePDB: function ( text ) {

+ 17 - 29
examples/js/loaders/PLYLoader.js

@@ -27,7 +27,9 @@
  */
 
 
-THREE.PLYLoader = function () {
+THREE.PLYLoader = function ( manager ) {
+
+	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
 
 	this.propertyNameMapping = {};
 
@@ -37,42 +39,30 @@ THREE.PLYLoader.prototype = {
 
 	constructor: THREE.PLYLoader,
 
-	setPropertyNameMapping: function ( mapping ) {
-
-		this.propertyNameMapping = mapping;
-
-	},
-
-	load: function ( url, callback ) {
+	load: function ( url, onLoad, onProgress, onError ) {
 
 		var scope = this;
-		var request = new XMLHttpRequest();
-
-		request.addEventListener( 'load', function ( event ) {
 
-			var geometry = scope.parse( event.target.response );
+		var loader = new THREE.XHRLoader( this.manager );
+		loader.setCrossOrigin( this.crossOrigin );
+		loader.setResponseType( 'arraybuffer' );
+		loader.load( url, function ( text ) {
 
-			scope.dispatchEvent( { type: 'load', content: geometry } );
+			onLoad( scope.parse( text ) );
 
-			if ( callback ) callback( geometry );
+		}, onProgress, onError );
 
-		}, false );
-
-		request.addEventListener( 'progress', function ( event ) {
-
-			scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } );
+	},
 
-		}, false );
+	setCrossOrigin: function ( value ) {
 
-		request.addEventListener( 'error', function () {
+		this.crossOrigin = value;
 
-			scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
+	},
 
-		}, false );
+	setPropertyNameMapping: function ( mapping ) {
 
-		request.open( 'GET', url, true );
-		request.responseType = "arraybuffer";
-		request.send( null );
+		this.propertyNameMapping = mapping;
 
 	},
 
@@ -474,6 +464,4 @@ THREE.PLYLoader.prototype = {
 
 	}
 
-};
-
-THREE.EventDispatcher.prototype.apply( THREE.PLYLoader.prototype );
+};

+ 37 - 35
examples/js/loaders/PVRLoader.js

@@ -1,4 +1,4 @@
-/*    
+/*
  *	 PVRLoader
  *   Author: pierre lepers
  *   Date: 17/09/2014 11:09
@@ -8,8 +8,10 @@
  *   TODO : implement loadMipmaps option
  */
 
+THREE.PVRLoader = function ( manager ) {
+
+	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
 
-THREE.PVRLoader = function () {
 	this._parser = THREE.PVRLoader.parse;
 };
 
@@ -30,7 +32,7 @@ THREE.PVRLoader.parse = function ( buffer, loadMipmaps ) {
 	// PVR v3
 	if( header[0] === 0x03525650 ) {
 		return THREE.PVRLoader._parseV3( pvrDatas );
-	} 
+	}
 	// PVR v2
 	else if( header[11] === 0x21525650) {
 		return THREE.PVRLoader._parseV2( pvrDatas );
@@ -42,10 +44,10 @@ THREE.PVRLoader.parse = function ( buffer, loadMipmaps ) {
 };
 
 THREE.PVRLoader._parseV3 = function ( pvrDatas ) {
-	
+
 	var header = pvrDatas.header;
 	var bpp, format;
-	
+
 
 	var metaLen 	  = header[12],
 		pixelFormat   =  header[2],
@@ -77,16 +79,16 @@ THREE.PVRLoader._parseV3 = function ( pvrDatas ) {
 	}
 
 	pvrDatas.dataPtr 	 = 52 + metaLen;
-  	pvrDatas.bpp 		 = bpp;
-  	pvrDatas.format 	 = format;
-  	pvrDatas.width 		 = width;
-  	pvrDatas.height 	 = height;
-  	pvrDatas.numSurfaces = numFaces;
-  	pvrDatas.numMipmaps  = numMipmaps;
+	pvrDatas.bpp 		 = bpp;
+	pvrDatas.format 	 = format;
+	pvrDatas.width 		 = width;
+	pvrDatas.height 	 = height;
+	pvrDatas.numSurfaces = numFaces;
+	pvrDatas.numMipmaps  = numMipmaps;
 
-  	pvrDatas.isCubemap 	= (numFaces === 6);
+	pvrDatas.isCubemap 	= (numFaces === 6);
 
-  	return THREE.PVRLoader._extract( pvrDatas );
+	return THREE.PVRLoader._extract( pvrDatas );
 };
 
 THREE.PVRLoader._parseV2 = function ( pvrDatas ) {
@@ -129,35 +131,35 @@ THREE.PVRLoader._parseV2 = function ( pvrDatas ) {
 	}
 	else
 		throw new Error( "pvrtc - unknown format "+formatFlags);
-	
+
 
 
 	pvrDatas.dataPtr 	 = headerLength;
-  	pvrDatas.bpp 		 = bpp;
-  	pvrDatas.format 	 = format;
-  	pvrDatas.width 		 = width;
-  	pvrDatas.height 	 = height;
-  	pvrDatas.numSurfaces = numSurfs;
-  	pvrDatas.numMipmaps  = numMipmaps + 1;
+	pvrDatas.bpp 		 = bpp;
+	pvrDatas.format 	 = format;
+	pvrDatas.width 		 = width;
+	pvrDatas.height 	 = height;
+	pvrDatas.numSurfaces = numSurfs;
+	pvrDatas.numMipmaps  = numMipmaps + 1;
 
-  	// guess cubemap type seems tricky in v2
-  	// it juste a pvr containing 6 surface (no explicit cubemap type)
-  	pvrDatas.isCubemap 	= (numSurfs === 6);
+	// guess cubemap type seems tricky in v2
+	// it juste a pvr containing 6 surface (no explicit cubemap type)
+	pvrDatas.isCubemap 	= (numSurfs === 6);
 
-  	return THREE.PVRLoader._extract( pvrDatas );
+	return THREE.PVRLoader._extract( pvrDatas );
 
 };
 
 
 THREE.PVRLoader._extract = function ( pvrDatas ) {
-	
+
 	var pvr = {
-		mipmaps: [], 
-		width: pvrDatas.width, 
-		height: pvrDatas.height, 
-		format: pvrDatas.format, 
-		mipmapCount: pvrDatas.numMipmaps, 
-		isCubemap : pvrDatas.isCubemap 
+		mipmaps: [],
+		width: pvrDatas.width,
+		height: pvrDatas.height,
+		format: pvrDatas.format,
+		mipmapCount: pvrDatas.numMipmaps,
+		isCubemap : pvrDatas.isCubemap
 	};
 
 	var buffer = pvrDatas.buffer;
@@ -230,10 +232,10 @@ THREE.PVRLoader._extract = function ( pvrDatas ) {
 
 			var byteArray = new Uint8Array( buffer, dataOffset, dataSize );
 
-			var mipmap = { 
-				data: byteArray, 
-				width: sWidth, 
-				height: sHeight 
+			var mipmap = {
+				data: byteArray,
+				width: sWidth,
+				height: sHeight
 			};
 
 			pvr.mipmaps[ surfIndex * pvrDatas.numMipmaps + mipLevel] = mipmap;

+ 10 - 4
examples/js/loaders/STLLoader.js

@@ -41,9 +41,9 @@ THREE.STLLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.XHRLoader( this.manager );
 		loader.setCrossOrigin( this.crossOrigin );
-		loader.setResponseType('arraybuffer');
+		loader.setResponseType( 'arraybuffer' );
 		loader.load( url, function ( text ) {
 
 			onLoad( scope.parse( text ) );
@@ -51,7 +51,13 @@ THREE.STLLoader.prototype = {
 		}, onProgress, onError );
 
 	},
-	
+
+	setCrossOrigin: function ( value ) {
+
+		this.crossOrigin = value;
+
+	},
+
 	parse: function ( data ) {
 
 		var isBinary = function () {
@@ -235,7 +241,7 @@ THREE.STLLoader.prototype = {
 		} else {
 			return buf;
 		}
-		
+
 	}
 
 };

+ 8 - 2
examples/js/loaders/SVGLoader.js

@@ -19,7 +19,7 @@ THREE.SVGLoader.prototype = {
 
 		var parser = new DOMParser();
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.XHRLoader( this.manager );
 		loader.setCrossOrigin( this.crossOrigin );
 		loader.load( url, function ( svgString ) {
 
@@ -29,5 +29,11 @@ THREE.SVGLoader.prototype = {
 
 		}, onProgress, onError );
 
-	}
+	},
+
+	setCrossOrigin: function ( value ) {
+
+		this.crossOrigin = value;
+
+	},
 };

+ 2 - 2
examples/js/loaders/SceneLoader.js

@@ -28,7 +28,7 @@ THREE.SceneLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.XHRLoader( this.manager );
 		loader.setCrossOrigin( this.crossOrigin );
 		loader.load( url, function ( text ) {
 
@@ -449,7 +449,7 @@ THREE.SceneLoader.prototype = {
 
 						} else if ( objJSON.target ) {
 
-						    camera.lookAt( new THREE.Vector3().fromArray( objJSON.target ) );
+							camera.lookAt( new THREE.Vector3().fromArray( objJSON.target ) );
 
 						}
 

+ 340 - 340
examples/js/loaders/UTF8Loader.js

@@ -19,7 +19,7 @@ THREE.UTF8Loader = function () {};
 
 THREE.UTF8Loader.prototype.load = function ( jsonUrl, callback, options ) {
 
-    this.downloadModelJson( jsonUrl, options, callback );
+	this.downloadModelJson( jsonUrl, options, callback );
 
 };
 
@@ -94,12 +94,12 @@ THREE.UTF8Loader.BufferGeometryCreator.prototype.create = function ( attribArray
 
 	}
 
-    geometry.addAttribute( 'index', new THREE.BufferAttribute( indices, 1 ) );
-    geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
-    geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
-    geometry.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
+	geometry.addAttribute( 'index', new THREE.BufferAttribute( indices, 1 ) );
+	geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
+	geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
+	geometry.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
 
-    geometry.offsets.push( { start: 0, count: indices.length, index: 0 } );
+	geometry.offsets.push( { start: 0, count: indices.length, index: 0 } );
 
 	geometry.computeBoundingSphere();
 
@@ -133,18 +133,18 @@ THREE.UTF8Loader.BufferGeometryCreator.prototype.create = function ( attribArray
 
 var DEFAULT_DECODE_PARAMS = {
 
-    decodeOffsets: [-4095, -4095, -4095, 0, 0, -511, -511, -511],
-    decodeScales: [1/8191, 1/8191, 1/8191, 1/1023, 1/1023, 1/1023, 1/1023, 1/1023]
+	decodeOffsets: [-4095, -4095, -4095, 0, 0, -511, -511, -511],
+	decodeScales: [1/8191, 1/8191, 1/8191, 1/1023, 1/1023, 1/1023, 1/1023, 1/1023]
 
-    // TODO: normal decoding? (see walt.js)
-    // needs to know: input, output (from vertex format!)
-    //
-    // Should split attrib/index.
-    // 1) Decode position and non-normal attributes.
-    // 2) Decode indices, computing normals
-    // 3) Maybe normalize normals? Only necessary for refinement, or fixed?
-    // 4) Maybe refine normals? Should this be part of regular refinement?
-    // 5) Morphing
+	// TODO: normal decoding? (see walt.js)
+	// needs to know: input, output (from vertex format!)
+	//
+	// Should split attrib/index.
+	// 1) Decode position and non-normal attributes.
+	// 2) Decode indices, computing normals
+	// 3) Maybe normalize normals? Only necessary for refinement, or fixed?
+	// 4) Maybe refine normals? Should this be part of regular refinement?
+	// 5) Morphing
 
 };
 
@@ -155,486 +155,486 @@ var DEFAULT_DECODE_PARAMS = {
 // decodeScale?
 
 THREE.UTF8Loader.prototype.decompressAttribsInner_ = function ( str, inputStart, inputEnd,
-                                                                  output, outputStart, stride,
-                                                                  decodeOffset, decodeScale ) {
+																  output, outputStart, stride,
+																  decodeOffset, decodeScale ) {
 
-    var prev = 0;
+	var prev = 0;
 
-    for ( var j = inputStart; j < inputEnd; j ++ ) {
+	for ( var j = inputStart; j < inputEnd; j ++ ) {
 
-        var code = str.charCodeAt( j );
-        prev += ( code >> 1 ) ^ ( -( code & 1 ) );
+		var code = str.charCodeAt( j );
+		prev += ( code >> 1 ) ^ ( -( code & 1 ) );
 
-        output[ outputStart ] = decodeScale * ( prev + decodeOffset );
-        outputStart += stride;
+		output[ outputStart ] = decodeScale * ( prev + decodeOffset );
+		outputStart += stride;
 
-    }
+	}
 
 };
 
 THREE.UTF8Loader.prototype.decompressIndices_ = function( str, inputStart, numIndices,
-                                                            output, outputStart ) {
+															output, outputStart ) {
 
 	var highest = 0;
 
-    for ( var i = 0; i < numIndices; i ++ ) {
+	for ( var i = 0; i < numIndices; i ++ ) {
 
-        var code = str.charCodeAt( inputStart ++ );
+		var code = str.charCodeAt( inputStart ++ );
 
-        output[ outputStart ++ ] = highest - code;
+		output[ outputStart ++ ] = highest - code;
 
-        if ( code === 0 ) {
+		if ( code === 0 ) {
 
-            highest ++;
+			highest ++;
 
-        }
+		}
 
-    }
+	}
 
 };
 
 THREE.UTF8Loader.prototype.decompressAABBs_ = function ( str, inputStart, numBBoxen,
-                                                           decodeOffsets, decodeScales ) {
-    var numFloats = 6 * numBBoxen;
+														   decodeOffsets, decodeScales ) {
+	var numFloats = 6 * numBBoxen;
 
-    var inputEnd = inputStart + numFloats;
-    var outputStart = 0;
+	var inputEnd = inputStart + numFloats;
+	var outputStart = 0;
 
-    var bboxen = new Float32Array( numFloats );
+	var bboxen = new Float32Array( numFloats );
 
-    for ( var i = inputStart; i < inputEnd; i += 6 ) {
+	for ( var i = inputStart; i < inputEnd; i += 6 ) {
 
-        var minX = str.charCodeAt(i + 0) + decodeOffsets[0];
-        var minY = str.charCodeAt(i + 1) + decodeOffsets[1];
-        var minZ = str.charCodeAt(i + 2) + decodeOffsets[2];
+		var minX = str.charCodeAt(i + 0) + decodeOffsets[0];
+		var minY = str.charCodeAt(i + 1) + decodeOffsets[1];
+		var minZ = str.charCodeAt(i + 2) + decodeOffsets[2];
 
-        var radiusX = (str.charCodeAt(i + 3) + 1) >> 1;
-        var radiusY = (str.charCodeAt(i + 4) + 1) >> 1;
-        var radiusZ = (str.charCodeAt(i + 5) + 1) >> 1;
+		var radiusX = (str.charCodeAt(i + 3) + 1) >> 1;
+		var radiusY = (str.charCodeAt(i + 4) + 1) >> 1;
+		var radiusZ = (str.charCodeAt(i + 5) + 1) >> 1;
 
-        bboxen[ outputStart++ ] = decodeScales[0] * (minX + radiusX);
-        bboxen[ outputStart++ ] = decodeScales[1] * (minY + radiusY);
-        bboxen[ outputStart++ ] = decodeScales[2] * (minZ + radiusZ);
+		bboxen[ outputStart++ ] = decodeScales[0] * (minX + radiusX);
+		bboxen[ outputStart++ ] = decodeScales[1] * (minY + radiusY);
+		bboxen[ outputStart++ ] = decodeScales[2] * (minZ + radiusZ);
 
-        bboxen[ outputStart++ ] = decodeScales[0] * radiusX;
-        bboxen[ outputStart++ ] = decodeScales[1] * radiusY;
-        bboxen[ outputStart++ ] = decodeScales[2] * radiusZ;
+		bboxen[ outputStart++ ] = decodeScales[0] * radiusX;
+		bboxen[ outputStart++ ] = decodeScales[1] * radiusY;
+		bboxen[ outputStart++ ] = decodeScales[2] * radiusZ;
 
-    }
+	}
 
-    return bboxen;
+	return bboxen;
 
 };
 
 THREE.UTF8Loader.prototype.decompressMesh =  function ( str, meshParams, decodeParams, name, idx, callback ) {
 
-    // Extract conversion parameters from attribArrays.
+	// Extract conversion parameters from attribArrays.
 
-    var stride = decodeParams.decodeScales.length;
+	var stride = decodeParams.decodeScales.length;
 
-    var decodeOffsets = decodeParams.decodeOffsets;
-    var decodeScales = decodeParams.decodeScales;
+	var decodeOffsets = decodeParams.decodeOffsets;
+	var decodeScales = decodeParams.decodeScales;
 
-    var attribStart = meshParams.attribRange[0];
-    var numVerts = meshParams.attribRange[1];
+	var attribStart = meshParams.attribRange[0];
+	var numVerts = meshParams.attribRange[1];
 
-    // Decode attributes.
+	// Decode attributes.
 
-    var inputOffset = attribStart;
-    var attribsOut = new Float32Array( stride * numVerts );
+	var inputOffset = attribStart;
+	var attribsOut = new Float32Array( stride * numVerts );
 
-    for (var j = 0; j < stride; j ++ ) {
+	for (var j = 0; j < stride; j ++ ) {
 
-        var end = inputOffset + numVerts;
+		var end = inputOffset + numVerts;
 
 		var decodeScale = decodeScales[j];
 
-        if ( decodeScale ) {
+		if ( decodeScale ) {
 
-            // Assume if decodeScale is never set, simply ignore the
-            // attribute.
+			// Assume if decodeScale is never set, simply ignore the
+			// attribute.
 
-            this.decompressAttribsInner_( str, inputOffset, end,
-                attribsOut, j, stride,
-                decodeOffsets[j], decodeScale );
-        }
+			this.decompressAttribsInner_( str, inputOffset, end,
+				attribsOut, j, stride,
+				decodeOffsets[j], decodeScale );
+		}
 
-        inputOffset = end;
+		inputOffset = end;
 
-    }
+	}
 
-    var indexStart = meshParams.indexRange[ 0 ];
-    var numIndices = 3 * meshParams.indexRange[ 1 ];
+	var indexStart = meshParams.indexRange[ 0 ];
+	var numIndices = 3 * meshParams.indexRange[ 1 ];
 
-    var indicesOut = new Uint16Array( numIndices );
+	var indicesOut = new Uint16Array( numIndices );
 
-    this.decompressIndices_( str, inputOffset, numIndices, indicesOut, 0 );
+	this.decompressIndices_( str, inputOffset, numIndices, indicesOut, 0 );
 
-    // Decode bboxen.
+	// Decode bboxen.
 
-    var bboxen = undefined;
-    var bboxOffset = meshParams.bboxes;
+	var bboxen = undefined;
+	var bboxOffset = meshParams.bboxes;
 
-    if ( bboxOffset ) {
+	if ( bboxOffset ) {
 
-        bboxen = this.decompressAABBs_( str, bboxOffset, meshParams.names.length, decodeOffsets, decodeScales );
-    }
+		bboxen = this.decompressAABBs_( str, bboxOffset, meshParams.names.length, decodeOffsets, decodeScales );
+	}
 
-    callback( name, idx, attribsOut, indicesOut, bboxen, meshParams );
+	callback( name, idx, attribsOut, indicesOut, bboxen, meshParams );
 
 };
 
 THREE.UTF8Loader.prototype.copyAttrib = function ( stride, attribsOutFixed, lastAttrib, index ) {
 
-    for ( var j = 0; j < stride; j ++ ) {
+	for ( var j = 0; j < stride; j ++ ) {
 
-        lastAttrib[ j ] = attribsOutFixed[ stride * index + j ];
+		lastAttrib[ j ] = attribsOutFixed[ stride * index + j ];
 
-    }
+	}
 
 };
 
 THREE.UTF8Loader.prototype.decodeAttrib2 = function ( str, stride, decodeOffsets, decodeScales, deltaStart,
-                                                        numVerts, attribsOut, attribsOutFixed, lastAttrib,
-                                                        index ) {
+														numVerts, attribsOut, attribsOutFixed, lastAttrib,
+														index ) {
 
-    for ( var j = 0; j < 5; j ++ ) {
+	for ( var j = 0; j < 5; j ++ ) {
 
-        var code = str.charCodeAt( deltaStart + numVerts*j + index );
-        var delta = ( code >> 1) ^ (-(code & 1));
+		var code = str.charCodeAt( deltaStart + numVerts*j + index );
+		var delta = ( code >> 1) ^ (-(code & 1));
 
-        lastAttrib[ j ] += delta;
-        attribsOutFixed[ stride * index + j ] = lastAttrib[ j ];
-        attribsOut[ stride * index + j ] = decodeScales[ j ] * ( lastAttrib[ j ] + decodeOffsets[ j ] );
-    }
+		lastAttrib[ j ] += delta;
+		attribsOutFixed[ stride * index + j ] = lastAttrib[ j ];
+		attribsOut[ stride * index + j ] = decodeScales[ j ] * ( lastAttrib[ j ] + decodeOffsets[ j ] );
+	}
 
 };
 
 THREE.UTF8Loader.prototype.accumulateNormal = function ( i0, i1, i2, attribsOutFixed, crosses ) {
 
-    var p0x = attribsOutFixed[ 8*i0 ];
-    var p0y = attribsOutFixed[ 8*i0 + 1 ];
-    var p0z = attribsOutFixed[ 8*i0 + 2 ];
+	var p0x = attribsOutFixed[ 8*i0 ];
+	var p0y = attribsOutFixed[ 8*i0 + 1 ];
+	var p0z = attribsOutFixed[ 8*i0 + 2 ];
 
-    var p1x = attribsOutFixed[ 8*i1 ];
-    var p1y = attribsOutFixed[ 8*i1 + 1 ];
-    var p1z = attribsOutFixed[ 8*i1 + 2 ];
+	var p1x = attribsOutFixed[ 8*i1 ];
+	var p1y = attribsOutFixed[ 8*i1 + 1 ];
+	var p1z = attribsOutFixed[ 8*i1 + 2 ];
 
-    var p2x = attribsOutFixed[ 8*i2 ];
-    var p2y = attribsOutFixed[ 8*i2 + 1 ];
-    var p2z = attribsOutFixed[ 8*i2 + 2 ];
+	var p2x = attribsOutFixed[ 8*i2 ];
+	var p2y = attribsOutFixed[ 8*i2 + 1 ];
+	var p2z = attribsOutFixed[ 8*i2 + 2 ];
 
-    p1x -= p0x;
-    p1y -= p0y;
-    p1z -= p0z;
+	p1x -= p0x;
+	p1y -= p0y;
+	p1z -= p0z;
 
-    p2x -= p0x;
-    p2y -= p0y;
-    p2z -= p0z;
+	p2x -= p0x;
+	p2y -= p0y;
+	p2z -= p0z;
 
-    p0x = p1y*p2z - p1z*p2y;
-    p0y = p1z*p2x - p1x*p2z;
-    p0z = p1x*p2y - p1y*p2x;
+	p0x = p1y*p2z - p1z*p2y;
+	p0y = p1z*p2x - p1x*p2z;
+	p0z = p1x*p2y - p1y*p2x;
 
-    crosses[ 3*i0 ]     += p0x;
-    crosses[ 3*i0 + 1 ] += p0y;
-    crosses[ 3*i0 + 2 ] += p0z;
+	crosses[ 3*i0 ]     += p0x;
+	crosses[ 3*i0 + 1 ] += p0y;
+	crosses[ 3*i0 + 2 ] += p0z;
 
-    crosses[ 3*i1 ]     += p0x;
-    crosses[ 3*i1 + 1 ] += p0y;
-    crosses[ 3*i1 + 2 ] += p0z;
+	crosses[ 3*i1 ]     += p0x;
+	crosses[ 3*i1 + 1 ] += p0y;
+	crosses[ 3*i1 + 2 ] += p0z;
 
-    crosses[ 3*i2 ]     += p0x;
-    crosses[ 3*i2 + 1 ] += p0y;
-    crosses[ 3*i2 + 2 ] += p0z;
+	crosses[ 3*i2 ]     += p0x;
+	crosses[ 3*i2 + 1 ] += p0y;
+	crosses[ 3*i2 + 2 ] += p0z;
 
 };
 
 THREE.UTF8Loader.prototype.decompressMesh2 = function( str, meshParams, decodeParams, name, idx, callback ) {
 
-    var MAX_BACKREF = 96;
+	var MAX_BACKREF = 96;
 
-    // Extract conversion parameters from attribArrays.
+	// Extract conversion parameters from attribArrays.
 
-    var stride = decodeParams.decodeScales.length;
+	var stride = decodeParams.decodeScales.length;
 
 	var decodeOffsets = decodeParams.decodeOffsets;
-    var decodeScales = decodeParams.decodeScales;
+	var decodeScales = decodeParams.decodeScales;
 
-    var deltaStart = meshParams.attribRange[ 0 ];
-    var numVerts = meshParams.attribRange[ 1 ];
+	var deltaStart = meshParams.attribRange[ 0 ];
+	var numVerts = meshParams.attribRange[ 1 ];
 
-    var codeStart = meshParams.codeRange[ 0 ];
-    var codeLength = meshParams.codeRange[ 1 ];
+	var codeStart = meshParams.codeRange[ 0 ];
+	var codeLength = meshParams.codeRange[ 1 ];
 
-    var numIndices = 3 * meshParams.codeRange[ 2 ];
+	var numIndices = 3 * meshParams.codeRange[ 2 ];
 
-    var indicesOut = new Uint16Array( numIndices );
+	var indicesOut = new Uint16Array( numIndices );
 
-    var crosses = new Int32Array( 3 * numVerts );
+	var crosses = new Int32Array( 3 * numVerts );
 
-    var lastAttrib = new Uint16Array( stride );
+	var lastAttrib = new Uint16Array( stride );
 
-    var attribsOutFixed = new Uint16Array( stride * numVerts );
-    var attribsOut = new Float32Array( stride * numVerts );
+	var attribsOutFixed = new Uint16Array( stride * numVerts );
+	var attribsOut = new Float32Array( stride * numVerts );
 
-    var highest = 0;
-    var outputStart = 0;
+	var highest = 0;
+	var outputStart = 0;
 
-    for ( var i = 0; i < numIndices; i += 3 ) {
+	for ( var i = 0; i < numIndices; i += 3 ) {
 
-        var code = str.charCodeAt( codeStart ++ );
+		var code = str.charCodeAt( codeStart ++ );
 
-        var max_backref = Math.min( i, MAX_BACKREF );
+		var max_backref = Math.min( i, MAX_BACKREF );
 
-        if ( code < max_backref ) {
+		if ( code < max_backref ) {
 
-            // Parallelogram
+			// Parallelogram
 
-            var winding = code % 3;
-            var backref = i - ( code - winding );
-            var i0, i1, i2;
+			var winding = code % 3;
+			var backref = i - ( code - winding );
+			var i0, i1, i2;
 
-            switch ( winding ) {
+			switch ( winding ) {
 
-                case 0:
+				case 0:
 
-                    i0 = indicesOut[ backref + 2 ];
-                    i1 = indicesOut[ backref + 1 ];
-                    i2 = indicesOut[ backref + 0 ];
-                    break;
+					i0 = indicesOut[ backref + 2 ];
+					i1 = indicesOut[ backref + 1 ];
+					i2 = indicesOut[ backref + 0 ];
+					break;
 
-                case 1:
+				case 1:
 
-                    i0 = indicesOut[ backref + 0 ];
-                    i1 = indicesOut[ backref + 2 ];
-                    i2 = indicesOut[ backref + 1 ];
-                    break;
+					i0 = indicesOut[ backref + 0 ];
+					i1 = indicesOut[ backref + 2 ];
+					i2 = indicesOut[ backref + 1 ];
+					break;
 
-                case 2:
+				case 2:
 
-                    i0 = indicesOut[ backref + 1 ];
-                    i1 = indicesOut[ backref + 0 ];
-                    i2 = indicesOut[ backref + 2 ];
-                    break;
+					i0 = indicesOut[ backref + 1 ];
+					i1 = indicesOut[ backref + 0 ];
+					i2 = indicesOut[ backref + 2 ];
+					break;
 
-            }
+			}
 
-            indicesOut[ outputStart ++ ] = i0;
-            indicesOut[ outputStart ++ ] = i1;
+			indicesOut[ outputStart ++ ] = i0;
+			indicesOut[ outputStart ++ ] = i1;
 
-            code = str.charCodeAt( codeStart ++ );
+			code = str.charCodeAt( codeStart ++ );
 
-            var index = highest - code;
-            indicesOut[ outputStart ++ ] = index;
+			var index = highest - code;
+			indicesOut[ outputStart ++ ] = index;
 
-            if ( code === 0 ) {
+			if ( code === 0 ) {
 
-                for (var j = 0; j < 5; j ++ ) {
+				for (var j = 0; j < 5; j ++ ) {
 
-                    var deltaCode = str.charCodeAt( deltaStart + numVerts * j + highest );
+					var deltaCode = str.charCodeAt( deltaStart + numVerts * j + highest );
 
-                    var prediction = ((deltaCode >> 1) ^ (-(deltaCode & 1))) +
-                        attribsOutFixed[stride*i0 + j] +
-                        attribsOutFixed[stride*i1 + j] -
-                        attribsOutFixed[stride*i2 + j];
+					var prediction = ((deltaCode >> 1) ^ (-(deltaCode & 1))) +
+						attribsOutFixed[stride*i0 + j] +
+						attribsOutFixed[stride*i1 + j] -
+						attribsOutFixed[stride*i2 + j];
 
-                    lastAttrib[j] = prediction;
+					lastAttrib[j] = prediction;
 
-                    attribsOutFixed[ stride * highest + j ] = prediction;
-                    attribsOut[ stride * highest + j ] = decodeScales[ j ] * ( prediction + decodeOffsets[ j ] );
+					attribsOutFixed[ stride * highest + j ] = prediction;
+					attribsOut[ stride * highest + j ] = decodeScales[ j ] * ( prediction + decodeOffsets[ j ] );
 
-                }
+				}
 
-                highest ++;
+				highest ++;
 
-            } else {
+			} else {
 
-                this.copyAttrib( stride, attribsOutFixed, lastAttrib, index );
+				this.copyAttrib( stride, attribsOutFixed, lastAttrib, index );
 
-            }
+			}
 
-            this.accumulateNormal( i0, i1, index, attribsOutFixed, crosses );
+			this.accumulateNormal( i0, i1, index, attribsOutFixed, crosses );
 
-        } else {
+		} else {
 
-            // Simple
+			// Simple
 
-            var index0 = highest - ( code - max_backref );
+			var index0 = highest - ( code - max_backref );
 
-            indicesOut[ outputStart ++ ] = index0;
+			indicesOut[ outputStart ++ ] = index0;
 
-            if ( code === max_backref ) {
+			if ( code === max_backref ) {
 
-                this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart,
-                    numVerts, attribsOut, attribsOutFixed, lastAttrib,
-                    highest ++ );
+				this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart,
+					numVerts, attribsOut, attribsOutFixed, lastAttrib,
+					highest ++ );
 
-            } else {
+			} else {
 
-                this.copyAttrib(stride, attribsOutFixed, lastAttrib, index0);
+				this.copyAttrib(stride, attribsOutFixed, lastAttrib, index0);
 
-            }
+			}
 
-            code = str.charCodeAt( codeStart ++ );
+			code = str.charCodeAt( codeStart ++ );
 
-            var index1 = highest - code;
-            indicesOut[ outputStart ++ ] = index1;
+			var index1 = highest - code;
+			indicesOut[ outputStart ++ ] = index1;
 
-            if ( code === 0 ) {
+			if ( code === 0 ) {
 
-                this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart,
-                    numVerts, attribsOut, attribsOutFixed, lastAttrib,
-                    highest ++ );
+				this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart,
+					numVerts, attribsOut, attribsOutFixed, lastAttrib,
+					highest ++ );
 
-            } else {
+			} else {
 
-                this.copyAttrib( stride, attribsOutFixed, lastAttrib, index1 );
+				this.copyAttrib( stride, attribsOutFixed, lastAttrib, index1 );
 
-            }
+			}
 
-            code = str.charCodeAt( codeStart ++ );
+			code = str.charCodeAt( codeStart ++ );
 
-            var index2 = highest - code;
-            indicesOut[ outputStart ++ ] = index2;
+			var index2 = highest - code;
+			indicesOut[ outputStart ++ ] = index2;
 
-            if ( code === 0 ) {
+			if ( code === 0 ) {
 
-                for ( var j = 0; j < 5; j ++ ) {
+				for ( var j = 0; j < 5; j ++ ) {
 
-                    lastAttrib[ j ] = ( attribsOutFixed[ stride * index0 + j ] + attribsOutFixed[ stride * index1 + j ] ) / 2;
+					lastAttrib[ j ] = ( attribsOutFixed[ stride * index0 + j ] + attribsOutFixed[ stride * index1 + j ] ) / 2;
 
-                }
+				}
 
-                this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart,
-                    numVerts, attribsOut, attribsOutFixed, lastAttrib,
-                    highest ++ );
+				this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart,
+					numVerts, attribsOut, attribsOutFixed, lastAttrib,
+					highest ++ );
 
-            } else {
+			} else {
 
-                this.copyAttrib( stride, attribsOutFixed, lastAttrib, index2 );
+				this.copyAttrib( stride, attribsOutFixed, lastAttrib, index2 );
 
-            }
+			}
 
-            this.accumulateNormal( index0, index1, index2, attribsOutFixed, crosses );
+			this.accumulateNormal( index0, index1, index2, attribsOutFixed, crosses );
 
-        }
+		}
 
-    }
+	}
 
-    for ( var i = 0; i < numVerts; i ++ ) {
+	for ( var i = 0; i < numVerts; i ++ ) {
 
-        var nx = crosses[ 3*i ];
-        var ny = crosses[ 3*i + 1 ];
-        var nz = crosses[ 3*i + 2 ];
+		var nx = crosses[ 3*i ];
+		var ny = crosses[ 3*i + 1 ];
+		var nz = crosses[ 3*i + 2 ];
 
-        var norm = 511.0 / Math.sqrt( nx*nx + ny*ny + nz*nz );
+		var norm = 511.0 / Math.sqrt( nx*nx + ny*ny + nz*nz );
 
-        var cx = str.charCodeAt( deltaStart + 5*numVerts + i );
-        var cy = str.charCodeAt( deltaStart + 6*numVerts + i );
-        var cz = str.charCodeAt( deltaStart + 7*numVerts + i );
+		var cx = str.charCodeAt( deltaStart + 5*numVerts + i );
+		var cy = str.charCodeAt( deltaStart + 6*numVerts + i );
+		var cz = str.charCodeAt( deltaStart + 7*numVerts + i );
 
-        attribsOut[ stride*i + 5 ] = norm*nx + ((cx >> 1) ^ (-(cx & 1)));
-        attribsOut[ stride*i + 6 ] = norm*ny + ((cy >> 1) ^ (-(cy & 1)));
-        attribsOut[ stride*i + 7 ] = norm*nz + ((cz >> 1) ^ (-(cz & 1)));
-    }
+		attribsOut[ stride*i + 5 ] = norm*nx + ((cx >> 1) ^ (-(cx & 1)));
+		attribsOut[ stride*i + 6 ] = norm*ny + ((cy >> 1) ^ (-(cy & 1)));
+		attribsOut[ stride*i + 7 ] = norm*nz + ((cz >> 1) ^ (-(cz & 1)));
+	}
 
-    callback( name, idx, attribsOut, indicesOut, undefined, meshParams );
+	callback( name, idx, attribsOut, indicesOut, undefined, meshParams );
 
 };
 
 THREE.UTF8Loader.prototype.downloadMesh = function ( path, name, meshEntry, decodeParams, callback ) {
 
-    var loader = this;
-    var idx = 0;
+	var loader = this;
+	var idx = 0;
 
-    function onprogress( req, e ) {
+	function onprogress( req, e ) {
 
-        while ( idx < meshEntry.length ) {
+		while ( idx < meshEntry.length ) {
 
-            var meshParams = meshEntry[ idx ];
-            var indexRange = meshParams.indexRange;
+			var meshParams = meshEntry[ idx ];
+			var indexRange = meshParams.indexRange;
 
-            if ( indexRange ) {
+			if ( indexRange ) {
 
-                var meshEnd = indexRange[ 0 ] + 3 * indexRange[ 1 ];
+				var meshEnd = indexRange[ 0 ] + 3 * indexRange[ 1 ];
 
-                if ( req.responseText.length < meshEnd ) break;
+				if ( req.responseText.length < meshEnd ) break;
 
-                loader.decompressMesh( req.responseText, meshParams, decodeParams, name, idx, callback );
+				loader.decompressMesh( req.responseText, meshParams, decodeParams, name, idx, callback );
 
-            } else {
+			} else {
 
-                var codeRange = meshParams.codeRange;
-                var meshEnd = codeRange[ 0 ] + codeRange[ 1 ];
+				var codeRange = meshParams.codeRange;
+				var meshEnd = codeRange[ 0 ] + codeRange[ 1 ];
 
-                if ( req.responseText.length < meshEnd ) break;
+				if ( req.responseText.length < meshEnd ) break;
 
-                loader.decompressMesh2( req.responseText, meshParams, decodeParams, name, idx, callback );
-            }
+				loader.decompressMesh2( req.responseText, meshParams, decodeParams, name, idx, callback );
+			}
 
-            ++idx;
+			++idx;
 
-        }
+		}
 
-    };
+	};
 
-    getHttpRequest( path, function( req, e ) {
+	getHttpRequest( path, function( req, e ) {
 
-        if ( req.status === 200 || req.status === 0 ) {
+		if ( req.status === 200 || req.status === 0 ) {
 
-            onprogress( req, e );
+			onprogress( req, e );
 
-        }
+		}
 
-        // TODO: handle errors.
+		// TODO: handle errors.
 
-    }, onprogress );
+	}, onprogress );
 
 };
 
 THREE.UTF8Loader.prototype.downloadMeshes = function ( path, meshUrlMap, decodeParams, callback ) {
 
-    for ( var url in meshUrlMap ) {
+	for ( var url in meshUrlMap ) {
 
-        var meshEntry = meshUrlMap[url];
-        this.downloadMesh( path + url, url, meshEntry, decodeParams, callback );
+		var meshEntry = meshUrlMap[url];
+		this.downloadMesh( path + url, url, meshEntry, decodeParams, callback );
 
-    }
+	}
 
 };
 
 THREE.UTF8Loader.prototype.createMeshCallback = function( materialBaseUrl, loadModelInfo, allDoneCallback ) {
 
 	var nCompletedUrls = 0;
-    var nExpectedUrls = 0;
+	var nExpectedUrls = 0;
 
-    var expectedMeshesPerUrl = {};
-    var decodedMeshesPerUrl = {};
+	var expectedMeshesPerUrl = {};
+	var decodedMeshesPerUrl = {};
 
 	var modelParts = {};
 
 	var meshUrlMap = loadModelInfo.urls;
 
-    for ( var url in meshUrlMap ) {
+	for ( var url in meshUrlMap ) {
 
-        expectedMeshesPerUrl[ url ] = meshUrlMap[ url ].length;
-        decodedMeshesPerUrl[ url ] = 0;
+		expectedMeshesPerUrl[ url ] = meshUrlMap[ url ].length;
+		decodedMeshesPerUrl[ url ] = 0;
 
 		nExpectedUrls ++;
 
-        modelParts[ url ] = new THREE.Object3D();
+		modelParts[ url ] = new THREE.Object3D();
 
-    }
+	}
 
-    var model = new THREE.Object3D();
+	var model = new THREE.Object3D();
 
-    // Prepare materials first...
+	// Prepare materials first...
 
-    var materialCreator = new THREE.MTLLoader.MaterialCreator( materialBaseUrl, loadModelInfo.options );
-    materialCreator.setMaterials( loadModelInfo.materials );
+	var materialCreator = new THREE.MTLLoader.MaterialCreator( materialBaseUrl, loadModelInfo.options );
+	materialCreator.setMaterials( loadModelInfo.materials );
 
-    materialCreator.preload();
+	materialCreator.preload();
 
 	// Create callback for creating mesh parts
 
@@ -642,42 +642,42 @@ THREE.UTF8Loader.prototype.createMeshCallback = function( materialBaseUrl, loadM
 
 	var meshCallback = function( name, idx, attribArray, indexArray, bboxen, meshParams ) {
 
-        // Got ourselves a new mesh
+		// Got ourselves a new mesh
 
-        // name identifies this part of the model (url)
-        // idx is the mesh index of this mesh of the part
-        // attribArray defines the vertices
-        // indexArray defines the faces
-        // bboxen defines the bounding box
-        // meshParams contains the material info
+		// name identifies this part of the model (url)
+		// idx is the mesh index of this mesh of the part
+		// attribArray defines the vertices
+		// indexArray defines the faces
+		// bboxen defines the bounding box
+		// meshParams contains the material info
 
 		var geometry = bufferGeometryCreator.create( attribArray, indexArray );
-        var material = materialCreator.create( meshParams.material );
+		var material = materialCreator.create( meshParams.material );
 
 		var mesh = new THREE.Mesh( geometry, material );
-        modelParts[ name ].add( mesh );
+		modelParts[ name ].add( mesh );
 
-        //model.add(new THREE.Mesh(geometry, material));
+		//model.add(new THREE.Mesh(geometry, material));
 
-        decodedMeshesPerUrl[ name ] ++;
+		decodedMeshesPerUrl[ name ] ++;
 
-        if ( decodedMeshesPerUrl[ name ] === expectedMeshesPerUrl[ name ] ) {
+		if ( decodedMeshesPerUrl[ name ] === expectedMeshesPerUrl[ name ] ) {
 
-            nCompletedUrls ++;
+			nCompletedUrls ++;
 
-            model.add( modelParts[ name ] );
+			model.add( modelParts[ name ] );
 
-            if ( nCompletedUrls === nExpectedUrls ) {
+			if ( nCompletedUrls === nExpectedUrls ) {
 
-                // ALL DONE!!!
+				// ALL DONE!!!
 
-                allDoneCallback( model );
+				allDoneCallback( model );
 
-            }
+			}
 
-        }
+		}
 
-    };
+	};
 
 	return meshCallback;
 
@@ -685,61 +685,61 @@ THREE.UTF8Loader.prototype.createMeshCallback = function( materialBaseUrl, loadM
 
 THREE.UTF8Loader.prototype.downloadModel = function ( geometryBase, materialBase, model, callback ) {
 
-    var meshCallback = this.createMeshCallback( materialBase, model, callback );
-    this.downloadMeshes( geometryBase, model.urls, model.decodeParams, meshCallback );
+	var meshCallback = this.createMeshCallback( materialBase, model, callback );
+	this.downloadMeshes( geometryBase, model.urls, model.decodeParams, meshCallback );
 
 };
 
 THREE.UTF8Loader.prototype.downloadModelJson = function ( jsonUrl, options, callback ) {
 
-    getJsonRequest( jsonUrl, function( loaded ) {
+	getJsonRequest( jsonUrl, function( loaded ) {
 
-        if ( ! loaded.decodeParams ) {
+		if ( ! loaded.decodeParams ) {
 
-            if ( options && options.decodeParams ) {
+			if ( options && options.decodeParams ) {
 
-                loaded.decodeParams = options.decodeParams;
+				loaded.decodeParams = options.decodeParams;
 
-            } else {
+			} else {
 
-                loaded.decodeParams = DEFAULT_DECODE_PARAMS;
+				loaded.decodeParams = DEFAULT_DECODE_PARAMS;
 
-            }
+			}
 
-        }
+		}
 
-        loaded.options = options;
+		loaded.options = options;
 
-        var geometryBase = jsonUrl.substr( 0, jsonUrl.lastIndexOf( "/" ) + 1 );
-        var materialBase = geometryBase;
+		var geometryBase = jsonUrl.substr( 0, jsonUrl.lastIndexOf( "/" ) + 1 );
+		var materialBase = geometryBase;
 
-        if ( options && options.geometryBase ) {
+		if ( options && options.geometryBase ) {
 
-            geometryBase = options.geometryBase;
+			geometryBase = options.geometryBase;
 
-            if ( geometryBase.charAt( geometryBase.length - 1 ) !== "/" ) {
+			if ( geometryBase.charAt( geometryBase.length - 1 ) !== "/" ) {
 
-                geometryBase = geometryBase + "/";
+				geometryBase = geometryBase + "/";
 
-            }
+			}
 
-        }
+		}
 
-        if ( options && options.materialBase ) {
+		if ( options && options.materialBase ) {
 
-            materialBase = options.materialBase;
+			materialBase = options.materialBase;
 
-            if ( materialBase.charAt( materialBase.length - 1 ) !== "/" ) {
+			if ( materialBase.charAt( materialBase.length - 1 ) !== "/" ) {
 
-                materialBase = materialBase  + "/";
+				materialBase = materialBase  + "/";
 
-            }
+			}
 
-        }
+		}
 
-        this.downloadModel( geometryBase, materialBase, loaded, callback );
+		this.downloadModel( geometryBase, materialBase, loaded, callback );
 
-    }.bind( this ) );
+	}.bind( this ) );
 
 };
 
@@ -747,35 +747,35 @@ THREE.UTF8Loader.prototype.downloadModelJson = function ( jsonUrl, options, call
 
 function getHttpRequest( url, onload, opt_onprogress ) {
 
-    var LISTENERS = {
+	var LISTENERS = {
 
-        load: function( e ) { onload( req, e ); },
-        progress: function( e ) { opt_onprogress( req, e ); }
+		load: function( e ) { onload( req, e ); },
+		progress: function( e ) { opt_onprogress( req, e ); }
 
-    };
+	};
 
-    var req = new XMLHttpRequest();
-    addListeners( req, LISTENERS );
+	var req = new XMLHttpRequest();
+	addListeners( req, LISTENERS );
 
-    req.open( 'GET', url, true );
-    req.send( null );
+	req.open( 'GET', url, true );
+	req.send( null );
 }
 
 function getJsonRequest( url, onjson ) {
 
-    getHttpRequest( url,
-        function( e ) { onjson( JSON.parse( e.responseText ) ); },
-        function() {} );
+	getHttpRequest( url,
+		function( e ) { onjson( JSON.parse( e.responseText ) ); },
+		function() {} );
 
 }
 
 function addListeners( dom, listeners ) {
 
-    // TODO: handle event capture, object binding.
+	// TODO: handle event capture, object binding.
 
-    for ( var key in listeners ) {
+	for ( var key in listeners ) {
 
-        dom.addEventListener( key, listeners[ key ] );
+		dom.addEventListener( key, listeners[ key ] );
 
-    }
+	}
 }

+ 15 - 26
examples/js/loaders/VRMLLoader.js

@@ -2,7 +2,11 @@
  * @author mrdoob / http://mrdoob.com/
  */
 
-THREE.VRMLLoader = function () {};
+THREE.VRMLLoader = function ( manager ) {
+
+	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
+
+};
 
 THREE.VRMLLoader.prototype = {
 
@@ -22,35 +26,23 @@ THREE.VRMLLoader.prototype = {
 
 	recordingFieldname: null,
 
-	load: function ( url, callback ) {
+	load: function ( url, onLoad, onProgress, onError ) {
 
 		var scope = this;
-		var request = new XMLHttpRequest();
-
-		request.addEventListener( 'load', function ( event ) {
-
-			var object = scope.parse( event.target.responseText );
-
-			scope.dispatchEvent( { type: 'load', content: object } );
-
-			if ( callback ) callback( object );
 
-		}, false );
+		var loader = new THREE.XHRLoader( this.manager );
+		loader.setCrossOrigin( this.crossOrigin );
+		loader.load( url, function ( text ) {
 
-		request.addEventListener( 'progress', function ( event ) {
+			onLoad( scope.parse( text ) );
 
-			scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } );
+		}, onProgress, onError );
 
-		}, false );
-
-		request.addEventListener( 'error', function () {
-
-			scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
+	},
 
-		}, false );
+	setCrossOrigin: function ( value ) {
 
-		request.open( 'GET', url, true );
-		request.send( null );
+		this.crossOrigin = value;
 
 	},
 
@@ -833,7 +825,4 @@ THREE.VRMLLoader.prototype = {
 
 	}
 
-};
-
-THREE.EventDispatcher.prototype.apply( THREE.VRMLLoader.prototype );
-
+};

+ 7 - 1
examples/js/loaders/VTKLoader.js

@@ -16,7 +16,7 @@ THREE.VTKLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.XHRLoader( this.manager );
 		loader.setCrossOrigin( this.crossOrigin );
 		loader.load( url, function ( text ) {
 
@@ -26,6 +26,12 @@ THREE.VTKLoader.prototype = {
 
 	},
 
+	setCrossOrigin: function ( value ) {
+
+		this.crossOrigin = value;
+
+	},
+
 	parse: function ( data ) {
 
 		var indices = [];

+ 1 - 4
examples/webgl_lights_pointlights.html

@@ -68,8 +68,7 @@
 
 				scene = new THREE.Scene();
 
-				loader = new THREE.BinaryLoader( true );
-				document.body.appendChild( loader.statusDomElement );
+				loader = new THREE.BinaryLoader();
 
 				var callback = function( geometry ) {
 
@@ -77,8 +76,6 @@
 					object.scale.x = object.scale.y = object.scale.z = 0.80;
 					scene.add( object );
 
-					loader.statusDomElement.style.display = "none";
-
 				};
 
 				loader.load( "obj/walt/WaltHead_bin.js", callback );

+ 1 - 3
examples/webgl_loader_ply.html

@@ -90,9 +90,8 @@
 				// PLY file
 
 				var loader = new THREE.PLYLoader();
-				loader.addEventListener( 'load', function ( event ) {
+				loader.load( './models/ply/ascii/dolphins.ply', function ( geometry ) {
 
-					var geometry = event.content;
 					var material = new THREE.MeshPhongMaterial( { ambient: 0x0055ff, color: 0x0055ff, specular: 0x111111, shininess: 200 } );
 					var mesh = new THREE.Mesh( geometry, material );
 
@@ -106,7 +105,6 @@
 					scene.add( mesh );
 
 				} );
-				loader.load( './models/ply/ascii/dolphins.ply' );
 
 				// Lights
 

+ 2 - 5
examples/webgl_loader_vrml.html

@@ -79,12 +79,9 @@
 				camera.add( dirLight.target );
 
 				var loader = new THREE.VRMLLoader();
-				loader.addEventListener( 'load', function ( event ) {
-
-					scene.add(event.content);
-
+				loader.load( "models/vrml/house.wrl", function(object) {
+					scene.add(object);
 				} );
-				loader.load( "models/vrml/house.wrl" );
 
 				// renderer
 

+ 11 - 2
src/loaders/BinaryTextureLoader.js

@@ -4,7 +4,9 @@
  * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)
  */
 
-THREE.DataTextureLoader = THREE.BinaryTextureLoader = function () {
+THREE.DataTextureLoader = THREE.BinaryTextureLoader = function ( manager ) {
+
+	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
 
 	// override in sub classes
 	this._parser = null;
@@ -21,7 +23,8 @@ THREE.BinaryTextureLoader.prototype = {
 
 		var texture = new THREE.DataTexture( );
 
-		var loader = new THREE.XHRLoader();
+		var loader = new THREE.XHRLoader( this.manager );
+		loader.setCrossOrigin( this.crossOrigin );
 		loader.setResponseType( 'arraybuffer' );
 
 		loader.load( url, function ( buffer ) {
@@ -82,6 +85,12 @@ THREE.BinaryTextureLoader.prototype = {
 
 		return texture;
 
+	},
+
+	setCrossOrigin: function ( value ) {
+
+		this.crossOrigin = value;
+
 	}
 
 };

+ 1 - 1
src/loaders/BufferGeometryLoader.js

@@ -16,7 +16,7 @@ THREE.BufferGeometryLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.XHRLoader( this.manager );
 		loader.setCrossOrigin( this.crossOrigin );
 		loader.load( url, function ( text ) {
 

+ 17 - 8
src/loaders/CompressedTextureLoader.js

@@ -4,7 +4,9 @@
  * Abstract Base class to block based textures loader (dds, pvr, ...)
  */
 
-THREE.CompressedTextureLoader = function () {
+THREE.CompressedTextureLoader = function ( manager ) {
+
+	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
 
 	// override in sub classes
 	this._parser = null;
@@ -16,7 +18,7 @@ THREE.CompressedTextureLoader.prototype = {
 
 	constructor: THREE.CompressedTextureLoader,
 
-	load: function ( url, onLoad, onError ) {
+	load: function ( url, onLoad, onProgress, onError ) {
 
 		var scope = this;
 
@@ -25,7 +27,8 @@ THREE.CompressedTextureLoader.prototype = {
 		var texture = new THREE.CompressedTexture();
 		texture.image = images;
 
-		var loader = new THREE.XHRLoader();
+		var loader = new THREE.XHRLoader( this.manager );
+		loader.setCrossOrigin( this.crossOrigin );
 		loader.setResponseType( 'arraybuffer' );
 
 		if ( url instanceof Array ) {
@@ -49,8 +52,8 @@ THREE.CompressedTextureLoader.prototype = {
 
 					if ( loaded === 6 ) {
 
- 						if (texDatas.mipmapCount == 1)
- 							texture.minFilter = THREE.LinearFilter;
+						if (texDatas.mipmapCount == 1)
+							texture.minFilter = THREE.LinearFilter;
 
 						texture.format = texDatas.format;
 						texture.needsUpdate = true;
@@ -59,7 +62,7 @@ THREE.CompressedTextureLoader.prototype = {
 
 					}
 
-				} );
+				}, onProgress, onError );
 
 			};
 
@@ -115,12 +118,18 @@ THREE.CompressedTextureLoader.prototype = {
 
 				if ( onLoad ) onLoad( texture );
 
-			} );
+			}, onProgress, onError );
 
 		}
 
 		return texture;
 
-	}
+	},
+
+	setCrossOrigin: function ( value ) {
+
+		this.crossOrigin = value;
+
+	},
 
 };

+ 1 - 1
src/loaders/GeometryLoader.js

@@ -16,7 +16,7 @@ THREE.GeometryLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader();
+		var loader = new THREE.XHRLoader( this.manager );
 		loader.setCrossOrigin( this.crossOrigin );
 		loader.load( url, function ( text ) {
 

+ 264 - 314
src/loaders/JSONLoader.js

@@ -3,542 +3,492 @@
  * @author alteredq / http://alteredqualia.com/
  */
 
-THREE.JSONLoader = function ( showStatus ) {
+THREE.JSONLoader = function ( manager ) {
 
-	THREE.Loader.call( this, showStatus );
+	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
 
 	this.withCredentials = false;
 
 };
 
-THREE.JSONLoader.prototype = Object.create( THREE.Loader.prototype );
-THREE.JSONLoader.prototype.constructor = THREE.JSONLoader;
+THREE.JSONLoader.prototype = {
 
-THREE.JSONLoader.prototype.load = function ( url, callback, texturePath ) {
+	constructor: THREE.JSONLoader,
 
-	var scope = this;
+	load: function( url, onLoad, onProgress, onError ) {
 
-	// todo: unify load API to for easier SceneLoader use
+		var scope = this;
 
-	texturePath = texturePath && ( typeof texturePath === 'string' ) ? texturePath : this.extractUrlBase( url );
+		this.texturePath = this.texturePath && ( typeof this.texturePath === "string" ) ? this.texturePath : this.extractUrlBase( url );
 
-	this.onLoadStart();
-	this.loadAjaxJSON( this, url, callback, texturePath );
-
-};
-
-THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, texturePath, callbackProgress ) {
-
-	var xhr = new XMLHttpRequest();
-
-	var length = 0;
-
-	xhr.onreadystatechange = function () {
-
-		if ( xhr.readyState === xhr.DONE ) {
-
-			if ( xhr.status === 200 || xhr.status === 0 ) {
-
-				if ( xhr.responseText ) {
-
-					var json = JSON.parse( xhr.responseText );
-
-					if ( json.metadata !== undefined && json.metadata.type === 'scene' ) {
-
-						console.error( 'THREE.JSONLoader: "' + url + '" seems to be a Scene. Use THREE.SceneLoader instead.' );
-						return;
-
-					}
-
-					var result = context.parse( json, texturePath );
-					callback( result.geometry, result.materials );
-
-				} else {
-
-					console.error( 'THREE.JSONLoader: "' + url + '" seems to be unreachable or the file is empty.' );
-
-				}
-
-				// in context of more complex asset initialization
-				// do not block on single failed file
-				// maybe should go even one more level up
-
-				context.onLoadComplete();
-
-			} else {
-
-				console.error( 'THREE.JSONLoader: Couldn\'t load "' + url + '" (' + xhr.status + ')' );
+		var loader = new THREE.XHRLoader( this.manager );
+		loader.setCrossOrigin( this.crossOrigin );
+		loader.setWithCredentials( this.withCredentials );
+		loader.load( url, function ( text ) {
+			var json = JSON.parse( text ), scene, metadata;
 
+			if ( json.metadata !== undefined && json.metadata.type === 'scene' ) {
+				console.error( 'THREE.JSONLoader: "' + url + '" seems to be a Scene. Use THREE.SceneLoader instead.' );
+				return;
 			}
 
-		} else if ( xhr.readyState === xhr.LOADING ) {
+			var object = scope.parse(json, texturePath);
+			onLoad( object.geometry, object.materials );
 
-			if ( callbackProgress ) {
+		} );
 
-				if ( length === 0 ) {
+	},
 
-					length = xhr.getResponseHeader( 'Content-Length' );
+	setCrossOrigin: function ( value ) {
 
-				}
+		this.crossOrigin = value;
 
-				callbackProgress( { total: length, loaded: xhr.responseText.length } );
+	},
 
-			}
+	setTexturePath: function ( value ) {
 
-		} else if ( xhr.readyState === xhr.HEADERS_RECEIVED ) {
+		this.texturePath = value;
 
-			if ( callbackProgress !== undefined ) {
+	},
 
-				length = xhr.getResponseHeader( 'Content-Length' );
+	parse = function ( json, texturePath ) {
 
-			}
-
-		}
+		var scope = this,
+		geometry = new THREE.Geometry(),
+		scale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;
 
-	};
+		parseModel( scale );
 
-	xhr.open( 'GET', url, true );
-	xhr.withCredentials = this.withCredentials;
-	xhr.send( null );
+		parseSkin();
+		parseMorphing( scale );
 
-};
+		geometry.computeFaceNormals();
+		geometry.computeBoundingSphere();
 
-THREE.JSONLoader.prototype.parse = function ( json, texturePath ) {
+		function parseModel( scale ) {
 
-	var scope = this,
-	geometry = new THREE.Geometry(),
-	scale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;
+			function isBitSet( value, position ) {
 
-	parseModel( scale );
+				return value & ( 1 << position );
 
-	parseSkin();
-	parseMorphing( scale );
-
-	geometry.computeFaceNormals();
-	geometry.computeBoundingSphere();
+			}
 
-	function parseModel( scale ) {
+			var i, j, fi,
 
-		function isBitSet( value, position ) {
+			offset, zLength,
 
-			return value & ( 1 << position );
+			colorIndex, normalIndex, uvIndex, materialIndex,
 
-		}
+			type,
+			isQuad,
+			hasMaterial,
+			hasFaceVertexUv,
+			hasFaceNormal, hasFaceVertexNormal,
+			hasFaceColor, hasFaceVertexColor,
 
-		var i, j, fi,
+			vertex, face, faceA, faceB, color, hex, normal,
 
-		offset, zLength,
+			uvLayer, uv, u, v,
 
-		colorIndex, normalIndex, uvIndex, materialIndex,
+			faces = json.faces,
+			vertices = json.vertices,
+			normals = json.normals,
+			colors = json.colors,
 
-		type,
-		isQuad,
-		hasMaterial,
-		hasFaceVertexUv,
-		hasFaceNormal, hasFaceVertexNormal,
-		hasFaceColor, hasFaceVertexColor,
+			nUvLayers = 0;
 
-		vertex, face, faceA, faceB, color, hex, normal,
+			if ( json.uvs !== undefined ) {
 
-		uvLayer, uv, u, v,
+				// disregard empty arrays
 
-		faces = json.faces,
-		vertices = json.vertices,
-		normals = json.normals,
-		colors = json.colors,
+				for ( i = 0; i < json.uvs.length; i ++ ) {
 
-		nUvLayers = 0;
+					if ( json.uvs[ i ].length ) nUvLayers ++;
 
-		if ( json.uvs !== undefined ) {
+				}
 
-			// disregard empty arrays
+				for ( i = 0; i < nUvLayers; i ++ ) {
 
-			for ( i = 0; i < json.uvs.length; i ++ ) {
+					geometry.faceVertexUvs[ i ] = [];
 
-				if ( json.uvs[ i ].length ) nUvLayers ++;
+				}
 
 			}
 
-			for ( i = 0; i < nUvLayers; i ++ ) {
-
-				geometry.faceVertexUvs[ i ] = [];
+			offset = 0;
+			zLength = vertices.length;
 
-			}
-
-		}
+			while ( offset < zLength ) {
 
-		offset = 0;
-		zLength = vertices.length;
+				vertex = new THREE.Vector3();
 
-		while ( offset < zLength ) {
+				vertex.x = vertices[ offset ++ ] * scale;
+				vertex.y = vertices[ offset ++ ] * scale;
+				vertex.z = vertices[ offset ++ ] * scale;
 
-			vertex = new THREE.Vector3();
+				geometry.vertices.push( vertex );
 
-			vertex.x = vertices[ offset ++ ] * scale;
-			vertex.y = vertices[ offset ++ ] * scale;
-			vertex.z = vertices[ offset ++ ] * scale;
-
-			geometry.vertices.push( vertex );
+			}
 
-		}
+			offset = 0;
+			zLength = faces.length;
 
-		offset = 0;
-		zLength = faces.length;
+			while ( offset < zLength ) {
 
-		while ( offset < zLength ) {
+				type = faces[ offset ++ ];
 
-			type = faces[ offset ++ ];
 
+				isQuad              = isBitSet( type, 0 );
+				hasMaterial         = isBitSet( type, 1 );
+				hasFaceVertexUv     = isBitSet( type, 3 );
+				hasFaceNormal       = isBitSet( type, 4 );
+				hasFaceVertexNormal = isBitSet( type, 5 );
+				hasFaceColor	     = isBitSet( type, 6 );
+				hasFaceVertexColor  = isBitSet( type, 7 );
 
-			isQuad              = isBitSet( type, 0 );
-			hasMaterial         = isBitSet( type, 1 );
-			hasFaceVertexUv     = isBitSet( type, 3 );
-			hasFaceNormal       = isBitSet( type, 4 );
-			hasFaceVertexNormal = isBitSet( type, 5 );
-			hasFaceColor	     = isBitSet( type, 6 );
-			hasFaceVertexColor  = isBitSet( type, 7 );
+				// console.log("type", type, "bits", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);
 
-			// console.log("type", type, "bits", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);
+				if ( isQuad ) {
 
-			if ( isQuad ) {
+					faceA = new THREE.Face3();
+					faceA.a = faces[ offset ];
+					faceA.b = faces[ offset + 1 ];
+					faceA.c = faces[ offset + 3 ];
 
-				faceA = new THREE.Face3();
-				faceA.a = faces[ offset ];
-				faceA.b = faces[ offset + 1 ];
-				faceA.c = faces[ offset + 3 ];
+					faceB = new THREE.Face3();
+					faceB.a = faces[ offset + 1 ];
+					faceB.b = faces[ offset + 2 ];
+					faceB.c = faces[ offset + 3 ];
 
-				faceB = new THREE.Face3();
-				faceB.a = faces[ offset + 1 ];
-				faceB.b = faces[ offset + 2 ];
-				faceB.c = faces[ offset + 3 ];
+					offset += 4;
 
-				offset += 4;
+					if ( hasMaterial ) {
 
-				if ( hasMaterial ) {
+						materialIndex = faces[ offset ++ ];
+						faceA.materialIndex = materialIndex;
+						faceB.materialIndex = materialIndex;
 
-					materialIndex = faces[ offset ++ ];
-					faceA.materialIndex = materialIndex;
-					faceB.materialIndex = materialIndex;
+					}
 
-				}
+					// to get face <=> uv index correspondence
 
-				// to get face <=> uv index correspondence
+					fi = geometry.faces.length;
 
-				fi = geometry.faces.length;
+					if ( hasFaceVertexUv ) {
 
-				if ( hasFaceVertexUv ) {
+						for ( i = 0; i < nUvLayers; i ++ ) {
 
-					for ( i = 0; i < nUvLayers; i ++ ) {
+							uvLayer = json.uvs[ i ];
 
-						uvLayer = json.uvs[ i ];
+							geometry.faceVertexUvs[ i ][ fi ] = [];
+							geometry.faceVertexUvs[ i ][ fi + 1 ] = []
 
-						geometry.faceVertexUvs[ i ][ fi ] = [];
-						geometry.faceVertexUvs[ i ][ fi + 1 ] = []
+							for ( j = 0; j < 4; j ++ ) {
 
-						for ( j = 0; j < 4; j ++ ) {
+								uvIndex = faces[ offset ++ ];
 
-							uvIndex = faces[ offset ++ ];
+								u = uvLayer[ uvIndex * 2 ];
+								v = uvLayer[ uvIndex * 2 + 1 ];
 
-							u = uvLayer[ uvIndex * 2 ];
-							v = uvLayer[ uvIndex * 2 + 1 ];
+								uv = new THREE.Vector2( u, v );
 
-							uv = new THREE.Vector2( u, v );
+								if ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );
+								if ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );
 
-							if ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );
-							if ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );
+							}
 
 						}
 
 					}
 
-				}
-
-				if ( hasFaceNormal ) {
-
-					normalIndex = faces[ offset ++ ] * 3;
-
-					faceA.normal.set(
-						normals[ normalIndex ++ ],
-						normals[ normalIndex ++ ],
-						normals[ normalIndex ]
-					);
-
-					faceB.normal.copy( faceA.normal );
-
-				}
-
-				if ( hasFaceVertexNormal ) {
-
-					for ( i = 0; i < 4; i ++ ) {
+					if ( hasFaceNormal ) {
 
 						normalIndex = faces[ offset ++ ] * 3;
 
-						normal = new THREE.Vector3(
+						faceA.normal.set(
 							normals[ normalIndex ++ ],
 							normals[ normalIndex ++ ],
 							normals[ normalIndex ]
 						);
 
-
-						if ( i !== 2 ) faceA.vertexNormals.push( normal );
-						if ( i !== 0 ) faceB.vertexNormals.push( normal );
+						faceB.normal.copy( faceA.normal );
 
 					}
 
-				}
+					if ( hasFaceVertexNormal ) {
 
+						for ( i = 0; i < 4; i ++ ) {
 
-				if ( hasFaceColor ) {
+							normalIndex = faces[ offset ++ ] * 3;
 
-					colorIndex = faces[ offset ++ ];
-					hex = colors[ colorIndex ];
+							normal = new THREE.Vector3(
+								normals[ normalIndex ++ ],
+								normals[ normalIndex ++ ],
+								normals[ normalIndex ]
+							);
 
-					faceA.color.setHex( hex );
-					faceB.color.setHex( hex );
 
-				}
+							if ( i !== 2 ) faceA.vertexNormals.push( normal );
+							if ( i !== 0 ) faceB.vertexNormals.push( normal );
 
+						}
 
-				if ( hasFaceVertexColor ) {
+					}
 
-					for ( i = 0; i < 4; i ++ ) {
+
+					if ( hasFaceColor ) {
 
 						colorIndex = faces[ offset ++ ];
 						hex = colors[ colorIndex ];
 
-						if ( i !== 2 ) faceA.vertexColors.push( new THREE.Color( hex ) );
-						if ( i !== 0 ) faceB.vertexColors.push( new THREE.Color( hex ) );
+						faceA.color.setHex( hex );
+						faceB.color.setHex( hex );
 
 					}
 
-				}
 
-				geometry.faces.push( faceA );
-				geometry.faces.push( faceB );
+					if ( hasFaceVertexColor ) {
+
+						for ( i = 0; i < 4; i ++ ) {
 
-			} else {
+							colorIndex = faces[ offset ++ ];
+							hex = colors[ colorIndex ];
 
-				face = new THREE.Face3();
-				face.a = faces[ offset ++ ];
-				face.b = faces[ offset ++ ];
-				face.c = faces[ offset ++ ];
+							if ( i !== 2 ) faceA.vertexColors.push( new THREE.Color( hex ) );
+							if ( i !== 0 ) faceB.vertexColors.push( new THREE.Color( hex ) );
 
-				if ( hasMaterial ) {
+						}
 
-					materialIndex = faces[ offset ++ ];
-					face.materialIndex = materialIndex;
+					}
 
-				}
+					geometry.faces.push( faceA );
+					geometry.faces.push( faceB );
 
-				// to get face <=> uv index correspondence
+				} else {
 
-				fi = geometry.faces.length;
+					face = new THREE.Face3();
+					face.a = faces[ offset ++ ];
+					face.b = faces[ offset ++ ];
+					face.c = faces[ offset ++ ];
 
-				if ( hasFaceVertexUv ) {
+					if ( hasMaterial ) {
 
-					for ( i = 0; i < nUvLayers; i ++ ) {
+						materialIndex = faces[ offset ++ ];
+						face.materialIndex = materialIndex;
 
-						uvLayer = json.uvs[ i ];
+					}
 
-						geometry.faceVertexUvs[ i ][ fi ] = [];
+					// to get face <=> uv index correspondence
 
-						for ( j = 0; j < 3; j ++ ) {
+					fi = geometry.faces.length;
 
-							uvIndex = faces[ offset ++ ];
+					if ( hasFaceVertexUv ) {
 
-							u = uvLayer[ uvIndex * 2 ];
-							v = uvLayer[ uvIndex * 2 + 1 ];
+						for ( i = 0; i < nUvLayers; i ++ ) {
 
-							uv = new THREE.Vector2( u, v );
+							uvLayer = json.uvs[ i ];
 
-							geometry.faceVertexUvs[ i ][ fi ].push( uv );
+							geometry.faceVertexUvs[ i ][ fi ] = [];
 
-						}
+							for ( j = 0; j < 3; j ++ ) {
 
-					}
+								uvIndex = faces[ offset ++ ];
 
-				}
+								u = uvLayer[ uvIndex * 2 ];
+								v = uvLayer[ uvIndex * 2 + 1 ];
 
-				if ( hasFaceNormal ) {
+								uv = new THREE.Vector2( u, v );
 
-					normalIndex = faces[ offset ++ ] * 3;
+								geometry.faceVertexUvs[ i ][ fi ].push( uv );
 
-					face.normal.set(
-						normals[ normalIndex ++ ],
-						normals[ normalIndex ++ ],
-						normals[ normalIndex ]
-					);
+							}
 
-				}
+						}
 
-				if ( hasFaceVertexNormal ) {
+					}
 
-					for ( i = 0; i < 3; i ++ ) {
+					if ( hasFaceNormal ) {
 
 						normalIndex = faces[ offset ++ ] * 3;
 
-						normal = new THREE.Vector3(
+						face.normal.set(
 							normals[ normalIndex ++ ],
 							normals[ normalIndex ++ ],
 							normals[ normalIndex ]
 						);
 
-						face.vertexNormals.push( normal );
-
 					}
 
-				}
+					if ( hasFaceVertexNormal ) {
 
+						for ( i = 0; i < 3; i ++ ) {
 
-				if ( hasFaceColor ) {
+							normalIndex = faces[ offset ++ ] * 3;
 
-					colorIndex = faces[ offset ++ ];
-					face.color.setHex( colors[ colorIndex ] );
+							normal = new THREE.Vector3(
+								normals[ normalIndex ++ ],
+								normals[ normalIndex ++ ],
+								normals[ normalIndex ]
+							);
 
-				}
+							face.vertexNormals.push( normal );
 
+						}
 
-				if ( hasFaceVertexColor ) {
+					}
 
-					for ( i = 0; i < 3; i ++ ) {
+
+					if ( hasFaceColor ) {
 
 						colorIndex = faces[ offset ++ ];
-						face.vertexColors.push( new THREE.Color( colors[ colorIndex ] ) );
+						face.color.setHex( colors[ colorIndex ] );
 
 					}
 
-				}
 
-				geometry.faces.push( face );
+					if ( hasFaceVertexColor ) {
+
+						for ( i = 0; i < 3; i ++ ) {
+
+							colorIndex = faces[ offset ++ ];
+							face.vertexColors.push( new THREE.Color( colors[ colorIndex ] ) );
+
+						}
+
+					}
+
+					geometry.faces.push( face );
+
+				}
 
 			}
 
-		}
+		};
 
-	};
+		function parseSkin() {
+			var influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;
 
-	function parseSkin() {
-		var influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;
+			if ( json.skinWeights ) {
 
-		if ( json.skinWeights ) {
+				for ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {
 
-			for ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {
+					var x =                               json.skinWeights[ i     ];
+					var y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;
+					var z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;
+					var w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;
 
-				var x =                               json.skinWeights[ i     ];
-				var y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;
-				var z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;
-				var w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;
+					geometry.skinWeights.push( new THREE.Vector4( x, y, z, w ) );
 
-				geometry.skinWeights.push( new THREE.Vector4( x, y, z, w ) );
+				}
 
 			}
 
-		}
+			if ( json.skinIndices ) {
 
-		if ( json.skinIndices ) {
+				for ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {
 
-			for ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {
+					var a =                               json.skinIndices[ i     ];
+					var b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;
+					var c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;
+					var d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;
 
-				var a =                               json.skinIndices[ i     ];
-				var b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;
-				var c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;
-				var d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;
+					geometry.skinIndices.push( new THREE.Vector4( a, b, c, d ) );
 
-				geometry.skinIndices.push( new THREE.Vector4( a, b, c, d ) );
+				}
 
 			}
 
-		}
+			geometry.bones = json.bones;
 
-		geometry.bones = json.bones;
+			if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {
 
-		if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {
+					console.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +
+						geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );
 
-				console.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +
-					geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );
+			}
 
-		}
 
+			// could change this to json.animations[0] or remove completely
 
-		// could change this to json.animations[0] or remove completely
+			geometry.animation = json.animation;
+			geometry.animations = json.animations;
 
-		geometry.animation = json.animation;
-		geometry.animations = json.animations;
+		};
 
-	};
+		function parseMorphing( scale ) {
 
-	function parseMorphing( scale ) {
+			if ( json.morphTargets !== undefined ) {
 
-		if ( json.morphTargets !== undefined ) {
+				var i, l, v, vl, dstVertices, srcVertices;
 
-			var i, l, v, vl, dstVertices, srcVertices;
+				for ( i = 0, l = json.morphTargets.length; i < l; i ++ ) {
 
-			for ( i = 0, l = json.morphTargets.length; i < l; i ++ ) {
+					geometry.morphTargets[ i ] = {};
+					geometry.morphTargets[ i ].name = json.morphTargets[ i ].name;
+					geometry.morphTargets[ i ].vertices = [];
 
-				geometry.morphTargets[ i ] = {};
-				geometry.morphTargets[ i ].name = json.morphTargets[ i ].name;
-				geometry.morphTargets[ i ].vertices = [];
+					dstVertices = geometry.morphTargets[ i ].vertices;
+					srcVertices = json.morphTargets [ i ].vertices;
 
-				dstVertices = geometry.morphTargets[ i ].vertices;
-				srcVertices = json.morphTargets [ i ].vertices;
+					for ( v = 0, vl = srcVertices.length; v < vl; v += 3 ) {
 
-				for ( v = 0, vl = srcVertices.length; v < vl; v += 3 ) {
+						var vertex = new THREE.Vector3();
+						vertex.x = srcVertices[ v ] * scale;
+						vertex.y = srcVertices[ v + 1 ] * scale;
+						vertex.z = srcVertices[ v + 2 ] * scale;
 
-					var vertex = new THREE.Vector3();
-					vertex.x = srcVertices[ v ] * scale;
-					vertex.y = srcVertices[ v + 1 ] * scale;
-					vertex.z = srcVertices[ v + 2 ] * scale;
+						dstVertices.push( vertex );
 
-					dstVertices.push( vertex );
+					}
 
 				}
 
 			}
 
-		}
+			if ( json.morphColors !== undefined ) {
 
-		if ( json.morphColors !== undefined ) {
+				var i, l, c, cl, dstColors, srcColors, color;
 
-			var i, l, c, cl, dstColors, srcColors, color;
+				for ( i = 0, l = json.morphColors.length; i < l; i ++ ) {
 
-			for ( i = 0, l = json.morphColors.length; i < l; i ++ ) {
+					geometry.morphColors[ i ] = {};
+					geometry.morphColors[ i ].name = json.morphColors[ i ].name;
+					geometry.morphColors[ i ].colors = [];
 
-				geometry.morphColors[ i ] = {};
-				geometry.morphColors[ i ].name = json.morphColors[ i ].name;
-				geometry.morphColors[ i ].colors = [];
+					dstColors = geometry.morphColors[ i ].colors;
+					srcColors = json.morphColors [ i ].colors;
 
-				dstColors = geometry.morphColors[ i ].colors;
-				srcColors = json.morphColors [ i ].colors;
+					for ( c = 0, cl = srcColors.length; c < cl; c += 3 ) {
 
-				for ( c = 0, cl = srcColors.length; c < cl; c += 3 ) {
+						color = new THREE.Color( 0xffaa00 );
+						color.setRGB( srcColors[ c ], srcColors[ c + 1 ], srcColors[ c + 2 ] );
+						dstColors.push( color );
 
-					color = new THREE.Color( 0xffaa00 );
-					color.setRGB( srcColors[ c ], srcColors[ c + 1 ], srcColors[ c + 2 ] );
-					dstColors.push( color );
+					}
 
 				}
 
 			}
 
-		}
+		};
 
-	};
+		if ( json.materials === undefined || json.materials.length === 0 ) {
 
-	if ( json.materials === undefined || json.materials.length === 0 ) {
+			return { geometry: geometry };
 
-		return { geometry: geometry };
+		} else {
 
-	} else {
+			var materials = this.initMaterials( json.materials, texturePath );
 
-		var materials = this.initMaterials( json.materials, texturePath );
+			if ( this.needsTangents( materials ) ) {
 
-		if ( this.needsTangents( materials ) ) {
+				geometry.computeTangents();
 
-			geometry.computeTangents();
+			}
 
-		}
+			return { geometry: geometry, materials: materials };
 
-		return { geometry: geometry, materials: materials };
+		}
 
 	}
 

+ 10 - 1
src/loaders/LoadingManager.js

@@ -6,7 +6,7 @@ THREE.LoadingManager = function ( onLoad, onProgress, onError ) {
 
 	var scope = this;
 
-	var loaded = 0, total = 0;
+	var loaded = 0, total = 0, loading = false;
 
 	this.onLoad = onLoad;
 	this.onProgress = onProgress;
@@ -16,6 +16,14 @@ THREE.LoadingManager = function ( onLoad, onProgress, onError ) {
 
 		total ++;
 
+		if ( scope.onStart !== undefined && loading === false ) {
+
+			scope.onStart( url, loaded, total );
+
+		}
+
+		loading = true;
+
 	};
 
 	this.itemEnd = function ( url ) {
@@ -31,6 +39,7 @@ THREE.LoadingManager = function ( onLoad, onProgress, onError ) {
 		if ( loaded === total && scope.onLoad !== undefined ) {
 
 			scope.onLoad();
+			loading = false;
 
 		}
 

+ 1 - 1
src/loaders/MaterialLoader.js

@@ -16,7 +16,7 @@ THREE.MaterialLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.XHRLoader( this.manager );
 		loader.setCrossOrigin( this.crossOrigin );
 		loader.load( url, function ( text ) {
 

+ 8 - 1
src/loaders/XHRLoader.js

@@ -61,6 +61,7 @@ THREE.XHRLoader.prototype = {
 
 		if ( this.crossOrigin !== undefined ) request.crossOrigin = this.crossOrigin;
 		if ( this.responseType !== undefined ) request.responseType = this.responseType;
+		if ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;
 
 		request.send( null );
 
@@ -78,6 +79,12 @@ THREE.XHRLoader.prototype = {
 
 		this.crossOrigin = value;
 
-	}
+	},
+
+	setWithCredentials: function ( value ) {
+
+		this.withCredentials = value;
+
+	},
 
 };

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio