123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959 |
- /**
- * @author Tony Parisi / http://www.tonyparisi.com/
- */
- THREE.glTFLoader = function () {
- this.meshesRequested = 0;
- this.meshesLoaded = 0;
- this.pendingMeshes = [];
- this.animationsRequested = 0;
- this.animationsLoaded = 0;
- this.animations = [];
- this.shadersRequested = 0;
- this.shadersLoaded = 0;
- this.shaders = {};
- this.loadRequests = [];
- THREE.glTFShaders.removeAll();
- THREE.Loader.call( this );
- }
- 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 componentsPerElementForGLType(type) {
- switch(type) {
- case "SCALAR" :
- nElements = 1;
- break;
- case "VEC2" :
- nElements = 2;
- break;
- case "VEC3" :
- nElements = 3;
- break;
- case "VEC4" :
- nElements = 4;
- break;
- case "MAT2" :
- nElements = 4;
- break;
- case "MAT3" :
- nElements = 9;
- break;
- case "MAT4" :
- nElements = 16;
- break;
- default :
- debugger;
- break;
- }
- return nElements;
- }
- function replaceShaderDefinitions(shader, material) {
- // Three.js seems too dependent on attribute names so globally
- // replace those in the shader code
- var program = material.params.program;
- var shaderParams = material.params.technique.parameters;
- var shaderAttributes = material.params.technique.attributes;
- var params = {};
- for (var attribute in material.params.attributes) {
- var pname = shaderAttributes[attribute];
- var shaderParam = shaderParams[pname];
- var semantic = shaderParam.semantic;
- if (semantic) {
- params[attribute] = shaderParam;
- }
- }
- var s = shader;
- var r = "";
- for (var pname in params) {
- var param = params[pname];
- var semantic = param.semantic;
- r = eval("/" + pname + "/g");
- switch (semantic) {
- case "POSITION" :
- s = s.replace(r, 'position');
- break;
- case "NORMAL" :
- s = s.replace(r, 'normal');
- break;
- case "TEXCOORD_0" :
- s = s.replace(r, 'uv');
- break;
- case "WEIGHT" :
- s = s.replace(r, 'skinWeight');
- break;
- case "JOINT" :
- s = s.replace(r, 'skinIndex');
- break;
- default :
- break;
- }
- }
- return s;
- }
- function replaceShaderSemantics(material) {
- var vertexShader = theLoader.shaders[material.params.vertexShader];
- if (vertexShader) {
- vertexShader = replaceShaderDefinitions(vertexShader, material);
- theLoader.shaders[material.params.vertexShader] = vertexShader;
- }
- }
- function createShaderMaterial(material) {
- // replace named attributes and uniforms with Three.js built-ins
- replaceShaderSemantics(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 (!vertexShader) {
- console.log("ERROR: Missing vertex shader definition:", material.params.vertexShader);
- return new THREE.MeshPhongMaterial;
- }
- // clone most uniforms but then clobber textures, we want them to
- // be reused
- var uniforms = Objecct.asasign( {}, material.params.uniforms);
- for (uniform in material.params.uniforms) {
- var src = material.params.uniforms[uniform];
- var dst = uniforms[uniform];
- if (dst.type == "t") {
- dst.value = src.value;
- }
- }
- var shaderMaterial = new THREE.RawShaderMaterial( {
- fragmentShader: fragmentShader,
- vertexShader: vertexShader,
- uniforms: uniforms,
- transparent: material.params.transparent,
- } );
- // console.log("New shader material")
- return shaderMaterial;
- }
- function LoadTexture(src) {
- if(!src) { return null; }
- var isDataUriRegex = /^data:/;
- var loadImage = function(url, success, error) {
- var image = new Image();
- image.onload = function() {
- success(image);
- };
- if (typeof error !== 'undefined') {
- image.onerror = error;
- }
- image.src = url;
- };
- function loadImageFromTypedArray(uint8Array, format) {
- //>>includeStart('debug', pragmas.debug);
- if (!defined(uint8Array)) {
- throw new DeveloperError('uint8Array is required.');
- }
- if (!defined(format)) {
- throw new DeveloperError('format is required.');
- }
- //>>includeEnd('debug');
- var blob = new Blob([uint8Array], {
- type : format
- });
- };
- function decodeDataUriText(isBase64, data) {
- var result = decodeURIComponent(data);
- if (isBase64) {
- return atob(result);
- }
- return result;
- }
- function decodeDataUriArrayBuffer(isBase64, data) {
- var byteString = decodeDataUriText(isBase64, data);
- var buffer = new ArrayBuffer(byteString.length);
- var view = new Uint8Array(buffer);
- for (var i = 0; i < byteString.length; i++) {
- view[i] = byteString.charCodeAt(i);
- }
- return buffer;
- }
- function decodeDataUri(dataUriRegexResult, responseType) {
- responseType = typeof responseType !== 'undefined' ? responseType : '';
- var mimeType = dataUriRegexResult[1];
- var isBase64 = !!dataUriRegexResult[2];
- var data = dataUriRegexResult[3];
- switch (responseType) {
- case '':
- case 'text':
- return decodeDataUriText(isBase64, data);
- case 'ArrayBuffer':
- return decodeDataUriArrayBuffer(isBase64, data);
- case 'blob':
- var buffer = decodeDataUriArrayBuffer(isBase64, data);
- return new Blob([buffer], {
- type : mimeType
- });
- case 'document':
- var parser = new DOMParser();
- return parser.parseFromString(decodeDataUriText(isBase64, data), mimeType);
- case 'json':
- return JSON.parse(decodeDataUriText(isBase64, data));
- default:
- throw 'Unhandled responseType: ' + responseType;
- }
- }
- var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;
- var dataUriRegexResult = dataUriRegex.exec(src);
- if (dataUriRegexResult !== null) {
- var texture = new THREE.Texture;
- var blob = decodeDataUri(dataUriRegexResult, 'blob');
- var blobUrl = window.URL.createObjectURL(blob);
- loadImage(blobUrl, function(img) {
- texture.image = img;
- texture.needsUpdate = true;
- });
- return texture;
- }
- var textureLoader = THREE.Loader.Handlers.get(src);
- if ( textureLoader === null ) {
- textureLoader = new THREE.TextureLoader();
- }
- textureLoader.crossOrigin = true;
- return textureLoader.load(src);
- }
- function CreateTexture(resources, resource) {
- var texturePath = null;
- var textureParams = null;
- if (resource)
- {
- var texture = resource;
- if (texture) {
- var textureEntry = resources.getEntry(texture);
- if (textureEntry) {
- {
- var imageEntry = resources.getEntry(textureEntry.description.source);
- if (imageEntry) {
- texturePath = imageEntry.description.uri;
- }
- var samplerEntry = resources.getEntry(textureEntry.description.sampler);
- if (samplerEntry) {
- textureParams = samplerEntry.description;
- }
- }
- }
- }
- }
- var texture = LoadTexture(texturePath);
- if (texture && textureParams) {
- if (textureParams.wrapS == THREE.GLTFLoaderUtils.WEBGL_CONSTANTS.REPEAT)
- texture.wrapS = THREE.RepeatWrapping;
- if (textureParams.wrapT == THREE.GLTFLoaderUtils.WEBGL_CONSTANTS.REPEAT)
- texture.wrapT = THREE.RepeatWrapping;
- if (textureParams.magFilter == THREE.GLTFLoaderUtils.WEBGL_CONSTANTS.LINEAR)
- texture.magFilter = THREE.LinearFilter;
- // if (textureParams.minFilter == "LINEAR")
- // texture.minFilter = THREE.LinearFilter;
- }
- return texture;
- }
- // Geometry processing
- var ClassicGeometry = function() {
- this.geometry = new THREE.BufferGeometry;
- 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.buildBufferGeometry = function() {
- // Build indexed mesh
- var geometry = this.geometry;
- geometry.setIndex(new THREE.BufferAttribute( this.indexArray, 1 ) );
- var offset = {
- start: 0,
- index: 0,
- count: this.indexArray.length
- };
- geometry.groups.push( offset );
- geometry.computeBoundingSphere();
- }
- ClassicGeometry.prototype.checkFinished = function() {
- if(this.indexArray && this.loadedAttributes === this.totalAttributes) {
- this.buildBufferGeometry();
- 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.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.addAttribute( 'position', new THREE.BufferAttribute( floatArray, 3 ) );
- } else if (semantic == "NORMAL") {
- nComponents = componentsPerElementForGLType(attribute.type);
- floatArray = new Float32Array(glResource, 0, attribute.count * nComponents);
- geom.geometry.addAttribute( 'normal', new THREE.BufferAttribute( floatArray, 3 ) );
- } 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.addAttribute( 'uv', new THREE.BufferAttribute( floatArray, nComponents ) );
- }
- else if (semantic == "WEIGHT") {
- nComponents = componentsPerElementForGLType(attribute.type);
- floatArray = new Float32Array(glResource, 0, attribute.count * nComponents);
- geom.geometry.addAttribute( 'skinWeight', new THREE.BufferAttribute( floatArray, nComponents ) );
- }
- else if (semantic == "JOINT") {
- nComponents = componentsPerElementForGLType(attribute.type);
- floatArray = new Float32Array(glResource, 0, attribute.count * nComponents);
- geom.geometry.addAttribute( 'skinIndex', new THREE.BufferAttribute( floatArray, nComponents ) );
- }
- }
- VertexAttributeDelegate.prototype.resourceAvailable = function(glResource, ctx) {
- this.bufferResourceAvailable(glResource, ctx);
- var geom = ctx.geometry;
- geom.loadedAttributes++;
- geom.checkFinished();
- return true;
- };
- var vertexAttributeDelegate = new VertexAttributeDelegate();
- var VertexAttributeContext = function(attribute, semantic, geometry) {
- 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
- var that = this;
- this.primitives.forEach(function(primitive) {
- /*if(!primitive.mesh) {
- primitive.mesh = new THREE.Mesh(primitive.geometry, primitive.material);
- }*/
- var material = primitive.material;
- var materialParams = material.params;
- if (!(material instanceof THREE.Material)) {
- material = createShaderMaterial(material);
- }
- if (!that.skin) {
- // console.log ("New mesh")
- var threeMesh = new THREE.Mesh(primitive.geometry.geometry, material);
- threeMesh.castShadow = true;
- threeNode.add(threeMesh);
- if (material instanceof THREE.ShaderMaterial) {
- var glTFShader = new THREE.glTFShader(material, materialParams, threeMesh, theLoader.rootObj);
- THREE.glTFShaders.add(glTFShader);
- }
- }
- });
- };
- // 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 "SCALAR" :
- case "VEC2" :
- case "VEC3" :
- case "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 "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.uri = 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 = {};
- 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,
- uri : description.uri,
- };
- var shaderContext = new ShaderContext(entryID, description.uri);
- 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) {
- description.refCount = 0;
- this.resources.setEntry(entryID, null, description);
- return true;
- }
- },
- createShaderParams : {
- value: function(materialId, values, params, programID, technique) {
- var program = this.resources.getEntry(programID);
- params.uniforms = {};
- params.attributes = {};
- params.program = program;
- params.technique = technique;
- if (program) {
- params.fragmentShader = program.description.fragmentShader;
- params.vertexShader = program.description.vertexShader;
- for (var uniform in technique.uniforms) {
- var pname = technique.uniforms[uniform];
- var shaderParam = technique.parameters[pname];
- var ptype = shaderParam.type;
- var pcount = shaderParam.count;
- var value = values[pname];
- var utype = "";
- var uvalue;
- var ulength;
- // THIS: for (n in WebGLRenderingContext) { z = WebGLRenderingContext[n]; idx[z] = n; }
- //console.log("shader uniform param type: ", ptype, "-", theLoader.idx[ptype])
- switch (ptype) {
- case THREE.GLTFLoaderUtils.WEBGL_CONSTANTS.FLOAT :
- utype = "f";
- uvalue = shaderParam.value;
- if (pname == "transparency") {
- var USE_A_ONE = true; // for now, hack because file format isn't telling us
- var opacity = USE_A_ONE ? value : (1.0 - value);
- uvalue = opacity;
- params.transparent = true;
- }
- break;
- case THREE.GLTFLoaderUtils.WEBGL_CONSTANTS.FLOAT_VEC2 :
- utype = "v2";
- uvalue = new THREE.Vector2;
- if (shaderParam && shaderParam.value) {
- var v2 = shaderParam.value;
- uvalue.fromArray(v2);
- }
- if (value) {
- uvalue.fromArray(value);
- }
- break;
- case THREE.GLTFLoaderUtils.WEBGL_CONSTANTS.FLOAT_VEC3 :
- utype = "v3";
- uvalue = new THREE.Vector3;
- if (shaderParam && shaderParam.value) {
- var v3 = shaderParam.value;
- uvalue.fromArray(v3);
- }
- if (value) {
- uvalue.fromArray(value);
- }
- break;
- case THREE.GLTFLoaderUtils.WEBGL_CONSTANTS.FLOAT_VEC4 :
- utype = "v4";
- uvalue = new THREE.Vector4;
- if (shaderParam && shaderParam.value) {
- var v4 = shaderParam.value;
- uvalue.fromArray(v4);
- }
- if (value) {
- uvalue.fromArray(value);
- }
- break;
- case THREE.GLTFLoaderUtils.WEBGL_CONSTANTS.FLOAT_MAT2 :
- // what to do?
- console.log("Warning: FLOAT_MAT2");
- break;
- case THREE.GLTFLoaderUtils.WEBGL_CONSTANTS.FLOAT_MAT3 :
- utype = "m3";
- uvalue = new THREE.Matrix3;
- if (shaderParam && shaderParam.value) {
- var m3 = shaderParam.value;
- uvalue.fromArray(m3);
- }
- if (value) {
- uvalue.fromArray(value);
- }
- break;
- case THREE.GLTFLoaderUtils.WEBGL_CONSTANTS.FLOAT_MAT4 :
- if (pcount !== undefined) {
- utype = "m4v";
- uvalue = new Array(pcount);
- for (var mi = 0; mi < pcount; mi++) {
- uvalue[mi] = new THREE.Matrix4;
- }
- ulength = pcount;
- if (shaderParam && shaderParam.value) {
- var m4v = shaderParam.value;
- uvalue.fromArray(m4v);
- }
- if (value) {
- uvalue.fromArray(value);
- }
- }
- else {
- utype = "m4";
- uvalue = new THREE.Matrix4;
- if (shaderParam && shaderParam.value) {
- var m4 = shaderParam.value;
- uvalue.fromArray(m4);
- }
- if (value) {
- uvalue.fromArray(value);
- }
- }
- break;
- case THREE.GLTFLoaderUtils.WEBGL_CONSTANTS.SAMPLER_2D :
- utype = "t";
- uvalue = value ? CreateTexture(this.resources, value) : null;
- break;
- default :
- throw new Error("Unknown shader uniform param type: " + ptype + " - " + theLoader.idx[ptype]);
- break;
- }
- var udecl = { type : utype, value : uvalue, length : ulength };
- params.uniforms[uniform] = udecl;
- }
- for (var attribute in technique.attributes) {
- var pname = technique.attributes[attribute];
- var param = technique.parameters[pname];
- var atype = param.type;
- var semantic = param.semantic;
- var adecl = { type : atype, semantic : semantic };
- params.attributes[attribute] = adecl;
- }
- }
- }
- },
- threeJSMaterialType : {
- value: function(materialId, material, params) {
- var extensions = material.extensions;
- var khr_material = extensions ? extensions.KHR_materials_common : null;
- var materialType = null;
- var values;
- if (khr_material) {
- switch (khr_material.technique)
- {
- case 'BLINN' :
- case 'PHONG' :
- materialType = THREE.MeshPhongMaterial;
- break;
- case 'LAMBERT' :
- materialType = THREE.MeshLambertMaterial;
- break;
- case 'CONSTANT' :
- default :
- materialType = THREE.MeshBasicMaterial;
- break;
- }
- if (khr_material.doubleSided)
- {
- params.side = THREE.DoubleSide;
- }
- if (khr_material.transparent)
- {
- params.transparent = true;
- }
- values = {};
- for (prop in khr_material.values) {
- values[prop] = khr_material.values[prop];
- }
- }
- else if (material.technique === undefined) {
- materialType = THREE.MeshPhongMaterial;
- if (material.doubleSided)
- {
- params.side = THREE.DoubleSide;
- }
- if (material.transparent)
- {
- params.transparent = true;
- }
- values = {};
- for (var prop in material.values) {
- values[prop] = material.values[prop];
- }
- }
- else {
- var technique = this.resources.getEntry(material.technique);
- values = {};
- for (var prop in material.values) {
- values[prop] = material.values[prop];
- }
- var description = technique.description;
- if (++description.refCount > 1) {
- //console.log("refcount", description.refCount);
- }
- var programID = description.program;
- this.createShaderParams(materialId, values, params, programID, description);
- var loadshaders = true;
- if (loadshaders) {
- materialType = Material;
- }
- }
- if (values.diffuse && typeof(values.diffuse) == 'string') {
- params.map = CreateTexture(this.resources, values.diffuse);
- }
- if (values.reflective && typeof(values.reflective) == 'string') {
- params.envMap = CreateTexture(this.resources, values.reflective);
- }
- var shininess = values.shininesss || values.shininess; // N.B.: typo in converter!
- if (shininess)
- {
- shininess = shininess;
- }
- var diffuseColor = null;
- if (!params.map) {
- diffuseColor = values.diffuse;
- }
- 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;
- if (!(shininess === undefined))
- {
- params.shininess = Math.max( shininess, 1e-4 );
- }
- delete params.ambient;
- 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) {
- var params = {};
- var materialType = this.threeJSMaterialType(entryID, description, params);
- var material = new materialType(params);
- 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.mode === THREE.GLTFLoaderUtils.WEBGL_CONSTANTS.TRIANGLES) {
- var geometry = new ClassicGeometry();
- var materialEntry = this.resources.getEntry(primitiveDescription.material);
- mesh.addPrimitive(geometry, materialEntry.object);
- var allAttributes = Object.keys(primitiveDescription.attributes);
- // count them first, async issues otherwise
- allAttributes.forEach( function(semantic) {
- geometry.totalAttributes++;
- }, this);
- 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,
- componentType : indices.description.componentType,
- type : indices.description.type
- };
- var indicesContext = new IndicesContext(indicesObject, geometry);
- var loaddata = {
- indicesObject : indicesObject,
- indicesDelegate : indicesDelegate,
- indicesContext : indicesContext
- };
- theLoader.scheduleLoad(function(data) {
- var alreadyProcessedIndices =
- THREE.GLTFLoaderUtils.getBuffer(data.indicesObject,
- data.indicesDelegate, data.indicesContext);
- if (alreadyProcessedIndices) {
- data.indicesDelegate.resourceAvailable(
- alreadyProcessedIndices, data.indicesContext);
- }
- }, loaddata);
- // Load Vertex Attributes
- allAttributes.forEach( function(semantic) {
- 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,
- componentType : attribute.componentType,
- type : attribute.type,
- id : attributeID
- };
- var attribContext = new VertexAttributeContext(attributeObject, semantic, geometry);
- var loaddata = {
- attributeObject : attributeObject,
- vertexAttributeDelegate : vertexAttributeDelegate,
- attribContext : attribContext
- };
- theLoader.scheduleLoad(function(data) {
- var alreadyProcessedAttribute =
- THREE.GLTFLoaderUtils.getBuffer(data.attributeObject,
- data.vertexAttributeDelegate, data.attribContext);
- if (alreadyProcessedAttribute) {
- data.vertexAttributeDelegate.resourceAvailable(
- alreadyProcessedAttribute, data.attribContext);
- }
- }, loaddata);
- }, 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 (xfov === undefined) {
- if (yfov)
- {
- // According to COLLADA spec...
- // aspect_ratio = xfov / yfov
- xfov = yfov * aspect_ratio;
- }
- }
- if (yfov === undefined)
- {
- if (xfov)
- {
- // According to COLLADA spec...
- // aspect_ratio = xfov / yfov
- yfov = xfov / aspect_ratio;
- }
- }
- if (xfov)
- {
- xfov = THREE.Math.radToDeg(xfov);
- camera = new THREE.PerspectiveCamera(xfov, 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.jointName) {
- threeNode = new THREE.Bone();
- threeNode.jointName = description.jointName;
- this.joints[description.jointName] = entryID;
- }
- else {
- threeNode = new THREE.Object3D();
- }
- threeNode.name = description.name;
- threeNode.glTFID = entryID;
- threeNode.glTF = description;
- this.resources.setEntry(entryID, threeNode, description);
- var m = description.matrix;
- if(m) {
- threeNode.matrixAutoUpdate = false;
- threeNode.applyMatrix(new THREE.Matrix4().set(
- 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;
- 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(1, 1, 1);
- var matrix = new THREE.Matrix4;
- matrix.compose(position, rotation, scale);
- threeNode.matrixAutoUpdate = false;
- threeNode.applyMatrix(matrix);
- }
- var self = this;
- if (description.meshes) {
- description.meshInstances = {};
- var skinEntry;
- if (description.skin) {
- skinEntry = this.resources.getEntry(description.skin);
- }
- description.meshes.forEach( function(meshID) {
- meshEntry = this.resources.getEntry(meshID);
- theLoader.meshesRequested++;
- meshEntry.object.onComplete(function(mesh) {
- self.addPendingMesh(mesh, threeNode);
- description.meshInstances[meshID] = meshEntry.object;
- if (skinEntry) {
- mesh.skin = skinEntry;
- description.instanceSkin = skinEntry.object;
- }
- 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.extensions && description.extensions.KHR_materials_common
- && description.extensions.KHR_materials_common.light) {
- var lightID = description.extensions.KHR_materials_common.light;
- var lightEntry = this.resources.getEntry(lightID);
- if (lightEntry) {
- threeNode.add(lightEntry.object);
- this.lights.push(lightEntry.object);
- }
- }
- return true;
- }
- },
- handleExtension: {
- value: function(entryID, description, userInfo) {
- // console.log("Extension", entryID, description);
- switch (entryID) {
- case 'KHR_materials_common' :
- var lights = description.lights;
- for (lightID in lights) {
- var light = lights[lightID];
- this.handleLight(lightID, light);
- }
- break;
- }
- 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 glTF = node.glTF;
- var skin = glTF.instanceSkin;
- var skeletons = glTF.skeletons;
- if (skin) {
- skeletons.forEach(function(skeleton) {
- var nodeEntry = this.resources.getEntry(skeleton);
- if (nodeEntry) {
- var rootSkeleton = nodeEntry.object;
- node.add(rootSkeleton);
- var dobones = true;
- for (meshID in glTF.meshInstances) {
- var mesh = glTF.meshInstances[meshID];
- var threeMesh = null;
- mesh.primitives.forEach(function(primitive) {
- var material = primitive.material;
- var materialParams = material.params;
- if (!(material instanceof THREE.Material)) {
- material = createShaderMaterial(material);
- }
- threeMesh = new THREE.SkinnedMesh(primitive.geometry.geometry, material, false);
- 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;
- var jointNames = skin.jointNames;
- var joints = [];
- var bones = [];
- var boneInverses = [];
- var i, len = jointNames.length;
- for (i = 0; i < len; i++) {
- var jointName = jointNames[i];
- var nodeForJoint = this.joints[jointName];
- var joint = this.resources.getEntry(nodeForJoint).object;
- if (joint) {
- joint.skin = threeMesh;
- joints.push(joint);
- bones.push(joint);
- var m = skin.inverseBindMatrices;
- var mat = new THREE.Matrix4().set(
- m[i * 16 + 0], m[i * 16 + 4], m[i * 16 + 8], m[i * 16 + 12],
- m[i * 16 + 1], m[i * 16 + 5], m[i * 16 + 9], m[i * 16 + 13],
- m[i * 16 + 2], m[i * 16 + 6], m[i * 16 + 10], m[i * 16 + 14],
- m[i * 16 + 3], m[i * 16 + 7], m[i * 16 + 11], m[i * 16 + 15]
- );
- boneInverses.push(mat);
- } else {
- console.log("WARNING: jointName:"+jointName+" cannot be found in skeleton:"+skeleton);
- }
- }
- threeMesh.bind( new THREE.Skeleton( bones,
- boneInverses, false ), skin.bindShapeMatrix );
- //threeMesh.bindMode = "detached";
- //threeMesh.normalizeSkinWeights();
- //threeMesh.pose();
- }
- if (threeMesh) {
- threeMesh.castShadow = true;
- node.add(threeMesh);
- if (material instanceof THREE.ShaderMaterial) {
- materialParams.joints = joints;
- var glTFShader = new THREE.glTFShader(material, materialParams, threeMesh, theLoader.rootObj);
- THREE.glTFShaders.add(glTFShader);
- }
- }
- }, this);
- }
- }
- }, this);
- }
- }
- },
- buildSkins: {
- value: function(node) {
- if (node.glTF && node.glTF.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);
- }
- theLoader.loadAllAssets();
- 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;
- 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) {
- // async help
- animation.totalParameters++;
- }, this);
- var params = Object.keys(parameters);
- params.forEach( function(param) {
- 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,
- componentType : accessor.componentType,
- type : accessor.type,
- id : accessor.bufferView,
- name : param
- };
- var paramContext = new AnimationParameterContext(paramObject, animation);
- var loaddata = {
- paramObject : paramObject,
- animationParameterDelegate : animationParameterDelegate,
- paramContext : paramContext
- };
- theLoader.scheduleLoad(function(data) {
- var alreadyProcessedAttribute =
- THREE.GLTFLoaderUtils.getBuffer(data.paramObject,
- data.animationParameterDelegate, data.paramContext);
- if (alreadyProcessedAttribute) {
- data.animationParameterDelegate.resourceAvailable(
- alreadyProcessedAttribute, data.paramContext);
- }
- }, loaddata);
- }, 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().set(
- 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.jointNames = description.jointNames;
- var inverseBindMatricesDescription = this.resources.getEntry(description.inverseBindMatrices);
- inverseBindMatricesDescription = inverseBindMatricesDescription.description;
- skin.inverseBindMatricesDescription = inverseBindMatricesDescription;
- skin.inverseBindMatricesDescription.id = description.inverseBindMatrices;
- var bufferEntry = this.resources.getEntry(inverseBindMatricesDescription.bufferView);
- var paramObject = {
- bufferView : bufferEntry,
- byteOffset : inverseBindMatricesDescription.byteOffset,
- count : inverseBindMatricesDescription.count,
- componentType : inverseBindMatricesDescription.componentType,
- type : inverseBindMatricesDescription.type,
- id : inverseBindMatricesDescription.bufferView,
- name : skin.inverseBindMatricesDescription.id
- };
- var context = new InverseBindMatricesContext(paramObject, skin);
- var loaddata = {
- paramObject : paramObject,
- inverseBindMatricesDelegate : inverseBindMatricesDelegate,
- context : context
- };
- theLoader.scheduleLoad(function(data) {
- var alreadyProcessedAttribute =
- THREE.GLTFLoaderUtils.getBuffer(data.paramObject,
- data.inverseBindMatricesDelegate, data.context);
- if (alreadyProcessedAttribute) {
- data.inverseBindMatricesDelegate.resourceAvailable(
- alreadyProcessedAttribute, data.context);
- }
- }, loaddata);
- 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;
- this.callback = callback;
- this.rootObj = rootObj;
- this.loader = Object.create(ThreeGLTFLoader);
- this.loader.initWithPath(url);
- this.loader.load(new Context(rootObj,
- function(obj) {
- }),
- null);
- return rootObj;
- }
- THREE.glTFLoader.prototype.scheduleLoad = function(loadFn, data) {
- this.loadRequests.push({fn: loadFn, data:data});
- }
- THREE.glTFLoader.prototype.loadAllAssets = function() {
- for (var i = 0, len = this.loadRequests.length; i < len; i++) {
- var request = this.loadRequests[i];
- request.fn(request.data);
- }
- }
- THREE.glTFLoader.prototype.callLoadedCallback = function() {
- var result = {
- scene : this.rootObj,
- cameras : this.loader.cameras,
- animations : this.loader.animations,
- shaders : this.loader.shaders,
- };
- 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);
- THREE.glTFShaders.bindShaderParameters(this.rootObj);
- this.callLoadedCallback();
- }
- }
|