Răsfoiți Sursa

Merge branch 'dev' of https://github.com/tparisi/three.js into dev

Mr.doob 11 ani în urmă
părinte
comite
25ae71ca6d

+ 1 - 0
examples/index.html

@@ -168,6 +168,7 @@
 				"webgl_loader_collada_skinning",
 				"webgl_loader_ctm",
 				"webgl_loader_ctm_materials",
+				"webgl_loader_gltf",
 				"webgl_loader_json_blender",
 				"webgl_loader_json_objconverter",
 				"webgl_loader_obj",

+ 392 - 0
examples/js/loaders/gltf/glTF-parser.js

@@ -0,0 +1,392 @@
+// Copyright (c) 2013 Fabrice Robinet
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
+//    documentation and/or other materials provided with the distribution.
+//
+//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/*
+    The Abstract Loader has two modes:
+        #1: [static] load all the JSON at once [as of now]
+        #2: [stream] stream and parse JSON progressively [not yet supported]
+
+    Whatever is the mechanism used to parse the JSON (#1 or #2),
+    The loader starts by resolving the paths to binaries and referenced json files (by replace the value of the path property with an absolute path if it was relative).
+
+    In case #1: it is guaranteed to call the concrete loader implementation methods in a order that solves the dependencies between the entries.
+    only the nodes requires an extra pass to set up the hirerarchy.
+    In case #2: the concrete implementation will have to solve the dependencies. no order is guaranteed.
+
+    When case #1 is used the followed dependency order is:
+
+    scenes -> nodes -> meshes -> materials -> techniques -> shaders
+                    -> buffers
+                    -> cameras
+                    -> lights
+
+    The readers starts with the leafs, i.e:
+        shaders, techniques, materials, meshes, buffers, cameras, lights, nodes, scenes
+
+    For each called handle method called the client should return true if the next handle can be call right after returning,
+    or false if a callback on client side will notify the loader that the next handle method can be called.
+
+*/
+var global = window;
+(function (root, factory) {
+    if (typeof exports === 'object') {
+        // Node. Does not work with strict CommonJS, but
+        // only CommonJS-like enviroments that support module.exports,
+        // like Node.
+        factory(module.exports);
+    } else if (typeof define === 'function' && define.amd) {
+        // AMD. Register as an anonymous module.
+        define([], function () {
+            return factory(root);
+        });
+    } else {
+        // Browser globals
+        factory(root);
+    }
+}(this, function (root) {
+    "use strict";
+
+    var categoriesDepsOrder = ["buffers", "bufferViews", "images",  "videos", "samplers", "textures", "shaders", "programs", "techniques", "materials", "accessors", "meshes", "cameras", "lights", "skins", "nodes", "scenes", "animations"];
+
+    var glTFParser = Object.create(Object.prototype, {
+
+        _rootDescription: { value: null, writable: true },
+
+        rootDescription: {
+            set: function(value) {
+                this._rootDescription = value;
+            },
+            get: function() {
+                return this._rootDescription;
+            }
+        },
+
+        baseURL: { value: null, writable: true },
+
+        //detect absolute path following the same protocol than window.location
+        _isAbsolutePath: {
+            value: function(path) {
+                var isAbsolutePathRegExp = new RegExp("^"+window.location.protocol, "i");
+
+                return path.match(isAbsolutePathRegExp) ? true : false;
+            }
+        },
+
+        resolvePathIfNeeded: {
+            value: function(path) {
+                if (this._isAbsolutePath(path)) {
+                    return path;
+                }
+
+                return this.baseURL + path;
+            }
+        },
+
+        _resolvePathsForCategories: {
+            value: function(categories) {
+                categories.forEach( function(category) {
+                    var descriptions = this.json[category];
+                    if (descriptions) {
+                        var descriptionKeys = Object.keys(descriptions);
+                        descriptionKeys.forEach( function(descriptionKey) {
+                            var description = descriptions[descriptionKey];
+                            description.path = this.resolvePathIfNeeded(description.path);
+                        }, this);
+                    }
+                }, this);
+            }
+        },
+
+        _json: {
+            value: null,
+            writable: true
+        },
+
+        json: {
+            enumerable: true,
+            get: function() {
+                return this._json;
+            },
+            set: function(value) {
+                if (this._json !== value) {
+                    this._json = value;
+                    this._resolvePathsForCategories(["buffers", "shaders", "images", "videos"]);
+                }
+            }
+        },
+
+        _path: {
+            value: null,
+            writable: true
+        },
+
+        getEntryDescription: {
+            value: function (entryID, entryType) {
+                var entries = null;
+
+                var category = entryType;
+                entries = this.rootDescription[category];
+                if (!entries) {
+                    console.log("ERROR:CANNOT find expected category named:"+category);
+                    return null;
+                }
+
+                return entries ? entries[entryID] : null;
+            }
+        },
+
+        _stepToNextCategory: {
+            value: function() {
+                this._state.categoryIndex = this.getNextCategoryIndex(this._state.categoryIndex + 1);
+                if (this._state.categoryIndex !== -1) {
+                    this._state.categoryState.index = 0;
+                    return true;
+                }
+
+                return false;
+            }
+        },
+
+        _stepToNextDescription: {
+            enumerable: false,
+            value: function() {
+                var categoryState = this._state.categoryState;
+                var keys = categoryState.keys;
+                if (!keys) {
+                    console.log("INCONSISTENCY ERROR");
+                    return false;
+                }
+
+                categoryState.index++;
+                categoryState.keys = null;
+                if (categoryState.index >= keys.length) {
+                    return this._stepToNextCategory();
+                }
+                return false;
+            }
+        },
+
+        hasCategory: {
+            value: function(category) {
+                return this.rootDescription[category] ? true : false;
+            }
+        },
+
+        _handleState: {
+            value: function() {
+
+                var methodForType = {
+                    "buffers" : this.handleBuffer,
+                    "bufferViews" : this.handleBufferView,
+                    "shaders" : this.handleShader,
+                    "programs" : this.handleProgram,
+                    "techniques" : this.handleTechnique,
+                    "materials" : this.handleMaterial,
+                    "meshes" : this.handleMesh,
+                    "cameras" : this.handleCamera,
+                    "lights" : this.handleLight,
+                    "nodes" : this.handleNode,
+                    "scenes" : this.handleScene,
+                    "images" : this.handleImage,
+                    "animations" : this.handleAnimation,
+                    "accessors" : this.handleAccessor,
+                    "skins" : this.handleSkin,
+                    "samplers" : this.handleSampler,
+                    "textures" : this.handleTexture,
+                    "videos" : this.handleVideo
+
+                };
+
+                var success = true;
+                while (this._state.categoryIndex !== -1) {
+                    var category = categoriesDepsOrder[this._state.categoryIndex];
+                    var categoryState = this._state.categoryState;
+                    var keys = categoryState.keys;
+                    if (!keys) {
+                        categoryState.keys = keys = Object.keys(this.rootDescription[category]);
+                        if (keys) {
+                            if (keys.length == 0) {
+                                this._stepToNextDescription();
+                                continue;
+                            }
+                        }
+                    }
+
+                    var type = category;
+                    var entryID = keys[categoryState.index];
+                    var description = this.getEntryDescription(entryID, type);
+                    if (!description) {
+                        if (this.handleError) {
+                            this.handleError("INCONSISTENCY ERROR: no description found for entry "+entryID);
+                            success = false;
+                            break;
+                        }
+                    } else {
+
+                        if (methodForType[type]) {
+                            if (methodForType[type].call(this, entryID, description, this._state.userInfo) === false) {
+                                success = false;
+                                break;
+                            }
+                        }
+
+                        this._stepToNextDescription();
+                    }
+                }
+
+                if (this.handleLoadCompleted) {
+                    this.handleLoadCompleted(success);
+                }
+
+            }
+        },
+
+        _loadJSONIfNeeded: {
+            enumerable: true,
+            value: function(callback) {
+                var self = this;
+                //FIXME: handle error
+                if (!this._json)  {
+                    var jsonPath = this._path;
+                    var i = jsonPath.lastIndexOf("/");
+                    this.baseURL = (i !== 0) ? jsonPath.substring(0, i + 1) : '';
+                    var jsonfile = new XMLHttpRequest();
+                    jsonfile.open("GET", jsonPath, true);
+                    jsonfile.onreadystatechange = function() {
+                        if (jsonfile.readyState == 4) {
+                            if (jsonfile.status == 200) {
+                                self.json = JSON.parse(jsonfile.responseText);
+                                if (callback) {
+                                    callback(self.json);
+                                }
+                            }
+                        }
+                    };
+                    jsonfile.send(null);
+               } else {
+                    if (callback) {
+                        callback(this.json);
+                    }
+                }
+            }
+        },
+
+        /* load JSON and assign it as description to the reader */
+        _buildLoader: {
+            value: function(callback) {
+                var self = this;
+                function JSONReady(json) {
+                    self.rootDescription = json;
+                    if (callback)
+                        callback(this);
+                }
+
+                this._loadJSONIfNeeded(JSONReady);
+            }
+        },
+
+        _state: { value: null, writable: true },
+
+        _getEntryType: {
+            value: function(entryID) {
+                var rootKeys = categoriesDepsOrder;
+                for (var i = 0 ;  i < rootKeys.length ; i++) {
+                    var rootValues = this.rootDescription[rootKeys[i]];
+                    if (rootValues) {
+                        return rootKeys[i];
+                    }
+                }
+                return null;
+            }
+        },
+
+        getNextCategoryIndex: {
+            value: function(currentIndex) {
+                for (var i = currentIndex ; i < categoriesDepsOrder.length ; i++) {
+                    if (this.hasCategory(categoriesDepsOrder[i])) {
+                        return i;
+                    }
+                }
+
+                return -1;
+            }
+        },
+
+        load: {
+            enumerable: true,
+            value: function(userInfo, options) {
+                var self = this;
+                this._buildLoader(function loaderReady(reader) {
+                    var startCategory = self.getNextCategoryIndex.call(self,0);
+                    if (startCategory !== -1) {
+                        self._state = { "userInfo" : userInfo,
+                                        "options" : options,
+                                        "categoryIndex" : startCategory,
+                                        "categoryState" : { "index" : "0" } };
+                        self._handleState();
+                    }
+                });
+            }
+        },
+
+        initWithPath: {
+            value: function(path) {
+                this._path = path;
+                this._json = null;
+                return this;
+            }
+        },
+
+        //this is meant to be global and common for all instances
+        _knownURLs: { writable: true, value: {} },
+
+        //to be invoked by subclass, so that ids can be ensured to not overlap
+        loaderContext: {
+            value: function() {
+                if (typeof this._knownURLs[this._path] === "undefined") {
+                    this._knownURLs[this._path] = Object.keys(this._knownURLs).length;
+                }
+                return "__" + this._knownURLs[this._path];
+            }
+        },
+
+        initWithJSON: {
+            value: function(json, baseURL) {
+                this.json = json;
+                this.baseURL = baseURL;
+                if (!baseURL) {
+                    console.log("WARNING: no base URL passed to Reader:initWithJSON");
+                }
+                return this;
+            }
+        }
+
+    });
+
+    if(root) {
+        root.glTFParser = glTFParser;
+    }
+
+    return glTFParser;
+
+}));

+ 251 - 0
examples/js/loaders/gltf/glTFAnimation.js

@@ -0,0 +1,251 @@
+/**
+ * @author Tony Parisi / http://www.tonyparisi.com/
+ */
+
+THREE.glTFAnimator = ( function () {
+
+	var animators = [];
+
+	return	{
+		add : function(animator)
+		{
+			animators.push(animator);
+		},
+
+		remove: function(animator)
+		{
+
+			var i = animators.indexOf(animator);
+
+			if ( i !== -1 ) {
+				animators.splice( i, 1 );
+			}
+		},
+
+		update : function()
+		{
+			for (i = 0; i < animators.length; i++)
+			{
+				animators[i].update();
+			}
+		},
+	};
+})();
+
+// Construction/initialization
+THREE.glTFAnimation = function(interps)
+{
+	this.running = false;
+	this.loop = false;
+	this.duration = 0;
+	this.startTime = 0;
+	this.interps = [];
+	
+	if (interps)
+	{
+		this.createInterpolators(interps);
+	}
+}
+
+THREE.glTFAnimation.prototype.createInterpolators = function(interps)
+{
+	var i, len = interps.length;
+	for (i = 0; i < len; i++)
+	{
+		var interp = new THREE.glTFInterpolator(interps[i]);
+		this.interps.push(interp);
+		this.duration = Math.max(this.duration, interp.duration);
+	}
+}
+
+// Start/stop
+THREE.glTFAnimation.prototype.play = function()
+{
+	if (this.running)
+		return;
+	
+	this.startTime = Date.now();
+	this.running = true;
+	THREE.glTFAnimator.add(this);
+}
+
+THREE.glTFAnimation.prototype.stop = function()
+{
+	this.running = false;
+	THREE.glTFAnimator.remove(this);
+}
+
+// Update - drive key frame evaluation
+THREE.glTFAnimation.prototype.update = function()
+{
+	if (!this.running)
+		return;
+	
+	var now = Date.now();
+	var deltat = (now - this.startTime) / 1000;
+	var t = deltat % this.duration;
+	var nCycles = Math.floor(deltat / this.duration);
+	
+	if (nCycles >= 1 && !this.loop)
+	{
+		this.running = false;
+		var i, len = this.interps.length;
+		for (i = 0; i < len; i++)
+		{
+			this.interps[i].interp(this.duration);
+		}
+		this.stop();
+		return;
+	}
+	else
+	{
+		var i, len = this.interps.length;
+		for (i = 0; i < len; i++)
+		{
+			this.interps[i].interp(t);
+		}
+	}
+}
+
+//Interpolator class
+//Construction/initialization
+THREE.glTFInterpolator = function(param) 
+{	    		
+	this.keys = param.keys;
+	this.values = param.values;
+	this.count = param.count;
+	this.type = param.type;
+	this.path = param.path;
+	this.isRot = false;
+	
+	var node = param.target;
+	node.updateMatrix();
+	node.matrixAutoUpdate = true;
+	this.targetNode = node;
+	
+	switch (param.path) {
+		case "translation" :
+			this.target = node.position;
+			this.originalValue = node.position.clone();
+			break;
+		case "rotation" :
+			this.target = node.quaternion;
+			this.originalValue = node.quaternion.clone();
+			this.isRot = true;
+			break;
+		case "scale" :
+			this.target = node.scale;
+			this.originalValue = node.scale.clone();
+			break;
+	}
+	
+	this.duration = this.keys[this.count - 1];
+	
+	this.vec1 = new THREE.Vector3;
+	this.vec2 = new THREE.Vector3;
+	this.vec3 = new THREE.Vector3;
+	this.quat1 = new THREE.Quaternion;
+	this.quat2 = new THREE.Quaternion;
+	this.quat3 = new THREE.Quaternion;
+}
+
+//Interpolation and tweening methods
+THREE.glTFInterpolator.prototype.interp = function(t)
+{
+	var i, j;
+	if (t == this.keys[0])
+	{
+		if (this.isRot) {
+			this.quat3.set(this.values[0], this.values[1], this.values[2], this.values[3]);
+		}
+		else {
+			this.vec3.set(this.values[0], this.values[1], this.values[2]);
+		}
+	}
+	else if (t < this.keys[0])
+	{
+		if (this.isRot) {
+			this.quat1.set(this.originalValue.x,
+					this.originalValue.y,
+					this.originalValue.z,
+					this.originalValue.w);
+			this.quat2.set(this.values[0],
+					this.values[1],
+					this.values[2],
+					this.values[3]);
+			THREE.Quaternion.slerp(this.quat1, this.quat2, this.quat3, t / this.keys[0]);
+		}
+		else {
+			this.vec3.set(this.originalValue.x,
+					this.originalValue.y,
+					this.originalValue.z);
+			this.vec2.set(this.values[0],
+					this.values[1],
+					this.values[2]);
+
+			this.vec3.lerp(this.vec2, t / this.keys[0]);
+		}
+	}
+	else if (t >= this.keys[this.count - 1])
+	{
+		if (this.isRot) {
+			this.quat3.set(this.values[(this.count - 1) * 4], 
+					this.values[(this.count - 1) * 4 + 1],
+					this.values[(this.count - 1) * 4 + 2],
+					this.values[(this.count - 1) * 4 + 3]);
+		}
+		else {
+			this.vec3.set(this.values[(this.count - 1) * 3], 
+					this.values[(this.count - 1) * 3 + 1],
+					this.values[(this.count - 1) * 3 + 2]);
+		}
+	}
+	else
+	{
+		for (i = 0; i < this.count - 1; i++)
+		{
+			var key1 = this.keys[i];
+			var key2 = this.keys[i + 1];
+	
+			if (t >= key1 && t <= key2)
+			{
+				if (this.isRot) {
+					this.quat1.set(this.values[i * 4],
+							this.values[i * 4 + 1],
+							this.values[i * 4 + 2],
+							this.values[i * 4 + 3]);
+					this.quat2.set(this.values[(i + 1) * 4],
+							this.values[(i + 1) * 4 + 1],
+							this.values[(i + 1) * 4 + 2],
+							this.values[(i + 1) * 4 + 3]);
+					THREE.Quaternion.slerp(this.quat1, this.quat2, this.quat3, (t - key1) / (key2 - key1));
+				}
+				else {
+					this.vec3.set(this.values[i * 3],
+							this.values[i * 3 + 1],
+							this.values[i * 3 + 2]);
+					this.vec2.set(this.values[(i + 1) * 3],
+							this.values[(i + 1) * 3 + 1],
+							this.values[(i + 1) * 3 + 2]);
+	
+					this.vec3.lerp(this.vec2, (t - key1) / (key2 - key1));
+				}
+			}
+		}
+	}
+	
+	if (this.target)
+	{
+		this.copyValue(this.target);
+	}
+}
+
+THREE.glTFInterpolator.prototype.copyValue = function(target) {
+	
+	if (this.isRot) {
+		target.copy(this.quat3);
+	}
+	else {
+		target.copy(this.vec3);
+	}		
+}

+ 1643 - 0
examples/js/loaders/gltf/glTFLoader.js

@@ -0,0 +1,1643 @@
+/**
+ * @author Tony Parisi / http://www.tonyparisi.com/
+ */
+
+
+THREE.glTFLoader = function (showStatus) {
+	this.useBufferGeometry = (THREE.glTFLoader.useBufferGeometry !== undefined ) ?
+			THREE.glTFLoader.useBufferGeometry : true;
+    this.meshesRequested = 0;
+    this.meshesLoaded = 0;
+    this.pendingMeshes = [];
+    this.animationsRequested = 0;
+    this.animationsLoaded = 0;
+    this.animations = [];
+    this.shadersRequested = 0;
+    this.shadersLoaded = 0;
+    this.shaders = {};
+    THREE.Loader.call( this, showStatus );
+}
+
+THREE.glTFLoader.prototype = new THREE.Loader();
+THREE.glTFLoader.prototype.constructor = THREE.glTFLoader;
+
+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),
+            a = 255;
+
+        var color = (a << 24) + (r << 16) + (g << 8) + b;
+
+        return color;
+    }
+    
+    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;
+    	}
+    }
+
+    function componentsPerElementForGLType(glType) {
+        switch (glType) {
+            case WebGLRenderingContext.FLOAT :
+            case WebGLRenderingContext.UNSIGNED_BYTE :
+            case WebGLRenderingContext.UNSIGNED_SHORT :
+                return 1;
+            case WebGLRenderingContext.FLOAT_VEC2 :
+                return 2;
+            case WebGLRenderingContext.FLOAT_VEC3 :
+                return 3;
+            case WebGLRenderingContext.FLOAT_VEC4 :
+                return 4;
+            case WebGLRenderingContext.FLOAT_MAT4 :
+                return 16;
+            default:
+                return null;
+        }
+    }
+
+
+    function LoadTexture(src) {
+        if(!src) { return null; }
+        return THREE.ImageUtils.loadTexture(src);
+    }
+
+    // Geometry processing
+
+    var ClassicGeometry = function() {
+
+    	if (theLoader.useBufferGeometry) {
+    		this.geometry = new THREE.BufferGeometry;
+    	}
+    	else {
+    		this.geometry = new THREE.Geometry;
+    	}
+        this.totalAttributes = 0;
+        this.loadedAttributes = 0;
+        this.indicesLoaded = false;
+        this.finished = false;
+
+        this.onload = null;
+
+        this.uvs = null;
+        this.indexArray = null;
+    };
+
+    ClassicGeometry.prototype.constructor = ClassicGeometry;
+
+    ClassicGeometry.prototype.buildArrayGeometry = function() {
+
+    	// Build indexed mesh
+        var geometry = this.geometry;
+        var normals = geometry.normals;
+        var indexArray = this.indexArray;
+        var uvs = this.uvs;
+        var a, b, c;
+        var i, l;
+        var faceNormals = null;
+        var faceTexcoords = null;
+        
+        for(i = 0, l = this.indexArray.length; i < l; i += 3) {
+            a = indexArray[i];
+            b = indexArray[i+1];
+            c = indexArray[i+2];
+            if(normals) {
+                faceNormals = [normals[a], normals[b], normals[c]];
+            }
+            geometry.faces.push( new THREE.Face3( a, b, c, faceNormals, null, null ) );
+            if(uvs) {
+                geometry.faceVertexUvs[0].push([ uvs[a], uvs[b], uvs[c] ]);
+            }
+        }
+
+        // Allow Three.js to calculate some values for us
+        geometry.computeBoundingBox();
+        geometry.computeBoundingSphere();
+        geometry.computeCentroids();
+        geometry.computeFaceNormals();
+        if(!normals) {
+            geometry.computeVertexNormals();
+        }
+
+    }
+
+    ClassicGeometry.prototype.buildBufferGeometry = function() {
+        // Build indexed mesh
+        var geometry = this.geometry;
+        geometry.attributes.index = {
+        		itemSize: 1,
+        		array : this.indexArray
+        };
+
+		var offset = {
+				start: 0,
+				index: 0,
+				count: this.indexArray.length
+			};
+
+		geometry.offsets.push( offset );
+
+        geometry.computeBoundingSphere();
+    }
+    
+    ClassicGeometry.prototype.checkFinished = function() {
+        if(this.indexArray && this.loadedAttributes === this.totalAttributes) {
+        	
+        	if (theLoader.useBufferGeometry) {
+        		this.buildBufferGeometry();
+        	}
+        	else {
+        		this.buildArrayGeometry();
+        	}
+        	
+            this.finished = true;
+
+            if(this.onload) {
+                this.onload();
+            }
+        }
+    };
+
+    // 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.convert = function(resource, ctx) {
+        return new Uint16Array(resource, 0, ctx.indices.count);
+    };
+
+    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) {
+        this.indices = indices;
+        this.geometry = geometry;
+    };
+    
+    // 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.convert = function(resource, ctx) {
+        return resource;
+    };
+
+
+
+    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] ) );
+            }
+        } 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] ) );
+            }
+        } 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] ) );
+            }
+        }
+    }
+    
+    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") {
+            // TODO: Should be easy to take strides into account here
+            floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type));
+            geom.geometry.attributes.position = {
+            		itemSize: 3,
+            		array : floatArray
+            };
+        } else if(semantic == "NORMAL") {
+            floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type));
+            geom.geometry.attributes.normal = {
+            		itemSize: 3,
+            		array : floatArray
+            };
+        } 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];
+            }
+            geom.geometry.attributes.uv = {
+            		itemSize: nComponents,
+            		array : floatArray
+            };
+        }
+        else if (semantic == "WEIGHT") {
+        	nComponents = componentsPerElementForGLType(attribute.type);
+            floatArray = new Float32Array(glResource, 0, attribute.count * nComponents);
+            geom.geometry.attributes.skinWeight = {
+            		itemSize: nComponents,
+            		array : floatArray
+            };        	
+        }
+        else if (semantic == "JOINT") {
+        	nComponents = componentsPerElementForGLType(attribute.type);
+            floatArray = new Float32Array(glResource, 0, attribute.count * nComponents);
+            geom.geometry.attributes.skinIndex = {
+            		itemSize: nComponents,
+            		array : floatArray
+            };        	
+        }
+    }
+    
+    VertexAttributeDelegate.prototype.resourceAvailable = function(glResource, ctx) {
+    	if (theLoader.useBufferGeometry) {
+    		this.bufferResourceAvailable(glResource, ctx);
+    	}
+    	else {
+    		this.arrayResourceAvailable(glResource, ctx);
+    	}
+    	
+        var geom = ctx.geometry;
+        geom.loadedAttributes++;
+        geom.checkFinished();
+        return true;
+    };
+
+    var vertexAttributeDelegate = new VertexAttributeDelegate();
+
+    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) {
+        
+    	var self = this;
+        geometry.onload = function() {
+            self.loadedGeometry++;
+            self.checkComplete();
+        };
+        
+        this.primitives.push({
+            geometry: geometry,
+            material: material,
+            mesh: null
+        });
+    };
+
+    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);
+            });
+            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);
+            }*/
+        	var material = primitive.material;
+        	if (!(material instanceof THREE.Material)) {
+        		material = theLoader.createShaderMaterial(material);
+        	}
+
+        	var threeMesh = new THREE.Mesh(primitive.geometry.geometry, material);
+            threeMesh.castShadow = true;
+            threeNode.add(threeMesh);
+        });
+    };
+
+    // Delayed-loaded material
+    var Material = function(params) {
+    	this.params = params;
+    };
+    
+    // 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.convert = function(resource, ctx) {
+    	var parameter = ctx.parameter;
+
+    	var glResource = null;
+    	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));
+	        	break;
+	        default:
+	        	break;
+    	}
+    	
+        return glResource;
+    };
+
+    AnimationParameterDelegate.prototype.resourceAvailable = function(glResource, ctx) {
+    	var animation = ctx.animation;
+    	var parameter = ctx.parameter;
+    	parameter.data = glResource;
+    	animation.handleParameterLoaded(parameter);
+        return true;
+    };
+
+    var animationParameterDelegate = new AnimationParameterDelegate();
+
+    var AnimationParameterContext = function(parameter, animation) {
+        this.parameter = parameter;
+        this.animation = animation;
+    };
+
+    // Animations
+    var Animation = function() {
+
+    	// create Three.js keyframe here
+        this.totalParameters = 0;
+        this.loadedParameters = 0;
+        this.parameters = {};
+        this.finishedLoading = false;
+        this.onload = null;
+
+    };
+
+    Animation.prototype.constructor = Animation;
+
+    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
+            this.finishedLoading = true;
+
+            if (this.onload) {
+                this.onload();
+            }
+        }
+    };
+    
+    // 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.convert = function(resource, ctx) {
+    	var parameter = ctx.parameter;
+
+    	var glResource = null;
+    	switch (parameter.type) {
+	        case WebGLRenderingContext.FLOAT_MAT4 :
+	        	glResource = new Float32Array(resource, 0, parameter.count * componentsPerElementForGLType(parameter.type));
+	        	break;
+	        default:
+	        	break;
+    	}
+    	
+        return glResource;
+    };
+
+    InverseBindMatricesDelegate.prototype.resourceAvailable = function(glResource, ctx) {
+    	var skin = ctx.skin;
+    	skin.inverseBindMatrices = glResource;
+        return true;
+    };
+
+    var inverseBindMatricesDelegate = new InverseBindMatricesDelegate();
+
+    var InverseBindMatricesContext = function(param, skin) {
+    	this.parameter = param;
+        this.skin = skin;
+    };
+
+    // 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.convert = function(resource, ctx) {
+    	return resource; 
+    }
+    
+    ShaderDelegate.prototype.resourceAvailable = function(data, ctx) {
+        theLoader.shadersLoaded++;
+        theLoader.shaders[ctx.id] = data;
+        return true;
+    };
+
+    var shaderDelegate = new ShaderDelegate();
+
+    var ShaderContext = function(id, path) {
+    	this.id = id;
+    	this.path = path;
+    };
+    
+    // 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);
+            return;
+        }
+
+        if (this._entries[entryID]) {
+            console.warn("entry["+entryID+"] is being overwritten");
+        }
+    
+        this._entries[entryID] = new ResourceEntry(entryID, object, description );
+    };
+    
+    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);
+    }
+    
+    // Loader
+
+    var ThreeGLTFLoader = Object.create(glTFParser, {
+
+        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;
+        		}
+        		
+        		var uniforms = {};
+        		var shaderMaterial = new THREE.ShaderMaterial( {
+
+        			fragmentShader: fragmentShader,
+        			vertexShader: vertexShader,
+        			uniforms: uniforms,
+
+        		} );
+
+        		return new THREE.MeshPhongMaterial(material.params);
+        	}
+        },
+        
+        createShaderParams : {
+        	value: function(materialId, values, params, instanceProgram) {
+				var program = this.resources.getEntry(instanceProgram.program);
+				
+				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) {
+        				
+        				var instanceProgram = defaultPass.instanceProgram;
+
+    					this.createShaderParams(materialId, values, params, instanceProgram);
+    					
+    					var loadshaders = true;
+    					
+    					if (loadshaders) {
+    						materialType = Material;
+    					}
+        			}
+        		}
+        		
+                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) {
+                	
+                	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;
+                	
+                    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;
+                        		}
+                        	}
+                        }
+                    }                    
+                }
+
+                var texture = LoadTexture(envMapPath);
+                if (texture && envMapParams) {
+                	
+                	if (envMapParams.wrapS == WebGLRenderingContext.REPEAT)
+                		texture.wrapS = THREE.RepeatWrapping;
+
+                	if (envMapParams.wrapT == WebGLRenderingContext.REPEAT)
+                		texture.wrapT = THREE.RepeatWrapping;
+                	
+                	if (envMapParams.magFilter == WebGLRenderingContext.LINEAR)
+                		texture.magFilter = THREE.LinearFilter;
+
+//                	if (envMapParams.minFilter == WebGLRenderingContext.LINEAR)
+//               		texture.minFilter = THREE.LinearFilter;
+                	
+                    params.envMap = texture;
+                }
+                
+                var shininess = values.shininesss || values.shininess; // N.B.: typo in converter!
+                if (shininess)
+                {
+                	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.ambient === undefined) && !(typeof(values.ambient) == 'string'))
+                {
+                	params.ambient = RgbArraytoHex(values.ambient);
+                }
+
+                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.matrixAutoUpdate = false;
+                    threeNode.applyMatrix(new THREE.Matrix4(
+                        m[0],  m[4],  m[8],  m[12],
+                        m[1],  m[5],  m[9],  m[13],
+                        m[2],  m[6],  m[10], m[14],
+                        m[3],  m[7],  m[11], m[15]
+                    ));                    
+                }
+                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.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 joints = [];
+        	                            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;
+        	                                    joints.push(joint);
+        	                                    threeMesh.bones.push(joint);
+        	                                    
+        	                                    var m = skin.inverseBindMatrices;
+        	                    	            var mat = new THREE.Matrix4(
+        	                                            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]
+        	                                        );
+        	                                    threeMesh.boneInverses.push(mat);
+        	                                    threeMesh.pose();
+        	                                    
+        	                                } else {
+        	                                    console.log("WARNING: jointId:"+jointId+" cannot be found in skeleton:"+skeleton);
+        	                                }
+        	                            }
+                                    }
+                                    
+                                    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);
+                    }*/
+                }, 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(
+                        m[0],  m[4],  m[8],  m[12],
+                        m[1],  m[5],  m[9],  m[13],
+                        m[2],  m[6],  m[10], m[14],
+                        m[3],  m[7],  m[11], m[15]
+                    );
+	            
+	            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);
+
+    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,
+	};
+	
+	this.callback(result);
+}
+
+THREE.glTFLoader.prototype.checkComplete = function() {
+	if (this.meshesLoaded == this.meshesRequested 
+			&& this.shadersLoaded == this.shadersRequested
+			&& 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.animationsLoaded; i++) {
+			var animation = this.animations[i];
+			this.loader.buildAnimation(animation);
+		}
+
+		this.loader.createAnimations();
+		this.loader.createMeshAnimations(this.rootObj);
+        
+		this.callLoadedCallback();
+	}
+}
+
+
+

