/**
 * Copyright 2019 the three.js authors
 * SPDX-License-Identifier: MIT
 */

/**
 * @author Rich Tibbett / https://github.com/richtr
 * @author mrdoob / http://mrdoob.com/
 * @author Tony Parisi / http://www.tonyparisi.com/
 * @author Takahiro / https://github.com/takahirox
 * @author Don McCurdy / https://www.donmccurdy.com
 */

/**
 * A modified version of THREE.GLTFLoader, with support for the (hypothetical)
 * GOOGLE_texture_basis extension. This extension is defined for the sake of
 * example only – the glTF format will officially reference Basis files within
 * a KTX2 wrapper.
 */
THREE.GLTFLoader = ( function () {

  function GLTFLoader( manager ) {

    this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
    this.dracoLoader = null;

  }

  GLTFLoader.prototype = {

    constructor: GLTFLoader,

    crossOrigin: 'anonymous',

    load: function ( url, onLoad, onProgress, onError ) {

      var scope = this;

      var resourcePath;

      if ( this.resourcePath !== undefined ) {

        resourcePath = this.resourcePath;

      } else if ( this.path !== undefined ) {

        resourcePath = this.path;

      } else {

        resourcePath = THREE.LoaderUtils.extractUrlBase( url );

      }

      // Tells the LoadingManager to track an extra item, which resolves after
      // the model is fully loaded. This means the count of items loaded will
      // be incorrect, but ensures manager.onLoad() does not fire early.
      scope.manager.itemStart( url );

      var _onError = function ( e ) {

        if ( onError ) {

          onError( e );

        } else {

          console.error( e );

        }

        scope.manager.itemError( url );
        scope.manager.itemEnd( url );

      };

      var loader = new THREE.FileLoader( scope.manager );

      loader.setPath( this.path );
      loader.setResponseType( 'arraybuffer' );

      loader.load( url, function ( data ) {

        try {

          scope.parse( data, resourcePath, function ( gltf ) {

            onLoad( gltf );

            scope.manager.itemEnd( url );

          }, _onError );

        } catch ( e ) {

          _onError( e );

        }

      }, onProgress, _onError );

    },

    setCrossOrigin: function ( value ) {

      this.crossOrigin = value;
      return this;

    },

    setPath: function ( value ) {

      this.path = value;
      return this;

    },

    setResourcePath: function ( value ) {

      this.resourcePath = value;
      return this;

    },

    setDRACOLoader: function ( dracoLoader ) {

      this.dracoLoader = dracoLoader;
      return this;

    },

    parse: function ( data, path, onLoad, onError ) {

      var content;
      var extensions = {};

      if ( typeof data === 'string' ) {

        content = data;

      } else {

        var magic = THREE.LoaderUtils.decodeText( new Uint8Array( data, 0, 4 ) );

        if ( magic === BINARY_EXTENSION_HEADER_MAGIC ) {

          try {

            extensions[ EXTENSIONS.KHR_BINARY_GLTF ] = new GLTFBinaryExtension( data );

          } catch ( error ) {

            if ( onError ) onError( error );
            return;

          }

          content = extensions[ EXTENSIONS.KHR_BINARY_GLTF ].content;

        } else {

          content = THREE.LoaderUtils.decodeText( new Uint8Array( data ) );

        }

      }

      var json = JSON.parse( content );

      if ( json.asset === undefined || json.asset.version[ 0 ] < 2 ) {

        if ( onError ) onError( new Error( 'THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported. Use LegacyGLTFLoader instead.' ) );
        return;

      }

      if ( json.extensionsUsed ) {

        for ( var i = 0; i < json.extensionsUsed.length; ++ i ) {

          var extensionName = json.extensionsUsed[ i ];
          var extensionsRequired = json.extensionsRequired || [];

          switch ( extensionName ) {

            case EXTENSIONS.KHR_LIGHTS_PUNCTUAL:
              extensions[ extensionName ] = new GLTFLightsExtension( json );
              break;

            case EXTENSIONS.KHR_MATERIALS_UNLIT:
              extensions[ extensionName ] = new GLTFMaterialsUnlitExtension( json );
              break;

            case EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS:
              extensions[ extensionName ] = new GLTFMaterialsPbrSpecularGlossinessExtension( json );
              break;

            case EXTENSIONS.KHR_DRACO_MESH_COMPRESSION:
              extensions[ extensionName ] = new GLTFDracoMeshCompressionExtension( json, this.dracoLoader );
              break;

            case EXTENSIONS.MSFT_TEXTURE_DDS:
              extensions[ EXTENSIONS.MSFT_TEXTURE_DDS ] = new GLTFTextureDDSExtension();
              break;

            case EXTENSIONS.GOOGLE_TEXTURE_BASIS:
              extensions[ EXTENSIONS.GOOGLE_TEXTURE_BASIS ] = new GLTFTextureBasisExtension();
              break;

            case EXTENSIONS.KHR_TEXTURE_TRANSFORM:
              extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] = new GLTFTextureTransformExtension( json );
              break;

            default:

              if ( extensionsRequired.indexOf( extensionName ) >= 0 ) {

                console.warn( 'THREE.GLTFLoader: Unknown extension "' + extensionName + '".' );

              }

          }

        }

      }

      var parser = new GLTFParser( json, extensions, {

        path: path || this.resourcePath || '',
        crossOrigin: this.crossOrigin,
        manager: this.manager

      } );

      parser.parse( onLoad, onError );

    }

  };

  /* GLTFREGISTRY */

  function GLTFRegistry() {

    var objects = {};

    return  {

      get: function ( key ) {

        return objects[ key ];

      },

      add: function ( key, object ) {

        objects[ key ] = object;

      },

      remove: function ( key ) {

        delete objects[ key ];

      },

      removeAll: function () {

        objects = {};

      }

    };

  }

  /*********************************/
  /********** EXTENSIONS ***********/
  /*********************************/

  var EXTENSIONS = {
    KHR_BINARY_GLTF: 'KHR_binary_glTF',
    KHR_DRACO_MESH_COMPRESSION: 'KHR_draco_mesh_compression',
    KHR_LIGHTS_PUNCTUAL: 'KHR_lights_punctual',
    KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: 'KHR_materials_pbrSpecularGlossiness',
    KHR_MATERIALS_UNLIT: 'KHR_materials_unlit',
    KHR_TEXTURE_TRANSFORM: 'KHR_texture_transform',
    MSFT_TEXTURE_DDS: 'MSFT_texture_dds',
    GOOGLE_TEXTURE_BASIS: 'GOOGLE_texture_basis'
  };

  /**
   * DDS Texture Extension
   *
   * Specification:
   * https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_texture_dds
   *
   */
  function GLTFTextureDDSExtension() {

    if ( ! THREE.DDSLoader ) {

      throw new Error( 'THREE.GLTFLoader: Attempting to load .dds texture without importing THREE.DDSLoader' );

    }

    this.name = EXTENSIONS.MSFT_TEXTURE_DDS;
    this.ddsLoader = new THREE.DDSLoader();

  }

  /**
   * Basis Texture Extension
   *
   */
  function GLTFTextureBasisExtension() {

    this.name = EXTENSIONS.GOOGLE_TEXTURE_BASIS;

  }

  /**
   * Lights Extension
   *
   * Specification: PENDING
   */
  function GLTFLightsExtension( json ) {

    this.name = EXTENSIONS.KHR_LIGHTS_PUNCTUAL;

    var extension = ( json.extensions && json.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ] ) || {};
    this.lightDefs = extension.lights || [];

  }

  GLTFLightsExtension.prototype.loadLight = function ( lightIndex ) {

    var lightDef = this.lightDefs[ lightIndex ];
    var lightNode;

    var color = new THREE.Color( 0xffffff );
    if ( lightDef.color !== undefined ) color.fromArray( lightDef.color );

    var range = lightDef.range !== undefined ? lightDef.range : 0;

    switch ( lightDef.type ) {

      case 'directional':
        lightNode = new THREE.DirectionalLight( color );
        lightNode.target.position.set( 0, 0, - 1 );
        lightNode.add( lightNode.target );
        break;

      case 'point':
        lightNode = new THREE.PointLight( color );
        lightNode.distance = range;
        break;

      case 'spot':
        lightNode = new THREE.SpotLight( color );
        lightNode.distance = range;
        // Handle spotlight properties.
        lightDef.spot = lightDef.spot || {};
        lightDef.spot.innerConeAngle = lightDef.spot.innerConeAngle !== undefined ? lightDef.spot.innerConeAngle : 0;
        lightDef.spot.outerConeAngle = lightDef.spot.outerConeAngle !== undefined ? lightDef.spot.outerConeAngle : Math.PI / 4.0;
        lightNode.angle = lightDef.spot.outerConeAngle;
        lightNode.penumbra = 1.0 - lightDef.spot.innerConeAngle / lightDef.spot.outerConeAngle;
        lightNode.target.position.set( 0, 0, - 1 );
        lightNode.add( lightNode.target );
        break;

      default:
        throw new Error( 'THREE.GLTFLoader: Unexpected light type, "' + lightDef.type + '".' );

    }

    // Some lights (e.g. spot) default to a position other than the origin. Reset the position
    // here, because node-level parsing will only override position if explicitly specified.
    lightNode.position.set( 0, 0, 0 );

    lightNode.decay = 2;

    if ( lightDef.intensity !== undefined ) lightNode.intensity = lightDef.intensity;

    lightNode.name = lightDef.name || ( 'light_' + lightIndex );

    return Promise.resolve( lightNode );

  };

  /**
   * Unlit Materials Extension (pending)
   *
   * PR: https://github.com/KhronosGroup/glTF/pull/1163
   */
  function GLTFMaterialsUnlitExtension() {

    this.name = EXTENSIONS.KHR_MATERIALS_UNLIT;

  }

  GLTFMaterialsUnlitExtension.prototype.getMaterialType = function () {

    return THREE.MeshBasicMaterial;

  };

  GLTFMaterialsUnlitExtension.prototype.extendParams = function ( materialParams, materialDef, parser ) {

    var pending = [];

    materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 );
    materialParams.opacity = 1.0;

    var metallicRoughness = materialDef.pbrMetallicRoughness;

    if ( metallicRoughness ) {

      if ( Array.isArray( metallicRoughness.baseColorFactor ) ) {

        var array = metallicRoughness.baseColorFactor;

        materialParams.color.fromArray( array );
        materialParams.opacity = array[ 3 ];

      }

      if ( metallicRoughness.baseColorTexture !== undefined ) {

        pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture ) );

      }

    }

    return Promise.all( pending );

  };

  /* BINARY EXTENSION */

  var BINARY_EXTENSION_BUFFER_NAME = 'binary_glTF';
  var BINARY_EXTENSION_HEADER_MAGIC = 'glTF';
  var BINARY_EXTENSION_HEADER_LENGTH = 12;
  var BINARY_EXTENSION_CHUNK_TYPES = { JSON: 0x4E4F534A, BIN: 0x004E4942 };

  function GLTFBinaryExtension( data ) {

    this.name = EXTENSIONS.KHR_BINARY_GLTF;
    this.content = null;
    this.body = null;

    var headerView = new DataView( data, 0, BINARY_EXTENSION_HEADER_LENGTH );

    this.header = {
      magic: THREE.LoaderUtils.decodeText( new Uint8Array( data.slice( 0, 4 ) ) ),
      version: headerView.getUint32( 4, true ),
      length: headerView.getUint32( 8, true )
    };

    if ( this.header.magic !== BINARY_EXTENSION_HEADER_MAGIC ) {

      throw new Error( 'THREE.GLTFLoader: Unsupported glTF-Binary header.' );

    } else if ( this.header.version < 2.0 ) {

      throw new Error( 'THREE.GLTFLoader: Legacy binary file detected. Use LegacyGLTFLoader instead.' );

    }

    var chunkView = new DataView( data, BINARY_EXTENSION_HEADER_LENGTH );
    var chunkIndex = 0;

    while ( chunkIndex < chunkView.byteLength ) {

      var chunkLength = chunkView.getUint32( chunkIndex, true );
      chunkIndex += 4;

      var chunkType = chunkView.getUint32( chunkIndex, true );
      chunkIndex += 4;

      if ( chunkType === BINARY_EXTENSION_CHUNK_TYPES.JSON ) {

        var contentArray = new Uint8Array( data, BINARY_EXTENSION_HEADER_LENGTH + chunkIndex, chunkLength );
        this.content = THREE.LoaderUtils.decodeText( contentArray );

      } else if ( chunkType === BINARY_EXTENSION_CHUNK_TYPES.BIN ) {

        var byteOffset = BINARY_EXTENSION_HEADER_LENGTH + chunkIndex;
        this.body = data.slice( byteOffset, byteOffset + chunkLength );

      }

      // Clients must ignore chunks with unknown types.

      chunkIndex += chunkLength;

    }

    if ( this.content === null ) {

      throw new Error( 'THREE.GLTFLoader: JSON content not found.' );

    }

  }

  /**
   * DRACO Mesh Compression Extension
   *
   * Specification: https://github.com/KhronosGroup/glTF/pull/874
   */
  function GLTFDracoMeshCompressionExtension( json, dracoLoader ) {

    if ( ! dracoLoader ) {

      throw new Error( 'THREE.GLTFLoader: No DRACOLoader instance provided.' );

    }

    this.name = EXTENSIONS.KHR_DRACO_MESH_COMPRESSION;
    this.json = json;
    this.dracoLoader = dracoLoader;

  }

  GLTFDracoMeshCompressionExtension.prototype.decodePrimitive = function ( primitive, parser ) {

    var json = this.json;
    var dracoLoader = this.dracoLoader;
    var bufferViewIndex = primitive.extensions[ this.name ].bufferView;
    var gltfAttributeMap = primitive.extensions[ this.name ].attributes;
    var threeAttributeMap = {};
    var attributeNormalizedMap = {};
    var attributeTypeMap = {};

    for ( var attributeName in gltfAttributeMap ) {

      var threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase();

      threeAttributeMap[ threeAttributeName ] = gltfAttributeMap[ attributeName ];

    }

    for ( attributeName in primitive.attributes ) {

      var threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase();

      if ( gltfAttributeMap[ attributeName ] !== undefined ) {

        var accessorDef = json.accessors[ primitive.attributes[ attributeName ] ];
        var componentType = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];

        attributeTypeMap[ threeAttributeName ] = componentType;
        attributeNormalizedMap[ threeAttributeName ] = accessorDef.normalized === true;

      }

    }

    return parser.getDependency( 'bufferView', bufferViewIndex ).then( function ( bufferView ) {

      return new Promise( function ( resolve ) {

        dracoLoader.decodeDracoFile( bufferView, function ( geometry ) {

          for ( var attributeName in geometry.attributes ) {

            var attribute = geometry.attributes[ attributeName ];
            var normalized = attributeNormalizedMap[ attributeName ];

            if ( normalized !== undefined ) attribute.normalized = normalized;

          }

          resolve( geometry );

        }, threeAttributeMap, attributeTypeMap );

      } );

    } );

  };

  /**
   * Texture Transform Extension
   *
   * Specification:
   */
  function GLTFTextureTransformExtension() {

    this.name = EXTENSIONS.KHR_TEXTURE_TRANSFORM;

  }

  GLTFTextureTransformExtension.prototype.extendTexture = function ( texture, transform ) {

    texture = texture.clone();

    if ( transform.offset !== undefined ) {

      texture.offset.fromArray( transform.offset );

    }

    if ( transform.rotation !== undefined ) {

      texture.rotation = transform.rotation;

    }

    if ( transform.scale !== undefined ) {

      texture.repeat.fromArray( transform.scale );

    }

    if ( transform.texCoord !== undefined ) {

      console.warn( 'THREE.GLTFLoader: Custom UV sets in "' + this.name + '" extension not yet supported.' );

    }

    texture.needsUpdate = true;

    return texture;

  };

  /**
   * Specular-Glossiness Extension
   *
   * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness
   */
  function GLTFMaterialsPbrSpecularGlossinessExtension() {

    return {

      name: EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS,

      specularGlossinessParams: [
        'color',
        'map',
        'lightMap',
        'lightMapIntensity',
        'aoMap',
        'aoMapIntensity',
        'emissive',
        'emissiveIntensity',
        'emissiveMap',
        'bumpMap',
        'bumpScale',
        'normalMap',
        'displacementMap',
        'displacementScale',
        'displacementBias',
        'specularMap',
        'specular',
        'glossinessMap',
        'glossiness',
        'alphaMap',
        'envMap',
        'envMapIntensity',
        'refractionRatio',
      ],

      getMaterialType: function () {

        return THREE.ShaderMaterial;

      },

      extendParams: function ( materialParams, materialDef, parser ) {

        var pbrSpecularGlossiness = materialDef.extensions[ this.name ];

        var shader = THREE.ShaderLib[ 'standard' ];

        var uniforms = THREE.UniformsUtils.clone( shader.uniforms );

        var specularMapParsFragmentChunk = [
          '#ifdef USE_SPECULARMAP',
          '  uniform sampler2D specularMap;',
          '#endif'
        ].join( '\n' );

        var glossinessMapParsFragmentChunk = [
          '#ifdef USE_GLOSSINESSMAP',
          '  uniform sampler2D glossinessMap;',
          '#endif'
        ].join( '\n' );

        var specularMapFragmentChunk = [
          'vec3 specularFactor = specular;',
          '#ifdef USE_SPECULARMAP',
          '  vec4 texelSpecular = texture2D( specularMap, vUv );',
          '  texelSpecular = sRGBToLinear( texelSpecular );',
          '  // reads channel RGB, compatible with a glTF Specular-Glossiness (RGBA) texture',
          '  specularFactor *= texelSpecular.rgb;',
          '#endif'
        ].join( '\n' );

        var glossinessMapFragmentChunk = [
          'float glossinessFactor = glossiness;',
          '#ifdef USE_GLOSSINESSMAP',
          '  vec4 texelGlossiness = texture2D( glossinessMap, vUv );',
          '  // reads channel A, compatible with a glTF Specular-Glossiness (RGBA) texture',
          '  glossinessFactor *= texelGlossiness.a;',
          '#endif'
        ].join( '\n' );

        var lightPhysicalFragmentChunk = [
          'PhysicalMaterial material;',
          'material.diffuseColor = diffuseColor.rgb;',
          'material.specularRoughness = clamp( 1.0 - glossinessFactor, 0.04, 1.0 );',
          'material.specularColor = specularFactor.rgb;',
        ].join( '\n' );

        var fragmentShader = shader.fragmentShader
          .replace( 'uniform float roughness;', 'uniform vec3 specular;' )
          .replace( 'uniform float metalness;', 'uniform float glossiness;' )
          .replace( '#include <roughnessmap_pars_fragment>', specularMapParsFragmentChunk )
          .replace( '#include <metalnessmap_pars_fragment>', glossinessMapParsFragmentChunk )
          .replace( '#include <roughnessmap_fragment>', specularMapFragmentChunk )
          .replace( '#include <metalnessmap_fragment>', glossinessMapFragmentChunk )
          .replace( '#include <lights_physical_fragment>', lightPhysicalFragmentChunk );

        delete uniforms.roughness;
        delete uniforms.metalness;
        delete uniforms.roughnessMap;
        delete uniforms.metalnessMap;

        uniforms.specular = { value: new THREE.Color().setHex( 0x111111 ) };
        uniforms.glossiness = { value: 0.5 };
        uniforms.specularMap = { value: null };
        uniforms.glossinessMap = { value: null };

        materialParams.vertexShader = shader.vertexShader;
        materialParams.fragmentShader = fragmentShader;
        materialParams.uniforms = uniforms;
        materialParams.defines = { 'STANDARD': '' };

        materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 );
        materialParams.opacity = 1.0;

        var pending = [];

        if ( Array.isArray( pbrSpecularGlossiness.diffuseFactor ) ) {

          var array = pbrSpecularGlossiness.diffuseFactor;

          materialParams.color.fromArray( array );
          materialParams.opacity = array[ 3 ];

        }

        if ( pbrSpecularGlossiness.diffuseTexture !== undefined ) {

          pending.push( parser.assignTexture( materialParams, 'map', pbrSpecularGlossiness.diffuseTexture ) );

        }

        materialParams.emissive = new THREE.Color( 0.0, 0.0, 0.0 );
        materialParams.glossiness = pbrSpecularGlossiness.glossinessFactor !== undefined ? pbrSpecularGlossiness.glossinessFactor : 1.0;
        materialParams.specular = new THREE.Color( 1.0, 1.0, 1.0 );

        if ( Array.isArray( pbrSpecularGlossiness.specularFactor ) ) {

          materialParams.specular.fromArray( pbrSpecularGlossiness.specularFactor );

        }

        if ( pbrSpecularGlossiness.specularGlossinessTexture !== undefined ) {

          var specGlossMapDef = pbrSpecularGlossiness.specularGlossinessTexture;
          pending.push( parser.assignTexture( materialParams, 'glossinessMap', specGlossMapDef ) );
          pending.push( parser.assignTexture( materialParams, 'specularMap', specGlossMapDef ) );

        }

        return Promise.all( pending );

      },

      createMaterial: function ( params ) {

        // setup material properties based on MeshStandardMaterial for Specular-Glossiness

        var material = new THREE.ShaderMaterial( {
          defines: params.defines,
          vertexShader: params.vertexShader,
          fragmentShader: params.fragmentShader,
          uniforms: params.uniforms,
          fog: true,
          lights: true,
          opacity: params.opacity,
          transparent: params.transparent
        } );

        material.isGLTFSpecularGlossinessMaterial = true;

        material.color = params.color;

        material.map = params.map === undefined ? null : params.map;

        material.lightMap = null;
        material.lightMapIntensity = 1.0;

        material.aoMap = params.aoMap === undefined ? null : params.aoMap;
        material.aoMapIntensity = 1.0;

        material.emissive = params.emissive;
        material.emissiveIntensity = 1.0;
        material.emissiveMap = params.emissiveMap === undefined ? null : params.emissiveMap;

        material.bumpMap = params.bumpMap === undefined ? null : params.bumpMap;
        material.bumpScale = 1;

        material.normalMap = params.normalMap === undefined ? null : params.normalMap;

        if ( params.normalScale ) material.normalScale = params.normalScale;

        material.displacementMap = null;
        material.displacementScale = 1;
        material.displacementBias = 0;

        material.specularMap = params.specularMap === undefined ? null : params.specularMap;
        material.specular = params.specular;

        material.glossinessMap = params.glossinessMap === undefined ? null : params.glossinessMap;
        material.glossiness = params.glossiness;

        material.alphaMap = null;

        material.envMap = params.envMap === undefined ? null : params.envMap;
        material.envMapIntensity = 1.0;

        material.refractionRatio = 0.98;

        material.extensions.derivatives = true;

        return material;

      },

      /**
       * Clones a GLTFSpecularGlossinessMaterial instance. The ShaderMaterial.copy() method can
       * copy only properties it knows about or inherits, and misses many properties that would
       * normally be defined by MeshStandardMaterial.
       *
       * This method allows GLTFSpecularGlossinessMaterials to be cloned in the process of
       * loading a glTF model, but cloning later (e.g. by the user) would require these changes
       * AND also updating `.onBeforeRender` on the parent mesh.
       *
       * @param  {THREE.ShaderMaterial} source
       * @return {THREE.ShaderMaterial}
       */
      cloneMaterial: function ( source ) {

        var target = source.clone();

        target.isGLTFSpecularGlossinessMaterial = true;

        var params = this.specularGlossinessParams;

        for ( var i = 0, il = params.length; i < il; i ++ ) {

          target[ params[ i ] ] = source[ params[ i ] ];

        }

        return target;

      },

      // Here's based on refreshUniformsCommon() and refreshUniformsStandard() in WebGLRenderer.
      refreshUniforms: function ( renderer, scene, camera, geometry, material, group ) {

        if ( material.isGLTFSpecularGlossinessMaterial !== true ) {

          return;

        }

        var uniforms = material.uniforms;
        var defines = material.defines;

        uniforms.opacity.value = material.opacity;

        uniforms.diffuse.value.copy( material.color );
        uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );

        uniforms.map.value = material.map;
        uniforms.specularMap.value = material.specularMap;
        uniforms.alphaMap.value = material.alphaMap;

        uniforms.lightMap.value = material.lightMap;
        uniforms.lightMapIntensity.value = material.lightMapIntensity;

        uniforms.aoMap.value = material.aoMap;
        uniforms.aoMapIntensity.value = material.aoMapIntensity;

        // uv repeat and offset setting priorities
        // 1. color map
        // 2. specular map
        // 3. normal map
        // 4. bump map
        // 5. alpha map
        // 6. emissive map

        var uvScaleMap;

        if ( material.map ) {

          uvScaleMap = material.map;

        } else if ( material.specularMap ) {

          uvScaleMap = material.specularMap;

        } else if ( material.displacementMap ) {

          uvScaleMap = material.displacementMap;

        } else if ( material.normalMap ) {

          uvScaleMap = material.normalMap;

        } else if ( material.bumpMap ) {

          uvScaleMap = material.bumpMap;

        } else if ( material.glossinessMap ) {

          uvScaleMap = material.glossinessMap;

        } else if ( material.alphaMap ) {

          uvScaleMap = material.alphaMap;

        } else if ( material.emissiveMap ) {

          uvScaleMap = material.emissiveMap;

        }

        if ( uvScaleMap !== undefined ) {

          // backwards compatibility
          if ( uvScaleMap.isWebGLRenderTarget ) {

            uvScaleMap = uvScaleMap.texture;

          }

          if ( uvScaleMap.matrixAutoUpdate === true ) {

            uvScaleMap.updateMatrix();

          }

          uniforms.uvTransform.value.copy( uvScaleMap.matrix );

        }

        if ( material.envMap ) {

          uniforms.envMap.value = material.envMap;
          uniforms.envMapIntensity.value = material.envMapIntensity;

          // don't flip CubeTexture envMaps, flip everything else:
          //  WebGLRenderTargetCube will be flipped for backwards compatibility
          //  WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture
          // this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future
          uniforms.flipEnvMap.value = material.envMap.isCubeTexture ? - 1 : 1;

          uniforms.reflectivity.value = material.reflectivity;
          uniforms.refractionRatio.value = material.refractionRatio;

          uniforms.maxMipLevel.value = renderer.properties.get( material.envMap ).__maxMipLevel;

        }

        uniforms.specular.value.copy( material.specular );
        uniforms.glossiness.value = material.glossiness;

        uniforms.glossinessMap.value = material.glossinessMap;

        uniforms.emissiveMap.value = material.emissiveMap;
        uniforms.bumpMap.value = material.bumpMap;
        uniforms.normalMap.value = material.normalMap;

        uniforms.displacementMap.value = material.displacementMap;
        uniforms.displacementScale.value = material.displacementScale;
        uniforms.displacementBias.value = material.displacementBias;

        if ( uniforms.glossinessMap.value !== null && defines.USE_GLOSSINESSMAP === undefined ) {

          defines.USE_GLOSSINESSMAP = '';
          // set USE_ROUGHNESSMAP to enable vUv
          defines.USE_ROUGHNESSMAP = '';

        }

        if ( uniforms.glossinessMap.value === null && defines.USE_GLOSSINESSMAP !== undefined ) {

          delete defines.USE_GLOSSINESSMAP;
          delete defines.USE_ROUGHNESSMAP;

        }

      }

    };

  }

  /*********************************/
  /********** INTERPOLATION ********/
  /*********************************/

  // Spline Interpolation
  // Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#appendix-c-spline-interpolation
  function GLTFCubicSplineInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {

    THREE.Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );

  }

  GLTFCubicSplineInterpolant.prototype = Object.create( THREE.Interpolant.prototype );
  GLTFCubicSplineInterpolant.prototype.constructor = GLTFCubicSplineInterpolant;

  GLTFCubicSplineInterpolant.prototype.copySampleValue_ = function ( index ) {

    // Copies a sample value to the result buffer. See description of glTF
    // CUBICSPLINE values layout in interpolate_() function below.

    var result = this.resultBuffer,
      values = this.sampleValues,
      valueSize = this.valueSize,
      offset = index * valueSize * 3 + valueSize;

    for ( var i = 0; i !== valueSize; i ++ ) {

      result[ i ] = values[ offset + i ];

    }

    return result;

  };

  GLTFCubicSplineInterpolant.prototype.beforeStart_ = GLTFCubicSplineInterpolant.prototype.copySampleValue_;

  GLTFCubicSplineInterpolant.prototype.afterEnd_ = GLTFCubicSplineInterpolant.prototype.copySampleValue_;

  GLTFCubicSplineInterpolant.prototype.interpolate_ = function ( i1, t0, t, t1 ) {

    var result = this.resultBuffer;
    var values = this.sampleValues;
    var stride = this.valueSize;

    var stride2 = stride * 2;
    var stride3 = stride * 3;

    var td = t1 - t0;

    var p = ( t - t0 ) / td;
    var pp = p * p;
    var ppp = pp * p;

    var offset1 = i1 * stride3;
    var offset0 = offset1 - stride3;

    var s2 = - 2 * ppp + 3 * pp;
    var s3 = ppp - pp;
    var s0 = 1 - s2;
    var s1 = s3 - pp + p;

    // Layout of keyframe output values for CUBICSPLINE animations:
    //   [ inTangent_1, splineVertex_1, outTangent_1, inTangent_2, splineVertex_2, ... ]
    for ( var i = 0; i !== stride; i ++ ) {

      var p0 = values[ offset0 + i + stride ]; // splineVertex_k
      var m0 = values[ offset0 + i + stride2 ] * td; // outTangent_k * (t_k+1 - t_k)
      var p1 = values[ offset1 + i + stride ]; // splineVertex_k+1
      var m1 = values[ offset1 + i ] * td; // inTangent_k+1 * (t_k+1 - t_k)

      result[ i ] = s0 * p0 + s1 * m0 + s2 * p1 + s3 * m1;

    }

    return result;

  };

  /*********************************/
  /********** INTERNALS ************/
  /*********************************/

  /* CONSTANTS */

  var WEBGL_CONSTANTS = {
    FLOAT: 5126,
    //FLOAT_MAT2: 35674,
    FLOAT_MAT3: 35675,
    FLOAT_MAT4: 35676,
    FLOAT_VEC2: 35664,
    FLOAT_VEC3: 35665,
    FLOAT_VEC4: 35666,
    LINEAR: 9729,
    REPEAT: 10497,
    SAMPLER_2D: 35678,
    POINTS: 0,
    LINES: 1,
    LINE_LOOP: 2,
    LINE_STRIP: 3,
    TRIANGLES: 4,
    TRIANGLE_STRIP: 5,
    TRIANGLE_FAN: 6,
    UNSIGNED_BYTE: 5121,
    UNSIGNED_SHORT: 5123
  };

  var WEBGL_TYPE = {
    5126: Number,
    //35674: THREE.Matrix2,
    35675: THREE.Matrix3,
    35676: THREE.Matrix4,
    35664: THREE.Vector2,
    35665: THREE.Vector3,
    35666: THREE.Vector4,
    35678: THREE.Texture
  };

  var WEBGL_COMPONENT_TYPES = {
    5120: Int8Array,
    5121: Uint8Array,
    5122: Int16Array,
    5123: Uint16Array,
    5125: Uint32Array,
    5126: Float32Array
  };

  var WEBGL_FILTERS = {
    9728: THREE.NearestFilter,
    9729: THREE.LinearFilter,
    9984: THREE.NearestMipMapNearestFilter,
    9985: THREE.LinearMipMapNearestFilter,
    9986: THREE.NearestMipMapLinearFilter,
    9987: THREE.LinearMipMapLinearFilter
  };

  var WEBGL_WRAPPINGS = {
    33071: THREE.ClampToEdgeWrapping,
    33648: THREE.MirroredRepeatWrapping,
    10497: THREE.RepeatWrapping
  };

  var WEBGL_SIDES = {
    1028: THREE.BackSide, // Culling front
    1029: THREE.FrontSide // Culling back
    //1032: THREE.NoSide   // Culling front and back, what to do?
  };

  var WEBGL_DEPTH_FUNCS = {
    512: THREE.NeverDepth,
    513: THREE.LessDepth,
    514: THREE.EqualDepth,
    515: THREE.LessEqualDepth,
    516: THREE.GreaterEqualDepth,
    517: THREE.NotEqualDepth,
    518: THREE.GreaterEqualDepth,
    519: THREE.AlwaysDepth
  };

  var WEBGL_BLEND_EQUATIONS = {
    32774: THREE.AddEquation,
    32778: THREE.SubtractEquation,
    32779: THREE.ReverseSubtractEquation
  };

  var WEBGL_BLEND_FUNCS = {
    0: THREE.ZeroFactor,
    1: THREE.OneFactor,
    768: THREE.SrcColorFactor,
    769: THREE.OneMinusSrcColorFactor,
    770: THREE.SrcAlphaFactor,
    771: THREE.OneMinusSrcAlphaFactor,
    772: THREE.DstAlphaFactor,
    773: THREE.OneMinusDstAlphaFactor,
    774: THREE.DstColorFactor,
    775: THREE.OneMinusDstColorFactor,
    776: THREE.SrcAlphaSaturateFactor
    // The followings are not supported by Three.js yet
    //32769: CONSTANT_COLOR,
    //32770: ONE_MINUS_CONSTANT_COLOR,
    //32771: CONSTANT_ALPHA,
    //32772: ONE_MINUS_CONSTANT_COLOR
  };

  var WEBGL_TYPE_SIZES = {
    'SCALAR': 1,
    'VEC2': 2,
    'VEC3': 3,
    'VEC4': 4,
    'MAT2': 4,
    'MAT3': 9,
    'MAT4': 16
  };

  var ATTRIBUTES = {
    POSITION: 'position',
    NORMAL: 'normal',
    TANGENT: 'tangent',
    TEXCOORD_0: 'uv',
    TEXCOORD_1: 'uv2',
    COLOR_0: 'color',
    WEIGHTS_0: 'skinWeight',
    JOINTS_0: 'skinIndex',
  };

  var PATH_PROPERTIES = {
    scale: 'scale',
    translation: 'position',
    rotation: 'quaternion',
    weights: 'morphTargetInfluences'
  };

  var INTERPOLATION = {
    CUBICSPLINE: undefined, // We use a custom interpolant (GLTFCubicSplineInterpolation) for CUBICSPLINE tracks. Each
                            // keyframe track will be initialized with a default interpolation type, then modified.
    LINEAR: THREE.InterpolateLinear,
    STEP: THREE.InterpolateDiscrete
  };

  var STATES_ENABLES = {
    2884: 'CULL_FACE',
    2929: 'DEPTH_TEST',
    3042: 'BLEND',
    3089: 'SCISSOR_TEST',
    32823: 'POLYGON_OFFSET_FILL',
    32926: 'SAMPLE_ALPHA_TO_COVERAGE'
  };

  var ALPHA_MODES = {
    OPAQUE: 'OPAQUE',
    MASK: 'MASK',
    BLEND: 'BLEND'
  };

  var MIME_TYPE_FORMATS = {
    'image/png': THREE.RGBAFormat,
    'image/jpeg': THREE.RGBFormat
  };

  /* UTILITY FUNCTIONS */

  function resolveURL( url, path ) {

    // Invalid URL
    if ( typeof url !== 'string' || url === '' ) return '';

    // Absolute URL http://,https://,//
    if ( /^(https?:)?\/\//i.test( url ) ) return url;

    // Data URI
    if ( /^data:.*,.*$/i.test( url ) ) return url;

    // Blob URL
    if ( /^blob:.*$/i.test( url ) ) return url;

    // Relative URL
    return path + url;

  }

  var defaultMaterial;

  /**
   * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#default-material
   */
  function createDefaultMaterial() {

    defaultMaterial = defaultMaterial || new THREE.MeshStandardMaterial( {
      color: 0xFFFFFF,
      emissive: 0x000000,
      metalness: 1,
      roughness: 1,
      transparent: false,
      depthTest: true,
      side: THREE.FrontSide
    } );

    return defaultMaterial;

  }

  function addUnknownExtensionsToUserData( knownExtensions, object, objectDef ) {

    // Add unknown glTF extensions to an object's userData.

    for ( var name in objectDef.extensions ) {

      if ( knownExtensions[ name ] === undefined ) {

        object.userData.gltfExtensions = object.userData.gltfExtensions || {};
        object.userData.gltfExtensions[ name ] = objectDef.extensions[ name ];

      }

    }

  }

  /**
   * @param {THREE.Object3D|THREE.Material|THREE.BufferGeometry} object
   * @param {GLTF.definition} gltfDef
   */
  function assignExtrasToUserData( object, gltfDef ) {

    if ( gltfDef.extras !== undefined ) {

      if ( typeof gltfDef.extras === 'object' ) {

        object.userData = gltfDef.extras;

      } else {

        console.warn( 'THREE.GLTFLoader: Ignoring primitive type .extras, ' + gltfDef.extras );

      }

    }

  }

  /**
   * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#morph-targets
   *
   * @param {THREE.BufferGeometry} geometry
   * @param {Array<GLTF.Target>} targets
   * @param {GLTFParser} parser
   * @return {Promise<THREE.BufferGeometry>}
   */
  function addMorphTargets( geometry, targets, parser ) {

    var hasMorphPosition = false;
    var hasMorphNormal = false;

    for ( var i = 0, il = targets.length; i < il; i ++ ) {

      var target = targets[ i ];

      if ( target.POSITION !== undefined ) hasMorphPosition = true;
      if ( target.NORMAL !== undefined ) hasMorphNormal = true;

      if ( hasMorphPosition && hasMorphNormal ) break;

    }

    if ( ! hasMorphPosition && ! hasMorphNormal ) return Promise.resolve( geometry );

    var pendingPositionAccessors = [];
    var pendingNormalAccessors = [];

    for ( var i = 0, il = targets.length; i < il; i ++ ) {

      var target = targets[ i ];

      if ( hasMorphPosition ) {

        var pendingAccessor = target.POSITION !== undefined
          ? parser.getDependency( 'accessor', target.POSITION )
          : geometry.attributes.position;

        pendingPositionAccessors.push( pendingAccessor );

      }

      if ( hasMorphNormal ) {

        var pendingAccessor = target.NORMAL !== undefined
          ? parser.getDependency( 'accessor', target.NORMAL )
          : geometry.attributes.normal;

        pendingNormalAccessors.push( pendingAccessor );

      }

    }

    return Promise.all( [
      Promise.all( pendingPositionAccessors ),
      Promise.all( pendingNormalAccessors )
    ] ).then( function ( accessors ) {

      var morphPositions = accessors[ 0 ];
      var morphNormals = accessors[ 1 ];

      // Clone morph target accessors before modifying them.

      for ( var i = 0, il = morphPositions.length; i < il; i ++ ) {

        if ( geometry.attributes.position === morphPositions[ i ] ) continue;

        morphPositions[ i ] = cloneBufferAttribute( morphPositions[ i ] );

      }

      for ( var i = 0, il = morphNormals.length; i < il; i ++ ) {

        if ( geometry.attributes.normal === morphNormals[ i ] ) continue;

        morphNormals[ i ] = cloneBufferAttribute( morphNormals[ i ] );

      }

      for ( var i = 0, il = targets.length; i < il; i ++ ) {

        var target = targets[ i ];
        var attributeName = 'morphTarget' + i;

        if ( hasMorphPosition ) {

          // Three.js morph position is absolute value. The formula is
          //   basePosition
          //     + weight0 * ( morphPosition0 - basePosition )
          //     + weight1 * ( morphPosition1 - basePosition )
          //     ...
          // while the glTF one is relative
          //   basePosition
          //     + weight0 * glTFmorphPosition0
          //     + weight1 * glTFmorphPosition1
          //     ...
          // then we need to convert from relative to absolute here.

          if ( target.POSITION !== undefined ) {

            var positionAttribute = morphPositions[ i ];
            positionAttribute.name = attributeName;

            var position = geometry.attributes.position;

            for ( var j = 0, jl = positionAttribute.count; j < jl; j ++ ) {

              positionAttribute.setXYZ(
                j,
                positionAttribute.getX( j ) + position.getX( j ),
                positionAttribute.getY( j ) + position.getY( j ),
                positionAttribute.getZ( j ) + position.getZ( j )
              );

            }

          }

        }

        if ( hasMorphNormal ) {

          // see target.POSITION's comment

          if ( target.NORMAL !== undefined ) {

            var normalAttribute = morphNormals[ i ];
            normalAttribute.name = attributeName;

            var normal = geometry.attributes.normal;

            for ( var j = 0, jl = normalAttribute.count; j < jl; j ++ ) {

              normalAttribute.setXYZ(
                j,
                normalAttribute.getX( j ) + normal.getX( j ),
                normalAttribute.getY( j ) + normal.getY( j ),
                normalAttribute.getZ( j ) + normal.getZ( j )
              );

            }

          }

        }

      }

      if ( hasMorphPosition ) geometry.morphAttributes.position = morphPositions;
      if ( hasMorphNormal ) geometry.morphAttributes.normal = morphNormals;

      return geometry;

    } );

  }

  /**
   * @param {THREE.Mesh} mesh
   * @param {GLTF.Mesh} meshDef
   */
  function updateMorphTargets( mesh, meshDef ) {

    mesh.updateMorphTargets();

    if ( meshDef.weights !== undefined ) {

      for ( var i = 0, il = meshDef.weights.length; i < il; i ++ ) {

        mesh.morphTargetInfluences[ i ] = meshDef.weights[ i ];

      }

    }

    // .extras has user-defined data, so check that .extras.targetNames is an array.
    if ( meshDef.extras && Array.isArray( meshDef.extras.targetNames ) ) {

      var targetNames = meshDef.extras.targetNames;

      if ( mesh.morphTargetInfluences.length === targetNames.length ) {

        mesh.morphTargetDictionary = {};

        for ( var i = 0, il = targetNames.length; i < il; i ++ ) {

          mesh.morphTargetDictionary[ targetNames[ i ] ] = i;

        }

      } else {

        console.warn( 'THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.' );

      }

    }

  }
  function isObjectEqual( a, b ) {

    if ( Object.keys( a ).length !== Object.keys( b ).length ) return false;

    for ( var key in a ) {

      if ( a[ key ] !== b[ key ] ) return false;

    }

    return true;

  }

  function createPrimitiveKey( primitiveDef ) {

    var dracoExtension = primitiveDef.extensions && primitiveDef.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ];
    var geometryKey;

    if ( dracoExtension ) {

      geometryKey = 'draco:' + dracoExtension.bufferView
        + ':' + dracoExtension.indices
        + ':' + createAttributesKey( dracoExtension.attributes );

    } else {

      geometryKey = primitiveDef.indices + ':' + createAttributesKey( primitiveDef.attributes ) + ':' + primitiveDef.mode;

    }

    return geometryKey;

  }

  function createAttributesKey( attributes ) {

    var attributesKey = '';

    var keys = Object.keys( attributes ).sort();

    for ( var i = 0, il = keys.length; i < il; i ++ ) {

      attributesKey += keys[ i ] + ':' + attributes[ keys[ i ] ] + ';';

    }

    return attributesKey;

  }

  function cloneBufferAttribute( attribute ) {

    if ( attribute.isInterleavedBufferAttribute ) {

      var count = attribute.count;
      var itemSize = attribute.itemSize;
      var array = attribute.array.slice( 0, count * itemSize );

      for ( var i = 0, j = 0; i < count; ++ i ) {

        array[ j ++ ] = attribute.getX( i );
        if ( itemSize >= 2 ) array[ j ++ ] = attribute.getY( i );
        if ( itemSize >= 3 ) array[ j ++ ] = attribute.getZ( i );
        if ( itemSize >= 4 ) array[ j ++ ] = attribute.getW( i );

      }

      return new THREE.BufferAttribute( array, itemSize, attribute.normalized );

    }

    return attribute.clone();

  }

  /* GLTF PARSER */

  function GLTFParser( json, extensions, options ) {

    this.json = json || {};
    this.extensions = extensions || {};
    this.options = options || {};

    // loader object cache
    this.cache = new GLTFRegistry();

    // BufferGeometry caching
    this.primitiveCache = {};

    this.textureLoader = new THREE.TextureLoader( this.options.manager );
    this.textureLoader.setCrossOrigin( this.options.crossOrigin );

    this.fileLoader = new THREE.FileLoader( this.options.manager );
    this.fileLoader.setResponseType( 'arraybuffer' );

  }

  GLTFParser.prototype.parse = function ( onLoad, onError ) {

    var parser = this;
    var json = this.json;
    var extensions = this.extensions;

    // Clear the loader cache
    this.cache.removeAll();

    // Mark the special nodes/meshes in json for efficient parse
    this.markDefs();

    Promise.all( [

      this.getDependencies( 'scene' ),
      this.getDependencies( 'animation' ),
      this.getDependencies( 'camera' ),

    ] ).then( function ( dependencies ) {

      var result = {
        scene: dependencies[ 0 ][ json.scene || 0 ],
        scenes: dependencies[ 0 ],
        animations: dependencies[ 1 ],
        cameras: dependencies[ 2 ],
        asset: json.asset,
        parser: parser,
        userData: {}
      };

      addUnknownExtensionsToUserData( extensions, result, json );

      onLoad( result );

    } ).catch( onError );

  };

  /**
   * Marks the special nodes/meshes in json for efficient parse.
   */
  GLTFParser.prototype.markDefs = function () {

    var nodeDefs = this.json.nodes || [];
    var skinDefs = this.json.skins || [];
    var meshDefs = this.json.meshes || [];

    var meshReferences = {};
    var meshUses = {};

    // Nothing in the node definition indicates whether it is a Bone or an
    // Object3D. Use the skins' joint references to mark bones.
    for ( var skinIndex = 0, skinLength = skinDefs.length; skinIndex < skinLength; skinIndex ++ ) {

      var joints = skinDefs[ skinIndex ].joints;

      for ( var i = 0, il = joints.length; i < il; i ++ ) {

        nodeDefs[ joints[ i ] ].isBone = true;

      }

    }

    // Meshes can (and should) be reused by multiple nodes in a glTF asset. To
    // avoid having more than one THREE.Mesh with the same name, count
    // references and rename instances below.
    //
    // Example: CesiumMilkTruck sample model reuses "Wheel" meshes.
    for ( var nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex ++ ) {

      var nodeDef = nodeDefs[ nodeIndex ];

      if ( nodeDef.mesh !== undefined ) {

        if ( meshReferences[ nodeDef.mesh ] === undefined ) {

          meshReferences[ nodeDef.mesh ] = meshUses[ nodeDef.mesh ] = 0;

        }

        meshReferences[ nodeDef.mesh ] ++;

        // Nothing in the mesh definition indicates whether it is
        // a SkinnedMesh or Mesh. Use the node's mesh reference
        // to mark SkinnedMesh if node has skin.
        if ( nodeDef.skin !== undefined ) {

          meshDefs[ nodeDef.mesh ].isSkinnedMesh = true;

        }

      }

    }

    this.json.meshReferences = meshReferences;
    this.json.meshUses = meshUses;

  };

  /**
   * Requests the specified dependency asynchronously, with caching.
   * @param {string} type
   * @param {number} index
   * @return {Promise<THREE.Object3D|THREE.Material|THREE.Texture|THREE.AnimationClip|ArrayBuffer|Object>}
   */
  GLTFParser.prototype.getDependency = function ( type, index ) {

    var cacheKey = type + ':' + index;
    var dependency = this.cache.get( cacheKey );

    if ( ! dependency ) {

      switch ( type ) {

        case 'scene':
          dependency = this.loadScene( index );
          break;

        case 'node':
          dependency = this.loadNode( index );
          break;

        case 'mesh':
          dependency = this.loadMesh( index );
          break;

        case 'accessor':
          dependency = this.loadAccessor( index );
          break;

        case 'bufferView':
          dependency = this.loadBufferView( index );
          break;

        case 'buffer':
          dependency = this.loadBuffer( index );
          break;

        case 'material':
          dependency = this.loadMaterial( index );
          break;

        case 'texture':
          dependency = this.loadTexture( index );
          break;

        case 'skin':
          dependency = this.loadSkin( index );
          break;

        case 'animation':
          dependency = this.loadAnimation( index );
          break;

        case 'camera':
          dependency = this.loadCamera( index );
          break;

        case 'light':
          dependency = this.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].loadLight( index );
          break;

        default:
          throw new Error( 'Unknown type: ' + type );

      }

      this.cache.add( cacheKey, dependency );

    }

    return dependency;

  };

  /**
   * Requests all dependencies of the specified type asynchronously, with caching.
   * @param {string} type
   * @return {Promise<Array<Object>>}
   */
  GLTFParser.prototype.getDependencies = function ( type ) {

    var dependencies = this.cache.get( type );

    if ( ! dependencies ) {

      var parser = this;
      var defs = this.json[ type + ( type === 'mesh' ? 'es' : 's' ) ] || [];

      dependencies = Promise.all( defs.map( function ( def, index ) {

        return parser.getDependency( type, index );

      } ) );

      this.cache.add( type, dependencies );

    }

    return dependencies;

  };

  /**
   * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views
   * @param {number} bufferIndex
   * @return {Promise<ArrayBuffer>}
   */
  GLTFParser.prototype.loadBuffer = function ( bufferIndex ) {

    var bufferDef = this.json.buffers[ bufferIndex ];
    var loader = this.fileLoader;

    if ( bufferDef.type && bufferDef.type !== 'arraybuffer' ) {

      throw new Error( 'THREE.GLTFLoader: ' + bufferDef.type + ' buffer type is not supported.' );

    }

    // If present, GLB container is required to be the first buffer.
    if ( bufferDef.uri === undefined && bufferIndex === 0 ) {

      return Promise.resolve( this.extensions[ EXTENSIONS.KHR_BINARY_GLTF ].body );

    }

    var options = this.options;

    return new Promise( function ( resolve, reject ) {

      loader.load( resolveURL( bufferDef.uri, options.path ), resolve, undefined, function () {

        reject( new Error( 'THREE.GLTFLoader: Failed to load buffer "' + bufferDef.uri + '".' ) );

      } );

    } );

  };

  /**
   * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views
   * @param {number} bufferViewIndex
   * @return {Promise<ArrayBuffer>}
   */
  GLTFParser.prototype.loadBufferView = function ( bufferViewIndex ) {

    var bufferViewDef = this.json.bufferViews[ bufferViewIndex ];

    return this.getDependency( 'buffer', bufferViewDef.buffer ).then( function ( buffer ) {

      var byteLength = bufferViewDef.byteLength || 0;
      var byteOffset = bufferViewDef.byteOffset || 0;
      return buffer.slice( byteOffset, byteOffset + byteLength );

    } );

  };

  /**
   * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#accessors
   * @param {number} accessorIndex
   * @return {Promise<THREE.BufferAttribute|THREE.InterleavedBufferAttribute>}
   */
  GLTFParser.prototype.loadAccessor = function ( accessorIndex ) {

    var parser = this;
    var json = this.json;

    var accessorDef = this.json.accessors[ accessorIndex ];

    if ( accessorDef.bufferView === undefined && accessorDef.sparse === undefined ) {

      // Ignore empty accessors, which may be used to declare runtime
      // information about attributes coming from another source (e.g. Draco
      // compression extension).
      return Promise.resolve( null );

    }

    var pendingBufferViews = [];

    if ( accessorDef.bufferView !== undefined ) {

      pendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.bufferView ) );

    } else {

      pendingBufferViews.push( null );

    }

    if ( accessorDef.sparse !== undefined ) {

      pendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.sparse.indices.bufferView ) );
      pendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.sparse.values.bufferView ) );

    }

    return Promise.all( pendingBufferViews ).then( function ( bufferViews ) {

      var bufferView = bufferViews[ 0 ];

      var itemSize = WEBGL_TYPE_SIZES[ accessorDef.type ];
      var TypedArray = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];

      // For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.
      var elementBytes = TypedArray.BYTES_PER_ELEMENT;
      var itemBytes = elementBytes * itemSize;
      var byteOffset = accessorDef.byteOffset || 0;
      var byteStride = accessorDef.bufferView !== undefined ? json.bufferViews[ accessorDef.bufferView ].byteStride : undefined;
      var normalized = accessorDef.normalized === true;
      var array, bufferAttribute;

      // The buffer is not interleaved if the stride is the item size in bytes.
      if ( byteStride && byteStride !== itemBytes ) {

        var ibCacheKey = 'InterleavedBuffer:' + accessorDef.bufferView + ':' + accessorDef.componentType;
        var ib = parser.cache.get( ibCacheKey );

        if ( ! ib ) {

          // Use the full buffer if it's interleaved.
          array = new TypedArray( bufferView );

          // Integer parameters to IB/IBA are in array elements, not bytes.
          ib = new THREE.InterleavedBuffer( array, byteStride / elementBytes );

          parser.cache.add( ibCacheKey, ib );

        }

        bufferAttribute = new THREE.InterleavedBufferAttribute( ib, itemSize, byteOffset / elementBytes, normalized );

      } else {

        if ( bufferView === null ) {

          array = new TypedArray( accessorDef.count * itemSize );

        } else {

          array = new TypedArray( bufferView, byteOffset, accessorDef.count * itemSize );

        }

        bufferAttribute = new THREE.BufferAttribute( array, itemSize, normalized );

      }

      // https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#sparse-accessors
      if ( accessorDef.sparse !== undefined ) {

        var itemSizeIndices = WEBGL_TYPE_SIZES.SCALAR;
        var TypedArrayIndices = WEBGL_COMPONENT_TYPES[ accessorDef.sparse.indices.componentType ];

        var byteOffsetIndices = accessorDef.sparse.indices.byteOffset || 0;
        var byteOffsetValues = accessorDef.sparse.values.byteOffset || 0;

        var sparseIndices = new TypedArrayIndices( bufferViews[ 1 ], byteOffsetIndices, accessorDef.sparse.count * itemSizeIndices );
        var sparseValues = new TypedArray( bufferViews[ 2 ], byteOffsetValues, accessorDef.sparse.count * itemSize );

        if ( bufferView !== null ) {

          // Avoid modifying the original ArrayBuffer, if the bufferView wasn't initialized with zeroes.
          bufferAttribute.setArray( bufferAttribute.array.slice() );

        }

        for ( var i = 0, il = sparseIndices.length; i < il; i ++ ) {

          var index = sparseIndices[ i ];

          bufferAttribute.setX( index, sparseValues[ i * itemSize ] );
          if ( itemSize >= 2 ) bufferAttribute.setY( index, sparseValues[ i * itemSize + 1 ] );
          if ( itemSize >= 3 ) bufferAttribute.setZ( index, sparseValues[ i * itemSize + 2 ] );
          if ( itemSize >= 4 ) bufferAttribute.setW( index, sparseValues[ i * itemSize + 3 ] );
          if ( itemSize >= 5 ) throw new Error( 'THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.' );

        }

      }

      return bufferAttribute;

    } );

  };

  /**
   * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#textures
   * @param {number} textureIndex
   * @return {Promise<THREE.Texture>}
   */
  GLTFParser.prototype.loadTexture = function ( textureIndex ) {

    var parser = this;
    var json = this.json;
    var options = this.options;
    var textureLoader = this.textureLoader;

    var URL = window.URL || window.webkitURL;

    var textureDef = json.textures[ textureIndex ];

    var textureExtensions = textureDef.extensions || {};

    var source;

    if ( textureExtensions[ EXTENSIONS.MSFT_TEXTURE_DDS ] ) {

      source = json.images[ textureExtensions[ EXTENSIONS.MSFT_TEXTURE_DDS ].source ];

    } else if ( textureExtensions[ EXTENSIONS.GOOGLE_TEXTURE_BASIS ] ) {

      source = json.images[ textureExtensions[ EXTENSIONS.GOOGLE_TEXTURE_BASIS ].source ];

    } else {

      source = json.images[ textureDef.source ];

    }

    var sourceURI = source.uri;
    var isObjectURL = false;

    if ( source.bufferView !== undefined ) {

      // Load binary image data from bufferView, if provided.

      sourceURI = parser.getDependency( 'bufferView', source.bufferView ).then( function ( bufferView ) {

        isObjectURL = true;
        var blob = new Blob( [ bufferView ], { type: source.mimeType } );
        sourceURI = URL.createObjectURL( blob );
        return sourceURI;

      } );

    }

    return Promise.resolve( sourceURI ).then( function ( sourceURI ) {

      // Load Texture resource.

      var loader = THREE.Loader.Handlers.get( sourceURI );

      if ( ! loader ) {

        loader = textureExtensions[ EXTENSIONS.MSFT_TEXTURE_DDS ]
          ? parser.extensions[ EXTENSIONS.MSFT_TEXTURE_DDS ].ddsLoader
          : textureLoader;

      }

      return new Promise( function ( resolve, reject ) {

        loader.load( resolveURL( sourceURI, options.path ), resolve, undefined, reject );

      } );

    } ).then( function ( texture ) {

      // Clean up resources and configure Texture.

      if ( isObjectURL === true ) {

        URL.revokeObjectURL( sourceURI );

      }

      texture.flipY = false;

      if ( textureDef.name !== undefined ) texture.name = textureDef.name;

      // Ignore unknown mime types, like DDS files.
      if ( source.mimeType in MIME_TYPE_FORMATS ) {

        texture.format = MIME_TYPE_FORMATS[ source.mimeType ];

      }

      var samplers = json.samplers || {};
      var sampler = samplers[ textureDef.sampler ] || {};

      texture.magFilter = WEBGL_FILTERS[ sampler.magFilter ] || THREE.LinearFilter;
      texture.minFilter = WEBGL_FILTERS[ sampler.minFilter ] || THREE.LinearMipMapLinearFilter;
      texture.wrapS = WEBGL_WRAPPINGS[ sampler.wrapS ] || THREE.RepeatWrapping;
      texture.wrapT = WEBGL_WRAPPINGS[ sampler.wrapT ] || THREE.RepeatWrapping;

      return texture;

    } );

  };

  /**
   * Asynchronously assigns a texture to the given material parameters.
   * @param {Object} materialParams
   * @param {string} mapName
   * @param {Object} mapDef
   * @return {Promise}
   */
  GLTFParser.prototype.assignTexture = function ( materialParams, mapName, mapDef ) {

    var parser = this;

    return this.getDependency( 'texture', mapDef.index ).then( function ( texture ) {

      if ( ! texture.isCompressedTexture ) {

        switch ( mapName ) {

          case 'aoMap':
          case 'emissiveMap':
          case 'metalnessMap':
          case 'normalMap':
          case 'roughnessMap':
            texture.format = THREE.RGBFormat;
            break;

        }

      }

      if ( parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] ) {

        var transform = mapDef.extensions !== undefined ? mapDef.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] : undefined;

        if ( transform ) {

          texture = parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ].extendTexture( texture, transform );

        }

      }

      materialParams[ mapName ] = texture;

    } );

  };

  /**
   * Assigns final material to a Mesh, Line, or Points instance. The instance
   * already has a material (generated from the glTF material options alone)
   * but reuse of the same glTF material may require multiple threejs materials
   * to accomodate different primitive types, defines, etc. New materials will
   * be created if necessary, and reused from a cache.
   * @param  {THREE.Object3D} mesh Mesh, Line, or Points instance.
   */
  GLTFParser.prototype.assignFinalMaterial = function ( mesh ) {

    var geometry = mesh.geometry;
    var material = mesh.material;
    var extensions = this.extensions;

    var useVertexTangents = geometry.attributes.tangent !== undefined;
    var useVertexColors = geometry.attributes.color !== undefined;
    var useFlatShading = geometry.attributes.normal === undefined;
    var useSkinning = mesh.isSkinnedMesh === true;
    var useMorphTargets = Object.keys( geometry.morphAttributes ).length > 0;
    var useMorphNormals = useMorphTargets && geometry.morphAttributes.normal !== undefined;

    if ( mesh.isPoints ) {

      var cacheKey = 'PointsMaterial:' + material.uuid;

      var pointsMaterial = this.cache.get( cacheKey );

      if ( ! pointsMaterial ) {

        pointsMaterial = new THREE.PointsMaterial();
        THREE.Material.prototype.copy.call( pointsMaterial, material );
        pointsMaterial.color.copy( material.color );
        pointsMaterial.map = material.map;
        pointsMaterial.lights = false; // PointsMaterial doesn't support lights yet

        this.cache.add( cacheKey, pointsMaterial );

      }

      material = pointsMaterial;

    } else if ( mesh.isLine ) {

      var cacheKey = 'LineBasicMaterial:' + material.uuid;

      var lineMaterial = this.cache.get( cacheKey );

      if ( ! lineMaterial ) {

        lineMaterial = new THREE.LineBasicMaterial();
        THREE.Material.prototype.copy.call( lineMaterial, material );
        lineMaterial.color.copy( material.color );
        lineMaterial.lights = false; // LineBasicMaterial doesn't support lights yet

        this.cache.add( cacheKey, lineMaterial );

      }

      material = lineMaterial;

    }

    // Clone the material if it will be modified
    if ( useVertexTangents || useVertexColors || useFlatShading || useSkinning || useMorphTargets ) {

      var cacheKey = 'ClonedMaterial:' + material.uuid + ':';

      if ( material.isGLTFSpecularGlossinessMaterial ) cacheKey += 'specular-glossiness:';
      if ( useSkinning ) cacheKey += 'skinning:';
      if ( useVertexTangents ) cacheKey += 'vertex-tangents:';
      if ( useVertexColors ) cacheKey += 'vertex-colors:';
      if ( useFlatShading ) cacheKey += 'flat-shading:';
      if ( useMorphTargets ) cacheKey += 'morph-targets:';
      if ( useMorphNormals ) cacheKey += 'morph-normals:';

      var cachedMaterial = this.cache.get( cacheKey );

      if ( ! cachedMaterial ) {

        cachedMaterial = material.isGLTFSpecularGlossinessMaterial
          ? extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].cloneMaterial( material )
          : material.clone();

        if ( useSkinning ) cachedMaterial.skinning = true;
        if ( useVertexTangents ) cachedMaterial.vertexTangents = true;
        if ( useVertexColors ) cachedMaterial.vertexColors = THREE.VertexColors;
        if ( useFlatShading ) cachedMaterial.flatShading = true;
        if ( useMorphTargets ) cachedMaterial.morphTargets = true;
        if ( useMorphNormals ) cachedMaterial.morphNormals = true;

        this.cache.add( cacheKey, cachedMaterial );

      }

      material = cachedMaterial;

    }

    // workarounds for mesh and geometry

    if ( material.aoMap && geometry.attributes.uv2 === undefined && geometry.attributes.uv !== undefined ) {

      console.log( 'THREE.GLTFLoader: Duplicating UVs to support aoMap.' );
      geometry.addAttribute( 'uv2', new THREE.BufferAttribute( geometry.attributes.uv.array, 2 ) );

    }

    if ( material.isGLTFSpecularGlossinessMaterial ) {

      // for GLTFSpecularGlossinessMaterial(ShaderMaterial) uniforms runtime update
      mesh.onBeforeRender = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].refreshUniforms;

    }

    mesh.material = material;

  };

  /**
   * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#materials
   * @param {number} materialIndex
   * @return {Promise<THREE.Material>}
   */
  GLTFParser.prototype.loadMaterial = function ( materialIndex ) {

    var parser = this;
    var json = this.json;
    var extensions = this.extensions;
    var materialDef = json.materials[ materialIndex ];

    var materialType;
    var materialParams = {};
    var materialExtensions = materialDef.extensions || {};

    var pending = [];

    if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ] ) {

      var sgExtension = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ];
      materialType = sgExtension.getMaterialType();
      pending.push( sgExtension.extendParams( materialParams, materialDef, parser ) );

    } else if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] ) {

      var kmuExtension = extensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ];
      materialType = kmuExtension.getMaterialType();
      pending.push( kmuExtension.extendParams( materialParams, materialDef, parser ) );

    } else {

      // Specification:
      // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#metallic-roughness-material

      materialType = THREE.MeshStandardMaterial;

      var metallicRoughness = materialDef.pbrMetallicRoughness || {};

      materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 );
      materialParams.opacity = 1.0;

      if ( Array.isArray( metallicRoughness.baseColorFactor ) ) {

        var array = metallicRoughness.baseColorFactor;

        materialParams.color.fromArray( array );
        materialParams.opacity = array[ 3 ];

      }

      if ( metallicRoughness.baseColorTexture !== undefined ) {

        pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture ) );

      }

      materialParams.metalness = metallicRoughness.metallicFactor !== undefined ? metallicRoughness.metallicFactor : 1.0;
      materialParams.roughness = metallicRoughness.roughnessFactor !== undefined ? metallicRoughness.roughnessFactor : 1.0;

      if ( metallicRoughness.metallicRoughnessTexture !== undefined ) {

        pending.push( parser.assignTexture( materialParams, 'metalnessMap', metallicRoughness.metallicRoughnessTexture ) );
        pending.push( parser.assignTexture( materialParams, 'roughnessMap', metallicRoughness.metallicRoughnessTexture ) );

      }

    }

    if ( materialDef.doubleSided === true ) {

      materialParams.side = THREE.DoubleSide;

    }

    var alphaMode = materialDef.alphaMode || ALPHA_MODES.OPAQUE;

    if ( alphaMode === ALPHA_MODES.BLEND ) {

      materialParams.transparent = true;

    } else {

      materialParams.transparent = false;

      if ( alphaMode === ALPHA_MODES.MASK ) {

        materialParams.alphaTest = materialDef.alphaCutoff !== undefined ? materialDef.alphaCutoff : 0.5;

      }

    }

    if ( materialDef.normalTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) {

      pending.push( parser.assignTexture( materialParams, 'normalMap', materialDef.normalTexture ) );

      materialParams.normalScale = new THREE.Vector2( 1, 1 );

      if ( materialDef.normalTexture.scale !== undefined ) {

        materialParams.normalScale.set( materialDef.normalTexture.scale, materialDef.normalTexture.scale );

      }

    }

    if ( materialDef.occlusionTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) {

      pending.push( parser.assignTexture( materialParams, 'aoMap', materialDef.occlusionTexture ) );

      if ( materialDef.occlusionTexture.strength !== undefined ) {

        materialParams.aoMapIntensity = materialDef.occlusionTexture.strength;

      }

    }

    if ( materialDef.emissiveFactor !== undefined && materialType !== THREE.MeshBasicMaterial ) {

      materialParams.emissive = new THREE.Color().fromArray( materialDef.emissiveFactor );

    }

    if ( materialDef.emissiveTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) {

      pending.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture ) );

    }

    return Promise.all( pending ).then( function () {

      var material;

      if ( materialType === THREE.ShaderMaterial ) {

        material = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].createMaterial( materialParams );

      } else {

        material = new materialType( materialParams );

      }

      if ( materialDef.name !== undefined ) material.name = materialDef.name;

      // baseColorTexture, emissiveTexture, and specularGlossinessTexture use sRGB encoding.
      if ( material.map ) material.map.encoding = THREE.sRGBEncoding;
      if ( material.emissiveMap ) material.emissiveMap.encoding = THREE.sRGBEncoding;
      if ( material.specularMap ) material.specularMap.encoding = THREE.sRGBEncoding;

      assignExtrasToUserData( material, materialDef );

      if ( materialDef.extensions ) addUnknownExtensionsToUserData( extensions, material, materialDef );

      return material;

    } );

  };

  /**
   * @param {THREE.BufferGeometry} geometry
   * @param {GLTF.Primitive} primitiveDef
   * @param {GLTFParser} parser
   * @return {Promise<THREE.BufferGeometry>}
   */
  function addPrimitiveAttributes( geometry, primitiveDef, parser ) {

    var attributes = primitiveDef.attributes;

    var pending = [];

    function assignAttributeAccessor( accessorIndex, attributeName ) {

      return parser.getDependency( 'accessor', accessorIndex )
        .then( function ( accessor ) {

          geometry.addAttribute( attributeName, accessor );

        } );

    }

    for ( var gltfAttributeName in attributes ) {

      var threeAttributeName = ATTRIBUTES[ gltfAttributeName ] || gltfAttributeName.toLowerCase();

      // Skip attributes already provided by e.g. Draco extension.
      if ( threeAttributeName in geometry.attributes ) continue;

      pending.push( assignAttributeAccessor( attributes[ gltfAttributeName ], threeAttributeName ) );

    }

    if ( primitiveDef.indices !== undefined && ! geometry.index ) {

      var accessor = parser.getDependency( 'accessor', primitiveDef.indices ).then( function ( accessor ) {

        geometry.setIndex( accessor );

      } );

      pending.push( accessor );

    }

    assignExtrasToUserData( geometry, primitiveDef );

    return Promise.all( pending ).then( function () {

      return primitiveDef.targets !== undefined
        ? addMorphTargets( geometry, primitiveDef.targets, parser )
        : geometry;

    } );

  }

  /**
   * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#geometry
   *
   * Creates BufferGeometries from primitives.
   *
   * @param {Array<GLTF.Primitive>} primitives
   * @return {Promise<Array<THREE.BufferGeometry>>}
   */
  GLTFParser.prototype.loadGeometries = function ( primitives ) {

    var parser = this;
    var extensions = this.extensions;
    var cache = this.primitiveCache;

    function createDracoPrimitive( primitive ) {

      return extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ]
        .decodePrimitive( primitive, parser )
        .then( function ( geometry ) {

          return addPrimitiveAttributes( geometry, primitive, parser );

        } );

    }

    var pending = [];

    for ( var i = 0, il = primitives.length; i < il; i ++ ) {

      var primitive = primitives[ i ];
      var cacheKey = createPrimitiveKey( primitive );

      // See if we've already created this geometry
      var cached = cache[ cacheKey ];

      if ( cached ) {

        // Use the cached geometry if it exists
        pending.push( cached.promise );

      } else {

        var geometryPromise;

        if ( primitive.extensions && primitive.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] ) {

          // Use DRACO geometry if available
          geometryPromise = createDracoPrimitive( primitive );

        } else {

          // Otherwise create a new geometry
          geometryPromise = addPrimitiveAttributes( new THREE.BufferGeometry(), primitive, parser );

        }

        // Cache this geometry
        cache[ cacheKey ] = { primitive: primitive, promise: geometryPromise };

        pending.push( geometryPromise );

      }

    }

    return Promise.all( pending );

  };

  /**
   * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#meshes
   * @param {number} meshIndex
   * @return {Promise<THREE.Group|THREE.Mesh|THREE.SkinnedMesh>}
   */
  GLTFParser.prototype.loadMesh = function ( meshIndex ) {

    var parser = this;
    var json = this.json;
    var extensions = this.extensions;

    var meshDef = json.meshes[ meshIndex ];
    var primitives = meshDef.primitives;

    var pending = [];

    for ( var i = 0, il = primitives.length; i < il; i ++ ) {

      var material = primitives[ i ].material === undefined
        ? createDefaultMaterial()
        : this.getDependency( 'material', primitives[ i ].material );

      pending.push( material );

    }

    return Promise.all( pending ).then( function ( originalMaterials ) {

      return parser.loadGeometries( primitives ).then( function ( geometries ) {

        var meshes = [];

        for ( var i = 0, il = geometries.length; i < il; i ++ ) {

          var geometry = geometries[ i ];
          var primitive = primitives[ i ];

          // 1. create Mesh

          var mesh;

          var material = originalMaterials[ i ];

          if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES ||
            primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ||
            primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ||
            primitive.mode === undefined ) {

            // .isSkinnedMesh isn't in glTF spec. See .markDefs()
            mesh = meshDef.isSkinnedMesh === true
              ? new THREE.SkinnedMesh( geometry, material )
              : new THREE.Mesh( geometry, material );

            if ( mesh.isSkinnedMesh === true ) mesh.normalizeSkinWeights(); // #15319

            if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ) {

              mesh.drawMode = THREE.TriangleStripDrawMode;

            } else if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ) {

              mesh.drawMode = THREE.TriangleFanDrawMode;

            }

          } else if ( primitive.mode === WEBGL_CONSTANTS.LINES ) {

            mesh = new THREE.LineSegments( geometry, material );

          } else if ( primitive.mode === WEBGL_CONSTANTS.LINE_STRIP ) {

            mesh = new THREE.Line( geometry, material );

          } else if ( primitive.mode === WEBGL_CONSTANTS.LINE_LOOP ) {

            mesh = new THREE.LineLoop( geometry, material );

          } else if ( primitive.mode === WEBGL_CONSTANTS.POINTS ) {

            mesh = new THREE.Points( geometry, material );

          } else {

            throw new Error( 'THREE.GLTFLoader: Primitive mode unsupported: ' + primitive.mode );

          }

          if ( Object.keys( mesh.geometry.morphAttributes ).length > 0 ) {

            updateMorphTargets( mesh, meshDef );

          }

          mesh.name = meshDef.name || ( 'mesh_' + meshIndex );

          if ( geometries.length > 1 ) mesh.name += '_' + i;

          assignExtrasToUserData( mesh, meshDef );

          parser.assignFinalMaterial( mesh );

          meshes.push( mesh );

        }

        if ( meshes.length === 1 ) {

          return meshes[ 0 ];

        }

        var group = new THREE.Group();

        for ( var i = 0, il = meshes.length; i < il; i ++ ) {

          group.add( meshes[ i ] );

        }

        return group;

      } );

    } );

  };

  /**
   * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#cameras
   * @param {number} cameraIndex
   * @return {Promise<THREE.Camera>}
   */
  GLTFParser.prototype.loadCamera = function ( cameraIndex ) {

    var camera;
    var cameraDef = this.json.cameras[ cameraIndex ];
    var params = cameraDef[ cameraDef.type ];

    if ( ! params ) {

      console.warn( 'THREE.GLTFLoader: Missing camera parameters.' );
      return;

    }

    if ( cameraDef.type === 'perspective' ) {

      camera = new THREE.PerspectiveCamera( THREE.Math.radToDeg( params.yfov ), params.aspectRatio || 1, params.znear || 1, params.zfar || 2e6 );

    } else if ( cameraDef.type === 'orthographic' ) {

      camera = new THREE.OrthographicCamera( params.xmag / - 2, params.xmag / 2, params.ymag / 2, params.ymag / - 2, params.znear, params.zfar );

    }

    if ( cameraDef.name !== undefined ) camera.name = cameraDef.name;

    assignExtrasToUserData( camera, cameraDef );

    return Promise.resolve( camera );

  };

  /**
   * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins
   * @param {number} skinIndex
   * @return {Promise<Object>}
   */
  GLTFParser.prototype.loadSkin = function ( skinIndex ) {

    var skinDef = this.json.skins[ skinIndex ];

    var skinEntry = { joints: skinDef.joints };

    if ( skinDef.inverseBindMatrices === undefined ) {

      return Promise.resolve( skinEntry );

    }

    return this.getDependency( 'accessor', skinDef.inverseBindMatrices ).then( function ( accessor ) {

      skinEntry.inverseBindMatrices = accessor;

      return skinEntry;

    } );

  };

  /**
   * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations
   * @param {number} animationIndex
   * @return {Promise<THREE.AnimationClip>}
   */
  GLTFParser.prototype.loadAnimation = function ( animationIndex ) {

    var json = this.json;

    var animationDef = json.animations[ animationIndex ];

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

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

      var channel = animationDef.channels[ i ];
      var sampler = animationDef.samplers[ channel.sampler ];
      var target = channel.target;
      var name = target.node !== undefined ? target.node : target.id; // NOTE: target.id is deprecated.
      var input = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.input ] : sampler.input;
      var 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 ) {

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

      var tracks = [];

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

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

        if ( node === undefined ) continue;

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

        var TypedKeyframeTrack;

        switch ( PATH_PROPERTIES[ target.path ] ) {

          case PATH_PROPERTIES.weights:

            TypedKeyframeTrack = THREE.NumberKeyframeTrack;
            break;

          case PATH_PROPERTIES.rotation:

            TypedKeyframeTrack = THREE.QuaternionKeyframeTrack;
            break;

          case PATH_PROPERTIES.position:
          case PATH_PROPERTIES.scale:
          default:

            TypedKeyframeTrack = THREE.VectorKeyframeTrack;
            break;

        }

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

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

        var targetNames = [];

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

          // Node may be a THREE.Group (glTF mesh with several primitives) or a THREE.Mesh.
          node.traverse( function ( object ) {

            if ( object.isMesh === true && object.morphTargetInfluences ) {

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

            }

          } );

        } else {

          targetNames.push( targetName );

        }

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

          var track = new TypedKeyframeTrack(
            targetNames[ j ] + '.' + PATH_PROPERTIES[ target.path ],
            inputAccessor.array,
            outputAccessor.array,
            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.

              return new GLTFCubicSplineInterpolant( 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 );

        }

      }

      var name = animationDef.name !== undefined ? animationDef.name : 'animation_' + animationIndex;

      return new THREE.AnimationClip( name, undefined, tracks );

    } );

  };

  /**
   * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#nodes-and-hierarchy
   * @param {number} nodeIndex
   * @return {Promise<THREE.Object3D>}
   */
  GLTFParser.prototype.loadNode = function ( nodeIndex ) {

    var json = this.json;
    var extensions = this.extensions;
    var parser = this;

    var meshReferences = json.meshReferences;
    var meshUses = json.meshUses;

    var nodeDef = json.nodes[ nodeIndex ];

    return ( function () {

      // .isBone isn't in glTF spec. See .markDefs
      if ( nodeDef.isBone === true ) {

        return Promise.resolve( new THREE.Bone() );

      } else if ( nodeDef.mesh !== undefined ) {

        return parser.getDependency( 'mesh', nodeDef.mesh ).then( function ( mesh ) {

          var node;

          if ( meshReferences[ nodeDef.mesh ] > 1 ) {

            var instanceNum = meshUses[ nodeDef.mesh ] ++;

            node = mesh.clone();
            node.name += '_instance_' + instanceNum;

            // onBeforeRender copy for Specular-Glossiness
            node.onBeforeRender = mesh.onBeforeRender;

            for ( var i = 0, il = node.children.length; i < il; i ++ ) {

              node.children[ i ].name += '_instance_' + instanceNum;
              node.children[ i ].onBeforeRender = mesh.children[ i ].onBeforeRender;

            }

          } else {

            node = mesh;

          }

          // if weights are provided on the node, override weights on the mesh.
          if ( nodeDef.weights !== undefined ) {

            node.traverse( function ( o ) {

              if ( ! o.isMesh ) return;

              for ( var i = 0, il = nodeDef.weights.length; i < il; i ++ ) {

                o.morphTargetInfluences[ i ] = nodeDef.weights[ i ];

              }

            } );

          }

          return node;

        } );

      } else if ( nodeDef.camera !== undefined ) {

        return parser.getDependency( 'camera', nodeDef.camera );

      } else if ( nodeDef.extensions
        && nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ]
        && nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].light !== undefined ) {

        return parser.getDependency( 'light', nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].light );

      } else {

        return Promise.resolve( new THREE.Object3D() );

      }

    }() ).then( function ( node ) {

      if ( nodeDef.name !== undefined ) {

        node.name = THREE.PropertyBinding.sanitizeNodeName( nodeDef.name );

      }

      assignExtrasToUserData( node, nodeDef );

      if ( nodeDef.extensions ) addUnknownExtensionsToUserData( extensions, node, nodeDef );

      if ( nodeDef.matrix !== undefined ) {

        var matrix = new THREE.Matrix4();
        matrix.fromArray( nodeDef.matrix );
        node.applyMatrix( matrix );

      } else {

        if ( nodeDef.translation !== undefined ) {

          node.position.fromArray( nodeDef.translation );

        }

        if ( nodeDef.rotation !== undefined ) {

          node.quaternion.fromArray( nodeDef.rotation );

        }

        if ( nodeDef.scale !== undefined ) {

          node.scale.fromArray( nodeDef.scale );

        }

      }

      return node;

    } );

  };

  /**
   * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#scenes
   * @param {number} sceneIndex
   * @return {Promise<THREE.Scene>}
   */
  GLTFParser.prototype.loadScene = function () {

    // scene node hierachy builder

    function buildNodeHierachy( nodeId, parentObject, json, parser ) {

      var nodeDef = json.nodes[ nodeId ];

      return parser.getDependency( 'node', nodeId ).then( function ( node ) {

        if ( nodeDef.skin === undefined ) return node;

        // build skeleton here as well

        var skinEntry;

        return parser.getDependency( 'skin', nodeDef.skin ).then( function ( skin ) {

          skinEntry = skin;

          var pendingJoints = [];

          for ( var i = 0, il = skinEntry.joints.length; i < il; i ++ ) {

            pendingJoints.push( parser.getDependency( 'node', skinEntry.joints[ i ] ) );

          }

          return Promise.all( pendingJoints );

        } ).then( function ( jointNodes ) {

          var meshes = node.isGroup === true ? node.children : [ node ];

          for ( var i = 0, il = meshes.length; i < il; i ++ ) {

            var mesh = meshes[ i ];

            var bones = [];
            var boneInverses = [];

            for ( var j = 0, jl = jointNodes.length; j < jl; j ++ ) {

              var jointNode = jointNodes[ j ];

              if ( jointNode ) {

                bones.push( jointNode );

                var mat = new THREE.Matrix4();

                if ( skinEntry.inverseBindMatrices !== undefined ) {

                  mat.fromArray( skinEntry.inverseBindMatrices.array, j * 16 );

                }

                boneInverses.push( mat );

              } else {

                console.warn( 'THREE.GLTFLoader: Joint "%s" could not be found.', skinEntry.joints[ j ] );

              }

            }

            mesh.bind( new THREE.Skeleton( bones, boneInverses ), mesh.matrixWorld );

          }

          return node;

        } );

      } ).then( function ( node ) {

        // build node hierachy

        parentObject.add( node );

        var pending = [];

        if ( nodeDef.children ) {

          var children = nodeDef.children;

          for ( var i = 0, il = children.length; i < il; i ++ ) {

            var child = children[ i ];
            pending.push( buildNodeHierachy( child, node, json, parser ) );

          }

        }

        return Promise.all( pending );

      } );

    }

    return function loadScene( sceneIndex ) {

      var json = this.json;
      var extensions = this.extensions;
      var sceneDef = this.json.scenes[ sceneIndex ];
      var parser = this;

      var scene = new THREE.Scene();
      if ( sceneDef.name !== undefined ) scene.name = sceneDef.name;

      assignExtrasToUserData( scene, sceneDef );

      if ( sceneDef.extensions ) addUnknownExtensionsToUserData( extensions, scene, sceneDef );

      var nodeIds = sceneDef.nodes || [];

      var pending = [];

      for ( var i = 0, il = nodeIds.length; i < il; i ++ ) {

        pending.push( buildNodeHierachy( nodeIds[ i ], scene, json, parser ) );

      }

      return Promise.all( pending ).then( function () {

        return scene;

      } );

    };

  }();

  return GLTFLoader;

} )();