1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918 |
- /**
- * @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 = {};
- THREE.Loader.call( this );
- };
- THREE.glTFLoader.prototype = Object.create( THREE.Loader.prototype );
- 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() {
- 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.addAttribute( 'index', new THREE.BufferAttribute( this.indexArray, 1 ) );
- geometry.addDrawCall( 0, this.indexArray.length );
- geometry.computeBoundingSphere();
- };
- ClassicGeometry.prototype.checkFinished = function() {
- if ( this.indexArray && this.loadedAttributes === this.totalAttributes ) {
- 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.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.addAttribute( 'position', new THREE.BufferAttribute( floatArray, 3 ) );
- } else if ( semantic == "NORMAL" ) {
- floatArray = new Float32Array( glResource, 0, attribute.count * componentsPerElementForGLType( attribute.type ) );
- geom.geometry.addAttribute( 'normal', new THREE.BufferAttribute( floatArray, 3 ) );
- } else if ( ( semantic == "TEXCOORD_0" ) || ( semantic == "TEXCOORD" ) ) {
- 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
- 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;
- theLoader.checkComplete();
- 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.emission === undefined ) )
- {
- params.emissive = RgbArraytoHex( values.emission );
- }
- if ( ! ( values.specular === undefined ) )
- {
- params.specular = RgbArraytoHex( values.specular );
- }
- return materialType;
- }
- },
- handleMaterial: {
- value: function( entryID, description, userInfo ) {
- //this should be rewritten using the meta datas that actually create the shader.
- //here we will infer what needs to be pass to Three.js by looking inside the technique parameters.
- var technique = this.resources.getEntry( description.instanceTechnique.technique );
- var materialParams = {};
- var values = description.instanceTechnique.values;
- var materialType = this.threeJSMaterialType( entryID, technique, values, materialParams );
- var material = new materialType( materialParams );
- this.resources.setEntry( entryID, material, description );
- return true;
- }
- },
- handleMesh: {
- value: function( entryID, description, userInfo ) {
- var mesh = new Mesh();
- this.resources.setEntry( entryID, mesh, description );
- var primitivesDescription = description.primitives;
- if ( ! primitivesDescription ) {
- //FIXME: not implemented in delegate
- console.log( "MISSING_PRIMITIVES for mesh:" + entryID );
- return false;
- }
- for ( var i = 0 ; i < primitivesDescription.length ; i ++ ) {
- var primitiveDescription = primitivesDescription[ i ];
- if ( primitiveDescription.primitive === WebGLRenderingContext.TRIANGLES ) {
- var geometry = new ClassicGeometry();
- var materialEntry = this.resources.getEntry( primitiveDescription.material );
- mesh.addPrimitive( geometry, materialEntry.object );
- var indices = this.resources.getEntry( primitiveDescription.indices );
- var bufferEntry = this.resources.getEntry( indices.description.bufferView );
- var indicesObject = {
- bufferView : bufferEntry,
- byteOffset : indices.description.byteOffset,
- count : indices.description.count,
- id : indices.entryID,
- type : indices.description.type
- };
- var indicesContext = new IndicesContext( indicesObject, geometry );
- var alreadyProcessedIndices = THREE.GLTFLoaderUtils.getBuffer( indicesObject, indicesDelegate, indicesContext );
- /*if(alreadyProcessedIndices) {
- indicesDelegate.resourceAvailable(alreadyProcessedIndices, indicesContext);
- }*/
-
- // Load Vertex Attributes
- var allAttributes = Object.keys( primitiveDescription.attributes );
- allAttributes.forEach( function( semantic ) {
- geometry.totalAttributes ++;
- var attribute;
- var attributeID = primitiveDescription.attributes[ semantic ];
- var attributeEntry = this.resources.getEntry( attributeID );
- if ( ! attributeEntry ) {
- //let's just use an anonymous object for the attribute
- attribute = description.attributes[ attributeID ];
- attribute.id = attributeID;
- this.resources.setEntry( attributeID, attribute, attribute );
- var bufferEntry = this.resources.getEntry( attribute.bufferView );
- attributeEntry = this.resources.getEntry( attributeID );
- } else {
- attribute = attributeEntry.object;
- attribute.id = attributeID;
- var bufferEntry = this.resources.getEntry( attribute.bufferView );
- }
- var attributeObject = {
- bufferView : bufferEntry,
- byteOffset : attribute.byteOffset,
- byteStride : attribute.byteStride,
- count : attribute.count,
- max : attribute.max,
- min : attribute.min,
- type : attribute.type,
- id : attributeID
- };
- var attribContext = new VertexAttributeContext( attributeObject, semantic, geometry );
- var alreadyProcessedAttribute = THREE.GLTFLoaderUtils.getBuffer( attributeObject, vertexAttributeDelegate, attribContext );
- /*if(alreadyProcessedAttribute) {
- vertexAttributeDelegate.resourceAvailable(alreadyProcessedAttribute, attribContext);
- }*/
-
- }, this );
- }
- }
- return true;
- }
- },
- handleCamera: {
- value: function( entryID, description, userInfo ) {
- var camera;
- if ( description.type == "perspective" ) {
- var znear = description.perspective.znear;
- var zfar = description.perspective.zfar;
- var yfov = description.perspective.yfov;
- var xfov = description.perspective.xfov;
- var aspect_ratio = description.perspective.aspect_ratio;
- if ( ! aspect_ratio ) {
-
- aspect_ratio = 1;
-
- }
- if ( yfov === undefined ) {
- if ( xfov ) {
- // According to COLLADA spec...
- // aspect_ratio = xfov / yfov
- yfov = xfov / aspect_ratio;
- }
- }
- if ( yfov ) {
- camera = new THREE.PerspectiveCamera( yfov, aspect_ratio, znear, zfar );
- }
- } else {
- camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, znear, zfar );
-
- }
- if ( camera ) {
- this.resources.setEntry( entryID, camera, description );
- }
- return true;
- }
- },
- handleLight: {
- value: function( entryID, description, userInfo ) {
- var light = null;
- var type = description.type;
- if ( type && description[ type ] ) {
- var lparams = description[ type ];
- var color = RgbArraytoHex( lparams.color );
- switch ( type ) {
- case "directional" :
- light = new THREE.DirectionalLight( color );
- light.position.set( 0, 0, 1 );
- break;
- case "point" :
- light = new THREE.PointLight( color );
- break;
- case "spot " :
- light = new THREE.SpotLight( color );
- light.position.set( 0, 0, 1 );
- break;
- case "ambient" :
- light = new THREE.AmbientLight( color );
- break;
- }
- }
- if ( light ) {
- this.resources.setEntry( entryID, light, description );
- }
- return true;
- }
- },
- addPendingMesh: {
- value: function( mesh, threeNode ) {
- theLoader.pendingMeshes.push( {
-
- mesh: mesh,
- node: threeNode
-
- } );
- }
- },
- handleNode: {
- value: function( entryID, description, userInfo ) {
- var threeNode = null;
- if ( description.jointId ) {
- threeNode = new THREE.Bone();
- threeNode.jointId = description.jointId;
- this.joints[ description.jointId ] = entryID;
- }
- else {
- threeNode = new THREE.Object3D();
- }
- threeNode.name = description.name;
- this.resources.setEntry( entryID, threeNode, description );
- var m = description.matrix;
- if ( m ) {
- threeNode.applyMatrix( new THREE.Matrix4().fromArray( m ) );
- threeNode.matrixAutoUpdate = false;
- threeNode.matrixWorldNeedsUpdate = true;
- } else {
- var t = description.translation;
- var r = description.rotation;
- var s = description.scale;
- var position = t ? new THREE.Vector3( t[ 0 ], t[ 1 ], t[ 2 ] ) : new THREE.Vector3;
-
- if ( r ) {
- convertAxisAngleToQuaternion( r, 1 );
- }
-
- var rotation = r ? new THREE.Quaternion( r[ 0 ], r[ 1 ], r[ 2 ], r[ 3 ] ) : new THREE.Quaternion;
- var scale = s ? new THREE.Vector3( s[ 0 ], s[ 1 ], s[ 2 ] ) : new THREE.Vector3;
- var matrix = new THREE.Matrix4;
- matrix.compose( position, rotation, scale );
- threeNode.matrixAutoUpdate = false;
- threeNode.matrixWorldNeedsUpdate = true;
- threeNode.applyMatrix( matrix );
- }
- var self = this;
- // Iterate through all node meshes and attach the appropriate objects
- //FIXME: decision needs to be made between these 2 ways, probably meshes will be discarded.
- var meshEntry;
- if ( description.mesh ) {
- meshEntry = this.resources.getEntry( description.mesh );
- theLoader.meshesRequested ++;
- meshEntry.object.onComplete( function( mesh ) {
- self.addPendingMesh( mesh, threeNode );
- theLoader.meshesLoaded ++;
- theLoader.checkComplete();
- } );
- }
- if ( description.meshes ) {
- description.meshes.forEach( function( meshID ) {
- meshEntry = this.resources.getEntry( meshID );
- theLoader.meshesRequested ++;
- meshEntry.object.onComplete( function( mesh ) {
- self.addPendingMesh( mesh, threeNode );
- theLoader.meshesLoaded ++;
- theLoader.checkComplete();
- } );
- }, this );
- }
- if ( description.instanceSkin ) {
- var skinEntry = this.resources.getEntry( description.instanceSkin.skin );
- if ( skinEntry ) {
- var skin = skinEntry.object;
- description.instanceSkin.skin = skin;
- threeNode.instanceSkin = description.instanceSkin;
- var sources = description.instanceSkin.sources;
- skin.meshes = [];
- sources.forEach( function( meshID ) {
- meshEntry = this.resources.getEntry( meshID );
- theLoader.meshesRequested ++;
- meshEntry.object.onComplete( function( mesh ) {
- skin.meshes.push( mesh );
- theLoader.meshesLoaded ++;
- theLoader.checkComplete();
- } );
- }, this );
- }
- }
- if ( description.camera ) {
- var cameraEntry = this.resources.getEntry( description.camera );
- if ( cameraEntry ) {
- threeNode.add( cameraEntry.object );
- this.cameras.push( cameraEntry.object );
- }
- }
- if ( description.light ) {
- var lightEntry = this.resources.getEntry( description.light );
- if ( lightEntry ) {
- threeNode.add( lightEntry.object );
- this.lights.push( lightEntry.object );
- }
- }
- return true;
- }
- },
- buildNodeHirerachy: {
- value: function( nodeEntryId, parentThreeNode ) {
- var nodeEntry = this.resources.getEntry( nodeEntryId );
- var threeNode = nodeEntry.object;
- parentThreeNode.add( threeNode );
- var children = nodeEntry.description.children;
- if ( children ) {
- children.forEach( function( childID ) {
- this.buildNodeHirerachy( childID, threeNode );
- }, this );
- }
- return threeNode;
- }
- },
- buildSkin: {
- value: function( node ) {
- var skin = node.instanceSkin.skin;
- if ( skin ) {
- node.instanceSkin.skeletons.forEach( function( skeleton ) {
- var nodeEntry = this.resources.getEntry( skeleton );
- if ( nodeEntry ) {
- var rootSkeleton = nodeEntry.object;
- var dobones = true;
- var i, len = skin.meshes.length;
- for ( i = 0; i < len; i ++ ) {
- var mesh = skin.meshes[ i ];
- var threeMesh = null;
- mesh.primitives.forEach( function( primitive ) {
- var material = primitive.material;
- if ( ! ( material instanceof THREE.Material ) ) {
- material = this.createShaderMaterial( material );
- }
- threeMesh = new THREE.SkinnedMesh( primitive.geometry.geometry, material, false );
- threeMesh.add( rootSkeleton );
- var geometry = primitive.geometry.geometry;
- var j;
- if ( geometry.vertices ) {
- for ( j = 0; j < geometry.vertices.length; j ++ ) {
- geometry.vertices[ j ].applyMatrix4( skin.bindShapeMatrix );
- }
- } else if ( geometry.attributes.position ) {
- var a = geometry.attributes.position.array;
- var v = new THREE.Vector3;
- for ( j = 0; j < a.length / 3; j ++ ) {
- v.set( a[ j * 3 ], a[ j * 3 + 1 ], a[ j * 3 + 2 ] );
- v.applyMatrix4( skin.bindShapeMatrix );
- a[ j * 3 ] = v.x;
- a[ j * 3 + 1 ] = v.y;
- a[ j * 3 + 2 ] = v.z;
- }
- }
- if ( threeMesh && dobones ) {
- material.skinning = true;
- threeMesh.boneInverses = [];
- var jointsIds = skin.jointsIds;
- var bones = [];
- var boneInverses = [];
- var i, len = jointsIds.length;
- for ( i = 0; i < len; i ++ ) {
- var jointId = jointsIds[ i ];
- var nodeForJoint = this.joints[ jointId ];
- var joint = this.resources.getEntry( nodeForJoint ).object;
- if ( joint ) {
- joint.skin = threeMesh;
- bones.push( joint );
- var m = skin.inverseBindMatrices;
- var mat = new THREE.Matrix4().set(
- m[ i * 16 + 0 ], m[ i * 16 + 4 ], m[ i * 16 + 8 ], m[ i * 16 + 12 ],
- m[ i * 16 + 1 ], m[ i * 16 + 5 ], m[ i * 16 + 9 ], m[ i * 16 + 13 ],
- m[ i * 16 + 2 ], m[ i * 16 + 6 ], m[ i * 16 + 10 ], m[ i * 16 + 14 ],
- m[ i * 16 + 3 ], m[ i * 16 + 7 ], m[ i * 16 + 11 ], m[ i * 16 + 15 ]
- );
- boneInverses.push( mat );
- } else {
- console.log( "WARNING: jointId:" + jointId + " cannot be found in skeleton:" + skeleton );
- }
- }
-
- threeMesh.bind( new THREE.Skeleton( bones, boneInverses, false ), threeMesh.matrixWorld );
- }
- if ( threeMesh ) {
- threeMesh.castShadow = true;
- node.add( threeMesh );
- }
- }, this );
- }
- }
- }, this );
- }
- }
- },
- buildSkins: {
- value: function( node ) {
- if ( node.instanceSkin ) {
- this.buildSkin( node );
- }
- var children = node.children;
-
- if ( children ) {
- children.forEach( function( child ) {
- this.buildSkins( child );
- }, this );
- }
- }
- },
- createMeshAnimations : {
- value : function( root ) {
- this.buildSkins( root );
- }
- },
- handleScene: {
- value: function( entryID, description, userInfo ) {
- if ( ! description.nodes ) {
- console.log( "ERROR: invalid file required nodes property is missing from scene" );
- return false;
- }
- description.nodes.forEach( function( nodeUID ) {
- this.buildNodeHirerachy( nodeUID, userInfo.rootObj );
- }, this );
- if ( this.delegate ) {
- this.delegate.loadCompleted( userInfo.callback, userInfo.rootObj );
- }
- return true;
- }
- },
- handleImage: {
- value: function( entryID, description, userInfo ) {
- this.resources.setEntry( entryID, null, description );
- return true;
- }
- },
- addNodeAnimationChannel : {
- value : function( name, channel, interp ) {
- if ( ! this.nodeAnimationChannels ) {
-
- this.nodeAnimationChannels = {};
-
- }
- if ( ! this.nodeAnimationChannels[ name ] ) {
- this.nodeAnimationChannels[ name ] = [];
- }
- this.nodeAnimationChannels[ name ].push( interp );
- },
- },
- createAnimations : {
- value : function() {
- for ( var name in this.nodeAnimationChannels ) {
- var nodeAnimationChannels = this.nodeAnimationChannels[ name ];
- var i, len = nodeAnimationChannels.length;
- //console.log(" animation channels for node " + name);
- //for (i = 0; i < len; i++) {
- // console.log(nodeAnimationChannels[i]);
- //}
- var anim = new THREE.glTFAnimation( nodeAnimationChannels );
- anim.name = "animation_" + name;
- this.animations.push( anim );
- }
- }
- },
- buildAnimation: {
- value : function( animation ) {
- var interps = [];
- var i, len = animation.channels.length;
- for ( i = 0; i < len; i ++ ) {
- var channel = animation.channels[ i ];
- var sampler = animation.samplers[ channel.sampler ];
- if ( sampler ) {
- var input = animation.parameters[ sampler.input ];
- if ( input && input.data ) {
- var output = animation.parameters[ sampler.output ];
- if ( output && output.data ) {
- var target = channel.target;
- var node = this.resources.getEntry( target.id );
- if ( node ) {
- var path = target.path;
- if ( path == "rotation" ) {
- convertAxisAngleToQuaternion( output.data, output.count );
- }
- var interp = {
- keys : input.data,
- values : output.data,
- count : input.count,
- target : node.object,
- path : path,
- type : sampler.interpolation
- };
- this.addNodeAnimationChannel( target.id, channel, interp );
- interps.push( interp );
- }
- }
- }
- }
- }
- }
- },
- handleAnimation: {
- value: function( entryID, description, userInfo ) {
- var self = this;
- theLoader.animationsRequested ++;
- var animation = new Animation();
- animation.name = entryID;
- animation.onload = function() {
- // self.buildAnimation(animation);
- theLoader.animationsLoaded ++;
- theLoader.animations.push( animation );
- theLoader.checkComplete();
- };
- animation.channels = description.channels;
- animation.samplers = description.samplers;
- this.resources.setEntry( entryID, animation, description );
- var parameters = description.parameters;
- if ( ! parameters ) {
- //FIXME: not implemented in delegate
- console.log( "MISSING_PARAMETERS for animation:" + entryID );
- return false;
- }
- // Load parameter buffers
- var params = Object.keys( parameters );
- params.forEach( function( param ) {
- animation.totalParameters ++;
- var parameter = parameters[ param ];
- var accessor = this.resources.getEntry( parameter );
-
- if ( ! accessor ) {
- debugger;
- }
-
- accessor = accessor.object;
- var bufferView = this.resources.getEntry( accessor.bufferView );
- var paramObject = {
- bufferView : bufferView,
- byteOffset : accessor.byteOffset,
- count : accessor.count,
- type : accessor.type,
- id : accessor.bufferView,
- name : param
- };
- var paramContext = new AnimationParameterContext( paramObject, animation );
- var alreadyProcessedAttribute = THREE.GLTFLoaderUtils.getBuffer( paramObject, animationParameterDelegate, paramContext );
- /*if ( alreadyProcessedAttribute ) {
- vertexAttributeDelegate.resourceAvailable(alreadyProcessedAttribute, attribContext);
- }*/
-
- }, this );
- return true;
- }
- },
- handleAccessor: {
-
- value: function( entryID, description, userInfo ) {
- // Save attribute entry
- this.resources.setEntry( entryID, description, description );
- return true;
- }
- },
- handleSkin: {
-
- value: function( entryID, description, userInfo ) {
- // Save skin entry
- var skin = {};
- var m = description.bindShapeMatrix;
- skin.bindShapeMatrix = new THREE.Matrix4().fromArray( m );
- skin.jointsIds = description.joints;
- var inverseBindMatricesDescription = description.inverseBindMatrices;
- skin.inverseBindMatricesDescription = inverseBindMatricesDescription;
- skin.inverseBindMatricesDescription.id = entryID + "_inverseBindMatrices";
- var bufferEntry = this.resources.getEntry( inverseBindMatricesDescription.bufferView );
- var paramObject = {
-
- bufferView : bufferEntry,
- byteOffset : inverseBindMatricesDescription.byteOffset,
- count : inverseBindMatricesDescription.count,
- type : inverseBindMatricesDescription.type,
- id : inverseBindMatricesDescription.bufferView,
- name : skin.inverseBindMatricesDescription.id
-
- };
- var context = new InverseBindMatricesContext( paramObject, skin );
- var alreadyProcessedAttribute = THREE.GLTFLoaderUtils.getBuffer( paramObject, inverseBindMatricesDelegate, context );
- var bufferView = this.resources.getEntry( skin.inverseBindMatricesDescription.bufferView );
- skin.inverseBindMatricesDescription.bufferView =
- bufferView.object;
- this.resources.setEntry( entryID, skin, description );
- return true;
- }
- },
- handleSampler: {
- value: function( entryID, description, userInfo ) {
- // Save attribute entry
- this.resources.setEntry( entryID, description, description );
- return true;
- }
- },
- handleTexture: {
- value: function( entryID, description, userInfo ) {
- // Save attribute entry
- this.resources.setEntry( entryID, null, description );
- return true;
- }
- },
- handleError: {
- value: function( msg ) {
- throw new Error( msg );
- return true;
- }
- },
- _delegate: {
- value: new LoadDelegate,
- writable: true
- },
- delegate: {
- enumerable: true,
- get: function() {
- return this._delegate;
- },
- set: function( value ) {
- this._delegate = value;
- }
- }
- } );
- // Loader
- var Context = function( rootObj, callback ) {
- this.rootObj = rootObj;
- this.callback = callback;
- };
- var rootObj = new THREE.Object3D();
- var self = this;
- var loader = Object.create( ThreeGLTFLoader );
- loader.initWithPath( url );
- loader.load( new Context( rootObj, function( obj ) {} ), null );
- 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();
- }
- };
|