+ 223 - 0
examples/js/loaders/gltf/glTFLoaderUtils.js

@@ -0,0 +1,223 @@
+/**
+ * @author Tony Parisi / http://www.tonyparisi.com/
+ */
+
+THREE.GLTFLoaderUtils = Object.create(Object, {
+
+    // errors
+    MISSING_DESCRIPTION: { value: "MISSING_DESCRIPTION" },
+    INVALID_PATH: { value: "INVALID_PATH" },
+    INVALID_TYPE: { value: "INVALID_TYPE" },
+    XMLHTTPREQUEST_STATUS_ERROR: { value: "XMLHTTPREQUEST_STATUS_ERROR" },
+    NOT_FOUND: { value: "NOT_FOUND" },
+    // misc constants
+    ARRAY_BUFFER: { value: "ArrayBuffer" },
+
+    _streams : { value:{}, writable: true },
+
+    _streamsStatus: { value: {}, writable: true },
+    
+    _resources: { value: {}, writable: true },
+
+    _resourcesStatus: { value: {}, writable: true },
+
+    // initialization
+    init: {
+        value: function() {
+	        this._streams = {};
+	        this._streamsStatus = {};
+            this._resources = {};
+            this._resourcesStatus = {};
+        }
+    },
+
+    //manage entries
+    _containsResource: {
+        enumerable: false,
+        value: function(resourceID) {
+            return this._resources[resourceID] ? true : false;
+        }
+    },
+
+    _storeResource: {
+        enumerable: false,
+        value: function(resourceID, resource) {
+            if (!resourceID) {
+                console.log("ERROR: entry does not contain id, cannot store");
+                return;
+            }
+
+            if (this._containsResource[resourceID]) {
+                console.log("WARNING: resource:"+resourceID+" is already stored, overriding");
+            }
+
+           this._resources[resourceID] = resource;
+        }
+    },
+
+    _getResource: {
+        enumerable: false,
+        value: function(resourceID) {
+            return this._resources[resourceID];
+        }
+    },
+
+    _loadStream: {
+        value: function(path, type, delegate) {
+            var self = this;
+
+            if (!type) {
+                delegate.handleError(THREE.GLTFLoaderUtils.INVALID_TYPE, null);
+                return;
+            }
+
+            if (!path) {
+                delegate.handleError(THREE.GLTFLoaderUtils.INVALID_PATH);
+                return;
+            }
+
+            var xhr = new XMLHttpRequest();
+            xhr.open('GET', path, true);
+            xhr.responseType = (type === this.ARRAY_BUFFER) ? "arraybuffer" : "text";
+
+            //if this is not specified, 1 "big blob" scenes fails to load.
+            xhr.setRequestHeader("If-Modified-Since", "Sat, 01 Jan 1970 00:00:00 GMT");
+            xhr.onload = function(e) {
+                if ((xhr.status == 200) || (xhr.status == 206)) {
+
+                    delegate.streamAvailable(path, xhr.response);
+
+                } else {
+                    delegate.handleError(THREE.GLTFLoaderUtils.XMLHTTPREQUEST_STATUS_ERROR, this.status);
+                }
+            };
+            xhr.send(null);
+        }
+    },
+
+    send: { value: 0, writable: true },
+    requested: { value: 0, writable: true },
+
+    _handleRequest: {
+        value: function(request) {
+            var resourceStatus = this._resourcesStatus[request.id];
+            if (resourceStatus)
+            {
+            	this._resourcesStatus[request.id]++;
+            }
+            else
+            {
+            	this._resourcesStatus[request.id] = 1;
+            }
+            
+            var streamStatus = this._streamsStatus[request.path];
+            if (streamStatus && streamStatus.status === "loading" )
+            {
+            	streamStatus.requests.push(request);
+                return;
+            }
+            
+            this._streamsStatus[request.path] = { status : "loading", requests : [request] };
+    		
+            var self = this;
+            var processResourceDelegate = {};
+
+            processResourceDelegate.streamAvailable = function(path, res_) {
+            	var streamStatus = self._streamsStatus[path];
+            	var requests = streamStatus.requests;
+                requests.forEach( function(req_) {
+                    var subArray = res_.slice(req_.range[0], req_.range[1]);
+                    var convertedResource = req_.delegate.convert(subArray, req_.ctx);
+                    self._storeResource(req_.id, convertedResource);
+                    req_.delegate.resourceAvailable(convertedResource, req_.ctx);
+                    --self._resourcesStatus[req_.id];
+
+                }, this);
+            	
+                delete self._streamsStatus[path];
+
+            };
+
+            processResourceDelegate.handleError = function(errorCode, info) {
+                request.delegate.handleError(errorCode, info);
+            }
+
+            this._loadStream(request.path, request.type, processResourceDelegate);
+        }
+    },
+
+
+    _elementSizeForGLType: {
+        value: function(glType) {
+            switch (glType) {
+                case WebGLRenderingContext.FLOAT :
+                    return Float32Array.BYTES_PER_ELEMENT;
+                case WebGLRenderingContext.UNSIGNED_BYTE :
+                    return Uint8Array.BYTES_PER_ELEMENT;
+                case WebGLRenderingContext.UNSIGNED_SHORT :
+                    return Uint16Array.BYTES_PER_ELEMENT;
+                case WebGLRenderingContext.FLOAT_VEC2 :
+                    return Float32Array.BYTES_PER_ELEMENT * 2;
+                case WebGLRenderingContext.FLOAT_VEC3 :
+                    return Float32Array.BYTES_PER_ELEMENT * 3;
+                case WebGLRenderingContext.FLOAT_VEC4 :
+                    return Float32Array.BYTES_PER_ELEMENT * 4;
+                case WebGLRenderingContext.FLOAT_MAT3 :
+                    return Float32Array.BYTES_PER_ELEMENT * 9;
+                case WebGLRenderingContext.FLOAT_MAT4 :
+                    return Float32Array.BYTES_PER_ELEMENT * 16;
+                default:
+                    return null;
+            }
+        }
+    },
+
+    _handleWrappedBufferViewResourceLoading: {
+        value: function(wrappedBufferView, delegate, ctx) {
+            var bufferView = wrappedBufferView.bufferView;
+            var buffer = bufferView.buffer;
+            var byteOffset = wrappedBufferView.byteOffset + bufferView.description.byteOffset;
+            var range = [byteOffset , (this._elementSizeForGLType(wrappedBufferView.type) * wrappedBufferView.count) + byteOffset];
+
+            this._handleRequest({   "id" : wrappedBufferView.id,
+                                    "range" : range,
+                                    "type" : buffer.description.type,
+                                    "path" : buffer.description.path,
+                                    "delegate" : delegate,
+                                    "ctx" : ctx }, null);
+        }
+    },
+    
+    getBuffer: {
+    	
+            value: function(wrappedBufferView, delegate, ctx) {
+
+            var savedBuffer = this._getResource(wrappedBufferView.id);
+            if (savedBuffer) {
+                return savedBuffer;
+            } else {
+                this._handleWrappedBufferViewResourceLoading(wrappedBufferView, delegate, ctx);
+            }
+
+            return null;
+        }
+    },
+
+    getFile: {
+    	
+        value: function(request, delegate, ctx) {
+
+    		request.delegate = delegate;
+    		request.ctx = ctx;
+
+            this._handleRequest({   "id" : request.id,
+                "path" : request.path,
+                "range" : [0],
+                "type" : "text",
+                "delegate" : delegate,
+                "ctx" : ctx }, null);
+    	
+            return null;
+	    }
+	},    
+});

