loadAnimation( animationIndex ) {

    		const json = this.json;

    		const animationDef = json.animations[ animationIndex ];

    		const pendingNodes = [];
    		const pendingInputAccessors = [];
    		const pendingOutputAccessors = [];
    		const pendingSamplers = [];
    		const pendingTargets = [];

    		for ( let i = 0, il = animationDef.channels.length; i < il; i ++ ) {

    			const channel = animationDef.channels[ i ];
    			const sampler = animationDef.samplers[ channel.sampler ];
    			const target = channel.target;
    			const name = target.node !== undefined ? target.node : target.id; // NOTE: target.id is deprecated.
    			const input = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.input ] : sampler.input;
    			const output = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.output ] : sampler.output;

    			pendingNodes.push( this.getDependency( 'node', name ) );
    			pendingInputAccessors.push( this.getDependency( 'accessor', input ) );
    			pendingOutputAccessors.push( this.getDependency( 'accessor', output ) );
    			pendingSamplers.push( sampler );
    			pendingTargets.push( target );

    		}

    		return Promise.all( [

    			Promise.all( pendingNodes ),
    			Promise.all( pendingInputAccessors ),
    			Promise.all( pendingOutputAccessors ),
    			Promise.all( pendingSamplers ),
    			Promise.all( pendingTargets )

    		] ).then( function ( dependencies ) {

    			const nodes = dependencies[ 0 ];
    			const inputAccessors = dependencies[ 1 ];
    			const outputAccessors = dependencies[ 2 ];
    			const samplers = dependencies[ 3 ];
    			const targets = dependencies[ 4 ];

    			const tracks = [];

    			for ( let i = 0, il = nodes.length; i < il; i ++ ) {

    				const node = nodes[ i ];
    				const inputAccessor = inputAccessors[ i ];
    				const outputAccessor = outputAccessors[ i ];
    				const sampler = samplers[ i ];
    				const target = targets[ i ];

    				if ( node === undefined ) continue;

    				node.updateMatrix();
    				node.matrixAutoUpdate = true;

    				let TypedKeyframeTrack;

    				switch ( PATH_PROPERTIES$1[ target.path ] ) {

    					case PATH_PROPERTIES$1.weights:

    						TypedKeyframeTrack = NumberKeyframeTrack;
    						break;

    					case PATH_PROPERTIES$1.rotation:

    						TypedKeyframeTrack = QuaternionKeyframeTrack;
    						break;

    					case PATH_PROPERTIES$1.position:
    					case PATH_PROPERTIES$1.scale:
    					default:

    						TypedKeyframeTrack = VectorKeyframeTrack;
    						break;

    				}

    				const targetName = node.name ? node.name : node.uuid;

    				const interpolation = sampler.interpolation !== undefined ? INTERPOLATION[ sampler.interpolation ] : InterpolateLinear;

    				const targetNames = [];

    				if ( PATH_PROPERTIES$1[ target.path ] === PATH_PROPERTIES$1.weights ) {

    					node.traverse( function ( object ) {

    						if ( object.morphTargetInfluences ) {

    							targetNames.push( object.name ? object.name : object.uuid );

    						}

    					} );

    				} else {

    					targetNames.push( targetName );

    				}

    				let outputArray = outputAccessor.array;

    				if ( outputAccessor.normalized ) {

    					const scale = getNormalizedComponentScale( outputArray.constructor );
    					const scaled = new Float32Array( outputArray.length );

    					for ( let j = 0, jl = outputArray.length; j < jl; j ++ ) {

    						scaled[ j ] = outputArray[ j ] * scale;

    					}

    					outputArray = scaled;

    				}

    				for ( let j = 0, jl = targetNames.length; j < jl; j ++ ) {

    					const track = new TypedKeyframeTrack(
    						targetNames[ j ] + '.' + PATH_PROPERTIES$1[ target.path ],
    						inputAccessor.array,
    						outputArray,
    						interpolation
    					);

    					// Override interpolation with custom factory method.
    					if ( sampler.interpolation === 'CUBICSPLINE' ) {

    						track.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline( result ) {

    							// A CUBICSPLINE keyframe in glTF has three output values for each input value,
    							// representing inTangent, splineVertex, and outTangent. As a result, track.getValueSize()
    							// must be divided by three to get the interpolant's sampleSize argument.

    							const interpolantType = ( this instanceof QuaternionKeyframeTrack ) ? GLTFCubicSplineQuaternionInterpolant : GLTFCubicSplineInterpolant;

    							return new interpolantType( this.times, this.values, this.getValueSize() / 3, result );

    						};

    						// Mark as CUBICSPLINE. `track.getInterpolation()` doesn't support custom interpolants.
    						track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true;

    					}

    					tracks.push( track );

    				}

    			}

    			const name = animationDef.name ? animationDef.name : 'animation_' + animationIndex;

    			return new AnimationClip( name, undefined, tracks );

    		} );

    	}
Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations
@param {number} animationIndex
@return {Promise<AnimationClip>}