Explorar o código

Reverted styling for glTFLoader.js

Greg Tatum %!s(int64=10) %!d(string=hai) anos
pai
achega
ddae8d4cc0
Modificáronse 1 ficheiros con 1074 adicións e 1438 borrados
  1. 1074 1438
      examples/js/loaders/gltf/glTFLoader.js

+ 1074 - 1438
examples/js/loaders/gltf/glTFLoader.js

@@ -4,7 +4,6 @@
 
 
 THREE.glTFLoader = function () {
-
 	this.meshesRequested = 0;
 	this.meshesLoaded = 0;
 	this.pendingMeshes = [];
@@ -15,7 +14,6 @@ THREE.glTFLoader = function () {
 	this.shadersLoaded = 0;
 	this.shaders = {};
 	THREE.Loader.call( this );
-
 };
 
 THREE.glTFLoader.prototype = Object.create( THREE.Loader.prototype );
@@ -26,45 +24,39 @@ THREE.glTFLoader.prototype.load = function( url, callback ) {
 	var theLoader = this;
 	// Utilities
 
-	function RgbArraytoHex( colorArray ) {
-
-		if ( ! colorArray ) return 0xFFFFFFFF;
-		var r = Math.floor( colorArray[ 0 ] * 255 ),
-            g = Math.floor( colorArray[ 1 ] * 255 ),
-            b = Math.floor( colorArray[ 2 ] * 255 ),
+	function RgbArraytoHex(colorArray) {
+		if (!colorArray) return 0xFFFFFFFF;
+		var r = Math.floor(colorArray[0] * 255),
+            g = Math.floor(colorArray[1] * 255),
+            b = Math.floor(colorArray[2] * 255),
             a = 255;
 
-		var color = ( a << 24 ) + ( r << 16 ) + ( g << 8 ) + b;
+		var color = (a << 24) + (r << 16) + (g << 8) + b;
 
 		return color;
-
 	}
 
-	function convertAxisAngleToQuaternion( rotations, count ) {
-
+	function convertAxisAngleToQuaternion(rotations, count)
+    {
 		var q = new THREE.Quaternion;
 		var axis = new THREE.Vector3;
 		var euler = new THREE.Vector3;
 
 		var i;
-		for ( i = 0; i < count; i ++ ) {
-
-			axis.set( rotations[ i * 4 ], rotations[ i * 4 + 1 ],
-    				rotations[ i * 4 + 2 ] ).normalize();
-			var angle = rotations[ i * 4 + 3 ];
-			q.setFromAxisAngle( axis, angle );
-			rotations[ i * 4 ] = q.x;
-			rotations[ i * 4 + 1 ] = q.y;
-			rotations[ i * 4 + 2 ] = q.z;
-			rotations[ i * 4 + 3 ] = q.w;
-
+		for (i = 0; i < count; i ++) {
+			axis.set(rotations[i * 4], rotations[i * 4 + 1],
+    				rotations[i * 4 + 2]).normalize();
+			var angle = rotations[i * 4 + 3];
+			q.setFromAxisAngle(axis, angle);
+			rotations[i * 4] = q.x;
+			rotations[i * 4 + 1] = q.y;
+			rotations[i * 4 + 2] = q.z;
+			rotations[i * 4 + 3] = q.w;
 		}
-
 	}
 
-	function componentsPerElementForGLType( glType ) {
-
-		switch ( glType ) {
+	function componentsPerElementForGLType(glType) {
+		switch (glType) {
 			case WebGLRenderingContext.FLOAT :
 			case WebGLRenderingContext.UNSIGNED_BYTE :
 			case WebGLRenderingContext.UNSIGNED_SHORT :
@@ -80,21 +72,15 @@ THREE.glTFLoader.prototype.load = function( url, callback ) {
 			default:
 				return null;
 		}
-
 	}
 
-	function LoadTexture( src ) {
-
-		if ( ! src ) {
-
-			return null;
-
-		}
-		return THREE.ImageUtils.loadTexture( src );
 
+	function LoadTexture(src) {
+		if (!src) { return null; }
+		return THREE.ImageUtils.loadTexture(src);
 	}
 
-	// Geometry processing
+    // Geometry processing
 
 	var ClassicGeometry = function() {
 
@@ -109,361 +95,276 @@ THREE.glTFLoader.prototype.load = function( url, callback ) {
 
 		this.uvs = null;
 		this.indexArray = null;
-
 	};
 
 	ClassicGeometry.prototype.constructor = ClassicGeometry;
 
 	ClassicGeometry.prototype.buildBufferGeometry = function() {
-
-		// Build indexed mesh
+        // Build indexed mesh
 		var geometry = this.geometry;
 
 		geometry.addAttribute( 'index', new THREE.BufferAttribute( this.indexArray, 1 ) );
 		geometry.addDrawCall( 0, this.indexArray.length );
 
 		geometry.computeBoundingSphere();
-
 	};
 
 	ClassicGeometry.prototype.checkFinished = function() {
-
-		if ( this.indexArray && this.loadedAttributes === this.totalAttributes ) {
+		if (this.indexArray && this.loadedAttributes === this.totalAttributes) {
 
 			this.buildBufferGeometry();
 
 			this.finished = true;
 
-			if ( this.onload ) {
-
+			if (this.onload) {
 				this.onload();
-
 			}
-
 		}
-
 	};
 
-	// Delegate for processing index buffers
+    // Delegate for processing index buffers
 	var IndicesDelegate = function() {};
 
-	IndicesDelegate.prototype.handleError = function( errorCode, info ) {
-
-		// FIXME: report error
-		console.log( "ERROR(IndicesDelegate):" + errorCode + ":" + info );
-
+	IndicesDelegate.prototype.handleError = function(errorCode, info) {
+        // FIXME: report error
+		console.log("ERROR(IndicesDelegate):" + errorCode + ":" + info);
 	};
 
-	IndicesDelegate.prototype.convert = function( resource, ctx ) {
-
-		return new Uint16Array( resource, 0, ctx.indices.count );
-
+	IndicesDelegate.prototype.convert = function(resource, ctx) {
+		return new Uint16Array(resource, 0, ctx.indices.count);
 	};
 
-	IndicesDelegate.prototype.resourceAvailable = function( glResource, ctx ) {
-
+	IndicesDelegate.prototype.resourceAvailable = function(glResource, ctx) {
 		var geometry = ctx.geometry;
 		geometry.indexArray = glResource;
 		geometry.checkFinished();
 		return true;
-
 	};
 
 	var indicesDelegate = new IndicesDelegate();
 
-	var IndicesContext = function( indices, geometry ) {
-
+	var IndicesContext = function(indices, geometry) {
 		this.indices = indices;
 		this.geometry = geometry;
-
 	};
 
-	// Delegate for processing vertex attribute buffers
+    // Delegate for processing vertex attribute buffers
 	var VertexAttributeDelegate = function() {};
 
-	VertexAttributeDelegate.prototype.handleError = function( errorCode, info ) {
-
-		// FIXME: report error
-		console.log( "ERROR(VertexAttributeDelegate):" + errorCode + ":" + info );
-
+	VertexAttributeDelegate.prototype.handleError = function(errorCode, info) {
+        // FIXME: report error
+		console.log("ERROR(VertexAttributeDelegate):" + errorCode + ":" + info);
 	};
 
-	VertexAttributeDelegate.prototype.convert = function( resource, ctx ) {
-
+	VertexAttributeDelegate.prototype.convert = function(resource, ctx) {
 		return resource;
-
 	};
 
-	VertexAttributeDelegate.prototype.arrayResourceAvailable = function( glResource, ctx ) {
 
+
+	VertexAttributeDelegate.prototype.arrayResourceAvailable = function(glResource, ctx) {
 		var geom = ctx.geometry;
 		var attribute = ctx.attribute;
 		var semantic = ctx.semantic;
 		var floatArray;
 		var i, l;
-		//FIXME: Float32 is assumed here, but should be checked.
-
-		if ( semantic == "POSITION" ) {
-
-			// TODO: Should be easy to take strides into account here
-			floatArray = new Float32Array( glResource, 0, attribute.count * componentsPerElementForGLType( attribute.type ) );
-			for ( i = 0, l = floatArray.length; i < l; i += 3 ) {
-
-				geom.geometry.vertices.push( new THREE.Vector3( floatArray[ i ], floatArray[ i + 1 ], floatArray[ i + 2 ] ) );
+        //FIXME: Float32 is assumed here, but should be checked.
 
+		if (semantic == "POSITION") {
+            // TODO: Should be easy to take strides into account here
+			floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type));
+			for (i = 0, l = floatArray.length; i < l; i += 3) {
+				geom.geometry.vertices.push( new THREE.Vector3( floatArray[i], floatArray[i + 1], floatArray[i + 2] ) );
 			}
-
-		} else if ( semantic == "NORMAL" ) {
-
+		} else if (semantic == "NORMAL") {
 			geom.geometry.normals = [];
-			floatArray = new Float32Array( glResource, 0, attribute.count * componentsPerElementForGLType( attribute.type ) );
-			for ( i = 0, l = floatArray.length; i < l; i += 3 ) {
-
-				geom.geometry.normals.push( new THREE.Vector3( floatArray[ i ], floatArray[ i + 1 ], floatArray[ i + 2 ] ) );
-
+			floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type));
+			for (i = 0, l = floatArray.length; i < l; i += 3) {
+				geom.geometry.normals.push( new THREE.Vector3( floatArray[i], floatArray[i + 1], floatArray[i + 2] ) );
 			}
-
-		} else if ( ( semantic == "TEXCOORD_0" ) || ( semantic == "TEXCOORD" ) ) {
-
+		} else if ((semantic == "TEXCOORD_0") || (semantic == "TEXCOORD" )) {
 			geom.uvs = [];
-			floatArray = new Float32Array( glResource, 0, attribute.count * componentsPerElementForGLType( attribute.type ) );
-			for ( i = 0, l = floatArray.length; i < l; i += 2 ) {
-
-				geom.uvs.push( new THREE.Vector2( floatArray[ i ], 1.0 - floatArray[ i + 1 ] ) );
-
-			}
-
-		}
-		else if ( semantic == "WEIGHT" ) {
-
-			nComponents = componentsPerElementForGLType( attribute.type );
-			floatArray = new Float32Array( glResource, 0, attribute.count * nComponents );
-			for ( i = 0, l = floatArray.length; i < l; i += 4 ) {
-
-				geom.geometry.skinWeights.push( new THREE.Vector4( floatArray[ i ], floatArray[ i + 1 ], floatArray[ i + 2 ], floatArray[ i + 3 ] ) );
-
-			}
-
-		}
-		else if ( semantic == "JOINT" ) {
-
-			nComponents = componentsPerElementForGLType( attribute.type );
-			floatArray = new Float32Array( glResource, 0, attribute.count * nComponents );
-			for ( i = 0, l = floatArray.length; i < l; i += 4 ) {
-
-				geom.geometry.skinIndices.push( new THREE.Vector4( floatArray[ i ], floatArray[ i + 1 ], floatArray[ i + 2 ], floatArray[ i + 3 ] ) );
-
+			floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type));
+			for (i = 0, l = floatArray.length; i < l; i += 2) {
+				geom.uvs.push( new THREE.Vector2( floatArray[i], 1.0 - floatArray[i + 1] ) );
 			}
-
 		}
-
+        else if (semantic == "WEIGHT") {
+	nComponents = componentsPerElementForGLType(attribute.type);
+	floatArray = new Float32Array(glResource, 0, attribute.count * nComponents);
+	for (i = 0, l = floatArray.length; i < l; i += 4) {
+		geom.geometry.skinWeights.push( new THREE.Vector4( floatArray[i], floatArray[i + 1], floatArray[i + 2], floatArray[i + 3] ) );
+	}
+        }
+        else if (semantic == "JOINT") {
+	nComponents = componentsPerElementForGLType(attribute.type);
+	floatArray = new Float32Array(glResource, 0, attribute.count * nComponents);
+	for (i = 0, l = floatArray.length; i < l; i += 4) {
+		geom.geometry.skinIndices.push( new THREE.Vector4( floatArray[i], floatArray[i + 1], floatArray[i + 2], floatArray[i + 3] ) );
+	}
+        }
 	};
 
-	VertexAttributeDelegate.prototype.bufferResourceAvailable = function( glResource, ctx ) {
-
+	VertexAttributeDelegate.prototype.bufferResourceAvailable = function(glResource, ctx) {
 		var geom = ctx.geometry;
 		var attribute = ctx.attribute;
 		var semantic = ctx.semantic;
 		var floatArray;
 		var i, l;
 		var nComponents;
-		//FIXME: Float32 is assumed here, but should be checked.
-
-		if ( semantic == "POSITION" ) {
+        //FIXME: Float32 is assumed here, but should be checked.
 
-			// TODO: Should be easy to take strides into account here
-			floatArray = new Float32Array( glResource, 0, attribute.count * componentsPerElementForGLType( attribute.type ) );
+		if (semantic == "POSITION") {
+            // TODO: Should be easy to take strides into account here
+			floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type));
 			geom.geometry.addAttribute( 'position', new THREE.BufferAttribute( floatArray, 3 ) );
-
-		} else if ( semantic == "NORMAL" ) {
-
-			floatArray = new Float32Array( glResource, 0, attribute.count * componentsPerElementForGLType( attribute.type ) );
+		} else if (semantic == "NORMAL") {
+			floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type));
 			geom.geometry.addAttribute( 'normal', new THREE.BufferAttribute( floatArray, 3 ) );
+		} else if ((semantic == "TEXCOORD_0") || (semantic == "TEXCOORD" )) {
 
-		} else if ( ( semantic == "TEXCOORD_0" ) || ( semantic == "TEXCOORD" ) ) {
-
-			nComponents = componentsPerElementForGLType( attribute.type );
-			floatArray = new Float32Array( glResource, 0, attribute.count * nComponents );
-			// N.B.: flip Y value... should we just set texture.flipY everywhere?
-			for ( i = 0; i < floatArray.length / 2; i ++ ) {
-
-				floatArray[ i * 2 + 1 ] = 1.0 - floatArray[ i * 2 + 1 ];
-
+			nComponents = componentsPerElementForGLType(attribute.type);
+			floatArray = new Float32Array(glResource, 0, attribute.count * nComponents);
+            // N.B.: flip Y value... should we just set texture.flipY everywhere?
+			for (i = 0; i < floatArray.length / 2; i ++) {
+				floatArray[i * 2 + 1] = 1.0 - floatArray[i * 2 + 1];
 			}
 			geom.geometry.addAttribute( 'uv', new THREE.BufferAttribute( floatArray, nComponents ) );
-
-		}
-		else if ( semantic == "WEIGHT" ) {
-
-			nComponents = componentsPerElementForGLType( attribute.type );
-			floatArray = new Float32Array( glResource, 0, attribute.count * nComponents );
-			geom.geometry.addAttribute( 'skinWeight', new THREE.BufferAttribute( floatArray, nComponents ) );
-
-		}
-		else if ( semantic == "JOINT" ) {
-
-			nComponents = componentsPerElementForGLType( attribute.type );
-			floatArray = new Float32Array( glResource, 0, attribute.count * nComponents );
-			geom.geometry.addAttribute( 'skinIndex', new THREE.BufferAttribute( floatArray, nComponents ) );
-
 		}
-
+        else if (semantic == "WEIGHT") {
+	nComponents = componentsPerElementForGLType(attribute.type);
+	floatArray = new Float32Array(glResource, 0, attribute.count * nComponents);
+	geom.geometry.addAttribute( 'skinWeight', new THREE.BufferAttribute( floatArray, nComponents ) );
+        }
+        else if (semantic == "JOINT") {
+	nComponents = componentsPerElementForGLType(attribute.type);
+	floatArray = new Float32Array(glResource, 0, attribute.count * nComponents);
+	geom.geometry.addAttribute( 'skinIndex', new THREE.BufferAttribute( floatArray, nComponents ) );
+        }
 	};
 
-	VertexAttributeDelegate.prototype.resourceAvailable = function( glResource, ctx ) {
+	VertexAttributeDelegate.prototype.resourceAvailable = function(glResource, ctx) {
 
-		this.bufferResourceAvailable( glResource, ctx );
+		this.bufferResourceAvailable(glResource, ctx);
 
 		var geom = ctx.geometry;
 		geom.loadedAttributes ++;
 		geom.checkFinished();
 		return true;
-
 	};
 
 	var vertexAttributeDelegate = new VertexAttributeDelegate();
 
-	var VertexAttributeContext = function( attribute, semantic, geometry ) {
-
+	var VertexAttributeContext = function(attribute, semantic, geometry) {
 		this.attribute = attribute;
 		this.semantic = semantic;
 		this.geometry = geometry;
-
 	};
 
 	var Mesh = function() {
-
 		this.primitives = [];
 		this.materialsPending = [];
 		this.loadedGeometry = 0;
 		this.onCompleteCallbacks = [];
-
 	};
 
-	Mesh.prototype.addPrimitive = function( geometry, material ) {
+	Mesh.prototype.addPrimitive = function(geometry, material) {
 
 		var self = this;
 		geometry.onload = function() {
-
 			self.loadedGeometry ++;
 			self.checkComplete();
-
 		};
 
-		this.primitives.push( {
-			geometry: geometry,
-			material: material,
-			mesh: null
-		} );
-
+		this.primitives.push({
+            geometry: geometry,
+            material: material,
+            mesh: null
+        });
 	};
 
-	Mesh.prototype.onComplete = function( callback ) {
-
-		this.onCompleteCallbacks.push( callback );
+	Mesh.prototype.onComplete = function(callback) {
+		this.onCompleteCallbacks.push(callback);
 		this.checkComplete();
-
 	};
 
 	Mesh.prototype.checkComplete = function() {
-
 		var self = this;
-		if ( this.onCompleteCallbacks.length && this.primitives.length == this.loadedGeometry ) {
-
-			this.onCompleteCallbacks.forEach( function( callback ) {
-
-				callback( self );
-
-			} );
+		if (this.onCompleteCallbacks.length && this.primitives.length == this.loadedGeometry) {
+			this.onCompleteCallbacks.forEach(function(callback) {
+				callback(self);
+			});
 			this.onCompleteCallbacks = [];
-
 		}
-
 	};
 
-	Mesh.prototype.attachToNode = function( threeNode ) {
-
-		// Assumes that the geometry is complete
-		this.primitives.forEach( function( primitive ) {
-
-			/*if(!primitive.mesh) {
-			                primitive.mesh = new THREE.Mesh(primitive.geometry, primitive.material);
-			            }*/
+	Mesh.prototype.attachToNode = function(threeNode) {
+        // Assumes that the geometry is complete
+		this.primitives.forEach(function(primitive) {
+            /*if(!primitive.mesh) {
+                primitive.mesh = new THREE.Mesh(primitive.geometry, primitive.material);
+            }*/
 			var material = primitive.material;
-			if ( ! ( material instanceof THREE.Material ) ) {
-
-				material = theLoader.createShaderMaterial( material );
-
+			if (!(material instanceof THREE.Material)) {
+				material = theLoader.createShaderMaterial(material);
 			}
 
-			var threeMesh = new THREE.Mesh( primitive.geometry.geometry, material );
+			var threeMesh = new THREE.Mesh(primitive.geometry.geometry, material);
 			threeMesh.castShadow = true;
-			threeNode.add( threeMesh );
-
-		} );
-
+			threeNode.add(threeMesh);
+		});
 	};
 
-	// Delayed-loaded material
-	var Material = function( params ) {
-
+    // Delayed-loaded material
+	var Material = function(params) {
 		this.params = params;
-
 	};
 
-	// Delegate for processing animation parameter buffers
+    // Delegate for processing animation parameter buffers
 	var AnimationParameterDelegate = function() {};
 
-	AnimationParameterDelegate.prototype.handleError = function( errorCode, info ) {
-
-		// FIXME: report error
-		console.log( "ERROR(AnimationParameterDelegate):" + errorCode + ":" + info );
-
+	AnimationParameterDelegate.prototype.handleError = function(errorCode, info) {
+        // FIXME: report error
+		console.log("ERROR(AnimationParameterDelegate):" + errorCode + ":" + info);
 	};
 
-	AnimationParameterDelegate.prototype.convert = function( resource, ctx ) {
-
+	AnimationParameterDelegate.prototype.convert = function(resource, ctx) {
 		var parameter = ctx.parameter;
 
 		var glResource = null;
-		switch ( parameter.type ) {
+		switch (parameter.type) {
 			case WebGLRenderingContext.FLOAT :
 			case WebGLRenderingContext.FLOAT_VEC2 :
 			case WebGLRenderingContext.FLOAT_VEC3 :
 			case WebGLRenderingContext.FLOAT_VEC4 :
-				glResource = new Float32Array( resource, 0, parameter.count * componentsPerElementForGLType( parameter.type ) );
+				glResource = new Float32Array(resource, 0, parameter.count * componentsPerElementForGLType(parameter.type));
 				break;
 			default:
 				break;
 		}
 
 		return glResource;
-
 	};
 
-	AnimationParameterDelegate.prototype.resourceAvailable = function( glResource, ctx ) {
-
+	AnimationParameterDelegate.prototype.resourceAvailable = function(glResource, ctx) {
 		var animation = ctx.animation;
 		var parameter = ctx.parameter;
 		parameter.data = glResource;
-		animation.handleParameterLoaded( parameter );
+		animation.handleParameterLoaded(parameter);
 		return true;
-
 	};
 
 	var animationParameterDelegate = new AnimationParameterDelegate();
 
-	var AnimationParameterContext = function( parameter, animation ) {
-
+	var AnimationParameterContext = function(parameter, animation) {
 		this.parameter = parameter;
 		this.animation = animation;
-
 	};
 
-	// Animations
+    // Animations
 	var Animation = function() {
 
-		// create Three.js keyframe here
+    	// create Three.js keyframe here
 		this.totalParameters = 0;
 		this.loadedParameters = 0;
 		this.parameters = {};
@@ -474,1445 +375,1180 @@ THREE.glTFLoader.prototype.load = function( url, callback ) {
 
 	Animation.prototype.constructor = Animation;
 
-	Animation.prototype.handleParameterLoaded = function( parameter ) {
-
-		this.parameters[ parameter.name ] = parameter;
+	Animation.prototype.handleParameterLoaded = function(parameter) {
+		this.parameters[parameter.name] = parameter;
 		this.loadedParameters ++;
 		this.checkFinished();
-
 	};
 
 	Animation.prototype.checkFinished = function() {
-
-		if ( this.loadedParameters === this.totalParameters ) {
-
-			// Build animation
+		if (this.loadedParameters === this.totalParameters) {
+            // Build animation
 			this.finishedLoading = true;
 
-			if ( this.onload ) {
-
+			if (this.onload) {
 				this.onload();
-
 			}
-
 		}
-
 	};
 
-	// Delegate for processing inverse bind matrices buffer
+    // Delegate for processing inverse bind matrices buffer
 	var InverseBindMatricesDelegate = function() {};
 
-	InverseBindMatricesDelegate.prototype.handleError = function( errorCode, info ) {
-
-		// FIXME: report error
-		console.log( "ERROR(InverseBindMatricesDelegate):" + errorCode + ":" + info );
-
+	InverseBindMatricesDelegate.prototype.handleError = function(errorCode, info) {
+        // FIXME: report error
+		console.log("ERROR(InverseBindMatricesDelegate):" + errorCode + ":" + info);
 	};
 
-	InverseBindMatricesDelegate.prototype.convert = function( resource, ctx ) {
-
+	InverseBindMatricesDelegate.prototype.convert = function(resource, ctx) {
 		var parameter = ctx.parameter;
 
 		var glResource = null;
-		switch ( parameter.type ) {
+		switch (parameter.type) {
 			case WebGLRenderingContext.FLOAT_MAT4 :
-				glResource = new Float32Array( resource, 0, parameter.count * componentsPerElementForGLType( parameter.type ) );
+				glResource = new Float32Array(resource, 0, parameter.count * componentsPerElementForGLType(parameter.type));
 				break;
 			default:
 				break;
 		}
 
 		return glResource;
-
 	};
 
-	InverseBindMatricesDelegate.prototype.resourceAvailable = function( glResource, ctx ) {
-
+	InverseBindMatricesDelegate.prototype.resourceAvailable = function(glResource, ctx) {
 		var skin = ctx.skin;
 		skin.inverseBindMatrices = glResource;
 		return true;
-
 	};
 
 	var inverseBindMatricesDelegate = new InverseBindMatricesDelegate();
 
-	var InverseBindMatricesContext = function( param, skin ) {
-
+	var InverseBindMatricesContext = function(param, skin) {
 		this.parameter = param;
 		this.skin = skin;
-
 	};
 
-	// Delegate for processing shaders from external files
+    // Delegate for processing shaders from external files
 	var ShaderDelegate = function() {};
 
-	ShaderDelegate.prototype.handleError = function( errorCode, info ) {
-
-		// FIXME: report error
-		console.log( "ERROR(ShaderDelegate):" + errorCode + ":" + info );
-
+	ShaderDelegate.prototype.handleError = function(errorCode, info) {
+        // FIXME: report error
+		console.log("ERROR(ShaderDelegate):" + errorCode + ":" + info);
 	};
 
-	ShaderDelegate.prototype.convert = function( resource, ctx ) {
-
+	ShaderDelegate.prototype.convert = function(resource, ctx) {
 		return resource;
-
 	};
 
-	ShaderDelegate.prototype.resourceAvailable = function( data, ctx ) {
-
+	ShaderDelegate.prototype.resourceAvailable = function(data, ctx) {
 		theLoader.shadersLoaded ++;
-		theLoader.shaders[ ctx.id ] = data;
+		theLoader.shaders[ctx.id] = data;
 		theLoader.checkComplete();
 		return true;
-
 	};
 
 	var shaderDelegate = new ShaderDelegate();
 
-	var ShaderContext = function( id, path ) {
-
+	var ShaderContext = function(id, path) {
 		this.id = id;
 		this.path = path;
-
 	};
 
-	// Resource management
-
-	var ResourceEntry = function( entryID, object, description ) {
+    // Resource management
 
+	var ResourceEntry = function(entryID, object, description) {
 		this.entryID = entryID;
 		this.object = object;
 		this.description = description;
-
 	};
 
 	var Resources = function() {
-
 		this._entries = {};
-
 	};
 
-	Resources.prototype.setEntry = function( entryID, object, description ) {
-
-		if ( ! entryID ) {
-
-			console.error( "No EntryID provided, cannot store", description );
+	Resources.prototype.setEntry = function(entryID, object, description) {
+		if (!entryID) {
+			console.error("No EntryID provided, cannot store", description);
 			return;
-
 		}
 
-		if ( this._entries[ entryID ] ) {
-
-			console.warn( "entry[" + entryID + "] is being overwritten" );
-
+		if (this._entries[entryID]) {
+			console.warn("entry[" + entryID + "] is being overwritten");
 		}
 
-		this._entries[ entryID ] = new ResourceEntry( entryID, object, description );
-
+		this._entries[entryID] = new ResourceEntry(entryID, object, description );
 	};
 
-	Resources.prototype.getEntry = function( entryID ) {
-
-		return this._entries[ entryID ];
-
+	Resources.prototype.getEntry = function(entryID) {
+		return this._entries[entryID];
 	};
 
 	Resources.prototype.clearEntries = function() {
-
 		this._entries = {};
-
 	};
 
-	LoadDelegate = function() {};
-
-	LoadDelegate.prototype.loadCompleted = function( callback, obj ) {
-
-		callback.call( Window, obj );
+	LoadDelegate = function() {
+    };
 
+	LoadDelegate.prototype.loadCompleted = function(callback, obj) {
+		callback.call(Window, obj);
 	};
 
-	// Loader
-
-	var ThreeGLTFLoader = Object.create( glTFParser, {
+    // Loader
 
-		load: {
-			enumerable: true,
-			value: function( userInfo, options ) {
+	var ThreeGLTFLoader = Object.create(glTFParser, {
 
-				this.resources = new Resources();
-				this.cameras = [];
-				this.lights = [];
-				this.animations = [];
-				this.joints = {};
-				this.skeltons = {};
-				THREE.GLTFLoaderUtils.init();
-				glTFParser.load.call( this, userInfo, options );
+        load: {
+            enumerable: true,
+            value: function(userInfo, options) {
+	this.resources = new Resources();
+	this.cameras = [];
+	this.lights = [];
+	this.animations = [];
+	this.joints = {};
+	this.skeltons = {};
+	THREE.GLTFLoaderUtils.init();
+	glTFParser.load.call(this, userInfo, options);
+            }
+        },
+
+        cameras: {
+        	enumerable: true,
+        	writable: true,
+        	value : []
+        },
+
+        lights: {
+        	enumerable: true,
+        	writable: true,
+        	value : []
+        },
+
+        animations: {
+        	enumerable: true,
+        	writable: true,
+        	value : []
+        },
+
+        // Implement WebGLTFLoader handlers
+
+        handleBuffer: {
+            value: function(entryID, description, userInfo) {
+	this.resources.setEntry(entryID, null, description);
+	description.type = "ArrayBuffer";
+	return true;
+            }
+        },
+
+        handleBufferView: {
+            value: function(entryID, description, userInfo) {
+	this.resources.setEntry(entryID, null, description);
+
+	var buffer =  this.resources.getEntry(description.buffer);
+	description.type = "ArrayBufferView";
+
+	var bufferViewEntry = this.resources.getEntry(entryID);
+	bufferViewEntry.buffer = buffer;
+	return true;
+            }
+        },
+
+        handleShader: {
+            value: function(entryID, description, userInfo) {
+	this.resources.setEntry(entryID, null, description);
+	var shaderRequest = {
+        				id : entryID,
+        				path : description.path,
+        		};
+
+	var shaderContext = new ShaderContext(entryID, description.path);
+
+	theLoader.shadersRequested ++;
+	THREE.GLTFLoaderUtils.getFile(shaderRequest, shaderDelegate, shaderContext);
+
+	return true;
+            }
+        },
+
+        handleProgram: {
+            value: function(entryID, description, userInfo) {
+	this.resources.setEntry(entryID, null, description);
+	return true;
+            }
+        },
+
+        handleTechnique: {
+            value: function(entryID, description, userInfo) {
+	this.resources.setEntry(entryID, null, description);
+	return true;
+            }
+        },
+
+        createShaderMaterial : {
+        	value: function(material) {
+
+	var fragmentShader = theLoader.shaders[material.params.fragmentShader];
+	if (!fragmentShader) {
+		console.log("ERROR: Missing fragment shader definition:", material.params.fragmentShader);
+		return new THREE.MeshPhongMaterial;
+	}
 
-			}
-		},
+	var vertexShader = theLoader.shaders[material.params.vertexShader];
+	if (!fragmentShader) {
+		console.log("ERROR: Missing vertex shader definition:", material.params.vertexShader);
+		return new THREE.MeshPhongMaterial;
+	}
 
-		cameras: {
-			enumerable: true,
-			writable: true,
-			value : []
-		},
+	var uniforms = {};
+	var shaderMaterial = new THREE.ShaderMaterial( {
 
-		lights: {
-			enumerable: true,
-			writable: true,
-			value : []
-		},
+        			fragmentShader: fragmentShader,
+        			vertexShader: vertexShader,
+        			uniforms: uniforms,
 
-		animations: {
-			enumerable: true,
-			writable: true,
-			value : []
-		},
+        		} );
 
-		// Implement WebGLTFLoader handlers
+	return new THREE.MeshPhongMaterial(material.params);
+        	}
+        },
 
-		handleBuffer: {
-			value: function( entryID, description, userInfo ) {
+        createShaderParams : {
+        	value: function(materialId, values, params, instanceProgram) {
+	var program = this.resources.getEntry(instanceProgram.program);
 
-				this.resources.setEntry( entryID, null, description );
-				description.type = "ArrayBuffer";
-				return true;
+	if (program) {
+		params.fragmentShader = program.description.fragmentShader;
+		params.vertexShader = program.description.vertexShader;
+		params.attributes = instanceProgram.attributes;
+		params.uniforms = instanceProgram.uniforms;
+	}
+        	}
+        },
+
+        threeJSMaterialType : {
+            value: function(materialId, technique, values, params) {
+
+	var materialType = THREE.MeshPhongMaterial;
+	var defaultPass = null;
+	if (technique && technique.description && technique.description.passes)
+        			defaultPass = technique.description.passes.defaultPass;
+
+	if (defaultPass) {
+		if (defaultPass.details && defaultPass.details.commonProfile) {
+			var profile = technique.description.passes.defaultPass.details.commonProfile;
+			if (profile)
+	            		{
+				switch (profile.lightingModel)
+		            		{
+					case 'Blinn' :
+					case 'Phong' :
+						materialType = THREE.MeshPhongMaterial;
+						break;
+
+					case 'Lambert' :
+						materialType = THREE.MeshLambertMaterial;
+						break;
+
+					default :
+						materialType = THREE.MeshBasicMaterial;
+						break;
+				}
 
+				if (profile.extras && profile.extras.doubleSided)
+		            		{
+					params.side = THREE.DoubleSide;
+				}
 			}
-		},
+		}
+        			else if (defaultPass.instanceProgram) {
 
-		handleBufferView: {
-			value: function( entryID, description, userInfo ) {
+	var instanceProgram = defaultPass.instanceProgram;
 
-				this.resources.setEntry( entryID, null, description );
+	this.createShaderParams(materialId, values, params, instanceProgram);
 
-				var buffer =  this.resources.getEntry( description.buffer );
-				description.type = "ArrayBufferView";
+	var loadshaders = true;
+
+	if (loadshaders) {
+		materialType = Material;
+	}
+        			}
+	}
 
-				var bufferViewEntry = this.resources.getEntry( entryID );
-				bufferViewEntry.buffer = buffer;
-				return true;
+	var texturePath = null;
+	var textureParams = null;
+	var diffuse = values.diffuse;
+	if (diffuse)
+                {
+		var texture = diffuse;
+		if (texture) {
+			var textureEntry = this.resources.getEntry(texture);
+			if (textureEntry) {
+				{
+					var imageEntry = this.resources.getEntry(textureEntry.description.source);
+					if (imageEntry) {
+						texturePath = imageEntry.description.path;
+					}
 
+					var samplerEntry = this.resources.getEntry(textureEntry.description.sampler);
+					if (samplerEntry) {
+						textureParams = samplerEntry.description;
+					}
+				}
 			}
-		},
+		}
+	}
+
+	var texture = LoadTexture(texturePath);
+	if (texture && textureParams) {
 
-		handleShader: {
-			value: function( entryID, description, userInfo ) {
+		if (textureParams.wrapS == WebGLRenderingContext.REPEAT)
+                		texture.wrapS = THREE.RepeatWrapping;
 
-				this.resources.setEntry( entryID, null, description );
-				var shaderRequest = {
-					id : entryID,
-					path : description.path,
-				};
+		if (textureParams.wrapT == WebGLRenderingContext.REPEAT)
+                		texture.wrapT = THREE.RepeatWrapping;
 
-				var shaderContext = new ShaderContext( entryID, description.path );
+		if (textureParams.magFilter == WebGLRenderingContext.LINEAR)
+                		texture.magFilter = THREE.LinearFilter;
 
-				theLoader.shadersRequested ++;
-				THREE.GLTFLoaderUtils.getFile( shaderRequest, shaderDelegate, shaderContext );
+//                	if (textureParams.minFilter == "LINEAR")
+//               		texture.minFilter = THREE.LinearFilter;
 
-				return true;
+		params.map = texture;
+	}
+
+	var envMapPath = null;
+	var envMapParams = null;
+	var reflective = values.reflective;
+	if (reflective)
+                {
+		var texture = reflective;
+		if (texture) {
+			var textureEntry = this.resources.getEntry(texture);
+			if (textureEntry) {
+				{
+					var imageEntry = this.resources.getEntry(textureEntry.description.source);
+					if (imageEntry) {
+						envMapPath = imageEntry.description.path;
+					}
 
+					var samplerEntry = this.resources.getEntry(textureEntry.description.sampler);
+					if (samplerEntry) {
+						envMapParams = samplerEntry.description;
+					}
+				}
 			}
-		},
+		}
+	}
 
-		handleProgram: {
-			value: function( entryID, description, userInfo ) {
+	var texture = LoadTexture(envMapPath);
+	if (texture && envMapParams) {
 
-				this.resources.setEntry( entryID, null, description );
-				return true;
+		if (envMapParams.wrapS == WebGLRenderingContext.REPEAT)
+                		texture.wrapS = THREE.RepeatWrapping;
 
-			}
-		},
+		if (envMapParams.wrapT == WebGLRenderingContext.REPEAT)
+                		texture.wrapT = THREE.RepeatWrapping;
 
-		handleTechnique: {
-			value: function( entryID, description, userInfo ) {
+		if (envMapParams.magFilter == WebGLRenderingContext.LINEAR)
+                		texture.magFilter = THREE.LinearFilter;
 
-				this.resources.setEntry( entryID, null, description );
-				return true;
+//                	if (envMapParams.minFilter == WebGLRenderingContext.LINEAR)
+//               		texture.minFilter = THREE.LinearFilter;
 
-			}
-		},
+		params.envMap = texture;
+	}
 
-		createShaderMaterial : {
-			value: function( material ) {
+	var shininess = values.shininesss || values.shininess; // N.B.: typo in converter!
+	if (shininess)
+                {
+		shininess = shininess;
+	}
 
-				var fragmentShader = theLoader.shaders[ material.params.fragmentShader ];
-				if ( ! fragmentShader ) {
+	var diffuseColor = !texturePath ? diffuse : null;
+	var opacity = 1.0;
+	if (values.hasOwnProperty("transparency"))
+                {
+		var USE_A_ONE = true; // for now, hack because file format isn't telling us
+		opacity =  USE_A_ONE ? values.transparency : (1.0 - values.transparency);
+	}
 
-					console.log( "ERROR: Missing fragment shader definition:", material.params.fragmentShader );
-					return new THREE.MeshPhongMaterial;
+                // if (diffuseColor) diffuseColor = [0, 1, 0];
 
-				}
+	params.color = RgbArraytoHex(diffuseColor);
+	params.opacity = opacity;
+	params.transparent = opacity < 1.0;
+                // hack hack hack
+	if (texturePath && texturePath.toLowerCase().indexOf(".png") != -1)
+                	params.transparent = true;
 
-				var vertexShader = theLoader.shaders[ material.params.vertexShader ];
-				if ( ! fragmentShader ) {
+	if (!(shininess === undefined))
+                {
+		params.shininess = shininess;
+	}
 
-					console.log( "ERROR: Missing vertex shader definition:", material.params.vertexShader );
-					return new THREE.MeshPhongMaterial;
+	if (!(values.emission === undefined))
+                {
+		params.emissive = RgbArraytoHex(values.emission);
+	}
 
-				}
+	if (!(values.specular === undefined))
+                {
+		params.specular = RgbArraytoHex(values.specular);
+	}
 
-				var uniforms = {};
-				var shaderMaterial = new THREE.ShaderMaterial( {
+	return materialType;
 
-					fragmentShader: fragmentShader,
-					vertexShader: vertexShader,
-					uniforms: uniforms,
+        	}
+        },
 
-				} );
+        handleMaterial: {
+            value: function(entryID, description, userInfo) {
+                //this should be rewritten using the meta datas that actually create the shader.
+                //here we will infer what needs to be pass to Three.js by looking inside the technique parameters.
+	var technique = this.resources.getEntry(description.instanceTechnique.technique);
+	var materialParams = {};
+	var values = description.instanceTechnique.values;
 
-				return new THREE.MeshPhongMaterial( material.params );
+	var materialType = this.threeJSMaterialType(entryID, technique, values, materialParams);
 
-			}
-		},
+	var material = new materialType(materialParams);
 
-		createShaderParams : {
-			value: function( materialId, values, params, instanceProgram ) {
+	this.resources.setEntry(entryID, material, description);
 
-				var program = this.resources.getEntry( instanceProgram.program );
+	return true;
+            }
+        },
 
-				if ( program ) {
+        handleMesh: {
+            value: function(entryID, description, userInfo) {
+	var mesh = new Mesh();
+	this.resources.setEntry(entryID, mesh, description);
+	var primitivesDescription = description.primitives;
+	if (!primitivesDescription) {
+                    //FIXME: not implemented in delegate
+		console.log("MISSING_PRIMITIVES for mesh:" + entryID);
+		return false;
+	}
 
-					params.fragmentShader = program.description.fragmentShader;
-					params.vertexShader = program.description.vertexShader;
-					params.attributes = instanceProgram.attributes;
-					params.uniforms = instanceProgram.uniforms;
+	for (var i = 0 ; i < primitivesDescription.length ; i ++) {
+		var primitiveDescription = primitivesDescription[i];
+
+		if (primitiveDescription.primitive === WebGLRenderingContext.TRIANGLES) {
+
+			var geometry = new ClassicGeometry();
+			var materialEntry = this.resources.getEntry(primitiveDescription.material);
+
+			mesh.addPrimitive(geometry, materialEntry.object);
+
+			var indices = this.resources.getEntry(primitiveDescription.indices);
+			var bufferEntry = this.resources.getEntry(indices.description.bufferView);
+			var indicesObject = {
+                        		bufferView : bufferEntry,
+                        		byteOffset : indices.description.byteOffset,
+                        		count : indices.description.count,
+                        		id : indices.entryID,
+                        		type : indices.description.type
+                        };
+
+			var indicesContext = new IndicesContext(indicesObject, geometry);
+			var alreadyProcessedIndices = THREE.GLTFLoaderUtils.getBuffer(indicesObject, indicesDelegate, indicesContext);
+                        /*if(alreadyProcessedIndices) {
+                            indicesDelegate.resourceAvailable(alreadyProcessedIndices, indicesContext);
+                        }*/
+
+                        // Load Vertex Attributes
+			var allAttributes = Object.keys(primitiveDescription.attributes);
+			allAttributes.forEach( function(semantic) {
+				geometry.totalAttributes ++;
+
+				var attribute;
+				var attributeID = primitiveDescription.attributes[semantic];
+				var attributeEntry = this.resources.getEntry(attributeID);
+				if (!attributeEntry) {
+                                //let's just use an anonymous object for the attribute
+					attribute = description.attributes[attributeID];
+					attribute.id = attributeID;
+					this.resources.setEntry(attributeID, attribute, attribute);
+
+					var bufferEntry = this.resources.getEntry(attribute.bufferView);
+					attributeEntry = this.resources.getEntry(attributeID);
 
+				} else {
+					attribute = attributeEntry.object;
+					attribute.id = attributeID;
+					var bufferEntry = this.resources.getEntry(attribute.bufferView);
 				}
 
+				var attributeObject = {
+                            		bufferView : bufferEntry,
+                            		byteOffset : attribute.byteOffset,
+                            		byteStride : attribute.byteStride,
+                            		count : attribute.count,
+                            		max : attribute.max,
+                            		min : attribute.min,
+                            		type : attribute.type,
+                            		id : attributeID
+                            };
+
+				var attribContext = new VertexAttributeContext(attributeObject, semantic, geometry);
+
+				var alreadyProcessedAttribute = THREE.GLTFLoaderUtils.getBuffer(attributeObject, vertexAttributeDelegate, attribContext);
+                            /*if(alreadyProcessedAttribute) {
+                                vertexAttributeDelegate.resourceAvailable(alreadyProcessedAttribute, attribContext);
+                            }*/
+			}, this);
+		}
+	}
+	return true;
+            }
+        },
+
+        handleCamera: {
+            value: function(entryID, description, userInfo) {
+	var camera;
+	if (description.type == "perspective")
+                {
+		var znear = description.perspective.znear;
+		var zfar = description.perspective.zfar;
+		var yfov = description.perspective.yfov;
+		var xfov = description.perspective.xfov;
+		var aspect_ratio = description.perspective.aspect_ratio;
+
+		if (!aspect_ratio)
+            			aspect_ratio = 1;
+
+		if (yfov === undefined)
+                	{
+			if (xfov)
+                		{
+                			// According to COLLADA spec...
+                			// aspect_ratio = xfov / yfov
+				yfov = xfov / aspect_ratio;
 			}
-		},
 
-		threeJSMaterialType : {
-			value: function( materialId, technique, values, params ) {
+		}
+
+		if (yfov)
+                	{
+			camera = new THREE.PerspectiveCamera(yfov, aspect_ratio, znear, zfar);
+		}
+	}
+                else
+	{
+		camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, znear, zfar );
+	}
 
-				var materialType = THREE.MeshPhongMaterial;
-				var defaultPass = null;
-				if ( technique && technique.description && technique.description.passes )
-			defaultPass = technique.description.passes.defaultPass;
+	if (camera)
+                {
+		this.resources.setEntry(entryID, camera, description);
+	}
 
-				if ( defaultPass ) {
+	return true;
+            }
+        },
 
-					if ( defaultPass.details && defaultPass.details.commonProfile ) {
+        handleLight: {
+            value: function(entryID, description, userInfo) {
 
-						var profile = technique.description.passes.defaultPass.details.commonProfile;
-						if ( profile )
-				{
+	var light = null;
+	var type = description.type;
+	if (type && description[type])
+        		{
+		var lparams = description[type];
+		var color = RgbArraytoHex(lparams.color);
 
-							switch ( profile.lightingModel )
-					{
-								case 'Blinn' :
-								case 'Phong' :
-									materialType = THREE.MeshPhongMaterial;
-									break;
+		switch (type) {
+			case "directional" :
+				light = new THREE.DirectionalLight(color);
+				light.position.set(0, 0, 1);
+				break;
 
-								case 'Lambert' :
-									materialType = THREE.MeshLambertMaterial;
-									break;
+			case "point" :
+				light = new THREE.PointLight(color);
+				break;
 
-								default :
-									materialType = THREE.MeshBasicMaterial;
-									break;
-							}
+			case "spot " :
+				light = new THREE.SpotLight(color);
+				light.position.set(0, 0, 1);
+				break;
 
-							if ( profile.extras && profile.extras.doubleSided )
-					{
+			case "ambient" :
+				light = new THREE.AmbientLight(color);
+				break;
+		}
+	}
 
-								params.side = THREE.DoubleSide;
+	if (light)
+        		{
+		this.resources.setEntry(entryID, light, description);
+	}
 
-							}
+	return true;
+            }
+        },
+
+        addPendingMesh: {
+            value: function(mesh, threeNode) {
+	theLoader.pendingMeshes.push({
+        			mesh: mesh,
+        			node: threeNode
+        		});
+        	}
+        },
+
+        handleNode: {
+            value: function(entryID, description, userInfo) {
+
+	var threeNode = null;
+	            if (description.jointId) {
+		threeNode = new THREE.Bone();
+		threeNode.jointId = description.jointId;
+		this.joints[description.jointId] = entryID;
+	            }
+	            else {
+		threeNode = new THREE.Object3D();
+	            }
+
+	threeNode.name = description.name;
+
+	this.resources.setEntry(entryID, threeNode, description);
+
+	var m = description.matrix;
+	if (m) {
+		threeNode.applyMatrix(new THREE.Matrix4().fromArray( m ));
+		threeNode.matrixAutoUpdate = false;
+		threeNode.matrixWorldNeedsUpdate = true;
+	}
+	else {
+		var t = description.translation;
+		var r = description.rotation;
+		var s = description.scale;
+
+		var position = t ? new THREE.Vector3(t[0], t[1], t[2]) :
+                		new THREE.Vector3;
+		if (r) {
+			convertAxisAngleToQuaternion(r, 1);
+		}
+		var rotation = r ? new THREE.Quaternion(r[0], r[1], r[2], r[3]) :
+                		new THREE.Quaternion;
+		var scale = s ? new THREE.Vector3(s[0], s[1], s[2]) :
+                		new THREE.Vector3;
+
+		var matrix = new THREE.Matrix4;
+		matrix.compose(position, rotation, scale);
+		threeNode.matrixAutoUpdate = false;
+		threeNode.matrixWorldNeedsUpdate = true;
+		threeNode.applyMatrix(matrix);
+	}
 
-						}
+	var self = this;
 
-					}
-					else if ( defaultPass.instanceProgram ) {
+                // Iterate through all node meshes and attach the appropriate objects
+                //FIXME: decision needs to be made between these 2 ways, probably meshes will be discarded.
+	var meshEntry;
+	if (description.mesh) {
+		meshEntry = this.resources.getEntry(description.mesh);
+		theLoader.meshesRequested ++;
+		meshEntry.object.onComplete(function(mesh) {
+			self.addPendingMesh(mesh, threeNode);
+			theLoader.meshesLoaded ++;
+			theLoader.checkComplete();
+		});
+	}
+
+	if (description.meshes) {
+		description.meshes.forEach( function(meshID) {
+			meshEntry = this.resources.getEntry(meshID);
+			theLoader.meshesRequested ++;
+			meshEntry.object.onComplete(function(mesh) {
+				self.addPendingMesh(mesh, threeNode);
+				theLoader.meshesLoaded ++;
+				theLoader.checkComplete();
+			});
+		}, this);
+	}
 
-						var instanceProgram = defaultPass.instanceProgram;
+	if (description.instanceSkin) {
 
-						this.createShaderParams( materialId, values, params, instanceProgram );
+		var skinEntry =  this.resources.getEntry(description.instanceSkin.skin);
 
-						var loadshaders = true;
+		if (skinEntry) {
 
-						if ( loadshaders ) {
+			var skin = skinEntry.object;
+			description.instanceSkin.skin = skin;
+			threeNode.instanceSkin = description.instanceSkin;
 
-							materialType = Material;
+			var sources = description.instanceSkin.sources;
+			skin.meshes = [];
+			sources.forEach( function(meshID) {
+				meshEntry = this.resources.getEntry(meshID);
+				theLoader.meshesRequested ++;
+				meshEntry.object.onComplete(function(mesh) {
 
-						}
+					skin.meshes.push(mesh);
+					theLoader.meshesLoaded ++;
+					theLoader.checkComplete();
+				});
+			}, this);
 
-					}
+		}
+	}
 
-				}
+	if (description.camera) {
+		var cameraEntry = this.resources.getEntry(description.camera);
+		if (cameraEntry) {
+			threeNode.add(cameraEntry.object);
+			this.cameras.push(cameraEntry.object);
+		}
+	}
 
-				var texturePath = null;
-				var textureParams = null;
-				var diffuse = values.diffuse;
-				if ( diffuse )
-			{
+	if (description.light) {
+		var lightEntry = this.resources.getEntry(description.light);
+		if (lightEntry) {
+			threeNode.add(lightEntry.object);
+			this.lights.push(lightEntry.object);
+		}
+	}
 
-					var texture = diffuse;
-					if ( texture ) {
+	return true;
+            }
+        },
+
+        buildNodeHirerachy: {
+            value: function(nodeEntryId, parentThreeNode) {
+	var nodeEntry = this.resources.getEntry(nodeEntryId);
+	var threeNode = nodeEntry.object;
+	parentThreeNode.add(threeNode);
+
+	var children = nodeEntry.description.children;
+	if (children) {
+		children.forEach( function(childID) {
+			this.buildNodeHirerachy(childID, threeNode);
+		}, this);
+	}
 
-						var textureEntry = this.resources.getEntry( texture );
-						if ( textureEntry ) {
+	return threeNode;
+            }
+        },
 
-							{
+        buildSkin: {
+            value: function(node) {
 
-								var imageEntry = this.resources.getEntry( textureEntry.description.source );
-								if ( imageEntry ) {
+	var skin = node.instanceSkin.skin;
+	if (skin) {
+		node.instanceSkin.skeletons.forEach(function(skeleton) {
+			var nodeEntry = this.resources.getEntry(skeleton);
+			if (nodeEntry) {
 
-									texturePath = imageEntry.description.path;
+				var rootSkeleton = nodeEntry.object;
 
-								}
+				var dobones = true;
 
-								var samplerEntry = this.resources.getEntry( textureEntry.description.sampler );
-								if ( samplerEntry ) {
+				var i, len = skin.meshes.length;
+				for (i = 0; i < len; i ++) {
+					var mesh = skin.meshes[i];
+					var threeMesh = null;
+					mesh.primitives.forEach(function(primitive) {
 
-									textureParams = samplerEntry.description;
+						var material = primitive.material;
+						if (!(material instanceof THREE.Material)) {
+							material = this.createShaderMaterial(material);
+						}
 
-								}
+						threeMesh = new THREE.SkinnedMesh(primitive.geometry.geometry, material, false);
+						threeMesh.add(rootSkeleton);
 
+						var geometry = primitive.geometry.geometry;
+						var j;
+						if (geometry.vertices) {
+							for ( j = 0; j < geometry.vertices.length; j ++ ) {
+								geometry.vertices[j].applyMatrix4( skin.bindShapeMatrix );
+							}
+						}
+                                    else if (geometry.attributes.position) {
+	var a = geometry.attributes.position.array;
+	var v = new THREE.Vector3;
+	                            		for ( j = 0; j < a.length / 3; j ++ ) {
+		v.set(a[j * 3], a[j * 3 + 1], a[j * 3 + 2]);
+		v.applyMatrix4( skin.bindShapeMatrix );
+		a[j * 3] = v.x;
+		a[j * 3 + 1] = v.y;
+		a[j * 3 + 2] = v.z;
+	                            		}
+                                    }
+
+						if (threeMesh && dobones) {
+
+							material.skinning = true;
+
+							threeMesh.boneInverses = [];
+							var jointsIds = skin.jointsIds;
+							var bones = [];
+							var boneInverses = [];
+							var i, len = jointsIds.length;
+							for (i = 0; i < len; i ++) {
+								var jointId = jointsIds[i];
+								var nodeForJoint = this.joints[jointId];
+								var joint = this.resources.getEntry(nodeForJoint).object;
+								if (joint) {
+
+									joint.skin = threeMesh;
+									bones.push(joint);
+
+									var m = skin.inverseBindMatrices;
+									var mat = new THREE.Matrix4().set(
+        	                                            m[i * 16 + 0],  m[i * 16 + 4],  m[i * 16 + 8],  m[i * 16 + 12],
+        	                                            m[i * 16 + 1],  m[i * 16 + 5],  m[i * 16 + 9],  m[i * 16 + 13],
+        	                                            m[i * 16 + 2],  m[i * 16 + 6],  m[i * 16 + 10], m[i * 16 + 14],
+        	                                            m[i * 16 + 3],  m[i * 16 + 7],  m[i * 16 + 11], m[i * 16 + 15]
+        	                                        );
+									boneInverses.push(mat);
+
+								} else {
+									console.log("WARNING: jointId:" + jointId + " cannot be found in skeleton:" + skeleton);
+								}
 							}
 
+							threeMesh.bind( new THREE.Skeleton( bones, boneInverses, false ), threeMesh.matrixWorld );
 						}
 
-					}
+						if (threeMesh) {
+							threeMesh.castShadow = true;
+							node.add(threeMesh);
+						}
 
+					}, this);
 				}
 
-				var texture = LoadTexture( texturePath );
-				if ( texture && textureParams ) {
-
-					if ( textureParams.wrapS == WebGLRenderingContext.REPEAT )
-			texture.wrapS = THREE.RepeatWrapping;
-
-					if ( textureParams.wrapT == WebGLRenderingContext.REPEAT )
-			texture.wrapT = THREE.RepeatWrapping;
+			}
 
-					if ( textureParams.magFilter == WebGLRenderingContext.LINEAR )
-			texture.magFilter = THREE.LinearFilter;
 
-					//                	if (textureParams.minFilter == "LINEAR")
-					//               		texture.minFilter = THREE.LinearFilter;
+		}, this);
 
-					params.map = texture;
+	}
+            }
+        },
 
-				}
+        buildSkins: {
+            value: function(node) {
 
-				var envMapPath = null;
-				var envMapParams = null;
-				var reflective = values.reflective;
-				if ( reflective )
-			{
+	if (node.instanceSkin)
+        			this.buildSkin(node);
 
-					var texture = reflective;
-					if ( texture ) {
+	var children = node.children;
+	if (children) {
+		children.forEach( function(child) {
+			this.buildSkins(child);
+		}, this);
+	}
+            }
+        },
 
-						var textureEntry = this.resources.getEntry( texture );
-						if ( textureEntry ) {
+        createMeshAnimations : {
+        	value : function(root) {
+	this.buildSkins(root);
+        		}
+        },
 
-							{
+        handleScene: {
+            value: function(entryID, description, userInfo) {
 
-								var imageEntry = this.resources.getEntry( textureEntry.description.source );
-								if ( imageEntry ) {
+	if (!description.nodes) {
+		console.log("ERROR: invalid file required nodes property is missing from scene");
+		return false;
+	}
 
-									envMapPath = imageEntry.description.path;
+	description.nodes.forEach( function(nodeUID) {
+		this.buildNodeHirerachy(nodeUID, userInfo.rootObj);
+	}, this);
 
-								}
+	if (this.delegate) {
+		this.delegate.loadCompleted(userInfo.callback, userInfo.rootObj);
+	}
 
-								var samplerEntry = this.resources.getEntry( textureEntry.description.sampler );
-								if ( samplerEntry ) {
+	return true;
+            }
+        },
 
-									envMapParams = samplerEntry.description;
+        handleImage: {
+            value: function(entryID, description, userInfo) {
+	this.resources.setEntry(entryID, null, description);
+	return true;
+            }
+        },
 
-								}
+        addNodeAnimationChannel : {
+        	value : function(name, channel, interp) {
+	if (!this.nodeAnimationChannels)
+        			this.nodeAnimationChannels = {};
 
-							}
+	if (!this.nodeAnimationChannels[name]) {
+		this.nodeAnimationChannels[name] = [];
+	}
 
-						}
+	this.nodeAnimationChannels[name].push(interp);
+        	},
+        },
+
+        createAnimations : {
+        	value : function() {
+	for (var name in this.nodeAnimationChannels) {
+		var nodeAnimationChannels = this.nodeAnimationChannels[name];
+		var i, len = nodeAnimationChannels.length;
+        			//console.log(" animation channels for node " + name);
+        			//for (i = 0; i < len; i++) {
+        			//	console.log(nodeAnimationChannels[i]);
+        			//}
+		var anim = new THREE.glTFAnimation(nodeAnimationChannels);
+		anim.name = "animation_" + name;
+		this.animations.push(anim);
+	}
+        	}
+        },
 
-					}
+        buildAnimation: {
+        	value : function(animation) {
 
-				}
+	var interps = [];
+	            var i, len = animation.channels.length;
+	            for (i = 0; i < len; i ++) {
 
-				var texture = LoadTexture( envMapPath );
-				if ( texture && envMapParams ) {
+		var channel = animation.channels[i];
+		var sampler = animation.samplers[channel.sampler];
+		if (sampler) {
 
-					if ( envMapParams.wrapS == WebGLRenderingContext.REPEAT )
-			texture.wrapS = THREE.RepeatWrapping;
+			var input = animation.parameters[sampler.input];
+			if (input && input.data) {
 
-					if ( envMapParams.wrapT == WebGLRenderingContext.REPEAT )
-			texture.wrapT = THREE.RepeatWrapping;
+				var output = animation.parameters[sampler.output];
+				if (output && output.data) {
 
-					if ( envMapParams.magFilter == WebGLRenderingContext.LINEAR )
-			texture.magFilter = THREE.LinearFilter;
+					var target = channel.target;
+					var node = this.resources.getEntry(target.id);
+					if (node) {
 
-					//                	if (envMapParams.minFilter == WebGLRenderingContext.LINEAR)
-					//               		texture.minFilter = THREE.LinearFilter;
+						var path = target.path;
 
-					params.envMap = texture;
+						if (path == "rotation")
+		            				{
+							convertAxisAngleToQuaternion(output.data, output.count);
+						}
 
+						var interp = {
+			            					keys : input.data,
+			            					values : output.data,
+			            					count : input.count,
+			            					target : node.object,
+			            					path : path,
+			            					type : sampler.interpolation
+			            			};
+
+						this.addNodeAnimationChannel(target.id, channel, interp);
+						interps.push(interp);
+					}
 				}
+			}
+		}
+	            }
+        	}
+        },
 
-				var shininess = values.shininesss || values.shininess; // N.B.: typo in converter!
-				if ( shininess )
-			{
+        handleAnimation: {
+            value: function(entryID, description, userInfo) {
 
-					shininess = shininess;
-
-				}
-
-				var diffuseColor = ! texturePath ? diffuse : null;
-				var opacity = 1.0;
-				if ( values.hasOwnProperty( "transparency" ) )
-			{
-
-					var USE_A_ONE = true; // for now, hack because file format isn't telling us
-					opacity =  USE_A_ONE ? values.transparency : ( 1.0 - values.transparency );
-
-				}
-
-				// if (diffuseColor) diffuseColor = [0, 1, 0];
-
-				params.color = RgbArraytoHex( diffuseColor );
-				params.opacity = opacity;
-				params.transparent = opacity < 1.0;
-				// hack hack hack
-				if ( texturePath && texturePath.toLowerCase().indexOf( ".png" ) != - 1 )
-			params.transparent = true;
-
-				if ( ! ( shininess === undefined ) )
-			{
-
-					params.shininess = shininess;
-
-				}
-
-				if ( ! ( values.emission === undefined ) )
-			{
-
-					params.emissive = RgbArraytoHex( values.emission );
-
-				}
-
-				if ( ! ( values.specular === undefined ) )
-			{
-
-					params.specular = RgbArraytoHex( values.specular );
-
-				}
-
-				return materialType;
-
-			}
-		},
-
-		handleMaterial: {
-			value: function( entryID, description, userInfo ) {
-
-				//this should be rewritten using the meta datas that actually create the shader.
-				//here we will infer what needs to be pass to Three.js by looking inside the technique parameters.
-				var technique = this.resources.getEntry( description.instanceTechnique.technique );
-				var materialParams = {};
-				var values = description.instanceTechnique.values;
-
-				var materialType = this.threeJSMaterialType( entryID, technique, values, materialParams );
-
-				var material = new materialType( materialParams );
-
-				this.resources.setEntry( entryID, material, description );
-
-				return true;
-
-			}
-		},
-
-		handleMesh: {
-			value: function( entryID, description, userInfo ) {
-
-				var mesh = new Mesh();
-				this.resources.setEntry( entryID, mesh, description );
-				var primitivesDescription = description.primitives;
-				if ( ! primitivesDescription ) {
-
-					//FIXME: not implemented in delegate
-					console.log( "MISSING_PRIMITIVES for mesh:" + entryID );
-					return false;
-
-				}
-
-				for ( var i = 0 ; i < primitivesDescription.length ; i ++ ) {
-
-					var primitiveDescription = primitivesDescription[ i ];
-
-					if ( primitiveDescription.primitive === WebGLRenderingContext.TRIANGLES ) {
-
-						var geometry = new ClassicGeometry();
-						var materialEntry = this.resources.getEntry( primitiveDescription.material );
-
-						mesh.addPrimitive( geometry, materialEntry.object );
-
-						var indices = this.resources.getEntry( primitiveDescription.indices );
-						var bufferEntry = this.resources.getEntry( indices.description.bufferView );
-						var indicesObject = {
-				bufferView : bufferEntry,
-				byteOffset : indices.description.byteOffset,
-				count : indices.description.count,
-				id : indices.entryID,
-				type : indices.description.type
-			};
-
-						var indicesContext = new IndicesContext( indicesObject, geometry );
-						var alreadyProcessedIndices = THREE.GLTFLoaderUtils.getBuffer( indicesObject, indicesDelegate, indicesContext );
-						/*if(alreadyProcessedIndices) {
-						                            indicesDelegate.resourceAvailable(alreadyProcessedIndices, indicesContext);
-						                        }*/
-						
-						// Load Vertex Attributes
-						var allAttributes = Object.keys( primitiveDescription.attributes );
-						allAttributes.forEach( function( semantic ) {
-
-							geometry.totalAttributes ++;
-
-							var attribute;
-							var attributeID = primitiveDescription.attributes[ semantic ];
-							var attributeEntry = this.resources.getEntry( attributeID );
-							if ( ! attributeEntry ) {
-
-								//let's just use an anonymous object for the attribute
-								attribute = description.attributes[ attributeID ];
-								attribute.id = attributeID;
-								this.resources.setEntry( attributeID, attribute, attribute );
-
-								var bufferEntry = this.resources.getEntry( attribute.bufferView );
-								attributeEntry = this.resources.getEntry( attributeID );
-
-							} else {
-
-								attribute = attributeEntry.object;
-								attribute.id = attributeID;
-								var bufferEntry = this.resources.getEntry( attribute.bufferView );
-
-							}
-
-							var attributeObject = {
-					bufferView : bufferEntry,
-					byteOffset : attribute.byteOffset,
-					byteStride : attribute.byteStride,
-					count : attribute.count,
-					max : attribute.max,
-					min : attribute.min,
-					type : attribute.type,
-					id : attributeID
-				};
-
-							var attribContext = new VertexAttributeContext( attributeObject, semantic, geometry );
-
-							var alreadyProcessedAttribute = THREE.GLTFLoaderUtils.getBuffer( attributeObject, vertexAttributeDelegate, attribContext );
-							/*if(alreadyProcessedAttribute) {
-							                                vertexAttributeDelegate.resourceAvailable(alreadyProcessedAttribute, attribContext);
-							                            }*/
-							
-						}, this );
-
-					}
-
-				}
-				return true;
-
-			}
-		},
-
-		handleCamera: {
-			value: function( entryID, description, userInfo ) {
-
-				var camera;
-				if ( description.type == "perspective" ) {
-
-					var znear = description.perspective.znear;
-					var zfar = description.perspective.zfar;
-					var yfov = description.perspective.yfov;
-					var xfov = description.perspective.xfov;
-					var aspect_ratio = description.perspective.aspect_ratio;
-
-					if ( ! aspect_ratio ) {
-						
-						aspect_ratio = 1;
-						
-					}
-
-					if ( yfov === undefined ) {
-
-						if ( xfov )	{
-
-							// According to COLLADA spec...
-							// aspect_ratio = xfov / yfov
-							yfov = xfov / aspect_ratio;
-
-						}
-
-					}
-
-					if ( yfov )	{
-
-						camera = new THREE.PerspectiveCamera( yfov, aspect_ratio, znear, zfar );
-
-					}
-
-				} else {
-
-					camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, znear, zfar );
-					
-				}
-
-				if ( camera ) {
-
-					this.resources.setEntry( entryID, camera, description );
-
-				}
-
-				return true;
-
-			}
-		},
-
-		handleLight: {
-			value: function( entryID, description, userInfo ) {
-
-				var light = null;
-				var type = description.type;
-				if ( type && description[ type ] ) {
-
-					var lparams = description[ type ];
-					var color = RgbArraytoHex( lparams.color );
-
-					switch ( type ) {
-						case "directional" :
-							light = new THREE.DirectionalLight( color );
-							light.position.set( 0, 0, 1 );
-							break;
-
-						case "point" :
-							light = new THREE.PointLight( color );
-							break;
-
-						case "spot " :
-							light = new THREE.SpotLight( color );
-							light.position.set( 0, 0, 1 );
-							break;
-
-						case "ambient" :
-							light = new THREE.AmbientLight( color );
-							break;
-					}
-
-				}
-
-				if ( light ) {
-
-					this.resources.setEntry( entryID, light, description );
-
-				}
-
-				return true;
-
-			}
-		},
-
-		addPendingMesh: {
-			value: function( mesh, threeNode ) {
-
-				theLoader.pendingMeshes.push( {
-					
-					mesh: mesh,
-					node: threeNode
-					
-				} );
-
-			}
-		},
-
-		handleNode: {
-			value: function( entryID, description, userInfo ) {
-
-				var threeNode = null;
-				if ( description.jointId ) {
-
-					threeNode = new THREE.Bone();
-					threeNode.jointId = description.jointId;
-					this.joints[ description.jointId ] = entryID;
-
-				}
-				else {
-
-					threeNode = new THREE.Object3D();
-
-				}
-
-				threeNode.name = description.name;
-
-				this.resources.setEntry( entryID, threeNode, description );
-
-				var m = description.matrix;
-				if ( m ) {
-
-					threeNode.applyMatrix( new THREE.Matrix4().fromArray( m ) );
-					threeNode.matrixAutoUpdate = false;
-					threeNode.matrixWorldNeedsUpdate = true;
-
-				} else {
-
-					var t = description.translation;
-					var r = description.rotation;
-					var s = description.scale;
-
-					var position = t ? new THREE.Vector3( t[ 0 ], t[ 1 ], t[ 2 ] ) : new THREE.Vector3;
-					
-					if ( r ) {
-
-						convertAxisAngleToQuaternion( r, 1 );
-
-					}
-					
-					var rotation = r ? new THREE.Quaternion( r[ 0 ], r[ 1 ], r[ 2 ], r[ 3 ] ) : new THREE.Quaternion;
-					var scale = s ? new THREE.Vector3( s[ 0 ], s[ 1 ], s[ 2 ] ) : new THREE.Vector3;
-
-					var matrix = new THREE.Matrix4;
-					matrix.compose( position, rotation, scale );
-					threeNode.matrixAutoUpdate = false;
-					threeNode.matrixWorldNeedsUpdate = true;
-					threeNode.applyMatrix( matrix );
-
-				}
-
-				var self = this;
-
-				// Iterate through all node meshes and attach the appropriate objects
-				//FIXME: decision needs to be made between these 2 ways, probably meshes will be discarded.
-				var meshEntry;
-				if ( description.mesh ) {
-
-					meshEntry = this.resources.getEntry( description.mesh );
-					theLoader.meshesRequested ++;
-					meshEntry.object.onComplete( function( mesh ) {
-
-						self.addPendingMesh( mesh, threeNode );
-						theLoader.meshesLoaded ++;
-						theLoader.checkComplete();
-
-					} );
-
-				}
-
-				if ( description.meshes ) {
-
-					description.meshes.forEach( function( meshID ) {
-
-						meshEntry = this.resources.getEntry( meshID );
-						theLoader.meshesRequested ++;
-						meshEntry.object.onComplete( function( mesh ) {
-
-							self.addPendingMesh( mesh, threeNode );
-							theLoader.meshesLoaded ++;
-							theLoader.checkComplete();
-
-						} );
-
-					}, this );
-
-				}
-
-				if ( description.instanceSkin ) {
-
-					var skinEntry =  this.resources.getEntry( description.instanceSkin.skin );
-
-					if ( skinEntry ) {
-
-						var skin = skinEntry.object;
-						description.instanceSkin.skin = skin;
-						threeNode.instanceSkin = description.instanceSkin;
-
-						var sources = description.instanceSkin.sources;
-						skin.meshes = [];
-						sources.forEach( function( meshID ) {
-
-							meshEntry = this.resources.getEntry( meshID );
-							theLoader.meshesRequested ++;
-							meshEntry.object.onComplete( function( mesh ) {
-
-								skin.meshes.push( mesh );
-								theLoader.meshesLoaded ++;
-								theLoader.checkComplete();
-
-							} );
-
-						}, this );
-
-					}
-
-				}
-
-				if ( description.camera ) {
-
-					var cameraEntry = this.resources.getEntry( description.camera );
-					if ( cameraEntry ) {
-
-						threeNode.add( cameraEntry.object );
-						this.cameras.push( cameraEntry.object );
-
-					}
-
-				}
-
-				if ( description.light ) {
-
-					var lightEntry = this.resources.getEntry( description.light );
-					if ( lightEntry ) {
-
-						threeNode.add( lightEntry.object );
-						this.lights.push( lightEntry.object );
-
-					}
-
-				}
-
-				return true;
-
-			}
-		},
-
-		buildNodeHirerachy: {
-			value: function( nodeEntryId, parentThreeNode ) {
-
-				var nodeEntry = this.resources.getEntry( nodeEntryId );
-				var threeNode = nodeEntry.object;
-				parentThreeNode.add( threeNode );
-
-				var children = nodeEntry.description.children;
-				if ( children ) {
-
-					children.forEach( function( childID ) {
-
-						this.buildNodeHirerachy( childID, threeNode );
-
-					}, this );
-
-				}
-
-				return threeNode;
-
-			}
-		},
-
-		buildSkin: {
-			value: function( node ) {
-
-				var skin = node.instanceSkin.skin;
-				if ( skin ) {
-
-					node.instanceSkin.skeletons.forEach( function( skeleton ) {
-
-						var nodeEntry = this.resources.getEntry( skeleton );
-						if ( nodeEntry ) {
-
-							var rootSkeleton = nodeEntry.object;
-
-							var dobones = true;
-
-							var i, len = skin.meshes.length;
-							for ( i = 0; i < len; i ++ ) {
-
-								var mesh = skin.meshes[ i ];
-								var threeMesh = null;
-								mesh.primitives.forEach( function( primitive ) {
-
-									var material = primitive.material;
-									if ( ! ( material instanceof THREE.Material ) ) {
-
-										material = this.createShaderMaterial( material );
-
-									}
-
-									threeMesh = new THREE.SkinnedMesh( primitive.geometry.geometry, material, false );
-									threeMesh.add( rootSkeleton );
-
-									var geometry = primitive.geometry.geometry;
-									var j;
-									if ( geometry.vertices ) {
-
-										for ( j = 0; j < geometry.vertices.length; j ++ ) {
-
-											geometry.vertices[ j ].applyMatrix4( skin.bindShapeMatrix );
-
-										}
-
-									} else if ( geometry.attributes.position ) {
-
-										var a = geometry.attributes.position.array;
-										var v = new THREE.Vector3;
-										for ( j = 0; j < a.length / 3; j ++ ) {
-
-											v.set( a[ j * 3 ], a[ j * 3 + 1 ], a[ j * 3 + 2 ] );
-											v.applyMatrix4( skin.bindShapeMatrix );
-											a[ j * 3 ] = v.x;
-											a[ j * 3 + 1 ] = v.y;
-											a[ j * 3 + 2 ] = v.z;
-
-										}
-
-									}
-
-									if ( threeMesh && dobones ) {
-
-										material.skinning = true;
-
-										threeMesh.boneInverses = [];
-										var jointsIds = skin.jointsIds;
-										var bones = [];
-										var boneInverses = [];
-										var i, len = jointsIds.length;
-										for ( i = 0; i < len; i ++ ) {
-
-											var jointId = jointsIds[ i ];
-											var nodeForJoint = this.joints[ jointId ];
-											var joint = this.resources.getEntry( nodeForJoint ).object;
-											if ( joint ) {
-
-												joint.skin = threeMesh;
-												bones.push( joint );
-
-												var m = skin.inverseBindMatrices;
-												var mat = new THREE.Matrix4().set(
-													m[ i * 16 + 0 ],  m[ i * 16 + 4 ],  m[ i * 16 + 8 ],  m[ i * 16 + 12 ],
-													m[ i * 16 + 1 ],  m[ i * 16 + 5 ],  m[ i * 16 + 9 ],  m[ i * 16 + 13 ],
-													m[ i * 16 + 2 ],  m[ i * 16 + 6 ],  m[ i * 16 + 10 ], m[ i * 16 + 14 ],
-													m[ i * 16 + 3 ],  m[ i * 16 + 7 ],  m[ i * 16 + 11 ], m[ i * 16 + 15 ]
-												);
-												boneInverses.push( mat );
-
-											} else {
-
-												console.log( "WARNING: jointId:" + jointId + " cannot be found in skeleton:" + skeleton );
-
-											}
-
-										}
-										
-										threeMesh.bind( new THREE.Skeleton( bones, boneInverses, false ), threeMesh.matrixWorld );
-
-									}
-
-									if ( threeMesh ) {
-
-										threeMesh.castShadow = true;
-										node.add( threeMesh );
-
-									}
-
-								}, this );
-
-							}
-
-						}
-
-
-					}, this );
-
-				}
-
-			}
-		},
-
-		buildSkins: {
-			value: function( node ) {
-
-				if ( node.instanceSkin ) {
-					this.buildSkin( node );
-				}
-
-				var children = node.children;
-				
-				if ( children ) {
-
-					children.forEach( function( child ) {
-
-						this.buildSkins( child );
-
-					}, this );
-
-				}
-
-			}
-		},
-
-		createMeshAnimations : {
-			value : function( root ) {
-
-				this.buildSkins( root );
-
-			}
-		},
-
-		handleScene: {
-			value: function( entryID, description, userInfo ) {
-
-				if ( ! description.nodes ) {
-
-					console.log( "ERROR: invalid file required nodes property is missing from scene" );
-					return false;
-
-				}
-
-				description.nodes.forEach( function( nodeUID ) {
-
-					this.buildNodeHirerachy( nodeUID, userInfo.rootObj );
-
-				}, this );
-
-				if ( this.delegate ) {
-
-					this.delegate.loadCompleted( userInfo.callback, userInfo.rootObj );
-
-				}
-
-				return true;
-
-			}
-		},
-
-		handleImage: {
-			value: function( entryID, description, userInfo ) {
-
-				this.resources.setEntry( entryID, null, description );
-				return true;
-
-			}
-		},
-
-		addNodeAnimationChannel : {
-			value : function( name, channel, interp ) {
-
-				if ( ! this.nodeAnimationChannels ) {
-					
-					this.nodeAnimationChannels = {};
-					
-				}
-
-				if ( ! this.nodeAnimationChannels[ name ] ) {
-
-					this.nodeAnimationChannels[ name ] = [];
-
-				}
-
-				this.nodeAnimationChannels[ name ].push( interp );
-
-			},
-		},
-
-		createAnimations : {
-			value : function() {
-
-				for ( var name in this.nodeAnimationChannels ) {
-
-					var nodeAnimationChannels = this.nodeAnimationChannels[ name ];
-					var i, len = nodeAnimationChannels.length;
-					//console.log(" animation channels for node " + name);
-					//for (i = 0; i < len; i++) {
-					//	console.log(nodeAnimationChannels[i]);
-					//}
-					var anim = new THREE.glTFAnimation( nodeAnimationChannels );
-					anim.name = "animation_" + name;
-					this.animations.push( anim );
-
-				}
-
-			}
-		},
-
-		buildAnimation: {
-			value : function( animation ) {
-
-				var interps = [];
-				var i, len = animation.channels.length;
-				for ( i = 0; i < len; i ++ ) {
-
-					var channel = animation.channels[ i ];
-					var sampler = animation.samplers[ channel.sampler ];
-					if ( sampler ) {
-
-						var input = animation.parameters[ sampler.input ];
-						if ( input && input.data ) {
-
-							var output = animation.parameters[ sampler.output ];
-							if ( output && output.data ) {
-
-								var target = channel.target;
-								var node = this.resources.getEntry( target.id );
-								if ( node ) {
-
-									var path = target.path;
-
-									if ( path == "rotation" ) {
-
-										convertAxisAngleToQuaternion( output.data, output.count );
-
-									}
-
-									var interp = {
-										keys : input.data,
-										values : output.data,
-										count : input.count,
-										target : node.object,
-										path : path,
-										type : sampler.interpolation
-									};
-
-									this.addNodeAnimationChannel( target.id, channel, interp );
-									interps.push( interp );
-
-								}
-
-							}
-
-						}
-
-					}
-
-				}
-
-			}
-		},
-
-		handleAnimation: {
-			value: function( entryID, description, userInfo ) {
-
-				var self = this;
-				theLoader.animationsRequested ++;
-				var animation = new Animation();
-				animation.name = entryID;
-				animation.onload = function() {
-
-					// self.buildAnimation(animation);
-					theLoader.animationsLoaded ++;
-					theLoader.animations.push( animation );
-					theLoader.checkComplete();
-
-				};
-
-				animation.channels = description.channels;
-				animation.samplers = description.samplers;
-				this.resources.setEntry( entryID, animation, description );
-				var parameters = description.parameters;
-				if ( ! parameters ) {
-
-					//FIXME: not implemented in delegate
-					console.log( "MISSING_PARAMETERS for animation:" + entryID );
-					return false;
-
-				}
-
-				// Load parameter buffers
-				var params = Object.keys( parameters );
-				params.forEach( function( param ) {
-
-					animation.totalParameters ++;
-					var parameter = parameters[ param ];
-					var accessor = this.resources.getEntry( parameter );
-					
-					if ( ! accessor ) {
-						debugger;
-					}
-					
-					accessor = accessor.object;
-					var bufferView = this.resources.getEntry( accessor.bufferView );
-					var paramObject = {
-						bufferView : bufferView,
-						byteOffset : accessor.byteOffset,
-						count : accessor.count,
-						type : accessor.type,
-						id : accessor.bufferView,
-						name : param
-					};
-
-					var paramContext = new AnimationParameterContext( paramObject, animation );
-
-					var alreadyProcessedAttribute = THREE.GLTFLoaderUtils.getBuffer( paramObject, animationParameterDelegate, paramContext );
-					/*if ( alreadyProcessedAttribute ) {
-	                        vertexAttributeDelegate.resourceAvailable(alreadyProcessedAttribute, attribContext);
+	var self = this;
+	            theLoader.animationsRequested ++;
+	            var animation = new Animation();
+	animation.name = entryID;
+	            animation.onload = function() {
+	            	// self.buildAnimation(animation);
+		theLoader.animationsLoaded ++;
+		theLoader.animations.push(animation);
+		theLoader.checkComplete();
+	            };
+
+	            animation.channels = description.channels;
+	            animation.samplers = description.samplers;
+	            this.resources.setEntry(entryID, animation, description);
+	            var parameters = description.parameters;
+	            if (!parameters) {
+	                //FIXME: not implemented in delegate
+		console.log("MISSING_PARAMETERS for animation:" + entryID);
+		return false;
+	            }
+
+                // Load parameter buffers
+	var params = Object.keys(parameters);
+	params.forEach( function(param) {
+
+		animation.totalParameters ++;
+		var parameter = parameters[param];
+		var accessor = this.resources.getEntry(parameter);
+		if (!accessor)
+                    	debugger;
+		accessor = accessor.object;
+		var bufferView = this.resources.getEntry(accessor.bufferView);
+		var paramObject = {
+                    		bufferView : bufferView,
+                    		byteOffset : accessor.byteOffset,
+                    		count : accessor.count,
+                    		type : accessor.type,
+                    		id : accessor.bufferView,
+                    		name : param
+                    };
+
+		var paramContext = new AnimationParameterContext(paramObject, animation);
+
+		var alreadyProcessedAttribute = THREE.GLTFLoaderUtils.getBuffer(paramObject, animationParameterDelegate, paramContext);
+                    /*if(alreadyProcessedAttribute) {
+                        vertexAttributeDelegate.resourceAvailable(alreadyProcessedAttribute, attribContext);
                     }*/
-					
-				}, this );
-
-				return true;
-
-			}
-		},
-
-		handleAccessor: {
-			
-			value: function( entryID, description, userInfo ) {
-
-				// Save attribute entry
-				this.resources.setEntry( entryID, description, description );
-				return true;
-
-			}
-		},
-
-		handleSkin: {
-			
-			value: function( entryID, description, userInfo ) {
-
-				// Save skin entry
-
-				var skin = {};
-
-				var m = description.bindShapeMatrix;
-				skin.bindShapeMatrix = new THREE.Matrix4().fromArray( m );
-
-				skin.jointsIds = description.joints;
-				var inverseBindMatricesDescription = description.inverseBindMatrices;
-				skin.inverseBindMatricesDescription = inverseBindMatricesDescription;
-				skin.inverseBindMatricesDescription.id = entryID + "_inverseBindMatrices";
-
-				var bufferEntry = this.resources.getEntry( inverseBindMatricesDescription.bufferView );
-
-				var paramObject = {
-					
-					bufferView : bufferEntry,
-					byteOffset : inverseBindMatricesDescription.byteOffset,
-					count : inverseBindMatricesDescription.count,
-					type : inverseBindMatricesDescription.type,
-					id : inverseBindMatricesDescription.bufferView,
-					name : skin.inverseBindMatricesDescription.id
-					
-				};
-
-				var context = new InverseBindMatricesContext( paramObject, skin );
-
-				var alreadyProcessedAttribute = THREE.GLTFLoaderUtils.getBuffer( paramObject, inverseBindMatricesDelegate, context );
-
-				var bufferView = this.resources.getEntry( skin.inverseBindMatricesDescription.bufferView );
-				skin.inverseBindMatricesDescription.bufferView =
-				bufferView.object;
-				this.resources.setEntry( entryID, skin, description );
-				return true;
-
-			}
-		},
-
-		handleSampler: {
-			value: function( entryID, description, userInfo ) {
-
-				// Save attribute entry
-				this.resources.setEntry( entryID, description, description );
-				return true;
-
-			}
-		},
-
-		handleTexture: {
-			value: function( entryID, description, userInfo ) {
-
-				// Save attribute entry
-				this.resources.setEntry( entryID, null, description );
-				return true;
-
-			}
-		},
-
-		handleError: {
-			value: function( msg ) {
-
-				throw new Error( msg );
-				return true;
-
-			}
-		},
-
-		_delegate: {
-			value: new LoadDelegate,
-			writable: true
-		},
-
-		delegate: {
-			enumerable: true,
-			get: function() {
-
-				return this._delegate;
-
-			},
-			set: function( value ) {
-
-				this._delegate = value;
-
-			}
-		}
-	} );
-
-
-	// Loader
-
-	var Context = function( rootObj, callback ) {
-
+	}, this);
+
+	            return true;
+            }
+        },
+
+        handleAccessor: {
+            value: function(entryID, description, userInfo) {
+	    		// Save attribute entry
+	    		this.resources.setEntry(entryID, description, description);
+	return true;
+            }
+        },
+
+        handleSkin: {
+            value: function(entryID, description, userInfo) {
+	    		// Save skin entry
+
+	var skin = {
+        		};
+
+	var m = description.bindShapeMatrix;
+	            skin.bindShapeMatrix = new THREE.Matrix4().fromArray( m );
+
+	            skin.jointsIds = description.joints;
+	            var inverseBindMatricesDescription = description.inverseBindMatrices;
+	            skin.inverseBindMatricesDescription = inverseBindMatricesDescription;
+	            skin.inverseBindMatricesDescription.id = entryID + "_inverseBindMatrices";
+
+	var bufferEntry = this.resources.getEntry(inverseBindMatricesDescription.bufferView);
+
+	var paramObject = {
+                		bufferView : bufferEntry,
+                		byteOffset : inverseBindMatricesDescription.byteOffset,
+                		count : inverseBindMatricesDescription.count,
+                		type : inverseBindMatricesDescription.type,
+                		id : inverseBindMatricesDescription.bufferView,
+                		name : skin.inverseBindMatricesDescription.id
+                };
+
+	            var context = new InverseBindMatricesContext(paramObject, skin);
+
+	var alreadyProcessedAttribute = THREE.GLTFLoaderUtils.getBuffer(paramObject, inverseBindMatricesDelegate, context);
+
+	            var bufferView = this.resources.getEntry(skin.inverseBindMatricesDescription.bufferView);
+	            skin.inverseBindMatricesDescription.bufferView =
+	            	bufferView.object;
+	    		this.resources.setEntry(entryID, skin, description);
+	return true;
+            }
+        },
+
+        handleSampler: {
+            value: function(entryID, description, userInfo) {
+	    		// Save attribute entry
+	    		this.resources.setEntry(entryID, description, description);
+	return true;
+            }
+        },
+
+        handleTexture: {
+            value: function(entryID, description, userInfo) {
+	    		// Save attribute entry
+	    		this.resources.setEntry(entryID, null, description);
+	return true;
+            }
+        },
+
+        handleError: {
+            value: function(msg) {
+
+	throw new Error(msg);
+	return true;
+        	}
+        },
+
+        _delegate: {
+            value: new LoadDelegate,
+            writable: true
+        },
+
+        delegate: {
+            enumerable: true,
+            get: function() {
+	return this._delegate;
+            },
+            set: function(value) {
+	this._delegate = value;
+            }
+        }
+    });
+
+
+    // Loader
+
+	var Context = function(rootObj, callback) {
 		this.rootObj = rootObj;
 		this.callback = callback;
-
 	};
 
 	var rootObj = new THREE.Object3D();
 
 	var self = this;
 
-	var loader = Object.create( ThreeGLTFLoader );
-	loader.initWithPath( url );
-	loader.load( new Context( rootObj, function( obj ) {} ), null );
+	var loader = Object.create(ThreeGLTFLoader);
+	loader.initWithPath(url);
+	loader.load(new Context(rootObj,
+    					function(obj) {
+    					}),
+    			null);
 
 	this.loader = loader;
 	this.callback = callback;
 	this.rootObj = rootObj;
 	return rootObj;
-
 };
 
 THREE.glTFLoader.prototype.callLoadedCallback = function() {
-
 	var result = {
-		scene : this.rootObj,
-		cameras : this.loader.cameras,
-		animations : this.loader.animations,
+			scene : this.rootObj,
+			cameras : this.loader.cameras,
+			animations : this.loader.animations,
 	};
 
-	this.callback( result );
-
+	this.callback(result);
 };
 
 THREE.glTFLoader.prototype.checkComplete = function() {
-
-	if ( this.meshesLoaded == this.meshesRequested
+	if (this.meshesLoaded == this.meshesRequested
 			&& this.shadersLoaded == this.shadersRequested
-			&& this.animationsLoaded == this.animationsRequested )
+			&& this.animationsLoaded == this.animationsRequested)
 	{
 
-		for ( var i = 0; i < this.pendingMeshes.length; i ++ ) {
-
-			var pending = this.pendingMeshes[ i ];
-			pending.mesh.attachToNode( pending.node );
-
+		for (var i = 0; i < this.pendingMeshes.length; i ++) {
+			var pending = this.pendingMeshes[i];
+			pending.mesh.attachToNode(pending.node);
 		}
 
-		for ( var i = 0; i < this.animationsLoaded; i ++ ) {
-
-			var animation = this.animations[ i ];
-			this.loader.buildAnimation( animation );
-
+		for (var i = 0; i < this.animationsLoaded; i ++) {
+			var animation = this.animations[i];
+			this.loader.buildAnimation(animation);
 		}
 
 		this.loader.createAnimations();
-		this.loader.createMeshAnimations( this.rootObj );
+		this.loader.createMeshAnimations(this.rootObj);
 
 		this.callLoadedCallback();
-
 	}
-
 };