+ 13 - 0
examples/models/gltf/duck/README.txt

@@ -0,0 +1,13 @@
+---UPDATED 2/21/2007

+Scaled down the duck to a more reasonable size, removed physics scene, removed extra "dummy" transforms and pivot points, added camera and light.

+---

+

+This model is a typical bathtub rubber duck.  It uses a single texture.

+

+One version uses a polylist the other is triangles only.

+

+The model has been stripped of all <extra> tags and should be COLLADA 1.4.1 compliant.

+

+For additional information post messages on www.collada.org or mail [email protected]

+

+These models are Copyright 2006 Sony Computer Entertainment Inc. and are distributed under the terms of the SCEA Shared Source License, available at http://research.scea.com/scea_shared_source_license.html

BIN
examples/models/gltf/duck/duck.bin


Fișier diff suprimat deoarece este prea mare
+ 122 - 0
examples/models/gltf/duck/duck.dae


+ 397 - 0
examples/models/gltf/duck/duck.json

@@ -0,0 +1,397 @@
+{
+    "accessors": {
+        "attribute_23": {
+            "bufferView": "bufferView_29",
+            "byteOffset": 0,
+            "byteStride": 12,
+            "count": 2399,
+            "max": [
+                96.1799,
+                163.97,
+                53.9252
+            ],
+            "min": [
+                -69.2985,
+                9.92937,
+                -61.3282
+            ],
+            "type": 35665
+        },
+        "attribute_25": {
+            "bufferView": "bufferView_29",
+            "byteOffset": 28788,
+            "byteStride": 12,
+            "count": 2399,
+            "max": [
+                0.999599,
+                0.999581,
+                0.998436
+            ],
+            "min": [
+                -0.999084,
+                -1,
+                -0.999832
+            ],
+            "type": 35665
+        },
+        "attribute_27": {
+            "bufferView": "bufferView_29",
+            "byteOffset": 57576,
+            "byteStride": 8,
+            "count": 2399,
+            "max": [
+                0.983346,
+                0.980037
+            ],
+            "min": [
+                0.026409,
+                0.019963
+            ],
+            "type": 35664
+        },
+        "indices_21": {
+            "bufferView": "bufferView_30",
+            "byteOffset": 0,
+            "count": 12636,
+            "type": 5123
+        }
+    },
+    "animations": {},
+    "asset": {
+        "generator": "collada2gltf@75061f683116dc0ffdad48f33c226e933132e98c"
+    },
+    "bufferViews": {
+        "bufferView_29": {
+            "buffer": "duck",
+            "byteLength": 76768,
+            "byteOffset": 0,
+            "target": 34962
+        },
+        "bufferView_30": {
+            "buffer": "duck",
+            "byteLength": 25272,
+            "byteOffset": 76768,
+            "target": 34963
+        },
+        "bufferView_31": {
+            "buffer": "duck",
+            "byteLength": 0,
+            "byteOffset": 102040
+        }
+    },
+    "buffers": {
+        "duck": {
+            "byteLength": 102040,
+            "path": "duck.bin",
+            "type": "arraybuffer"
+        }
+    },
+    "cameras": {
+        "camera_0": {
+            "perspective": {
+                "aspect_ratio": 1.5,
+                "yfov": 37.8492,
+                "zfar": 10000,
+                "znear": 1
+            },
+            "type": "perspective"
+        }
+    },
+    "images": {
+        "image_0": {
+            "path": "duckCM.png"
+        }
+    },
+    "lights": {
+        "directionalLightShape1-lib": {
+            "directional": {
+                "color": [
+                    1,
+                    1,
+                    1
+                ]
+            },
+            "type": "directional"
+        }
+    },
+    "materials": {
+        "blinn3-fx": {
+            "instanceTechnique": {
+                "technique": "technique1",
+                "values": {
+                    "ambient": [
+                        0,
+                        0,
+                        0,
+                        1
+                    ],
+                    "diffuse": "texture_image_0",
+                    "emission": [
+                        0,
+                        0,
+                        0,
+                        1
+                    ],
+                    "shininess": 38.4,
+                    "specular": [
+                        0,
+                        0,
+                        0,
+                        1
+                    ]
+                }
+            },
+            "name": "blinn3"
+        }
+    },
+    "meshes": {
+        "LOD3spShape-lib": {
+            "name": "LOD3spShape",
+            "primitives": [
+                {
+                    "attributes": {
+                        "NORMAL": "attribute_25",
+                        "POSITION": "attribute_23",
+                        "TEXCOORD_0": "attribute_27"
+                    },
+                    "indices": "indices_21",
+                    "material": "blinn3-fx",
+                    "primitive": 4
+                }
+            ]
+        }
+    },
+    "nodes": {
+        "LOD3sp": {
+            "children": [],
+            "matrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1
+            ],
+            "meshes": [
+                "LOD3spShape-lib"
+            ],
+            "name": "LOD3sp"
+        },
+        "camera1": {
+            "camera": "camera_0",
+            "children": [],
+            "matrix": [
+                -0.728969,
+                0,
+                -0.684547,
+                0,
+                -0.425205,
+                0.783693,
+                0.452797,
+                0,
+                0.536475,
+                0.621148,
+                -0.571288,
+                0,
+                400.113,
+                463.264,
+                -431.078,
+                1
+            ],
+            "name": "camera1"
+        },
+        "directionalLight1": {
+            "children": [],
+            "light": "directionalLightShape1-lib",
+            "matrix": [
+                -0.954692,
+                0.218143,
+                -0.202428,
+                0,
+                0.0146721,
+                0.713885,
+                0.700109,
+                0,
+                0.297235,
+                0.665418,
+                -0.684741,
+                0,
+                148.654,
+                183.672,
+                -292.179,
+                1
+            ],
+            "name": "directionalLight1"
+        }
+    },
+    "profile": "WebGL 1.0.2",
+    "programs": {
+        "program_0": {
+            "attributes": [
+                "a_normal",
+                "a_position",
+                "a_texcoord0"
+            ],
+            "fragmentShader": "duck0FS",
+            "vertexShader": "duck0VS"
+        }
+    },
+    "samplers": {
+        "sampler_0": {
+            "magFilter": 9729,
+            "minFilter": 9987,
+            "wrapS": 10497,
+            "wrapT": 10497
+        }
+    },
+    "scene": "defaultScene",
+    "scenes": {
+        "defaultScene": {
+            "nodes": [
+                "LOD3sp",
+                "camera1",
+                "directionalLight1"
+            ]
+        }
+    },
+    "shaders": {
+        "duck0FS": {
+            "path": "duck0FS.glsl"
+        },
+        "duck0VS": {
+            "path": "duck0VS.glsl"
+        }
+    },
+    "skins": {},
+    "techniques": {
+        "technique1": {
+            "parameters": {
+                "ambient": {
+                    "type": 35666
+                },
+                "diffuse": {
+                    "type": 35678
+                },
+                "emission": {
+                    "type": 35666
+                },
+                "light0Color": {
+                    "type": 35665,
+                    "value": [
+                        1,
+                        1,
+                        1
+                    ]
+                },
+                "light0Transform": {
+                    "source": "directionalLight1",
+                    "type": 35676
+                },
+                "modelViewMatrix": {
+                    "semantic": "MODELVIEW",
+                    "type": 35676
+                },
+                "normal": {
+                    "semantic": "NORMAL",
+                    "type": 35665
+                },
+                "normalMatrix": {
+                    "semantic": "MODELVIEWINVERSETRANSPOSE",
+                    "type": 35675
+                },
+                "position": {
+                    "semantic": "POSITION",
+                    "type": 35665
+                },
+                "projectionMatrix": {
+                    "semantic": "PROJECTION",
+                    "type": 35676
+                },
+                "shininess": {
+                    "type": 5126
+                },
+                "specular": {
+                    "type": 35666
+                },
+                "texcoord0": {
+                    "semantic": "TEXCOORD_0",
+                    "type": 35664
+                }
+            },
+            "pass": "defaultPass",
+            "passes": {
+                "defaultPass": {
+                    "details": {
+                        "commonProfile": {
+                            "extras": {
+                                "doubleSided": false
+                            },
+                            "lightingModel": "Blinn",
+                            "parameters": [
+                                "ambient",
+                                "diffuse",
+                                "emission",
+                                "light0Color",
+                                "light0Transform",
+                                "modelViewMatrix",
+                                "normalMatrix",
+                                "projectionMatrix",
+                                "shininess",
+                                "specular"
+                            ],
+                            "texcoordBindings": {
+                                "diffuse": "TEXCOORD_0"
+                            }
+                        },
+                        "type": "COLLADA-1.4.1/commonProfile"
+                    },
+                    "instanceProgram": {
+                        "attributes": {
+                            "a_normal": "normal",
+                            "a_position": "position",
+                            "a_texcoord0": "texcoord0"
+                        },
+                        "program": "program_0",
+                        "uniforms": {
+                            "u_ambient": "ambient",
+                            "u_diffuse": "diffuse",
+                            "u_emission": "emission",
+                            "u_light0Color": "light0Color",
+                            "u_light0Transform": "light0Transform",
+                            "u_modelViewMatrix": "modelViewMatrix",
+                            "u_normalMatrix": "normalMatrix",
+                            "u_projectionMatrix": "projectionMatrix",
+                            "u_shininess": "shininess",
+                            "u_specular": "specular"
+                        }
+                    },
+                    "states": {
+                        "blendEnable": 0,
+                        "cullFaceEnable": 1,
+                        "depthMask": 1,
+                        "depthTestEnable": 1
+                    }
+                }
+            }
+        }
+    },
+    "textures": {
+        "texture_image_0": {
+            "format": 6408,
+            "internalFormat": 6408,
+            "sampler": "sampler_0",
+            "source": "image_0",
+            "target": 3553
+        }
+    }
+}

