diff --git a/dependencies/loaders/STLLoader.js b/dependencies/loaders/STLLoader.js
index 4e5f426c3ea7908f4f84bc81993a1577d549f3e1..e309326e2056514f94b361b25ef669db74180ac5 100755
--- a/dependencies/loaders/STLLoader.js
+++ b/dependencies/loaders/STLLoader.js
@@ -1,446 +1,290 @@
 /**
- * @author aleeper / http://adamleeper.com/
- * @author mrdoob / http://mrdoob.com/
- * @author gero3 / https://github.com/gero3
- *
- * Description: A THREE loader for STL ASCII files, as created by Solidworks and other CAD programs.
- *
- * Supports both binary and ASCII encoded files, with automatic detection of type.
- *
- * Limitations:
- * 	Binary decoding supports "Magics" color format (http://en.wikipedia.org/wiki/STL_(file_format)#Color_in_binary_STL).
- * 	There is perhaps some question as to how valid it is to always assume little-endian-ness.
- * 	ASCII decoding assumes file is UTF-8. Seems to work for the examples...
- *
- * Usage:
- * 	var loader = new THREE.STLLoader();
- * 	loader.addEventListener( 'load', function ( event ) {
- *
- * 		var geometry = event.content;
- * 		scene.add( new THREE.Mesh( geometry ) );
- *
- * 	} );
- * 	loader.load( './models/stl/slotted_disk.stl' );
- *
- * For binary STLs geometry might contain colors for vertices. To use it:
- *  ... // use the same code to load STL as above
- *  var geometry = event.content;
- *  if (geometry.hasColors) {
- *    material = new THREE.MeshPhongMaterial({ opacity: geometry.alpha, vertexColors: THREE.VertexColors });
- *  } else { .... }
- * var mesh = new THREE.Mesh( geometry, material );
- */
-
-
-THREE.STLLoader = function () {};
-
-THREE.STLLoader.prototype = {
-
-	constructor: THREE.STLLoader
-
-};
-
-THREE.STLLoader.prototype.load = function ( url, callback ) {
-
-	var scope = this;
-
-	var xhr = new XMLHttpRequest();
-
-	function onloaded( event ) {
-
-		if ( event.target.status === 200 || event.target.status === 0 ) {
-
-			var geometry = scope.parse( event.target.response || event.target.responseText );
-
-			scope.dispatchEvent( { type: 'load', content: geometry } );
-
-			if ( callback ) callback( geometry );
-
-		} else {
-
-			scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']', response: event.target.statusText } );
-
-		}
-
-	}
-
-	xhr.addEventListener( 'load', onloaded, false );
-
-	xhr.addEventListener( 'progress', function ( event ) {
-
-		scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } );
-
-	}, false );
-
-	xhr.addEventListener( 'error', function () {
-
-		scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
-
-	}, false );
-
-	if ( xhr.overrideMimeType ) xhr.overrideMimeType( 'text/plain; charset=x-user-defined' );
-	xhr.open( 'GET', url, true );
-	xhr.responseType = 'arraybuffer';
-	xhr.send( null );
-
-};
-
-THREE.STLLoader.prototype.parse = function ( data ) {
-
-
-	var isBinary = function () {
-
-		var expect, face_size, n_faces, reader;
-		reader = new DataView( binData );
-		face_size = (32 / 8 * 3) + ((32 / 8 * 3) * 3) + (16 / 8);
-		n_faces = reader.getUint32(80,true);
-		expect = 80 + (32 / 8) + (n_faces * face_size);
-		return expect === reader.byteLength;
-
-	};
-
-	var binData = this.ensureBinary( data );
-
-	return isBinary()
-		? this.parseBinary( binData )
-		: this.parseASCII( this.ensureString( data ) );
-
+* @author aleeper / http://adamleeper.com/
+* @author mrdoob / http://mrdoob.com/
+* @author gero3 / https://github.com/gero3
+*
+* Description: A THREE loader for STL ASCII files, as created by Solidworks and other CAD programs.
+*
+* Supports both binary and ASCII encoded files, with automatic detection of type.
+*
+* Limitations:
+* Binary decoding supports "Magics" color format (http://en.wikipedia.org/wiki/STL_(file_format)#Color_in_binary_STL).
+* There is perhaps some question as to how valid it is to always assume little-endian-ness.
+* ASCII decoding assumes file is UTF-8. Seems to work for the examples...
+*
+* Usage:
+* var loader = new THREE.STLLoader();
+* loader.load( './models/stl/slotted_disk.stl', function ( geometry ) {
+* scene.add( new THREE.Mesh( geometry ) );
+* });
+*
+* For binary STLs geometry might contain colors for vertices. To use it:
+* // use the same code to load STL as above
+* if (geometry.hasColors) {
+* material = new THREE.MeshPhongMaterial({ opacity: geometry.alpha, vertexColors: THREE.VertexColors });
+* } else { .... }
+* var mesh = new THREE.Mesh( geometry, material );
+*/
+THREE.STLLoader = function ( manager ) {
+this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
 };
-
-THREE.STLLoader.prototype.parseBinary = function ( data ) {
-
-	var reader = new DataView( data );
-	var faces = reader.getUint32( 80, true );
-
-	var r, g, b, hasColors = false, colors;
-	var defaultR, defaultG, defaultB, alpha;
-
-	// process STL header
-	// check for default color in header ("COLOR=rgba" sequence).
-	for (var index = 0; index < 80 - 10; index++) {
-
-		if ((reader.getUint32(index, false) == 0x434F4C4F /*COLO*/) &&
-			(reader.getUint8(index + 4) == 0x52 /*'R'*/) &&
-			(reader.getUint8(index + 5) == 0x3D /*'='*/)) {
-
-				hasColors = true;
-				colors = new Float32Array( faces * 3 * 3);
-
-				defaultR = reader.getUint8(index + 6) / 255;
-				defaultG = reader.getUint8(index + 7) / 255;
-				defaultB = reader.getUint8(index + 8) / 255;
-				alpha = reader.getUint8(index + 9) / 255;
-			}
-		}
-
-	var dataOffset = 84;
-	var faceLength = 12 * 4 + 2;
-
-	var offset = 0;
-
-	var geometry = new THREE.BufferGeometry();
-
-	var vertices = new Float32Array( faces * 3 * 3 );
-	var normals = new Float32Array( faces * 3 * 3 );
-
-	for ( var face = 0; face < faces; face ++ ) {
-
-		var start = dataOffset + face * faceLength;
-		var normalX = reader.getFloat32(start, true);
-		var normalY = reader.getFloat32(start + 4, true);
-		var normalZ = reader.getFloat32(start + 8, true);
-
-		if (hasColors) {
-
-			var packedColor = reader.getUint16(start + 48, true);
-
-			if ((packedColor & 0x8000) === 0) { // facet has its own unique color
-
-				r = (packedColor & 0x1F) / 31;
-				g = ((packedColor >> 5) & 0x1F) / 31;
-				b = ((packedColor >> 10) & 0x1F) / 31;
-			} else {
-
-				r = defaultR;
-				g = defaultG;
-				b = defaultB;
-			}
-		}
-
-		for ( var i = 1; i <= 3; i ++ ) {
-
-			var vertexstart = start + i * 12;
-
-			vertices[ offset     ] = reader.getFloat32( vertexstart, true );
-			vertices[ offset + 1 ] = reader.getFloat32( vertexstart + 4, true );
-			vertices[ offset + 2 ] = reader.getFloat32( vertexstart + 8, true );
-
-			normals[ offset     ] = normalX;
-			normals[ offset + 1 ] = normalY;
-			normals[ offset + 2 ] = normalZ;
-
-			if (hasColors) {
-				colors[ offset     ] = r;
-				colors[ offset + 1 ] = g;
-				colors[ offset + 2 ] = b;
-			}
-
-			offset += 3;
-
-		}
-
-	}
-
-	geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
-	geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
-
-	if (hasColors) {
-		geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
-		geometry.hasColors = true;
-		geometry.alpha = alpha;
-	}
-
-	return geometry;
-
-};
-
-THREE.STLLoader.prototype.parseASCII = function (data) {
-
-	var geometry, length, normal, patternFace, patternNormal, patternVertex, result, text;
-	geometry = new THREE.Geometry();
-	patternFace = /facet([\s\S]*?)endfacet/g;
-
-	while ( ( result = patternFace.exec( data ) ) !== null ) {
-
-		text = result[0];
-		patternNormal = /normal[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
-
-		while ( ( result = patternNormal.exec( text ) ) !== null ) {
-
-			normal = new THREE.Vector3( parseFloat( result[ 1 ] ), parseFloat( result[ 3 ] ), parseFloat( result[ 5 ] ) );
-
-		}
-
-		patternVertex = /vertex[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
-
-		while ( ( result = patternVertex.exec( text ) ) !== null ) {
-
-			geometry.vertices.push( new THREE.Vector3( parseFloat( result[ 1 ] ), parseFloat( result[ 3 ] ), parseFloat( result[ 5 ] ) ) );
-
-		}
-
-		length = geometry.vertices.length;
-
-		geometry.faces.push( new THREE.Face3( length - 3, length - 2, length - 1, normal ) );
-
-	}
-
-	geometry.computeBoundingBox();
-	geometry.computeBoundingSphere();
-
-	return geometry;
-
-};
-
-THREE.STLLoader.prototype.ensureString = function (buf) {
-
-	if (typeof buf !== "string"){
-		var array_buffer = new Uint8Array(buf);
-		var str = '';
-		for(var i = 0; i < buf.byteLength; i++) {
-			str += String.fromCharCode(array_buffer[i]); // implicitly assumes little-endian
-		}
-		return str;
-	} else {
-		return buf;
-	}
-
+THREE.STLLoader.prototype = {
+constructor: THREE.STLLoader,
+load: function ( url, onLoad, onProgress, onError ) {
+var scope = this;
+var loader = new THREE.XHRLoader( scope.manager );
+loader.setCrossOrigin( this.crossOrigin );
+loader.setResponseType('arraybuffer');
+loader.load( url, function ( text ) {
+onLoad( scope.parse( text ) );
+}, onProgress, onError );
+},
+parse: function ( data ) {
+var isBinary = function () {
+var expect, face_size, n_faces, reader;
+reader = new DataView( binData );
+face_size = (32 / 8 * 3) + ((32 / 8 * 3) * 3) + (16 / 8);
+n_faces = reader.getUint32(80,true);
+expect = 80 + (32 / 8) + (n_faces * face_size);
+if ( expect === reader.byteLength ) {
+return true;
+}
+// some binary files will have different size from expected,
+// checking characters higher than ASCII to confirm is binary
+var fileLength = reader.byteLength;
+for ( var index = 0; index < fileLength; index ++ ) {
+if ( reader.getUint8(index, false) > 127 ) {
+return true;
+}
+}
+return false;
 };
-
-THREE.STLLoader.prototype.ensureBinary = function (buf) {
-
-	if (typeof buf === "string"){
-		var array_buffer = new Uint8Array(buf.length);
-		for(var i = 0; i < buf.length; i++) {
-			array_buffer[i] = buf.charCodeAt(i) & 0xff; // implicitly assumes little-endian
-		}
-		return array_buffer.buffer || array_buffer;
-	} else {
-		return buf;
-	}
-
+var binData = this.ensureBinary( data );
+return isBinary()
+? this.parseBinary( binData )
+: this.parseASCII( this.ensureString( data ) );
+},
+parseBinary: function ( data ) {
+var reader = new DataView( data );
+var faces = reader.getUint32( 80, true );
+var r, g, b, hasColors = false, colors;
+var defaultR, defaultG, defaultB, alpha;
+// process STL header
+// check for default color in header ("COLOR=rgba" sequence).
+for ( var index = 0; index < 80 - 10; index ++ ) {
+if ((reader.getUint32(index, false) == 0x434F4C4F /*COLO*/) &&
+(reader.getUint8(index + 4) == 0x52 /*'R'*/) &&
+(reader.getUint8(index + 5) == 0x3D /*'='*/)) {
+hasColors = true;
+colors = new Float32Array( faces * 3 * 3);
+defaultR = reader.getUint8(index + 6) / 255;
+defaultG = reader.getUint8(index + 7) / 255;
+defaultB = reader.getUint8(index + 8) / 255;
+alpha = reader.getUint8(index + 9) / 255;
+}
+}
+var dataOffset = 84;
+var faceLength = 12 * 4 + 2;
+var offset = 0;
+var geometry = new THREE.BufferGeometry();
+var vertices = new Float32Array( faces * 3 * 3 );
+var normals = new Float32Array( faces * 3 * 3 );
+for ( var face = 0; face < faces; face ++ ) {
+var start = dataOffset + face * faceLength;
+var normalX = reader.getFloat32(start, true);
+var normalY = reader.getFloat32(start + 4, true);
+var normalZ = reader.getFloat32(start + 8, true);
+if (hasColors) {
+var packedColor = reader.getUint16(start + 48, true);
+if ((packedColor & 0x8000) === 0) { // facet has its own unique color
+r = (packedColor & 0x1F) / 31;
+g = ((packedColor >> 5) & 0x1F) / 31;
+b = ((packedColor >> 10) & 0x1F) / 31;
+} else {
+r = defaultR;
+g = defaultG;
+b = defaultB;
+}
+}
+for ( var i = 1; i <= 3; i ++ ) {
+var vertexstart = start + i * 12;
+vertices[ offset ] = reader.getFloat32( vertexstart, true );
+vertices[ offset + 1 ] = reader.getFloat32( vertexstart + 4, true );
+vertices[ offset + 2 ] = reader.getFloat32( vertexstart + 8, true );
+normals[ offset ] = normalX;
+normals[ offset + 1 ] = normalY;
+normals[ offset + 2 ] = normalZ;
+if (hasColors) {
+colors[ offset ] = r;
+colors[ offset + 1 ] = g;
+colors[ offset + 2 ] = b;
+}
+offset += 3;
+}
+}
+geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
+geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
+if (hasColors) {
+geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
+geometry.hasColors = true;
+geometry.alpha = alpha;
+}
+return geometry;
+},
+parseASCII: function ( data ) {
+var geometry, length, normal, patternFace, patternNormal, patternVertex, result, text;
+geometry = new THREE.Geometry();
+patternFace = /facet([\s\S]*?)endfacet/g;
+while ( ( result = patternFace.exec( data ) ) !== null ) {
+text = result[0];
+patternNormal = /normal[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
+while ( ( result = patternNormal.exec( text ) ) !== null ) {
+normal = new THREE.Vector3( parseFloat( result[ 1 ] ), parseFloat( result[ 3 ] ), parseFloat( result[ 5 ] ) );
+}
+patternVertex = /vertex[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
+while ( ( result = patternVertex.exec( text ) ) !== null ) {
+geometry.vertices.push( new THREE.Vector3( parseFloat( result[ 1 ] ), parseFloat( result[ 3 ] ), parseFloat( result[ 5 ] ) ) );
+}
+length = geometry.vertices.length;
+geometry.faces.push( new THREE.Face3( length - 3, length - 2, length - 1, normal ) );
+}
+geometry.computeBoundingBox();
+geometry.computeBoundingSphere();
+return geometry;
+},
+ensureString: function ( buf ) {
+if (typeof buf !== "string"){
+var array_buffer = new Uint8Array(buf);
+var str = '';
+for(var i = 0; i < buf.byteLength; i++) {
+str += String.fromCharCode(array_buffer[i]); // implicitly assumes little-endian
+}
+return str;
+} else {
+return buf;
+}
+},
+ensureBinary: function ( buf ) {
+if (typeof buf === "string"){
+var array_buffer = new Uint8Array(buf.length);
+for(var i = 0; i < buf.length; i++) {
+array_buffer[i] = buf.charCodeAt(i) & 0xff; // implicitly assumes little-endian
+}
+return array_buffer.buffer || array_buffer;
+} else {
+return buf;
+}
+}
 };
-
-THREE.EventDispatcher.prototype.apply( THREE.STLLoader.prototype );
-
 if ( typeof DataView === 'undefined'){
-
-	DataView = function(buffer, byteOffset, byteLength){
-
-		this.buffer = buffer;
-		this.byteOffset = byteOffset || 0;
-		this.byteLength = byteLength || buffer.byteLength || buffer.length;
-		this._isString = typeof buffer === "string";
-
-	}
-
-	DataView.prototype = {
-
-		_getCharCodes:function(buffer,start,length){
-			start = start || 0;
-			length = length || buffer.length;
-			var end = start + length;
-			var codes = [];
-			for (var i = start; i < end; i++) {
-				codes.push(buffer.charCodeAt(i) & 0xff);
-			}
-			return codes;
-		},
-
-		_getBytes: function (length, byteOffset, littleEndian) {
-
-			var result;
-
-			// Handle the lack of endianness
-			if (littleEndian === undefined) {
-
-				littleEndian = this._littleEndian;
-
-			}
-
-			// Handle the lack of byteOffset
-			if (byteOffset === undefined) {
-
-				byteOffset = this.byteOffset;
-
-			} else {
-
-				byteOffset = this.byteOffset + byteOffset;
-
-			}
-
-			if (length === undefined) {
-
-				length = this.byteLength - byteOffset;
-
-			}
-
-			// Error Checking
-			if (typeof byteOffset !== 'number') {
-
-				throw new TypeError('DataView byteOffset is not a number');
-
-			}
-
-			if (length < 0 || byteOffset + length > this.byteLength) {
-
-				throw new Error('DataView length or (byteOffset+length) value is out of bounds');
-
-			}
-
-			if (this.isString){
-
-				result = this._getCharCodes(this.buffer, byteOffset, byteOffset + length);
-
-			} else {
-
-				result = this.buffer.slice(byteOffset, byteOffset + length);
-
-			}
-
-			if (!littleEndian && length > 1) {
-
-				if (!(result instanceof Array)) {
-
-					result = Array.prototype.slice.call(result);
-
-				}
-
-				result.reverse();
-			}
-
-			return result;
-
-		},
-
-		// Compatibility functions on a String Buffer
-
-		getFloat64: function (byteOffset, littleEndian) {
-
-			var b = this._getBytes(8, byteOffset, littleEndian),
-
-				sign = 1 - (2 * (b[7] >> 7)),
-				exponent = ((((b[7] << 1) & 0xff) << 3) | (b[6] >> 4)) - ((1 << 10) - 1),
-
-			// Binary operators such as | and << operate on 32 bit values, using + and Math.pow(2) instead
-				mantissa = ((b[6] & 0x0f) * Math.pow(2, 48)) + (b[5] * Math.pow(2, 40)) + (b[4] * Math.pow(2, 32)) +
-							(b[3] * Math.pow(2, 24)) + (b[2] * Math.pow(2, 16)) + (b[1] * Math.pow(2, 8)) + b[0];
-
-			if (exponent === 1024) {
-				if (mantissa !== 0) {
-					return NaN;
-				} else {
-					return sign * Infinity;
-				}
-			}
-
-			if (exponent === -1023) { // Denormalized
-				return sign * mantissa * Math.pow(2, -1022 - 52);
-			}
-
-			return sign * (1 + mantissa * Math.pow(2, -52)) * Math.pow(2, exponent);
-
-		},
-
-		getFloat32: function (byteOffset, littleEndian) {
-
-			var b = this._getBytes(4, byteOffset, littleEndian),
-
-				sign = 1 - (2 * (b[3] >> 7)),
-				exponent = (((b[3] << 1) & 0xff) | (b[2] >> 7)) - 127,
-				mantissa = ((b[2] & 0x7f) << 16) | (b[1] << 8) | b[0];
-
-			if (exponent === 128) {
-				if (mantissa !== 0) {
-					return NaN;
-				} else {
-					return sign * Infinity;
-				}
-			}
-
-			if (exponent === -127) { // Denormalized
-				return sign * mantissa * Math.pow(2, -126 - 23);
-			}
-
-			return sign * (1 + mantissa * Math.pow(2, -23)) * Math.pow(2, exponent);
-		},
-
-		getInt32: function (byteOffset, littleEndian) {
-			var b = this._getBytes(4, byteOffset, littleEndian);
-			return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0];
-		},
-
-		getUint32: function (byteOffset, littleEndian) {
-			return this.getInt32(byteOffset, littleEndian) >>> 0;
-		},
-
-		getInt16: function (byteOffset, littleEndian) {
-			return (this.getUint16(byteOffset, littleEndian) << 16) >> 16;
-		},
-
-		getUint16: function (byteOffset, littleEndian) {
-			var b = this._getBytes(2, byteOffset, littleEndian);
-			return (b[1] << 8) | b[0];
-		},
-
-		getInt8: function (byteOffset) {
-			return (this.getUint8(byteOffset) << 24) >> 24;
-		},
-
-		getUint8: function (byteOffset) {
-			return this._getBytes(1, byteOffset)[0];
-		}
-
-	 };
-
+DataView = function(buffer, byteOffset, byteLength){
+this.buffer = buffer;
+this.byteOffset = byteOffset || 0;
+this.byteLength = byteLength || buffer.byteLength || buffer.length;
+this._isString = typeof buffer === "string";
+}
+DataView.prototype = {
+_getCharCodes:function(buffer,start,length){
+start = start || 0;
+length = length || buffer.length;
+var end = start + length;
+var codes = [];
+for (var i = start; i < end; i++) {
+codes.push(buffer.charCodeAt(i) & 0xff);
+}
+return codes;
+},
+_getBytes: function (length, byteOffset, littleEndian) {
+var result;
+// Handle the lack of endianness
+if (littleEndian === undefined) {
+littleEndian = this._littleEndian;
+}
+// Handle the lack of byteOffset
+if (byteOffset === undefined) {
+byteOffset = this.byteOffset;
+} else {
+byteOffset = this.byteOffset + byteOffset;
+}
+if (length === undefined) {
+length = this.byteLength - byteOffset;
+}
+// Error Checking
+if (typeof byteOffset !== 'number') {
+throw new TypeError('DataView byteOffset is not a number');
+}
+if (length < 0 || byteOffset + length > this.byteLength) {
+throw new Error('DataView length or (byteOffset+length) value is out of bounds');
+}
+if (this.isString){
+result = this._getCharCodes(this.buffer, byteOffset, byteOffset + length);
+} else {
+result = this.buffer.slice(byteOffset, byteOffset + length);
 }
+if (!littleEndian && length > 1) {
+if (!(result instanceof Array)) {
+result = Array.prototype.slice.call(result);
+}
+result.reverse();
+}
+return result;
+},
+// Compatibility functions on a String Buffer
+getFloat64: function (byteOffset, littleEndian) {
+var b = this._getBytes(8, byteOffset, littleEndian),
+sign = 1 - (2 * (b[7] >> 7)),
+exponent = ((((b[7] << 1) & 0xff) << 3) | (b[6] >> 4)) - ((1 << 10) - 1),
+// Binary operators such as | and << operate on 32 bit values, using + and Math.pow(2) instead
+mantissa = ((b[6] & 0x0f) * Math.pow(2, 48)) + (b[5] * Math.pow(2, 40)) + (b[4] * Math.pow(2, 32)) +
+(b[3] * Math.pow(2, 24)) + (b[2] * Math.pow(2, 16)) + (b[1] * Math.pow(2, 8)) + b[0];
+if (exponent === 1024) {
+if (mantissa !== 0) {
+return NaN;
+} else {
+return sign * Infinity;
+}
+}
+if (exponent === -1023) { // Denormalized
+return sign * mantissa * Math.pow(2, -1022 - 52);
+}
+return sign * (1 + mantissa * Math.pow(2, -52)) * Math.pow(2, exponent);
+},
+getFloat32: function (byteOffset, littleEndian) {
+var b = this._getBytes(4, byteOffset, littleEndian),
+sign = 1 - (2 * (b[3] >> 7)),
+exponent = (((b[3] << 1) & 0xff) | (b[2] >> 7)) - 127,
+mantissa = ((b[2] & 0x7f) << 16) | (b[1] << 8) | b[0];
+if (exponent === 128) {
+if (mantissa !== 0) {
+return NaN;
+} else {
+return sign * Infinity;
+}
+}
+if (exponent === -127) { // Denormalized
+return sign * mantissa * Math.pow(2, -126 - 23);
+}
+return sign * (1 + mantissa * Math.pow(2, -23)) * Math.pow(2, exponent);
+},
+getInt32: function (byteOffset, littleEndian) {
+var b = this._getBytes(4, byteOffset, littleEndian);
+return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0];
+},
+getUint32: function (byteOffset, littleEndian) {
+return this.getInt32(byteOffset, littleEndian) >>> 0;
+},
+getInt16: function (byteOffset, littleEndian) {
+return (this.getUint16(byteOffset, littleEndian) << 16) >> 16;
+},
+getUint16: function (byteOffset, littleEndian) {
+var b = this._getBytes(2, byteOffset, littleEndian);
+return (b[1] << 8) | b[0];
+},
+getInt8: function (byteOffset) {
+return (this.getUint8(byteOffset) << 24) >> 24;
+},
+getUint8: function (byteOffset) {
+return this._getBytes(1, byteOffset)[0];
+}
+};
+}
\ No newline at end of file
diff --git a/js/fea/dmaCell.js b/js/fea/dmaCell.js
index bb41d71bfa31b42a085e0d714713f9656d03a8cf..48c9c52ebb977d40cbe07b71787918726fa72dfc 100644
--- a/js/fea/dmaCell.js
+++ b/js/fea/dmaCell.js
@@ -41,11 +41,12 @@
     function DMACell(mode, indices, scale) {
 
         this.indices = indices;
-        var position = this._calcPosition(scale, indices);
-        this.cellMesh = this._buildCellMesh(position, indices.z);
+        this.scale = scale;
+        this.position = this._calcPosition(scale, indices);
+        this.cellMesh = this._buildCellMesh(this.position, indices.z);
         window.three.sceneAdd(this.cellMesh);
 
-        this.parts = this._initParts(position, indices.z);
+        this.parts = this._initParts(this.position, indices.z);
         this.drawForMode(mode);
     }
 
@@ -64,7 +65,7 @@
     DMACell.prototype._initParts = function(position, zIndex){
         var parts  = [];
         for (var i=0;i<3;i++){
-            parts.push(new DMAPart(i, position, zIndex%2==1));
+            parts.push(new DMAPart(i, zIndex%2==1, this));
         }
         return parts;
     };
@@ -114,6 +115,8 @@
 
     DMACell.prototype.changeScale = function(scale){
 
+        this.scale = scale;
+
         //update geometry
         if (globalCellScale != scale) {
             setGlobalCellScale(scale);
@@ -124,10 +127,10 @@
             this._updateVertices(cellGeometry2.vertices);
         }
 
-        var position = this._calcPosition(scale, this.indices);
-        this._setMeshPosition(this.cellMesh, position);
+        this.position = this._calcPosition(scale, this.indices);
+        this._setMeshPosition(this.cellMesh, this.position);
         _.each(this.parts, function(part){
-                part.changeScale(scale, position);
+                part.changeScale(scale, this.position);
          });
     };
 
@@ -138,6 +141,10 @@
         });
     };
 
+    DMACell.prototype.getScale = function(){
+         return this.scale;//I don't like this stored here
+     };
+
     DMACell.prototype.remove = function(){
         if (this.cellMesh) window.three.sceneRemove(this.cellMesh);
     };
diff --git a/js/fea/dmaPart.js b/js/fea/dmaPart.js
index 0901841ec1644d1129f69bb0811103c49516fc27..f420c5c2f000e1facd3de8704612982d29849e0b 100644
--- a/js/fea/dmaPart.js
+++ b/js/fea/dmaPart.js
@@ -7,34 +7,24 @@
 
 (function () {
 
+    var unitPartGeo;
+
     //import part geometry
     var loader = new THREE.STLLoader();
-    loader.addEventListener('load', onMeshLoad);
-    loader.load("data/trianglePart.stl");
-
-    var unitPartGeo;
-    var partGeometry;
-    var globalPartScale = 30;
-    function onMeshLoad(e){
+    loader.load("data/trianglePart.stl", function(geometry){
         console.log("part loaded");
-        unitPartGeo = e.content;
+        unitPartGeo = geometry
         unitPartGeo.dynamic = true;
         unitPartGeo.computeBoundingBox();
         var unitScale = 1/unitPartGeo.boundingBox.max.y;
         unitPartGeo.applyMatrix(new THREE.Matrix4().makeScale(unitScale, unitScale, unitScale));
         unitPartGeo.applyMatrix(new THREE.Matrix4().makeTranslation(0.2,-0.5, 0));
         unitPartGeo.applyMatrix(new THREE.Matrix4().makeRotationZ(-Math.PI/6));
-        setGlobalPartScale(globalPartScale)
-    }
-
-    function setGlobalPartScale(scale){
-        globalPartScale = scale;
-        partGeometry = unitPartGeo.clone();
-        partGeometry.applyMatrix(new THREE.Matrix4().makeScale(scale,scale,scale));
-    }
+        unitPartGeo.dynamic = true;
+    });
 
-    function DMAPart(type, position, oddZFlag) {
-        this.position = position;
+    function DMAPart(type, oddZFlag, parent) {
+        this.parentCell = parent;//use this reference to get position and scale
         this.oddZFlag = oddZFlag;//this tells me if cell is at an odd z height in lattice, everything needs to rotate 180
         this.type = type;
     }
@@ -46,8 +36,9 @@
 
     DMAPart.prototype._makeMeshForType = function(type){
 
-        var mesh = new THREE.Mesh(partGeometry);
-        mesh = this._setMeshPosition(mesh, 30);
+        var mesh = new THREE.Mesh(unitPartGeo);
+        mesh = this._setMeshPosition(mesh);
+        mesh = this._setMeshScale(mesh);
 
         switch(type){
             case 1:
@@ -61,7 +52,8 @@
     };
 
     DMAPart.prototype._setMeshPosition = function(mesh, scale, position){
-        position = position || this.position;
+        position = position || this.parentCell.position;
+        scale = scale || this.parentCell.getScale();
         mesh.position.x = position.x;
         mesh.position.y = -scale/3*Math.sqrt(3)+position.y;
         mesh.position.z = position.z;
@@ -73,13 +65,16 @@
         return mesh;
     };
 
+    DMAPart.prototype._setMeshScale = function(mesh, scale){
+        mesh.scale.set(scale, scale, scale);
+        return mesh;
+    };
+
     DMAPart.prototype.changeScale = function(scale, position){
-        if (globalPartScale != scale) setGlobalPartScale(scale);
         this.position = position;
         if (this.mesh) {
             this._setMeshPosition(this.mesh, scale, position);
-            this.mesh.geometry.vertices = partGeometry.vertices;
-            this.mesh.geometry.verticesNeedUpdate = true;
+            this._setMeshScale(this.mesh, scale);
         }
     };
 
@@ -92,6 +87,10 @@
         if (this.mesh) this.mesh.visible = false;
     };
 
+    DMAPart.prototype._destroy = function(){
+        this.parentCell = null;
+    };
+
     self.DMAPart =  DMAPart;
 
 })();