+ 41 - 0
examples/models/gltf/duck/duck0FS.glsl

@@ -0,0 +1,41 @@
+precision highp float;
+varying vec3 v_normal;
+uniform vec3 u_light0Color;
+varying vec3 v_light0Direction;
+uniform float u_shininess;
+uniform vec4 u_ambient;
+varying vec2 v_texcoord0;
+uniform sampler2D u_diffuse;
+uniform vec4 u_emission;
+uniform vec4 u_specular;
+void main(void) {
+vec3 normal = normalize(v_normal);
+vec4 color = vec4(0., 0., 0., 0.);
+vec4 diffuse = vec4(0., 0., 0., 1.);
+vec3 diffuseLight = vec3(0., 0., 0.);
+vec4 emission;
+vec4 ambient;
+vec4 specular;
+vec3 specularLight = vec3(0., 0., 0.);
+{
+float diffuseIntensity;
+float specularIntensity;
+vec3 l = normalize(v_light0Direction);
+vec3 h = normalize(l+vec3(0.,0.,1.));
+diffuseIntensity = max(dot(normal,l), 0.);
+specularIntensity = pow(max(0.0,dot(normal,h)),u_shininess);
+specularLight += u_light0Color * specularIntensity;
+diffuseLight += u_light0Color * diffuseIntensity;
+}
+ambient = u_ambient;
+diffuse = texture2D(u_diffuse, v_texcoord0);
+emission = u_emission;
+specular = u_specular;
+specular.xyz *= specularLight;
+color.xyz += specular.xyz;
+diffuse.xyz *= diffuseLight;
+color.xyz += diffuse.xyz;
+color.xyz += emission.xyz;
+color = vec4(color.rgb * diffuse.a, diffuse.a);
+gl_FragColor = color;
+}

+ 18 - 0
examples/models/gltf/duck/duck0VS.glsl

@@ -0,0 +1,18 @@
+precision highp float;
+attribute vec3 a_position;
+attribute vec3 a_normal;
+varying vec3 v_normal;
+uniform mat3 u_normalMatrix;
+uniform mat4 u_modelViewMatrix;
+uniform mat4 u_projectionMatrix;
+uniform mat4 u_light0Transform;
+varying vec3 v_light0Direction;
+attribute vec2 a_texcoord0;
+varying vec2 v_texcoord0;
+void main(void) {
+vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);
+v_normal = normalize(u_normalMatrix * a_normal);
+v_light0Direction = normalize(mat3(u_light0Transform) * vec3(0.,0.,1.));
+v_texcoord0 = a_texcoord0;
+gl_Position = u_projectionMatrix * pos;
+}

BIN
examples/models/gltf/duck/duckCM.png


BIN
examples/models/gltf/monster/monster.bin


Fișier diff suprimat deoarece este prea mare
+ 64 - 0
examples/models/gltf/monster/monster.dae


BIN
examples/models/gltf/monster/monster.jpg


+ 3587 - 0
examples/models/gltf/monster/monster.json

@@ -0,0 +1,3587 @@
+{
+    "accessors": {
+        "accessor_10": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 3112,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_100": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 110576,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_101": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 111788,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_102": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 12808,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_103": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 113404,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_104": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 114616,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_105": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 115828,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_106": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 13212,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_107": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 117444,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_108": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 118656,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_109": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 119868,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_11": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 20484,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_110": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 13616,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_111": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 121484,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_112": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 122696,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_113": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 123908,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_114": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 14020,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_115": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 125524,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_116": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 126736,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_117": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 127948,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_118": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 14424,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_119": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 129564,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_12": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 21696,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_120": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 130776,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_121": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 131988,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_122": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 14828,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_123": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 133604,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_124": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 134816,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_125": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 136028,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_126": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 15232,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_127": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 137644,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_128": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 138856,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_129": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 140068,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_13": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 22908,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_130": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 15636,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_131": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 141684,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_132": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 142896,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_133": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 144108,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_14": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 3516,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_15": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 24524,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_16": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 25736,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_17": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 26948,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_18": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 3920,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_19": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 28564,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_20": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 29776,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_21": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 30988,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_22": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 4324,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_23": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 32604,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_24": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 33816,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_25": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 35028,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_26": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 4728,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_27": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 36644,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_28": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 37856,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_29": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 39068,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_30": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 5132,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_31": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 40684,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_32": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 41896,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_33": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 43108,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_34": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 5536,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_35": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 44724,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_36": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 45936,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_37": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 47148,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_38": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 5940,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_39": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 48764,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_40": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 49976,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_41": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 51188,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_42": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 6344,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_43": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 52804,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_44": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 54016,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_45": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 55228,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_46": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 6748,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_47": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 56844,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_48": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 58056,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_49": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 59268,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_50": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 7152,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_51": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 60884,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_52": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 62096,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_53": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 63308,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_54": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 7556,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_55": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 64924,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_56": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 66136,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_57": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 67348,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_58": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 7960,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_59": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 68964,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_6": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 2708,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_60": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 70176,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_61": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 71388,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_62": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 8364,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_63": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 73004,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_64": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 74216,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_65": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 75428,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_66": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 8768,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_67": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 77044,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_68": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 78256,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_69": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 79468,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_7": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 16444,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_70": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 9576,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_71": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 81084,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_72": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 82296,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_73": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 83508,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_74": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 9980,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_75": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 85124,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_76": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 86336,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_77": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 87548,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_78": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 10384,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_79": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 89164,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_8": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 17656,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_80": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 90376,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_81": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 91588,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_82": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 10788,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_83": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 93204,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_84": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 94416,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_85": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 95628,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_86": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 11192,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_87": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 97244,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_88": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 98456,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_89": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 99668,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_9": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 18868,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_90": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 11596,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_91": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 101284,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_92": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 102496,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_93": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 103708,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_94": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 12000,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_95": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 105324,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_96": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 106536,
+            "count": 101,
+            "type": 35665
+        },
+        "accessor_97": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 107748,
+            "count": 101,
+            "type": 35666
+        },
+        "accessor_98": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 12404,
+            "count": 101,
+            "type": 5126
+        },
+        "accessor_99": {
+            "bufferView": "bufferView_185",
+            "byteOffset": 109364,
+            "count": 101,
+            "type": 35665
+        },
+        "attribute_163": {
+            "bufferView": "bufferView_183",
+            "byteOffset": 0,
+            "byteStride": 12,
+            "count": 818,
+            "max": [
+                1154.32,
+                892.627,
+                584.533
+            ],
+            "min": [
+                -1746.98,
+                -913.328,
+                -504.127
+            ],
+            "type": 35665
+        },
+        "attribute_165": {
+            "bufferView": "bufferView_183",
+            "byteOffset": 9816,
+            "byteStride": 12,
+            "count": 818,
+            "max": [
+                0.997713,
+                0.999992,
+                0.998876
+            ],
+            "min": [
+                -0.976716,
+                -1,
+                -0.998876
+            ],
+            "type": 35665
+        },
+        "attribute_167": {
+            "bufferView": "bufferView_183",
+            "byteOffset": 19632,
+            "byteStride": 8,
+            "count": 818,
+            "max": [
+                1.00961,
+                0.991641
+            ],
+            "min": [
+                0.005086,
+                -0.07435
+            ],
+            "type": 35664
+        },
+        "attribute_176": {
+            "bufferView": "bufferView_183",
+            "byteOffset": 26176,
+            "byteStride": 16,
+            "count": 818,
+            "max": [
+                1,
+                0.5,
+                0.333333,
+                0.297741
+            ],
+            "min": [
+                0.202008,
+                0,
+                0,
+                0
+            ],
+            "type": 35666
+        },
+        "attribute_179": {
+            "bufferView": "bufferView_183",
+            "byteOffset": 39264,
+            "byteStride": 16,
+            "count": 818,
+            "max": [
+                34,
+                34,
+                28,
+                33
+            ],
+            "min": [
+                0,
+                0,
+                0,
+                0
+            ],
+            "type": 35666
+        },
+        "indices_161": {
+            "bufferView": "bufferView_184",
+            "byteOffset": 0,
+            "count": 2652,
+            "type": 5123
+        }
+    },
+    "animations": {
+        "animation_1": {
+            "channels": [
+                {
+                    "sampler": "animation_1_scale_sampler",
+                    "target": {
+                        "id": "Bip01_Spine-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_1_translation_sampler",
+                    "target": {
+                        "id": "Bip01_Spine-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_1_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_Spine-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_6",
+                "rotation": "accessor_9",
+                "scale": "accessor_7",
+                "translation": "accessor_8"
+            },
+            "samplers": {
+                "animation_1_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_1_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_1_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_10": {
+            "channels": [
+                {
+                    "sampler": "animation_10_scale_sampler",
+                    "target": {
+                        "id": "Bip01_L_Finger0Nub-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_10_translation_sampler",
+                    "target": {
+                        "id": "Bip01_L_Finger0Nub-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_10_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_L_Finger0Nub-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_42",
+                "rotation": "accessor_45",
+                "scale": "accessor_43",
+                "translation": "accessor_44"
+            },
+            "samplers": {
+                "animation_10_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_10_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_10_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_11": {
+            "channels": [
+                {
+                    "sampler": "animation_11_scale_sampler",
+                    "target": {
+                        "id": "Bip01_HeadNub-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_11_translation_sampler",
+                    "target": {
+                        "id": "Bip01_HeadNub-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_11_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_HeadNub-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_46",
+                "rotation": "accessor_49",
+                "scale": "accessor_47",
+                "translation": "accessor_48"
+            },
+            "samplers": {
+                "animation_11_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_11_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_11_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_12": {
+            "channels": [
+                {
+                    "sampler": "animation_12_scale_sampler",
+                    "target": {
+                        "id": "Bip01_R_Thigh-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_12_translation_sampler",
+                    "target": {
+                        "id": "Bip01_R_Thigh-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_12_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_R_Thigh-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_50",
+                "rotation": "accessor_53",
+                "scale": "accessor_51",
+                "translation": "accessor_52"
+            },
+            "samplers": {
+                "animation_12_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_12_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_12_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_13": {
+            "channels": [
+                {
+                    "sampler": "animation_13_scale_sampler",
+                    "target": {
+                        "id": "Bip01_R_Calf-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_13_translation_sampler",
+                    "target": {
+                        "id": "Bip01_R_Calf-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_13_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_R_Calf-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_54",
+                "rotation": "accessor_57",
+                "scale": "accessor_55",
+                "translation": "accessor_56"
+            },
+            "samplers": {
+                "animation_13_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_13_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_13_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_14": {
+            "channels": [
+                {
+                    "sampler": "animation_14_scale_sampler",
+                    "target": {
+                        "id": "Bip01_R_Foot-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_14_translation_sampler",
+                    "target": {
+                        "id": "Bip01_R_Foot-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_14_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_R_Foot-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_58",
+                "rotation": "accessor_61",
+                "scale": "accessor_59",
+                "translation": "accessor_60"
+            },
+            "samplers": {
+                "animation_14_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_14_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_14_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_15": {
+            "channels": [
+                {
+                    "sampler": "animation_15_scale_sampler",
+                    "target": {
+                        "id": "Bip01_R_Toe0-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_15_translation_sampler",
+                    "target": {
+                        "id": "Bip01_R_Toe0-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_15_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_R_Toe0-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_62",
+                "rotation": "accessor_65",
+                "scale": "accessor_63",
+                "translation": "accessor_64"
+            },
+            "samplers": {
+                "animation_15_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_15_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_15_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_16": {
+            "channels": [
+                {
+                    "sampler": "animation_16_scale_sampler",
+                    "target": {
+                        "id": "Bone01-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_16_translation_sampler",
+                    "target": {
+                        "id": "Bone01-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_16_rotation_sampler",
+                    "target": {
+                        "id": "Bone01-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_66",
+                "rotation": "accessor_69",
+                "scale": "accessor_67",
+                "translation": "accessor_68"
+            },
+            "samplers": {
+                "animation_16_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_16_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_16_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_18": {
+            "channels": [
+                {
+                    "sampler": "animation_18_scale_sampler",
+                    "target": {
+                        "id": "Bip01_R_Clavicle-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_18_translation_sampler",
+                    "target": {
+                        "id": "Bip01_R_Clavicle-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_18_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_R_Clavicle-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_70",
+                "rotation": "accessor_73",
+                "scale": "accessor_71",
+                "translation": "accessor_72"
+            },
+            "samplers": {
+                "animation_18_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_18_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_18_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_19": {
+            "channels": [
+                {
+                    "sampler": "animation_19_scale_sampler",
+                    "target": {
+                        "id": "Bone03-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_19_translation_sampler",
+                    "target": {
+                        "id": "Bone03-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_19_rotation_sampler",
+                    "target": {
+                        "id": "Bone03-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_74",
+                "rotation": "accessor_77",
+                "scale": "accessor_75",
+                "translation": "accessor_76"
+            },
+            "samplers": {
+                "animation_19_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_19_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_19_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_2": {
+            "channels": [
+                {
+                    "sampler": "animation_2_scale_sampler",
+                    "target": {
+                        "id": "Bip01_Spine1-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_2_translation_sampler",
+                    "target": {
+                        "id": "Bip01_Spine1-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_2_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_Spine1-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_10",
+                "rotation": "accessor_13",
+                "scale": "accessor_11",
+                "translation": "accessor_12"
+            },
+            "samplers": {
+                "animation_2_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_2_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_2_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_20": {
+            "channels": [
+                {
+                    "sampler": "animation_20_scale_sampler",
+                    "target": {
+                        "id": "Bone04-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_20_translation_sampler",
+                    "target": {
+                        "id": "Bone04-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_20_rotation_sampler",
+                    "target": {
+                        "id": "Bone04-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_78",
+                "rotation": "accessor_81",
+                "scale": "accessor_79",
+                "translation": "accessor_80"
+            },
+            "samplers": {
+                "animation_20_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_20_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_20_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_21": {
+            "channels": [
+                {
+                    "sampler": "animation_21_scale_sampler",
+                    "target": {
+                        "id": "Bip01_R_UpperArm-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_21_translation_sampler",
+                    "target": {
+                        "id": "Bip01_R_UpperArm-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_21_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_R_UpperArm-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_82",
+                "rotation": "accessor_85",
+                "scale": "accessor_83",
+                "translation": "accessor_84"
+            },
+            "samplers": {
+                "animation_21_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_21_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_21_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_22": {
+            "channels": [
+                {
+                    "sampler": "animation_22_scale_sampler",
+                    "target": {
+                        "id": "Bip01_R_Forearm-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_22_translation_sampler",
+                    "target": {
+                        "id": "Bip01_R_Forearm-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_22_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_R_Forearm-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_86",
+                "rotation": "accessor_89",
+                "scale": "accessor_87",
+                "translation": "accessor_88"
+            },
+            "samplers": {
+                "animation_22_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_22_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_22_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_23": {
+            "channels": [
+                {
+                    "sampler": "animation_23_scale_sampler",
+                    "target": {
+                        "id": "Bip01_R_Hand-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_23_translation_sampler",
+                    "target": {
+                        "id": "Bip01_R_Hand-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_23_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_R_Hand-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_90",
+                "rotation": "accessor_93",
+                "scale": "accessor_91",
+                "translation": "accessor_92"
+            },
+            "samplers": {
+                "animation_23_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_23_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_23_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_24": {
+            "channels": [
+                {
+                    "sampler": "animation_24_scale_sampler",
+                    "target": {
+                        "id": "Bip01_R_Finger0-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_24_translation_sampler",
+                    "target": {
+                        "id": "Bip01_R_Finger0-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_24_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_R_Finger0-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_94",
+                "rotation": "accessor_97",
+                "scale": "accessor_95",
+                "translation": "accessor_96"
+            },
+            "samplers": {
+                "animation_24_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_24_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_24_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_25": {
+            "channels": [
+                {
+                    "sampler": "animation_25_scale_sampler",
+                    "target": {
+                        "id": "Bip01_R_Finger0Nub-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_25_translation_sampler",
+                    "target": {
+                        "id": "Bip01_R_Finger0Nub-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_25_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_R_Finger0Nub-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_98",
+                "rotation": "accessor_101",
+                "scale": "accessor_99",
+                "translation": "accessor_100"
+            },
+            "samplers": {
+                "animation_25_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_25_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_25_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_26": {
+            "channels": [
+                {
+                    "sampler": "animation_26_scale_sampler",
+                    "target": {
+                        "id": "Bip01_L_Thigh-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_26_translation_sampler",
+                    "target": {
+                        "id": "Bip01_L_Thigh-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_26_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_L_Thigh-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_102",
+                "rotation": "accessor_105",
+                "scale": "accessor_103",
+                "translation": "accessor_104"
+            },
+            "samplers": {
+                "animation_26_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_26_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_26_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_27": {
+            "channels": [
+                {
+                    "sampler": "animation_27_scale_sampler",
+                    "target": {
+                        "id": "Bip01_L_Calf-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_27_translation_sampler",
+                    "target": {
+                        "id": "Bip01_L_Calf-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_27_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_L_Calf-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_106",
+                "rotation": "accessor_109",
+                "scale": "accessor_107",
+                "translation": "accessor_108"
+            },
+            "samplers": {
+                "animation_27_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_27_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_27_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_28": {
+            "channels": [
+                {
+                    "sampler": "animation_28_scale_sampler",
+                    "target": {
+                        "id": "Bip01_L_Foot-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_28_translation_sampler",
+                    "target": {
+                        "id": "Bip01_L_Foot-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_28_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_L_Foot-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_110",
+                "rotation": "accessor_113",
+                "scale": "accessor_111",
+                "translation": "accessor_112"
+            },
+            "samplers": {
+                "animation_28_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_28_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_28_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_29": {
+            "channels": [
+                {
+                    "sampler": "animation_29_scale_sampler",
+                    "target": {
+                        "id": "Bip01_L_Toe0-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_29_translation_sampler",
+                    "target": {
+                        "id": "Bip01_L_Toe0-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_29_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_L_Toe0-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_114",
+                "rotation": "accessor_117",
+                "scale": "accessor_115",
+                "translation": "accessor_116"
+            },
+            "samplers": {
+                "animation_29_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_29_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_29_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_3": {
+            "channels": [
+                {
+                    "sampler": "animation_3_scale_sampler",
+                    "target": {
+                        "id": "Bip01_Neck-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_3_translation_sampler",
+                    "target": {
+                        "id": "Bip01_Neck-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_3_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_Neck-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_14",
+                "rotation": "accessor_17",
+                "scale": "accessor_15",
+                "translation": "accessor_16"
+            },
+            "samplers": {
+                "animation_3_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_3_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_3_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_30": {
+            "channels": [
+                {
+                    "sampler": "animation_30_scale_sampler",
+                    "target": {
+                        "id": "Bip01_Tail-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_30_translation_sampler",
+                    "target": {
+                        "id": "Bip01_Tail-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_30_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_Tail-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_118",
+                "rotation": "accessor_121",
+                "scale": "accessor_119",
+                "translation": "accessor_120"
+            },
+            "samplers": {
+                "animation_30_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_30_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_30_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_31": {
+            "channels": [
+                {
+                    "sampler": "animation_31_scale_sampler",
+                    "target": {
+                        "id": "Bip01_Tail1-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_31_translation_sampler",
+                    "target": {
+                        "id": "Bip01_Tail1-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_31_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_Tail1-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_122",
+                "rotation": "accessor_125",
+                "scale": "accessor_123",
+                "translation": "accessor_124"
+            },
+            "samplers": {
+                "animation_31_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_31_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_31_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_32": {
+            "channels": [
+                {
+                    "sampler": "animation_32_scale_sampler",
+                    "target": {
+                        "id": "Bip01_Tail2-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_32_translation_sampler",
+                    "target": {
+                        "id": "Bip01_Tail2-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_32_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_Tail2-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_126",
+                "rotation": "accessor_129",
+                "scale": "accessor_127",
+                "translation": "accessor_128"
+            },
+            "samplers": {
+                "animation_32_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_32_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_32_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_33": {
+            "channels": [
+                {
+                    "sampler": "animation_33_scale_sampler",
+                    "target": {
+                        "id": "Bip01_TailNub-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_33_translation_sampler",
+                    "target": {
+                        "id": "Bip01_TailNub-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_33_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_TailNub-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_130",
+                "rotation": "accessor_133",
+                "scale": "accessor_131",
+                "translation": "accessor_132"
+            },
+            "samplers": {
+                "animation_33_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_33_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_33_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_4": {
+            "channels": [
+                {
+                    "sampler": "animation_4_scale_sampler",
+                    "target": {
+                        "id": "Bip01_Head-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_4_translation_sampler",
+                    "target": {
+                        "id": "Bip01_Head-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_4_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_Head-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_18",
+                "rotation": "accessor_21",
+                "scale": "accessor_19",
+                "translation": "accessor_20"
+            },
+            "samplers": {
+                "animation_4_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_4_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_4_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_5": {
+            "channels": [
+                {
+                    "sampler": "animation_5_scale_sampler",
+                    "target": {
+                        "id": "Bip01_L_Clavicle-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_5_translation_sampler",
+                    "target": {
+                        "id": "Bip01_L_Clavicle-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_5_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_L_Clavicle-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_22",
+                "rotation": "accessor_25",
+                "scale": "accessor_23",
+                "translation": "accessor_24"
+            },
+            "samplers": {
+                "animation_5_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_5_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_5_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_6": {
+            "channels": [
+                {
+                    "sampler": "animation_6_scale_sampler",
+                    "target": {
+                        "id": "Bip01_L_UpperArm-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_6_translation_sampler",
+                    "target": {
+                        "id": "Bip01_L_UpperArm-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_6_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_L_UpperArm-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_26",
+                "rotation": "accessor_29",
+                "scale": "accessor_27",
+                "translation": "accessor_28"
+            },
+            "samplers": {
+                "animation_6_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_6_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_6_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_7": {
+            "channels": [
+                {
+                    "sampler": "animation_7_scale_sampler",
+                    "target": {
+                        "id": "Bip01_L_Forearm-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_7_translation_sampler",
+                    "target": {
+                        "id": "Bip01_L_Forearm-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_7_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_L_Forearm-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_30",
+                "rotation": "accessor_33",
+                "scale": "accessor_31",
+                "translation": "accessor_32"
+            },
+            "samplers": {
+                "animation_7_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_7_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_7_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_8": {
+            "channels": [
+                {
+                    "sampler": "animation_8_scale_sampler",
+                    "target": {
+                        "id": "Bip01_L_Hand-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_8_translation_sampler",
+                    "target": {
+                        "id": "Bip01_L_Hand-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_8_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_L_Hand-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_34",
+                "rotation": "accessor_37",
+                "scale": "accessor_35",
+                "translation": "accessor_36"
+            },
+            "samplers": {
+                "animation_8_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_8_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_8_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_9": {
+            "channels": [
+                {
+                    "sampler": "animation_9_scale_sampler",
+                    "target": {
+                        "id": "Bip01_L_Finger0-node",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_9_translation_sampler",
+                    "target": {
+                        "id": "Bip01_L_Finger0-node",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_9_rotation_sampler",
+                    "target": {
+                        "id": "Bip01_L_Finger0-node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "count": 101,
+            "parameters": {
+                "TIME": "accessor_38",
+                "rotation": "accessor_41",
+                "scale": "accessor_39",
+                "translation": "accessor_40"
+            },
+            "samplers": {
+                "animation_9_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_9_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_9_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        }
+    },
+    "asset": {
+        "generator": "collada2gltf@fb6d6e65e66c3b0013c75a8d1e63650f4309bf77"
+    },
+    "bufferViews": {
+        "bufferView_183": {
+            "buffer": "monster",
+            "byteLength": 52352,
+            "byteOffset": 0,
+            "target": 34962
+        },
+        "bufferView_184": {
+            "buffer": "monster",
+            "byteLength": 5304,
+            "byteOffset": 52352,
+            "target": 34963
+        },
+        "bufferView_185": {
+            "buffer": "monster",
+            "byteLength": 145724,
+            "byteOffset": 57656
+        }
+    },
+    "buffers": {
+        "monster": {
+            "byteLength": 203380,
+            "path": "monster.bin",
+            "type": "arraybuffer"
+        }
+    },
+    "images": {
+        "image_0": {
+            "path": "monster.jpg"
+        }
+    },
+    "materials": {
+        "monster-fx": {
+            "instanceTechnique": {
+                "technique": "technique1",
+                "values": {
+                    "ambient": [
+                        0.588235,
+                        0.588235,
+                        0.588235,
+                        1
+                    ],
+                    "diffuse": "texture_image_0",
+                    "shininess": 20,
+                    "specular": [
+                        0.1,
+                        0.1,
+                        0.1,
+                        1
+                    ]
+                }
+            },
+            "name": "monster"
+        }
+    },
+    "meshes": {
+        "monster-mesh-skin": {
+            "name": "monster",
+            "primitives": [
+                {
+                    "attributes": {
+                        "JOINT": "attribute_179",
+                        "NORMAL": "attribute_165",
+                        "POSITION": "attribute_163",
+                        "TEXCOORD_0": "attribute_167",
+                        "WEIGHT": "attribute_176"
+                    },
+                    "indices": "indices_161",
+                    "material": "monster-fx",
+                    "primitive": 4
+                }
+            ]
+        }
+    },
+    "nodes": {
+        "Bip01_Head-node": {
+            "children": [
+                "Bip01_HeadNub-node"
+            ],
+            "jointId": "Bone5",
+            "name": "Bip01_Head",
+            "rotation": [
+                0.888952,
+                0.414921,
+                0.19392,
+                0.0773304
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                181.732,
+                -8e-05,
+                -2e-06
+            ]
+        },
+        "Bip01_HeadNub-node": {
+            "children": [],
+            "jointId": "Bone6",
+            "name": "Bip01_HeadNub",
+            "rotation": [
+                1,
+                0,
+                0,
+                0
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                345.132,
+                1.7e-05,
+                -7e-06
+            ]
+        },
+        "Bip01_L_Calf-node": {
+            "children": [
+                "Bip01_L_Foot-node"
+            ],
+            "jointId": "Bone24",
+            "name": "Bip01_L_Calf",
+            "rotation": [
+                0,
+                0,
+                -1,
+                1.19016
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                547.819,
+                -5e-06,
+                -1.2e-05
+            ]
+        },
+        "Bip01_L_Clavicle-node": {
+            "children": [
+                "Bip01_L_UpperArm-node"
+            ],
+            "jointId": "Bone7",
+            "name": "Bip01_L_Clavicle",
+            "rotation": [
+                0.821819,
+                0.385425,
+                0.419597,
+                3.13687
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                7.49618,
+                0.138573,
+                42.5129
+            ]
+        },
+        "Bip01_L_Finger0-node": {
+            "children": [
+                "Bip01_L_Finger0Nub-node"
+            ],
+            "jointId": "Bone11",
+            "name": "Bip01_L_Finger0",
+            "rotation": [
+                0.205207,
+                0.494818,
+                -0.84442,
+                0.520016
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                186.693,
+                -2.3e-05,
+                -9e-06
+            ]
+        },
+        "Bip01_L_Finger0Nub-node": {
+            "children": [],
+            "jointId": "Bone12",
+            "name": "Bip01_L_Finger0Nub",
+            "rotation": [
+                1,
+                0,
+                0,
+                0
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                167.761,
+                1.9e-05,
+                1.3e-05
+            ]
+        },
+        "Bip01_L_Foot-node": {
+            "children": [
+                "Bip01_L_Toe0-node"
+            ],
+            "jointId": "Bone25",
+            "name": "Bip01_L_Foot",
+            "rotation": [
+                0.0131495,
+                -0.264758,
+                0.964225,
+                1.13836
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                532.748,
+                5.1e-05,
+                -8e-06
+            ]
+        },
+        "Bip01_L_Forearm-node": {
+            "children": [
+                "Bip01_L_Hand-node"
+            ],
+            "jointId": "Bone9",
+            "name": "Bip01_L_Forearm",
+            "rotation": [
+                0,
+                0,
+                -1,
+                1.07887
+            ],
+            "scale": [
+                1,
+                0.999999,
+                1
+            ],
+            "translation": [
+                370.017,
+                2e-05,
+                0
+            ]
+        },
+        "Bip01_L_Hand-node": {
+            "children": [
+                "Bip01_L_Finger0-node"
+            ],
+            "jointId": "Bone10",
+            "name": "Bip01_L_Hand",
+            "rotation": [
+                -0.468739,
+                0.0882598,
+                0.878916,
+                0.630255
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                370.018,
+                -5.8e-05,
+                -4e-06
+            ]
+        },
+        "Bip01_L_Thigh-node": {
+            "children": [
+                "Bip01_L_Calf-node"
+            ],
+            "jointId": "Bone23",
+            "name": "Bip01_L_Thigh",
+            "rotation": [
+                0.84539,
+                0.505798,
+                0.171709,
+                3.10411
+            ],
+            "scale": [
+                1,
+                0.999999,
+                1
+            ],
+            "translation": [
+                -115.92,
+                125.412,
+                124.981
+            ]
+        },
+        "Bip01_L_Toe0-node": {
+            "children": [
+                "Bip01_L_Toe0Nub-node"
+            ],
+            "jointId": "Bone26",
+            "name": "Bip01_L_Toe0",
+            "rotation": [
+                0,
+                0,
+                1,
+                1.5708
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                214.572,
+                189.363,
+                3e-05
+            ]
+        },
+        "Bip01_L_Toe0Nub-node": {
+            "children": [],
+            "jointId": "Bone27",
+            "matrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                -1,
+                0,
+                166.968,
+                0,
+                8e-06,
+                1
+            ],
+            "name": "Bip01_L_Toe0Nub"
+        },
+        "Bip01_L_UpperArm-node": {
+            "children": [
+                "Bip01_L_Forearm-node"
+            ],
+            "jointId": "Bone8",
+            "name": "Bip01_L_UpperArm",
+            "rotation": [
+                0.977167,
+                -0.155223,
+                0.14509,
+                3.72504
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                175.071,
+                7.1e-05,
+                7e-06
+            ]
+        },
+        "Bip01_Neck-node": {
+            "children": [
+                "Bip01_Head-node",
+                "Bip01_L_Clavicle-node",
+                "Bip01_R_Clavicle-node"
+            ],
+            "jointId": "Bone4",
+            "name": "Bip01_Neck",
+            "rotation": [
+                -0.0848005,
+                -0.239893,
+                -0.967088,
+                0.699229
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                402.56,
+                -0.112731,
+                -1.7e-05
+            ]
+        },
+        "Bip01_Pelvis-node": {
+            "children": [
+                "Bip01_Spine-node"
+            ],
+            "jointId": "Bone1",
+            "name": "Bip01_Pelvis",
+            "rotation": [
+                -0.959472,
+                -0.199266,
+                -0.199266,
+                1.61216
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                524.412,
+                -3.8e-05,
+                898.736
+            ]
+        },
+        "Bip01_R_Calf-node": {
+            "children": [
+                "Bip01_R_Foot-node"
+            ],
+            "jointId": "Bone29",
+            "name": "Bip01_R_Calf",
+            "rotation": [
+                0,
+                0,
+                -1,
+                1.52677
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                547.819,
+                3.7e-05,
+                -1.5e-05
+            ]
+        },
+        "Bip01_R_Clavicle-node": {
+            "children": [
+                "Bip01_R_UpperArm-node"
+            ],
+            "jointId": "Bone13",
+            "name": "Bip01_R_Clavicle",
+            "rotation": [
+                -0.404858,
+                -0.236589,
+                0.883241,
+                3.63415
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                -7.49618,
+                0.150702,
+                -42.5129
+            ]
+        },
+        "Bip01_R_Finger0-node": {
+            "children": [
+                "Bip01_R_Finger0Nub-node"
+            ],
+            "jointId": "Bone17",
+            "name": "Bip01_R_Finger0",
+            "rotation": [
+                -0.100383,
+                -0.36566,
+                -0.925319,
+                0.743378
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                186.693,
+                5.6e-05,
+                3e-06
+            ]
+        },
+        "Bip01_R_Finger0Nub-node": {
+            "children": [],
+            "jointId": "Bone18",
+            "name": "Bip01_R_Finger0Nub",
+            "rotation": [
+                -0,
+                -0,
+                1,
+                3.14159
+            ],
+            "scale": [
+                -1,
+                -1,
+                -1
+            ],
+            "translation": [
+                167.761,
+                -5e-06,
+                -4.4e-05
+            ]
+        },
+        "Bip01_R_Foot-node": {
+            "children": [
+                "Bip01_R_Toe0-node"
+            ],
+            "jointId": "Bone30",
+            "name": "Bip01_R_Foot",
+            "rotation": [
+                0.725694,
+                0.362838,
+                0.584565,
+                0.354579
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                532.748,
+                4.1e-05,
+                -2e-06
+            ]
+        },
+        "Bip01_R_Forearm-node": {
+            "children": [
+                "Bip01_R_Hand-node"
+            ],
+            "jointId": "Bone15",
+            "name": "Bip01_R_Forearm",
+            "rotation": [
+                0,
+                0,
+                -1,
+                1.45794
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                370.017,
+                2.9e-05,
+                3e-06
+            ]
+        },
+        "Bip01_R_Hand-node": {
+            "children": [
+                "Bip01_R_Finger0-node"
+            ],
+            "jointId": "Bone16",
+            "name": "Bip01_R_Hand",
+            "rotation": [
+                0.983491,
+                -0.166018,
+                -0.0719935,
+                0.544696
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                370.017,
+                -2e-06,
+                6.4e-05
+            ]
+        },
+        "Bip01_R_Thigh-node": {
+            "children": [
+                "Bip01_R_Calf-node"
+            ],
+            "jointId": "Bone28",
+            "name": "Bip01_R_Thigh",
+            "rotation": [
+                0.99724,
+                -0.00466794,
+                -0.0741011,
+                3.2334
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                -64.1862,
+                86.8699,
+                -181.92
+            ]
+        },
+        "Bip01_R_Toe0-node": {
+            "children": [
+                "Bip01_R_Toe0Nub-node"
+            ],
+            "jointId": "Bone31",
+            "name": "Bip01_R_Toe0",
+            "rotation": [
+                0.0298918,
+                0.0389551,
+                0.998794,
+                1.47183
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                214.572,
+                189.364,
+                -0
+            ]
+        },
+        "Bip01_R_Toe0Nub-node": {
+            "children": [],
+            "jointId": "Bone32",
+            "name": "Bip01_R_Toe0Nub",
+            "rotation": [
+                1,
+                0,
+                0,
+                0
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                166.968,
+                4e-06,
+                -3.3e-05
+            ]
+        },
+        "Bip01_R_UpperArm-node": {
+            "children": [
+                "Bip01_R_Forearm-node"
+            ],
+            "jointId": "Bone14",
+            "name": "Bip01_R_UpperArm",
+            "rotation": [
+                0.747885,
+                -0.309236,
+                -0.587401,
+                1.24893
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                175.071,
+                -0.000136,
+                1.5e-05
+            ]
+        },
+        "Bip01_Spine-node": {
+            "children": [
+                "Bip01_Spine1-node",
+                "Bip01_R_Thigh-node",
+                "Bip01_L_Thigh-node",
+                "Bip01_Tail-node"
+            ],
+            "jointId": "Bone2",
+            "name": "Bip01_Spine",
+            "rotation": [
+                0.0503303,
+                0.236422,
+                0.970346,
+                0.884125
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                142.077,
+                -0.208117,
+                -0.038858
+            ]
+        },
+        "Bip01_Spine1-node": {
+            "children": [
+                "Bip01_Neck-node",
+                "Bone01-node",
+                "Bone03-node"
+            ],
+            "jointId": "Bone3",
+            "name": "Bip01_Spine1",
+            "rotation": [
+                0.339141,
+                0.634452,
+                0.694589,
+                0.318861
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                399.228,
+                -0.310882,
+                -0.041171
+            ]
+        },
+        "Bip01_Tail-node": {
+            "children": [
+                "Bip01_Tail1-node"
+            ],
+            "jointId": "Bone33",
+            "name": "Bip01_Tail",
+            "rotation": [
+                -0.0332696,
+                0.042712,
+                0.998533,
+                2.87002
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                -217.547,
+                76.1463,
+                -46.1944
+            ]
+        },
+        "Bip01_Tail1-node": {
+            "children": [
+                "Bip01_Tail2-node"
+            ],
+            "jointId": "Bone34",
+            "name": "Bip01_Tail1",
+            "rotation": [
+                0.0281731,
+                -0.223504,
+                0.974296,
+                0.258944
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                275.134,
+                -0.261342,
+                0
+            ]
+        },
+        "Bip01_Tail2-node": {
+            "children": [
+                "Bip01_TailNub-node"
+            ],
+            "jointId": "Bone35",
+            "name": "Bip01_Tail2",
+            "rotation": [
+                0,
+                -0,
+                1,
+                0.226614
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                339.089,
+                -0.290226,
+                -7e-06
+            ]
+        },
+        "Bip01_TailNub-node": {
+            "children": [],
+            "jointId": "Bone36",
+            "name": "Bip01_TailNub",
+            "rotation": [
+                0.707388,
+                0.706825,
+                7.06825e-07,
+                3.14159
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                374.193,
+                -3.8e-05,
+                -3e-06
+            ]
+        },
+        "Bone01-node": {
+            "children": [
+                "Bone02-node"
+            ],
+            "jointId": "Bone21",
+            "name": "Bone01",
+            "rotation": [
+                0.998254,
+                -0.012858,
+                -0.0576427,
+                3.00283
+            ],
+            "scale": [
+                0.993689,
+                1.09369,
+                9.75437
+            ],
+            "translation": [
+                179.053,
+                1051.53,
+                -104.193
+            ]
+        },
+        "Bone02-node": {
+            "children": [],
+            "jointId": "Bone22",
+            "name": "Bone02",
+            "rotation": [
+                1,
+                0,
+                0,
+                0
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                17.8219,
+                1.4e-05,
+                -2e-06
+            ]
+        },
+        "Bone03-node": {
+            "children": [
+                "Bone04-node"
+            ],
+            "jointId": "Bone19",
+            "name": "Bone03",
+            "rotation": [
+                0.998968,
+                -0.0442843,
+                0.0101098,
+                3.11183
+            ],
+            "scale": [
+                0.657025,
+                0.613551,
+                7.3972
+            ],
+            "translation": [
+                164.819,
+                1034.98,
+                -108.759
+            ]
+        },
+        "Bone04-node": {
+            "children": [],
+            "jointId": "Bone20",
+            "name": "Bone04",
+            "rotation": [
+                1,
+                0,
+                0,
+                0
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                17.8219,
+                7e-06,
+                -2e-06
+            ]
+        },
+        "monster-node": {
+            "children": [],
+            "instanceSkin": {
+                "skeletons": [
+                    "Bip01_Pelvis-node"
+                ],
+                "skin": "monster-mesh-skin-skin",
+                "sources": [
+                    "monster-mesh-skin"
+                ]
+            },
+            "matrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1
+            ],
+            "name": "monster"
+        }
+    },
+    "profile": "WebGL 1.0.2",
+    "programs": {
+        "program_0": {
+            "attributes": [
+                "a_joint",
+                "a_normal",
+                "a_position",
+                "a_texcoord0",
+                "a_weight"
+            ],
+            "fragmentShader": "monster0FS",
+            "vertexShader": "monster0VS"
+        }
+    },
+    "samplers": {
+        "sampler_0": {
+            "magFilter": 9729,
+            "minFilter": 9729,
+            "wrapS": 10497,
+            "wrapT": 10497
+        }
+    },
+    "scene": "defaultScene",
+    "scenes": {
+        "defaultScene": {
+            "nodes": [
+                "Bip01_Pelvis-node",
+                "monster-node"
+            ]
+        }
+    },
+    "shaders": {
+        "monster0FS": {
+            "path": "monster0FS.glsl"
+        },
+        "monster0VS": {
+            "path": "monster0VS.glsl"
+        }
+    },
+    "skins": {
+        "monster-mesh-skin-skin": {
+            "bindShapeMatrix": [
+                0,
+                -0.804999,
+                0.172274,
+                0,
+                0,
+                0.172274,
+                0.804999,
+                0,
+                -0.823226,
+                0,
+                0,
+                0,
+                -127.093,
+                -393.418,
+                597.2,
+                1
+            ],
+            "inverseBindMatrices": {
+                "bufferView": "bufferView_185",
+                "byteOffset": 0,
+                "count": 36,
+                "type": 35676
+            },
+            "joints": [
+                "Bone1",
+                "Bone2",
+                "Bone3",
+                "Bone4",
+                "Bone5",
+                "Bone6",
+                "Bone7",
+                "Bone8",
+                "Bone9",
+                "Bone10",
+                "Bone11",
+                "Bone12",
+                "Bone13",
+                "Bone14",
+                "Bone15",
+                "Bone16",
+                "Bone17",
+                "Bone18",
+                "Bone19",
+                "Bone20",
+                "Bone21",
+                "Bone22",
+                "Bone23",
+                "Bone24",
+                "Bone25",
+                "Bone26",
+                "Bone27",
+                "Bone28",
+                "Bone29",
+                "Bone30",
+                "Bone31",
+                "Bone32",
+                "Bone33",
+                "Bone34",
+                "Bone35",
+                "Bone36"
+            ]
+        }
+    },
+    "techniques": {
+        "technique1": {
+            "parameters": {
+                "ambient": {
+                    "type": 35666
+                },
+                "diffuse": {
+                    "type": 35678
+                },
+                "joint": {
+                    "semantic": "JOINT",
+                    "type": 35666
+                },
+                "jointMat": {
+                    "semantic": "JOINT_MATRIX",
+                    "type": 35676
+                },
+                "modelViewMatrix": {
+                    "semantic": "MODELVIEW",
+                    "type": 35676
+                },
+                "normal": {
+                    "semantic": "NORMAL",
+                    "type": 35665
+                },
+                "normalMatrix": {
+                    "semantic": "MODELVIEWINVERSETRANSPOSE",
+                    "type": 35675
+                },
+                "position": {
+                    "semantic": "POSITION",
+                    "type": 35665
+                },
+                "projectionMatrix": {
+                    "semantic": "PROJECTION",
+                    "type": 35676
+                },
+                "shininess": {
+                    "type": 5126
+                },
+                "specular": {
+                    "type": 35666
+                },
+                "texcoord0": {
+                    "semantic": "TEXCOORD_0",
+                    "type": 35664
+                },
+                "weight": {
+                    "semantic": "WEIGHT",
+                    "type": 35666
+                }
+            },
+            "pass": "defaultPass",
+            "passes": {
+                "defaultPass": {
+                    "details": {
+                        "commonProfile": {
+                            "extras": {
+                                "doubleSided": false
+                            },
+                            "lightingModel": "Blinn",
+                            "parameters": [
+                                "ambient",
+                                "diffuse",
+                                "jointMat",
+                                "modelViewMatrix",
+                                "normalMatrix",
+                                "projectionMatrix",
+                                "shininess",
+                                "specular"
+                            ],
+                            "texcoordBindings": {
+                                "diffuse": "TEXCOORD_0"
+                            }
+                        },
+                        "type": "COLLADA-1.4.1/commonProfile"
+                    },
+                    "instanceProgram": {
+                        "attributes": {
+                            "a_joint": "joint",
+                            "a_normal": "normal",
+                            "a_position": "position",
+                            "a_texcoord0": "texcoord0",
+                            "a_weight": "weight"
+                        },
+                        "program": "program_0",
+                        "uniforms": {
+                            "u_ambient": "ambient",
+                            "u_diffuse": "diffuse",
+                            "u_jointMat": "jointMat",
+                            "u_modelViewMatrix": "modelViewMatrix",
+                            "u_normalMatrix": "normalMatrix",
+                            "u_projectionMatrix": "projectionMatrix",
+                            "u_shininess": "shininess",
+                            "u_specular": "specular"
+                        }
+                    },
+                    "states": {
+                        "blendEnable": 0,
+                        "cullFaceEnable": 1,
+                        "depthMask": 1,
+                        "depthTestEnable": 1
+                    }
+                }
+            }
+        }
+    },
+    "textures": {
+        "texture_image_0": {
+            "format": 6408,
+            "internalFormat": 6408,
+            "sampler": "sampler_0",
+            "source": "image_0",
+            "target": 3553
+        }
+    }
+}

+ 23 - 0
examples/models/gltf/monster/monster0FS.glsl

@@ -0,0 +1,23 @@
+precision highp float;
+varying vec3 v_normal;
+varying vec4 v_joint;
+varying vec4 v_weight;
+uniform float u_shininess;
+uniform vec4 u_ambient;
+varying vec2 v_texcoord0;
+uniform sampler2D u_diffuse;
+uniform vec4 u_specular;
+void main(void) {
+vec3 normal = normalize(v_normal);
+vec4 color = vec4(0., 0., 0., 0.);
+vec4 diffuse = vec4(0., 0., 0., 1.);
+vec4 ambient;
+vec4 specular;
+ambient = u_ambient;
+diffuse = texture2D(u_diffuse, v_texcoord0);
+specular = u_specular;
+diffuse.xyz *= max(dot(normal,vec3(0.,0.,1.)), 0.);
+color.xyz += diffuse.xyz;
+color = vec4(color.rgb * diffuse.a, diffuse.a);
+gl_FragColor = color;
+}

+ 24 - 0
examples/models/gltf/monster/monster0VS.glsl

@@ -0,0 +1,24 @@
+precision highp float;
+attribute vec3 a_position;
+attribute vec3 a_normal;
+varying vec3 v_normal;
+attribute vec4 a_joint;
+varying vec4 v_joint;
+attribute vec4 a_weight;
+varying vec4 v_weight;
+uniform mat4 u_jointMat[60];
+uniform mat3 u_normalMatrix;
+uniform mat4 u_modelViewMatrix;
+uniform mat4 u_projectionMatrix;
+attribute vec2 a_texcoord0;
+varying vec2 v_texcoord0;
+void main(void) {
+mat4 skinMat = a_weight.x * u_jointMat[int(a_joint.x)];
+skinMat += a_weight.y * u_jointMat[int(a_joint.y)];
+skinMat += a_weight.z * u_jointMat[int(a_joint.z)];
+skinMat += a_weight.w * u_jointMat[int(a_joint.w)];
+vec4 pos = u_modelViewMatrix * skinMat * vec4(a_position,1.0);
+v_normal = normalize(u_normalMatrix * mat3(skinMat)* a_normal);
+v_texcoord0 = a_texcoord0;
+gl_Position = u_projectionMatrix * pos;
+}

+ 1 - 0
examples/models/gltf/monster/readme.txt

@@ -0,0 +1 @@
+Model from http://www.3drt.com/downloads.htm

+ 514 - 0
examples/webgl_loader_gltf.html

@@ -0,0 +1,514 @@
+<!doctype html>
+<html lang="en">
+    <head>
+        <title>three.js webgl - glTF</title>
+        <meta charset="utf-8">
+        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+        <style>
+            body {
+                font-family: Monospace;
+                background-color: #EEF;
+                margin: 0px;
+                overflow: hidden;
+            }
+            
+            #info {
+				color: #fff;
+                position: absolute;
+                top: 10px;
+                width: 100%;
+                text-align: center;
+                z-index: 100;
+                display:block;
+            }
+            
+            #container {
+            	position: absolute;
+            	top: 0px;
+            	width:100%;
+            	height:100%;
+            	z-index: -1;
+            }
+            
+            #controls {
+            	position:absolute;
+            	width:250px;
+            	bottom:0%;
+            	right:0%;
+            	height:134px;
+            	background-color:White;
+            	opacity:.9;
+            	font: 13px/1.231 "Lucida Grande", Lucida, Verdana, sans-serif;
+            }
+
+            #status {
+            	position:absolute;
+            	width:25%;
+            	left:2%;
+            	top:95%;
+            	height:5%;
+            	opacity:.9;
+            	font: 13px/1.231 "Lucida Grande", Lucida, Verdana, sans-serif;
+            }
+            
+            .control {
+            	position:absolute;
+            	margin-left:12px;
+            	width:100%;
+            	font-weight:bold;
+            }
+                        
+            .controlValue {
+            	position:absolute;
+            	left:36%;
+            	top:0%;
+            }
+            
+            #scenes_control {
+            	position:absolute;
+            	top:8px;
+            }
+
+            #cameras_control {
+            	position:absolute;
+            	top:40px;
+            }
+
+            #animations_control {
+            	position:absolute;
+            	top:72px;
+            }
+            
+            #buffer_geometry_control {
+            	position:absolute;
+            	top:104px;
+            }
+                        
+            #info a, .button { color: #f00; font-weight: bold; text-decoration: underline; cursor: pointer }
+        </style>
+    </head>
+
+    <body>
+        <div id="info">
+			<a href="http://threejs.org" target="_blank">three.js</a> - 
+			<a href="http://gltf.gl/" target="_blank">glTF</a> loader - 
+			<br></br>
+			monster by <a href="http://www.3drt.com/downloads.htm" target="_blank">3drt</a> -
+			COLLADA duck by Sony
+        </div>
+		<div id="container">
+		</div>
+		<div id="status">
+		</div>
+		<div id="controls">
+			<div class="control" id="scenes_control">
+				Model
+				<select class="controlValue" id="scenes_list" size="1" onchange="selectScene();" ondblclick="selectScene();">
+				</select>
+			</div>
+			
+			<div class="control" id="cameras_control">
+				Camera
+				<select class="controlValue" id="cameras_list" size="1" onchange="selectCamera();" ondblclick="selectCamera();">
+				</select>
+			</div>
+			<div class="control" id="animations_control">
+				Animations
+				<div class="controlValue"><input type="checkbox" checked onclick="toggleAnimations();">Play</input></div>
+			</div>
+			<div class="control" id="buffer_geometry_control">
+				Geometry
+				<div class="controlValue">
+				<input type="checkbox" id="buffer_geometry_checkbox" checked onclick="toggleBufferGeometry();">BufferGeometry</input>
+				</div>
+			</div>
+		</div>
+        <script src="../build/three.js"></script>
+        <script src="./js/controls/OrbitControls.js"></script>
+        <script src="./js/loaders/gltf/glTF-parser.js"></script>
+        <script src="./js/loaders/gltf/glTFLoader.js"></script>
+        <script src="./js/loaders/gltf/glTFLoaderUtils.js"></script>
+        <script src="./js/loaders/gltf/glTFAnimation.js"></script>
+
+        <script>
+        	var orbitControls = null;
+            var container, camera, scene, renderer, loader;
+
+            var cameraIndex = 0;
+			var cameras = [];
+			var cameraNames = [];
+			var defaultCamera = null;
+			var gltf = null;
+			
+			function onload() {
+
+				window.addEventListener( 'resize', onWindowResize, false );
+            	document.addEventListener( 'keypress', 
+            			function(e) { onKeyPress(e); }, false );
+
+                buildSceneList();
+                switchScene(0);
+                animate();
+
+            }
+
+            function initScene(index) {
+                container = document.getElementById( 'container' );
+
+                scene = new THREE.Scene();
+
+                defaultCamera = new THREE.PerspectiveCamera( 45, container.offsetWidth / container.offsetHeight, 1, 20000 );
+                
+                //defaultCamera.up = new THREE.Vector3( 0, 1, 0 );
+                scene.add( defaultCamera );
+                camera = defaultCamera;
+
+                var sceneInfo = sceneList[index];
+
+                var spot1 = null;
+                if (sceneInfo.addLights) {
+                    
+                    var ambient = new THREE.AmbientLight( 0x888888 );
+                    scene.add( ambient );
+
+                	var directionalLight = new THREE.DirectionalLight( 0xdddddd );
+                	directionalLight.position.set( 0, -1, 1 ).normalize();
+                	scene.add( directionalLight );
+                
+	                spot1   = new THREE.SpotLight( 0xffffff, 1 );
+	                spot1.position.set( -100, 200, 100 );
+	                spot1.target.position.set( 0, 0, 0 );
+
+	                if (sceneInfo.shadows) {
+		                
+		                spot1.shadowCameraNear      = 1;
+		                spot1.shadowCameraFar      = 1024;
+		                spot1.castShadow            = true;
+		                spot1.shadowDarkness        = 0.3;
+		                spot1.shadowBias = 0.0001;
+		                spot1.shadowMapWidth = 2048;
+		                spot1.shadowMapHeight = 2048;
+	                }
+	                scene.add( spot1 );
+                }
+				
+                // RENDERER
+
+                renderer = new THREE.WebGLRenderer({antialias:true});
+                renderer.setSize( container.offsetWidth, container.offsetHeight );
+
+                if (sceneInfo.shadows) {
+	                renderer.shadowMapEnabled = true;
+	                renderer.shadowMapSoft = true;
+	        		renderer.shadowMapType = THREE.PCFSoftShadowMap;
+                }
+                				
+                container.appendChild( renderer.domElement );
+
+                var ground = null;
+				if (sceneInfo.addGround) {
+	                var groundMaterial = new THREE.MeshPhongMaterial({
+	                        color: 0xFFFFFF,
+	                        ambient: 0x888888,
+	                        shading: THREE.SmoothShading,
+	                    });
+	                ground = new THREE.Mesh( new THREE.PlaneGeometry(1024, 1024), groundMaterial);
+
+	                if (sceneInfo.shadows) {
+		                ground.receiveShadow = true;
+	                }
+
+	                if (sceneInfo.groundPos) {
+		                ground.position.copy(sceneInfo.groundPos);
+	                }
+	                else {
+		                ground.position.z = -70;
+	                }
+	                ground.rotation.x = -Math.PI / 2;
+	                
+	                scene.add(ground);
+				}
+				
+                loader = new THREE.glTFLoader;
+                loader.useBufferGeometry = useBufferGeometry;
+                var loadStartTime = Date.now();
+                var status = document.getElementById("status");
+                status.innerHTML = "Loading...";
+                loader.load( sceneInfo.url, function(data) {
+
+                	gltf = data;
+                	
+                	var object = gltf.scene;
+                	
+                    var loadEndTime = Date.now();
+
+                    var loadTime = (loadEndTime - loadStartTime) / 1000;
+
+                    status.innerHTML = "Load time: " + loadTime.toFixed(2) + " seconds.";
+                    
+                	if (sceneInfo.cameraPos)
+                        defaultCamera.position.copy(sceneInfo.cameraPos);
+
+                	if (sceneInfo.center) {
+                        orbitControls.center.copy(sceneInfo.center);
+                	}
+                    
+                    if (sceneInfo.objectPosition) {
+                        object.position.copy(sceneInfo.objectPosition);
+
+                        if (spot1) {
+	    	                spot1.position.set(sceneInfo.objectPosition.x - 100, sceneInfo.objectPosition.y + 200, sceneInfo.objectPosition.z - 100 );
+    	                	spot1.target.position.copy(sceneInfo.objectPosition);
+                        }
+                    }
+                    
+                    if (sceneInfo.objectRotation)
+                        object.rotation.copy(sceneInfo.objectRotation);
+
+                    if (sceneInfo.objectScale)
+                        object.scale.copy(sceneInfo.objectScale);
+
+                    cameraIndex = 0;
+                    cameras = [];
+                    cameraNames = [];
+                    if (gltf.cameras && gltf.cameras.length)
+                    {
+                        var i, len = gltf.cameras.length;
+                        for (i = 0; i < len; i++)
+                        {
+                            var addCamera = true;
+                            var cameraName = gltf.cameras[i].parent.name;
+                            if (sceneInfo.cameras && !(cameraName in sceneInfo.cameras)) {
+                                    addCamera = false;
+                            }
+
+                            if (addCamera) {
+                            	cameraNames.push(cameraName);
+                            	cameras.push(gltf.cameras[i]);
+                            }
+                        }
+
+                        updateCamerasList();
+                        switchCamera(1);
+                    }
+                    else
+                    {
+                        updateCamerasList();
+                        switchCamera(0);
+                    }
+
+    				if (gltf.animations && gltf.animations.length) {
+    					var i, len = gltf.animations.length;
+	    				for (i = 0; i < len; i++) {
+	    					var animation = gltf.animations[i];
+	    					animation.loop = true;
+	    					// There's .3333 seconds junk at the tail of the Monster animation that
+	    					// keeps it from looping cleanly. Clip it at 3 seconds
+	    					if (sceneInfo.animationTime)
+		    					animation.duration = sceneInfo.animationTime;
+    						animation.play();
+	    				}
+    				}
+                                       
+                    scene.add( object );
+                    onWindowResize();
+
+                });
+
+        		orbitControls = new THREE.OrbitControls(defaultCamera, renderer.domElement);
+            }
+
+			function onWindowResize() {
+
+				defaultCamera.aspect = container.offsetWidth / container.offsetHeight;
+				defaultCamera.updateProjectionMatrix();
+				
+				var i, len = cameras.length;
+				for (i = 0; i < len; i++) // just do it for default
+				{
+					cameras[i].aspect = container.offsetWidth / container.offsetHeight;
+					cameras[i].updateProjectionMatrix();
+				}
+				
+				renderer.setSize( container.offsetWidth, container.offsetHeight );
+
+			}
+
+            function animate() {
+                requestAnimationFrame( animate );
+                THREE.glTFAnimator.update();
+                if (cameraIndex == 0)
+                    orbitControls.update();
+                render();
+            }
+
+            function render() {
+
+                renderer.render( scene, camera );
+            }
+
+            
+			
+			function onKeyPress(event) {
+				var chr = String.fromCharCode(event.keyCode);
+				if (chr == ' ')
+				{
+					index = cameraIndex + 1;
+					if (index > cameras.length)
+						index = 0;
+					switchCamera(index);
+				}
+				else {
+					var index = parseInt(chr);
+					if (!isNaN(index)  && (index <= cameras.length)) {
+						switchCamera(index);
+					}
+				}
+			}
+
+			var sceneList = 
+				[
+		             { name : "Monster", url : "./models/gltf/monster/monster.json", 
+			                 cameraPos: new THREE.Vector3(30, 10, 70), 
+			                 objectScale: new THREE.Vector3(0.01, 0.01, 0.01),
+			                 objectPosition: new THREE.Vector3(0, 1, 0),
+			                 objectRotation: new THREE.Euler(-Math.PI / 2, 0, -Math.PI / 2),
+			                 animationTime: 3,
+			                 addLights:true,
+			                 shadows:true,
+			                 addGround:true },
+	                 { name : "Duck", url : "./models/gltf/duck/duck.json", 
+		                 cameraPos: new THREE.Vector3(0, 30, -50),
+		                 objectScale: new THREE.Vector3(0.1, 0.1, 0.1),
+		                 addLights:true,
+		                 addGround:true,
+		                 shadows:true },
+     			];
+
+			function buildSceneList()
+			{
+				var elt = document.getElementById('scenes_list');
+				while( elt.hasChildNodes() ){
+				    elt.removeChild(elt.lastChild);
+				}
+
+				var i, len = sceneList.length;
+				for (i = 0; i < len; i++)
+				{
+					option = document.createElement("option");
+					option.text=sceneList[i].name;
+					elt.add(option);
+				}		
+			}
+			
+			function switchScene(index)
+			{
+				cleanup();
+				initScene(index);
+				var elt = document.getElementById('scenes_list');
+				elt.selectedIndex = index;
+			}
+
+			function selectScene()
+			{
+			    var select = document.getElementById("scenes_list");
+			    var index = select.selectedIndex;
+				if (index >= 0)
+				{
+					switchScene(index);
+				}
+			}
+			
+			function switchCamera(index)
+			{
+				cameraIndex = index;
+				
+				if (cameraIndex == 0) {
+					camera = defaultCamera;
+				}
+				if (cameraIndex >= 1 && cameraIndex <= cameras.length) {
+					camera = cameras[cameraIndex - 1];
+				}
+
+				var elt = document.getElementById('cameras_list');
+				elt.selectedIndex = cameraIndex;				
+			}
+					
+			function updateCamerasList() {
+				var elt = document.getElementById('cameras_list');
+				while( elt.hasChildNodes() ){
+				    elt.removeChild(elt.lastChild);
+				}
+
+				option = document.createElement("option");
+				option.text="[default]";
+				elt.add(option);
+				
+				var i, len = cameraNames.length;
+				for (i = 0; i < len; i++)
+				{
+					option = document.createElement("option");
+					option.text=cameraNames[i];
+					elt.add(option);
+				}		
+			}
+			
+			function selectCamera() {
+			    var select = document.getElementById("cameras_list");
+			    var index = select.selectedIndex;
+				if (index >= 0)
+				{
+					switchCamera(index);
+				}
+			}
+
+			function toggleAnimations() {
+				var i, len = gltf.animations.length;
+				for (i = 0; i < len; i++) {
+					var animation = gltf.animations[i];
+					if (animation.running) {
+						animation.stop();
+					}
+					else {
+						animation.play();
+					}
+				}
+			}
+
+			var usebuf = document.getElementById("buffer_geometry_checkbox");
+			var useBufferGeometry = usebuf.hasAttribute("checked");
+			function toggleBufferGeometry()
+			{
+				useBufferGeometry = !useBufferGeometry;
+				selectScene();
+			}
+			
+			function cleanup() {
+
+				if (container && renderer)
+				{
+					container.removeChild(renderer.domElement);
+				}
+
+	            cameraIndex = 0;
+				cameras = [];
+				cameraNames = [];
+				defaultCamera = null;
+				
+				if (!loader || !gltf.animations)
+					return;
+				
+				var i, len = gltf.animations.length;
+				for (i = 0; i < len; i++) {
+					var animation = gltf.animations[i];
+					if (animation.running) {
+						animation.stop();
+					}
+				}
+			}
+			
+            onload();
+        </script>
+
+    </body>
+</html>

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff