/* eslint-disable */
// Copy LegacyGLTFLoader file from THREE v110 because it was removed in THREE v111
import * as THREE from 'three';
const threeExamples = {};
/**
 * @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
 */

threeExamples.LegacyGLTFLoader = function () {
  class LegacyGLTFLoader extends THREE.Loader {
    constructor(manager) {
      super(manager);
    }
    load(url, onLoad, onProgress, onError) {
      var scope = this;
      var resourcePath;
      if (this.resourcePath !== '') {
        resourcePath = this.resourcePath;
      } else if (this.path !== '') {
        resourcePath = this.path;
      } else {
        resourcePath = THREE.LoaderUtils.extractUrlBase(url);
      }
      var loader = new THREE.FileLoader(scope.manager);
      loader.setPath(this.path);
      loader.setResponseType('arraybuffer');
      loader.load(url, function (data) {
        scope.parse(data, resourcePath, onLoad);
      }, onProgress, onError);
    }
    parse(data, path, callback) {
      var content;
      var extensions = {};
      var magic = THREE.LoaderUtils.decodeText(new Uint8Array(data, 0, 4));
      if (magic === BINARY_EXTENSION_HEADER_DEFAULTS.magic) {
        extensions[EXTENSIONS.KHR_BINARY_GLTF] = new GLTFBinaryExtension(data);
        content = extensions[EXTENSIONS.KHR_BINARY_GLTF].content;
      } else {
        content = THREE.LoaderUtils.decodeText(new Uint8Array(data));
      }
      var json = JSON.parse(content);
      if (json.extensionsUsed && json.extensionsUsed.indexOf(EXTENSIONS.KHR_MATERIALS_COMMON) >= 0) {
        extensions[EXTENSIONS.KHR_MATERIALS_COMMON] = new GLTFMaterialsCommonExtension(json);
      }
      var parser = new GLTFParser(json, extensions, {
        crossOrigin: this.crossOrigin,
        manager: this.manager,
        path: path || this.resourcePath || ''
      });
      parser.parse(function (scene, scenes, cameras, animations) {
        callback({
          "scene": scene,
          "scenes": scenes,
          "cameras": cameras,
          "animations": animations
        });
      });
    }
  }

  /* 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 = {};
      },
      update: function (scene, camera) {
        for (var name in objects) {
          var object = objects[name];
          if (object.update) {
            object.update(scene, camera);
          }
        }
      }
    };
  }

  /* GLTFSHADERS */

  LegacyGLTFLoader.Shaders = {
    update: function () {
      console.warn('threeExamples.LegacyGLTFLoader.Shaders has been deprecated, and now updates automatically.');
    }
  };

  /* GLTFSHADER */

  function GLTFShader(targetNode, allNodes) {
    var boundUniforms = {};

    // bind each uniform to its source node

    var uniforms = targetNode.material.uniforms;
    for (var uniformId in uniforms) {
      var uniform = uniforms[uniformId];
      if (uniform.semantic) {
        var sourceNodeRef = uniform.node;
        var sourceNode = targetNode;
        if (sourceNodeRef) {
          sourceNode = allNodes[sourceNodeRef];
        }
        boundUniforms[uniformId] = {
          semantic: uniform.semantic,
          sourceNode: sourceNode,
          targetNode: targetNode,
          uniform: uniform
        };
      }
    }
    this.boundUniforms = boundUniforms;
    this._m4 = new THREE.Matrix4();
  }

  // Update - update all the uniform values
  GLTFShader.prototype.update = function (scene, camera) {
    var boundUniforms = this.boundUniforms;
    for (var name in boundUniforms) {
      var boundUniform = boundUniforms[name];
      switch (boundUniform.semantic) {
        case "MODELVIEW":
          var m4 = boundUniform.uniform.value;
          m4.multiplyMatrices(camera.matrixWorldInverse, boundUniform.sourceNode.matrixWorld);
          break;
        case "MODELVIEWINVERSETRANSPOSE":
          var m3 = boundUniform.uniform.value;
          this._m4.multiplyMatrices(camera.matrixWorldInverse, boundUniform.sourceNode.matrixWorld);
          m3.getNormalMatrix(this._m4);
          break;
        case "PROJECTION":
          var m4 = boundUniform.uniform.value;
          m4.copy(camera.projectionMatrix);
          break;
        case "JOINTMATRIX":
          var m4v = boundUniform.uniform.value;
          for (var mi = 0; mi < m4v.length; mi++) {
            // So it goes like this:
            // SkinnedMesh world matrix is already baked into MODELVIEW;
            // transform joints to local space,
            // then transform using joint's inverse
            m4v[mi].getInverse(boundUniform.sourceNode.matrixWorld).multiply(boundUniform.targetNode.skeleton.bones[mi].matrixWorld).multiply(boundUniform.targetNode.skeleton.boneInverses[mi]).multiply(boundUniform.targetNode.bindMatrix);
          }
          break;
        default:
          console.warn("Unhandled shader semantic: " + boundUniform.semantic);
          break;
      }
    }
  };

  /* ANIMATION */

  LegacyGLTFLoader.Animations = {
    update: function () {
      console.warn('threeExamples.LegacyGLTFLoader.Animation has been deprecated. Use THREE.AnimationMixer instead.');
    }
  };

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

  var EXTENSIONS = {
    KHR_BINARY_GLTF: 'KHR_binary_glTF',
    KHR_MATERIALS_COMMON: 'KHR_materials_common'
  };

  /* MATERIALS COMMON EXTENSION */

  function GLTFMaterialsCommonExtension(json) {
    this.name = EXTENSIONS.KHR_MATERIALS_COMMON;
    this.lights = {};
    var extension = json.extensions && json.extensions[EXTENSIONS.KHR_MATERIALS_COMMON] || {};
    var lights = extension.lights || {};
    for (var lightId in lights) {
      var light = lights[lightId];
      var lightNode;
      var lightParams = light[light.type];
      var color = new THREE.Color().fromArray(lightParams.color);
      switch (light.type) {
        case "directional":
          lightNode = new THREE.DirectionalLight(color);
          lightNode.position.set(0, 0, 1);
          break;
        case "point":
          lightNode = new THREE.PointLight(color);
          break;
        case "spot":
          lightNode = new THREE.SpotLight(color);
          lightNode.position.set(0, 0, 1);
          break;
        case "ambient":
          lightNode = new THREE.AmbientLight(color);
          break;
      }
      if (lightNode) {
        this.lights[lightId] = lightNode;
      }
    }
  }

  /* BINARY EXTENSION */

  var BINARY_EXTENSION_HEADER_DEFAULTS = {
    magic: 'glTF',
    version: 1,
    contentFormat: 0
  };
  var BINARY_EXTENSION_HEADER_LENGTH = 20;
  function GLTFBinaryExtension(data) {
    this.name = EXTENSIONS.KHR_BINARY_GLTF;
    var headerView = new DataView(data, 0, BINARY_EXTENSION_HEADER_LENGTH);
    var header = {
      magic: THREE.LoaderUtils.decodeText(new Uint8Array(data.slice(0, 4))),
      version: headerView.getUint32(4, true),
      length: headerView.getUint32(8, true),
      contentLength: headerView.getUint32(12, true),
      contentFormat: headerView.getUint32(16, true)
    };
    for (var key in BINARY_EXTENSION_HEADER_DEFAULTS) {
      var value = BINARY_EXTENSION_HEADER_DEFAULTS[key];
      if (header[key] !== value) {
        throw new Error('Unsupported glTF-Binary header: Expected "%s" to be "%s".', key, value);
      }
    }
    var contentArray = new Uint8Array(data, BINARY_EXTENSION_HEADER_LENGTH, header.contentLength);
    this.header = header;
    this.content = THREE.LoaderUtils.decodeText(contentArray);
    this.body = data.slice(BINARY_EXTENSION_HEADER_LENGTH + header.contentLength, header.length);
  }
  GLTFBinaryExtension.prototype.loadShader = function (shader, bufferViews) {
    var bufferView = bufferViews[shader.extensions[EXTENSIONS.KHR_BINARY_GLTF].bufferView];
    var array = new Uint8Array(bufferView);
    return THREE.LoaderUtils.decodeText(array);
  };

  /*********************************/
  /********** 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,
    TRIANGLES: 4,
    LINES: 1,
    UNSIGNED_BYTE: 5121,
    UNSIGNED_SHORT: 5123,
    VERTEX_SHADER: 35633,
    FRAGMENT_SHADER: 35632
  };
  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_TEXTURE_FORMATS = {
    6406: THREE.AlphaFormat,
    6407: THREE.RGBAFormat,
    6408: THREE.RGBAFormat,
    6409: THREE.LuminanceFormat,
    6410: THREE.LuminanceAlphaFormat
  };
  var WEBGL_TEXTURE_DATATYPES = {
    5121: THREE.UnsignedByteType,
    32819: THREE.UnsignedShort4444Type,
    32820: THREE.UnsignedShort5551Type,
    33635: THREE.UnsignedShort5551Type
  };
  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 PATH_PROPERTIES = {
    scale: 'scale',
    translation: 'position',
    rotation: 'quaternion'
  };
  var INTERPOLATION = {
    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'
  };

  /* UTILITY FUNCTIONS */

  function _each(object, callback, thisObj) {
    if (!object) {
      return Promise.resolve();
    }
    var results;
    var fns = [];
    if (Object.prototype.toString.call(object) === '[object Array]') {
      results = [];
      var length = object.length;
      for (var idx = 0; idx < length; idx++) {
        var value = callback.call(thisObj || this, object[idx], idx);
        if (value) {
          fns.push(value);
          if (value instanceof Promise) {
            value.then(function (key, value) {
              results[key] = value;
            }.bind(this, idx));
          } else {
            results[idx] = value;
          }
        }
      }
    } else {
      results = {};
      for (var key in object) {
        if (object.hasOwnProperty(key)) {
          var value = callback.call(thisObj || this, object[key], key);
          if (value) {
            fns.push(value);
            if (value instanceof Promise) {
              value.then(function (key, value) {
                results[key] = value;
              }.bind(this, key));
            } else {
              results[key] = value;
            }
          }
        }
      }
    }
    return Promise.all(fns).then(function () {
      return results;
    });
  }
  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;
  }

  // Three.js seems too dependent on attribute names so globally
  // replace those in the shader code
  function replaceTHREEShaderAttributes(shaderText, technique) {
    // Expected technique attributes
    var attributes = {};
    for (var attributeId in technique.attributes) {
      var pname = technique.attributes[attributeId];
      var param = technique.parameters[pname];
      var atype = param.type;
      var semantic = param.semantic;
      attributes[attributeId] = {
        type: atype,
        semantic: semantic
      };
    }

    // Figure out which attributes to change in technique

    var shaderParams = technique.parameters;
    var shaderAttributes = technique.attributes;
    var params = {};
    for (var attributeId in attributes) {
      var pname = shaderAttributes[attributeId];
      var shaderParam = shaderParams[pname];
      var semantic = shaderParam.semantic;
      if (semantic) {
        params[attributeId] = shaderParam;
      }
    }
    for (var pname in params) {
      var param = params[pname];
      var semantic = param.semantic;
      var regEx = new RegExp("\\b" + pname + "\\b", "g");
      switch (semantic) {
        case "POSITION":
          shaderText = shaderText.replace(regEx, 'position');
          break;
        case "NORMAL":
          shaderText = shaderText.replace(regEx, 'normal');
          break;
        case 'TEXCOORD_0':
        case 'TEXCOORD0':
        case 'TEXCOORD':
          shaderText = shaderText.replace(regEx, 'uv');
          break;
        case 'TEXCOORD_1':
          shaderText = shaderText.replace(regEx, 'uv2');
          break;
        case 'COLOR_0':
        case 'COLOR0':
        case 'COLOR':
          shaderText = shaderText.replace(regEx, 'color');
          break;
        case "WEIGHT":
          shaderText = shaderText.replace(regEx, 'skinWeight');
          break;
        case "JOINT":
          shaderText = shaderText.replace(regEx, 'skinIndex');
          break;
      }
    }
    return shaderText;
  }
  function createDefaultMaterial() {
    return new THREE.MeshPhongMaterial({
      color: 0x00000,
      emissive: 0x888888,
      specular: 0x000000,
      shininess: 0,
      transparent: false,
      depthTest: true,
      side: THREE.FrontSide
    });
  }

  /**
   * Verifies if the shaders are Cesium specific: if they contain attributes, uniforms or functions starting with 
   * `czm_`. The cesium gltf-pipeline (the ancestor of cesium ion) used to create 3D Tiles tilesets they are only 
   * defined in Cesium. 
   * @param {Object} shaders
   */
  function areShadersCesiumSpecific(shaders) {
    for (const shaderId in shaders) {
      if (shaders[shaderId].includes('czm_')) {
        return true;
      }
    }
    return false;
  }

  // Deferred constructor for RawShaderMaterial types
  function DeferredShaderMaterial(params) {
    this.isDeferredShaderMaterial = true;
    this.params = params;
  }
  DeferredShaderMaterial.prototype.create = function () {
    var uniforms = THREE.UniformsUtils.clone(this.params.uniforms);
    for (var uniformId in this.params.uniforms) {
      var originalUniform = this.params.uniforms[uniformId];
      if (originalUniform.value instanceof THREE.Texture) {
        uniforms[uniformId].value = originalUniform.value;
        uniforms[uniformId].value.needsUpdate = true;
      }
      uniforms[uniformId].semantic = originalUniform.semantic;
      uniforms[uniformId].node = originalUniform.node;
    }
    this.params.uniforms = uniforms;
    return new THREE.RawShaderMaterial(this.params);
  };

  /* GLTF PARSER */

  function GLTFParser(json, extensions, options) {
    this.json = json || {};
    this.extensions = extensions || {};
    this.options = options || {};

    // loader object cache
    this.cache = new GLTFRegistry();
  }
  GLTFParser.prototype._withDependencies = function (dependencies) {
    var _dependencies = {};
    for (var i = 0; i < dependencies.length; i++) {
      var dependency = dependencies[i];
      var fnName = "load" + dependency.charAt(0).toUpperCase() + dependency.slice(1);
      var cached = this.cache.get(dependency);
      if (cached !== undefined) {
        _dependencies[dependency] = cached;
      } else if (this[fnName]) {
        var fn = this[fnName]();
        this.cache.add(dependency, fn);
        _dependencies[dependency] = fn;
      }
    }
    return _each(_dependencies, function (dependency) {
      return dependency;
    });
  };
  GLTFParser.prototype.parse = function (callback) {
    var json = this.json;

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

    // Fire the callback on complete
    this._withDependencies(["scenes", "cameras", "animations"]).then(function (dependencies) {
      var scenes = [];
      for (var name in dependencies.scenes) {
        scenes.push(dependencies.scenes[name]);
      }
      var scene = json.scene !== undefined ? dependencies.scenes[json.scene] : scenes[0];
      var cameras = [];
      for (var name in dependencies.cameras) {
        var camera = dependencies.cameras[name];
        cameras.push(camera);
      }
      var animations = [];
      for (var name in dependencies.animations) {
        animations.push(dependencies.animations[name]);
      }
      callback(scene, scenes, cameras, animations);
    });
  };
  GLTFParser.prototype.loadShaders = function () {
    var json = this.json;
    var extensions = this.extensions;
    var options = this.options;
    return this._withDependencies(["bufferViews"]).then(function (dependencies) {
      return _each(json.shaders, function (shader) {
        if (shader.extensions && shader.extensions[EXTENSIONS.KHR_BINARY_GLTF]) {
          return extensions[EXTENSIONS.KHR_BINARY_GLTF].loadShader(shader, dependencies.bufferViews);
        }
        return new Promise(function (resolve) {
          var loader = new THREE.FileLoader(options.manager);
          loader.setResponseType('text');
          loader.load(resolveURL(shader.uri, options.path), function (shaderText) {
            resolve(shaderText);
          });
        });
      });
    });
  };
  GLTFParser.prototype.loadBuffers = function () {
    var json = this.json;
    var extensions = this.extensions;
    var options = this.options;
    return _each(json.buffers, function (buffer, name) {
      if (name === 'binary_glTF' || name === EXTENSIONS.KHR_BINARY_GLTF) {
        return extensions[EXTENSIONS.KHR_BINARY_GLTF].body;
      }
      if (buffer.type === 'arraybuffer' || buffer.type === undefined) {
        return new Promise(function (resolve) {
          var loader = new THREE.FileLoader(options.manager);
          loader.setResponseType('arraybuffer');
          loader.load(resolveURL(buffer.uri, options.path), function (buffer) {
            resolve(buffer);
          });
        });
      } else {
        console.warn('threeExamples.LegacyGLTFLoader: ' + buffer.type + ' buffer type is not supported');
      }
    });
  };
  GLTFParser.prototype.loadBufferViews = function () {
    var json = this.json;
    return this._withDependencies(["buffers"]).then(function (dependencies) {
      return _each(json.bufferViews, function (bufferView) {
        var arraybuffer = dependencies.buffers[bufferView.buffer];
        var byteLength = bufferView.byteLength !== undefined ? bufferView.byteLength : 0;
        return arraybuffer.slice(bufferView.byteOffset, bufferView.byteOffset + byteLength);
      });
    });
  };
  GLTFParser.prototype.loadAccessors = function () {
    var json = this.json;
    return this._withDependencies(["bufferViews"]).then(function (dependencies) {
      return _each(json.accessors, function (accessor) {
        var arraybuffer = dependencies.bufferViews[accessor.bufferView];
        var itemSize = WEBGL_TYPE_SIZES[accessor.type];
        var TypedArray = WEBGL_COMPONENT_TYPES[accessor.componentType];

        // For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.
        var elementBytes = TypedArray.BYTES_PER_ELEMENT;
        // The buffer is not interleaved if the stride is the item size in bytes.
        if (accessor.byteStride && accessor.byteStride !== elementBytes * itemSize) {
          // Use the full buffer if it's interleaved.
          var array = new TypedArray(arraybuffer);

          // Integer parameters to IB/IBA are in array elements, not bytes.
          var ib = new THREE.InterleavedBuffer(array, accessor.byteStride / elementBytes);
          return new THREE.InterleavedBufferAttribute(ib, itemSize, accessor.byteOffset / elementBytes);
        } else {
          array = new TypedArray(arraybuffer, accessor.byteOffset, accessor.count * itemSize);
          return new THREE.BufferAttribute(array, itemSize);
        }
      });
    });
  };
  GLTFParser.prototype.loadTextures = function () {
    var json = this.json;
    var options = this.options;
    return this._withDependencies(["bufferViews"]).then(function (dependencies) {
      return _each(json.textures, function (texture) {
        if (texture.source) {
          return new Promise(function (resolve) {
            var source = json.images[texture.source];
            var sourceUri = source.uri;
            var isObjectURL = false;
            if (source.extensions && source.extensions[EXTENSIONS.KHR_BINARY_GLTF]) {
              var metadata = source.extensions[EXTENSIONS.KHR_BINARY_GLTF];
              var bufferView = dependencies.bufferViews[metadata.bufferView];
              var blob = new Blob([bufferView], {
                type: metadata.mimeType
              });
              sourceUri = URL.createObjectURL(blob);
              isObjectURL = true;
            }
            var textureLoader = options.manager.getHandler(sourceUri);
            if (textureLoader === null) {
              textureLoader = new THREE.TextureLoader(options.manager);
            }
            textureLoader.setCrossOrigin(options.crossOrigin);
            textureLoader.load(resolveURL(sourceUri, options.path), function (_texture) {
              if (isObjectURL) URL.revokeObjectURL(sourceUri);
              _texture.flipY = false;
              if (texture.name !== undefined) _texture.name = texture.name;
              _texture.format = texture.format !== undefined ? WEBGL_TEXTURE_FORMATS[texture.format] : THREE.RGBAFormat;
              if (texture.internalFormat !== undefined && _texture.format !== WEBGL_TEXTURE_FORMATS[texture.internalFormat]) {
                console.warn('threeExamples.LegacyGLTFLoader: Three.js doesn\'t support texture internalFormat which is different from texture format. ' + 'internalFormat will be forced to be the same value as format.');
              }
              _texture.type = texture.type !== undefined ? WEBGL_TEXTURE_DATATYPES[texture.type] : THREE.UnsignedByteType;
              if (texture.sampler) {
                var sampler = json.samplers[texture.sampler];
                _texture.magFilter = WEBGL_FILTERS[sampler.magFilter] || THREE.LinearFilter;
                _texture.minFilter = WEBGL_FILTERS[sampler.minFilter] || THREE.NearestMipmapLinearFilter;
                _texture.wrapS = WEBGL_WRAPPINGS[sampler.wrapS] || THREE.RepeatWrapping;
                _texture.wrapT = WEBGL_WRAPPINGS[sampler.wrapT] || THREE.RepeatWrapping;
              }
              resolve(_texture);
            }, undefined, function () {
              if (isObjectURL) URL.revokeObjectURL(sourceUri);
              resolve();
            });
          });
        }
      });
    });
  };
  GLTFParser.prototype.loadMaterials = function () {
    var json = this.json;
    return this._withDependencies(["shaders", "textures"]).then(function (dependencies) {
      return _each(json.materials, function (material) {
        var materialType;
        var materialValues = {};
        var materialParams = {};
        var khr_material;
        if (material.extensions && material.extensions[EXTENSIONS.KHR_MATERIALS_COMMON]) {
          khr_material = material.extensions[EXTENSIONS.KHR_MATERIALS_COMMON];
        }
        if (khr_material) {
          // don't copy over unused values to avoid material warning spam
          var keys = ['ambient', 'emission', 'transparent', 'transparency', 'doubleSided'];
          switch (khr_material.technique) {
            case 'BLINN':
            case 'PHONG':
              materialType = THREE.MeshPhongMaterial;
              keys.push('diffuse', 'specular', 'shininess');
              break;
            case 'LAMBERT':
              materialType = THREE.MeshLambertMaterial;
              keys.push('diffuse');
              break;
            case 'CONSTANT':
            default:
              materialType = THREE.MeshBasicMaterial;
              break;
          }
          keys.forEach(function (v) {
            if (khr_material.values[v] !== undefined) materialValues[v] = khr_material.values[v];
          });
          if (khr_material.doubleSided || materialValues.doubleSided) {
            materialParams.side = THREE.DoubleSide;
          }
          if (khr_material.transparent || materialValues.transparent) {
            materialParams.transparent = true;
            materialParams.opacity = materialValues.transparency !== undefined ? materialValues.transparency : 1;
          }
        } else if (material.technique === undefined) {
          materialType = THREE.MeshPhongMaterial;
          Object.assign(materialValues, material.values);
        } else {
          const technique = json.techniques[material.technique];

          // If shaders are Cesium specific, set up a MeshBasicMaterial to avoid an error at shader compilation
          if (areShadersCesiumSpecific(dependencies.shaders)) {
            materialType = THREE.MeshBasicMaterial;

            // Retrieve texture from uniforms so it is not lost in the process.
            let texture = null;
            const uniforms = technique.uniforms;
            for (const uniformId in uniforms) {
              const pname = uniforms[uniformId];
              const shaderParam = technique.parameters[pname];
              const ptype = shaderParam.type;
              if (ptype === WEBGL_CONSTANTS.SAMPLER_2D) {
                let value;
                if (material.values !== undefined) value = material.values[pname];
                if (value !== undefined) {
                  texture = dependencies.textures[value];
                } else if (shaderParam.value !== undefined) {
                  texture = dependencies.textures[shaderParam.value];
                }
              }
            }
            if (texture) {
              materialParams.map = texture;
            }
          } else {
            materialType = DeferredShaderMaterial;
            materialParams.uniforms = {};
            var program = json.programs[technique.program];
            if (program) {
              materialParams.fragmentShader = dependencies.shaders[program.fragmentShader];
              if (!materialParams.fragmentShader) {
                console.warn("ERROR: Missing fragment shader definition:", program.fragmentShader);
                materialType = THREE.MeshPhongMaterial;
              }
              var vertexShader = dependencies.shaders[program.vertexShader];
              if (!vertexShader) {
                console.warn("ERROR: Missing vertex shader definition:", program.vertexShader);
                materialType = THREE.MeshPhongMaterial;
              }

              // IMPORTANT: FIX VERTEX SHADER ATTRIBUTE DEFINITIONS
              materialParams.vertexShader = replaceTHREEShaderAttributes(vertexShader, technique);
              const uniforms = technique.uniforms;
              for (const uniformId in uniforms) {
                const pname = uniforms[uniformId];
                const shaderParam = technique.parameters[pname];
                const ptype = shaderParam.type;
                if (WEBGL_TYPE[ptype]) {
                  const pcount = shaderParam.count;
                  let value;
                  if (material.values !== undefined) value = material.values[pname];
                  var uvalue = new WEBGL_TYPE[ptype]();
                  var usemantic = shaderParam.semantic;
                  var unode = shaderParam.node;
                  switch (ptype) {
                    case WEBGL_CONSTANTS.FLOAT:
                      uvalue = shaderParam.value;
                      if (pname == "transparency") {
                        materialParams.transparent = true;
                      }
                      if (value !== undefined) {
                        uvalue = value;
                      }
                      break;
                    case WEBGL_CONSTANTS.FLOAT_VEC2:
                    case WEBGL_CONSTANTS.FLOAT_VEC3:
                    case WEBGL_CONSTANTS.FLOAT_VEC4:
                    case WEBGL_CONSTANTS.FLOAT_MAT3:
                      if (shaderParam && shaderParam.value) {
                        uvalue.fromArray(shaderParam.value);
                      }
                      if (value) {
                        uvalue.fromArray(value);
                      }
                      break;
                    case WEBGL_CONSTANTS.FLOAT_MAT2:
                      // what to do?
                      console.warn("FLOAT_MAT2 is not a supported uniform type");
                      break;
                    case WEBGL_CONSTANTS.FLOAT_MAT4:
                      if (pcount) {
                        uvalue = new Array(pcount);
                        for (var mi = 0; mi < pcount; mi++) {
                          uvalue[mi] = new WEBGL_TYPE[ptype]();
                        }
                        if (shaderParam && shaderParam.value) {
                          var m4v = shaderParam.value;
                          uvalue.fromArray(m4v);
                        }
                        if (value) {
                          uvalue.fromArray(value);
                        }
                      } else {
                        if (shaderParam && shaderParam.value) {
                          var m4 = shaderParam.value;
                          uvalue.fromArray(m4);
                        }
                        if (value) {
                          uvalue.fromArray(value);
                        }
                      }
                      break;
                    case WEBGL_CONSTANTS.SAMPLER_2D:
                      if (value !== undefined) {
                        uvalue = dependencies.textures[value];
                      } else if (shaderParam.value !== undefined) {
                        uvalue = dependencies.textures[shaderParam.value];
                      } else {
                        uvalue = null;
                      }
                      break;
                  }
                  materialParams.uniforms[uniformId] = {
                    value: uvalue,
                    semantic: usemantic,
                    node: unode
                  };
                } else {
                  throw new Error("Unknown shader uniform param type: " + ptype);
                }
              }
              var states = technique.states || {};
              var enables = states.enable || [];
              var functions = states.functions || {};
              var enableCullFace = false;
              var enableDepthTest = false;
              var enableBlend = false;
              for (var i = 0, il = enables.length; i < il; i++) {
                var enable = enables[i];
                switch (STATES_ENABLES[enable]) {
                  case 'CULL_FACE':
                    enableCullFace = true;
                    break;
                  case 'DEPTH_TEST':
                    enableDepthTest = true;
                    break;
                  case 'BLEND':
                    enableBlend = true;
                    break;

                  // TODO: implement
                  case 'SCISSOR_TEST':
                  case 'POLYGON_OFFSET_FILL':
                  case 'SAMPLE_ALPHA_TO_COVERAGE':
                    break;
                  default:
                    throw new Error("Unknown technique.states.enable: " + enable);
                }
              }
              if (enableCullFace) {
                materialParams.side = functions.cullFace !== undefined ? WEBGL_SIDES[functions.cullFace] : THREE.FrontSide;
              } else {
                materialParams.side = THREE.DoubleSide;
              }
              materialParams.depthTest = enableDepthTest;
              materialParams.depthFunc = functions.depthFunc !== undefined ? WEBGL_DEPTH_FUNCS[functions.depthFunc] : THREE.LessDepth;
              materialParams.depthWrite = functions.depthMask !== undefined ? functions.depthMask[0] : true;
              materialParams.blending = enableBlend ? THREE.CustomBlending : THREE.NoBlending;
              materialParams.transparent = enableBlend;
              var blendEquationSeparate = functions.blendEquationSeparate;
              if (blendEquationSeparate !== undefined) {
                materialParams.blendEquation = WEBGL_BLEND_EQUATIONS[blendEquationSeparate[0]];
                materialParams.blendEquationAlpha = WEBGL_BLEND_EQUATIONS[blendEquationSeparate[1]];
              } else {
                materialParams.blendEquation = THREE.AddEquation;
                materialParams.blendEquationAlpha = THREE.AddEquation;
              }
              var blendFuncSeparate = functions.blendFuncSeparate;
              if (blendFuncSeparate !== undefined) {
                materialParams.blendSrc = WEBGL_BLEND_FUNCS[blendFuncSeparate[0]];
                materialParams.blendDst = WEBGL_BLEND_FUNCS[blendFuncSeparate[1]];
                materialParams.blendSrcAlpha = WEBGL_BLEND_FUNCS[blendFuncSeparate[2]];
                materialParams.blendDstAlpha = WEBGL_BLEND_FUNCS[blendFuncSeparate[3]];
              } else {
                materialParams.blendSrc = THREE.OneFactor;
                materialParams.blendDst = THREE.ZeroFactor;
                materialParams.blendSrcAlpha = THREE.OneFactor;
                materialParams.blendDstAlpha = THREE.ZeroFactor;
              }
            }
          }
        }
        if (Array.isArray(materialValues.diffuse)) {
          materialParams.color = new THREE.Color().fromArray(materialValues.diffuse);
        } else if (typeof materialValues.diffuse === 'string') {
          materialParams.map = dependencies.textures[materialValues.diffuse];
        }
        delete materialParams.diffuse;
        if (typeof materialValues.reflective === 'string') {
          materialParams.envMap = dependencies.textures[materialValues.reflective];
        }
        if (typeof materialValues.bump === 'string') {
          materialParams.bumpMap = dependencies.textures[materialValues.bump];
        }
        if (Array.isArray(materialValues.emission)) {
          if (materialType === THREE.MeshBasicMaterial) {
            materialParams.color = new THREE.Color().fromArray(materialValues.emission);
          } else {
            materialParams.emissive = new THREE.Color().fromArray(materialValues.emission);
          }
        } else if (typeof materialValues.emission === 'string') {
          if (materialType === THREE.MeshBasicMaterial) {
            materialParams.map = dependencies.textures[materialValues.emission];
          } else {
            materialParams.emissiveMap = dependencies.textures[materialValues.emission];
          }
        }
        if (Array.isArray(materialValues.specular)) {
          materialParams.specular = new THREE.Color().fromArray(materialValues.specular);
        } else if (typeof materialValues.specular === 'string') {
          materialParams.specularMap = dependencies.textures[materialValues.specular];
        }
        if (materialValues.shininess !== undefined) {
          materialParams.shininess = materialValues.shininess;
        }
        var _material = new materialType(materialParams);
        if (material.name !== undefined) _material.name = material.name;
        return _material;
      });
    });
  };
  GLTFParser.prototype.loadMeshes = function () {
    var json = this.json;
    return this._withDependencies(["accessors", "materials"]).then(function (dependencies) {
      return _each(json.meshes, function (mesh) {
        var group = new THREE.Group();
        if (mesh.name !== undefined) group.name = mesh.name;
        if (mesh.extras) group.userData = mesh.extras;
        var primitives = mesh.primitives || [];
        for (var name in primitives) {
          var primitive = primitives[name];
          if (primitive.mode === WEBGL_CONSTANTS.TRIANGLES || primitive.mode === undefined) {
            var geometry = new THREE.BufferGeometry();
            var attributes = primitive.attributes;
            for (var attributeId in attributes) {
              var attributeEntry = attributes[attributeId];
              if (!attributeEntry) return;
              var bufferAttribute = dependencies.accessors[attributeEntry];
              switch (attributeId) {
                case 'POSITION':
                  geometry.setAttribute('position', bufferAttribute);
                  break;
                case 'NORMAL':
                  geometry.setAttribute('normal', bufferAttribute);
                  break;
                case 'TEXCOORD_0':
                case 'TEXCOORD0':
                case 'TEXCOORD':
                  geometry.setAttribute('uv', bufferAttribute);
                  break;
                case 'TEXCOORD_1':
                  geometry.setAttribute('uv2', bufferAttribute);
                  break;
                case 'COLOR_0':
                case 'COLOR0':
                case 'COLOR':
                  geometry.setAttribute('color', bufferAttribute);
                  break;
                case 'WEIGHT':
                  geometry.setAttribute('skinWeight', bufferAttribute);
                  break;
                case 'JOINT':
                  geometry.setAttribute('skinIndex', bufferAttribute);
                  break;
                default:
                  if (!primitive.material) break;
                  var material = json.materials[primitive.material];
                  if (!material.technique) break;
                  var parameters = json.techniques[material.technique].parameters || {};
                  for (var attributeName in parameters) {
                    if (parameters[attributeName]['semantic'] === attributeId) {
                      geometry.setAttribute(attributeName, bufferAttribute);
                    }
                  }
              }
            }
            if (primitive.indices) {
              geometry.setIndex(dependencies.accessors[primitive.indices]);
            }
            var material = dependencies.materials !== undefined ? dependencies.materials[primitive.material] : createDefaultMaterial();
            var meshNode = new THREE.Mesh(geometry, material);
            meshNode.castShadow = true;
            meshNode.name = name === "0" ? group.name : group.name + name;
            if (primitive.extras) meshNode.userData = primitive.extras;
            group.add(meshNode);
          } else if (primitive.mode === WEBGL_CONSTANTS.LINES) {
            var geometry = new THREE.BufferGeometry();
            var attributes = primitive.attributes;
            for (var attributeId in attributes) {
              var attributeEntry = attributes[attributeId];
              if (!attributeEntry) return;
              var bufferAttribute = dependencies.accessors[attributeEntry];
              switch (attributeId) {
                case 'POSITION':
                  geometry.setAttribute('position', bufferAttribute);
                  break;
                case 'COLOR_0':
                case 'COLOR0':
                case 'COLOR':
                  geometry.setAttribute('color', bufferAttribute);
                  break;
              }
            }
            var material = dependencies.materials[primitive.material];
            var meshNode;
            if (primitive.indices) {
              geometry.setIndex(dependencies.accessors[primitive.indices]);
              meshNode = new THREE.LineSegments(geometry, material);
            } else {
              meshNode = new THREE.Line(geometry, material);
            }
            meshNode.name = name === "0" ? group.name : group.name + name;
            if (primitive.extras) meshNode.userData = primitive.extras;
            group.add(meshNode);
          } else {
            console.warn("Only triangular and line primitives are supported");
          }
        }
        return group;
      });
    });
  };
  GLTFParser.prototype.loadCameras = function () {
    var json = this.json;
    return _each(json.cameras, function (camera) {
      if (camera.type == "perspective" && camera.perspective) {
        var yfov = camera.perspective.yfov;
        var aspectRatio = camera.perspective.aspectRatio !== undefined ? camera.perspective.aspectRatio : 1;

        // According to COLLADA spec...
        // aspectRatio = xfov / yfov

        var _camera = new THREE.PerspectiveCamera(THREE.MathUtils.radToDeg(yfov * aspectRatio), aspectRatio, camera.perspective.znear || 1, camera.perspective.zfar || 2e6);
        if (camera.name !== undefined) _camera.name = camera.name;
        if (camera.extras) _camera.userData = camera.extras;
        return _camera;
      } else if (camera.type == "orthographic" && camera.orthographic) {
        var _camera = new THREE.OrthographicCamera(window.innerWidth / -2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / -2, camera.orthographic.znear, camera.orthographic.zfar);
        if (camera.name !== undefined) _camera.name = camera.name;
        if (camera.extras) _camera.userData = camera.extras;
        return _camera;
      }
    });
  };
  GLTFParser.prototype.loadSkins = function () {
    var json = this.json;
    return this._withDependencies(["accessors"]).then(function (dependencies) {
      return _each(json.skins, function (skin) {
        var bindShapeMatrix = new THREE.Matrix4();
        if (skin.bindShapeMatrix !== undefined) bindShapeMatrix.fromArray(skin.bindShapeMatrix);
        var _skin = {
          bindShapeMatrix: bindShapeMatrix,
          jointNames: skin.jointNames,
          inverseBindMatrices: dependencies.accessors[skin.inverseBindMatrices]
        };
        return _skin;
      });
    });
  };
  GLTFParser.prototype.loadAnimations = function () {
    var json = this.json;
    return this._withDependencies(["accessors", "nodes"]).then(function (dependencies) {
      return _each(json.animations, function (animation, animationId) {
        var tracks = [];
        for (var channelId in animation.channels) {
          var channel = animation.channels[channelId];
          var sampler = animation.samplers[channel.sampler];
          if (sampler) {
            var target = channel.target;
            var name = target.id;
            var input = animation.parameters !== undefined ? animation.parameters[sampler.input] : sampler.input;
            var output = animation.parameters !== undefined ? animation.parameters[sampler.output] : sampler.output;
            var inputAccessor = dependencies.accessors[input];
            var outputAccessor = dependencies.accessors[output];
            var node = dependencies.nodes[name];
            if (node) {
              node.updateMatrix();
              node.matrixAutoUpdate = true;
              var TypedKeyframeTrack = PATH_PROPERTIES[target.path] === PATH_PROPERTIES.rotation ? THREE.QuaternionKeyframeTrack : THREE.VectorKeyframeTrack;
              var targetName = node.name ? node.name : node.uuid;
              var interpolation = sampler.interpolation !== undefined ? INTERPOLATION[sampler.interpolation] : THREE.InterpolateLinear;

              // KeyframeTrack.optimize() will modify given 'times' and 'values'
              // buffers before creating a truncated copy to keep. Because buffers may
              // be reused by other tracks, make copies here.
              tracks.push(new TypedKeyframeTrack(targetName + '.' + PATH_PROPERTIES[target.path], inputAccessor.array.slice(), outputAccessor.array.slice(), interpolation));
            }
          }
        }
        var name = animation.name !== undefined ? animation.name : "animation_" + animationId;
        return new THREE.AnimationClip(name, undefined, tracks);
      });
    });
  };
  GLTFParser.prototype.loadNodes = function () {
    var json = this.json;
    var extensions = this.extensions;
    var scope = this;
    return _each(json.nodes, function (node) {
      var matrix = new THREE.Matrix4();
      var _node;
      if (node.jointName) {
        _node = new THREE.Bone();
        _node.name = node.name !== undefined ? node.name : node.jointName;
        _node.jointName = node.jointName;
      } else {
        _node = new THREE.Object3D();
        if (node.name !== undefined) _node.name = node.name;
      }
      if (node.extras) _node.userData = node.extras;
      if (node.matrix !== undefined) {
        matrix.fromArray(node.matrix);
        _node.applyMatrix4(matrix);
      } else {
        if (node.translation !== undefined) {
          _node.position.fromArray(node.translation);
        }
        if (node.rotation !== undefined) {
          _node.quaternion.fromArray(node.rotation);
        }
        if (node.scale !== undefined) {
          _node.scale.fromArray(node.scale);
        }
      }
      return _node;
    }).then(function (__nodes) {
      return scope._withDependencies(["meshes", "skins", "cameras"]).then(function (dependencies) {
        return _each(__nodes, function (_node, nodeId) {
          var node = json.nodes[nodeId];
          if (node.meshes !== undefined) {
            for (var meshId in node.meshes) {
              var mesh = node.meshes[meshId];
              var group = dependencies.meshes[mesh];
              if (group === undefined) {
                console.warn('LegacyGLTFLoader: Couldn\'t find node "' + mesh + '".');
                continue;
              }
              for (var childrenId in group.children) {
                var child = group.children[childrenId];

                // clone Mesh to add to _node

                var originalMaterial = child.material;
                var originalGeometry = child.geometry;
                var originalUserData = child.userData;
                var originalName = child.name;
                var material;
                if (originalMaterial.isDeferredShaderMaterial) {
                  originalMaterial = material = originalMaterial.create();
                } else {
                  material = originalMaterial;
                }
                switch (child.type) {
                  case 'LineSegments':
                    child = new THREE.LineSegments(originalGeometry, material);
                    break;
                  case 'LineLoop':
                    child = new THREE.LineLoop(originalGeometry, material);
                    break;
                  case 'Line':
                    child = new THREE.Line(originalGeometry, material);
                    break;
                  default:
                    child = new THREE.Mesh(originalGeometry, material);
                }
                child.castShadow = true;
                child.userData = originalUserData;
                child.name = originalName;
                var skinEntry;
                if (node.skin) {
                  skinEntry = dependencies.skins[node.skin];
                }

                // Replace Mesh with SkinnedMesh in library
                if (skinEntry) {
                  var getJointNode = function (jointId) {
                    var keys = Object.keys(__nodes);
                    for (var i = 0, il = keys.length; i < il; i++) {
                      var n = __nodes[keys[i]];
                      if (n.jointName === jointId) return n;
                    }
                    return null;
                  };
                  var geometry = originalGeometry;
                  var material = originalMaterial;
                  material.skinning = true;
                  child = new THREE.SkinnedMesh(geometry, material);
                  child.castShadow = true;
                  child.userData = originalUserData;
                  child.name = originalName;
                  var bones = [];
                  var boneInverses = [];
                  for (var i = 0, l = skinEntry.jointNames.length; i < l; i++) {
                    var jointId = skinEntry.jointNames[i];
                    var jointNode = getJointNode(jointId);
                    if (jointNode) {
                      bones.push(jointNode);
                      var m = skinEntry.inverseBindMatrices.array;
                      var mat = new THREE.Matrix4().fromArray(m, i * 16);
                      boneInverses.push(mat);
                    } else {
                      console.warn("WARNING: joint: '" + jointId + "' could not be found");
                    }
                  }
                  child.bind(new THREE.Skeleton(bones, boneInverses), skinEntry.bindShapeMatrix);
                  var buildBoneGraph = function (parentJson, parentObject, property) {
                    var children = parentJson[property];
                    if (children === undefined) return;
                    for (var i = 0, il = children.length; i < il; i++) {
                      var nodeId = children[i];
                      var bone = __nodes[nodeId];
                      var boneJson = json.nodes[nodeId];
                      if (bone !== undefined && bone.isBone === true && boneJson !== undefined) {
                        parentObject.add(bone);
                        buildBoneGraph(boneJson, bone, 'children');
                      }
                    }
                  };
                  buildBoneGraph(node, child, 'skeletons');
                }
                _node.add(child);
              }
            }
          }
          if (node.camera !== undefined) {
            var camera = dependencies.cameras[node.camera];
            _node.add(camera);
          }
          if (node.extensions && node.extensions[EXTENSIONS.KHR_MATERIALS_COMMON] && node.extensions[EXTENSIONS.KHR_MATERIALS_COMMON].light) {
            var extensionLights = extensions[EXTENSIONS.KHR_MATERIALS_COMMON].lights;
            var light = extensionLights[node.extensions[EXTENSIONS.KHR_MATERIALS_COMMON].light];
            _node.add(light);
          }
          return _node;
        });
      });
    });
  };
  GLTFParser.prototype.loadScenes = function () {
    var json = this.json;

    // scene node hierachy builder

    function buildNodeHierachy(nodeId, parentObject, allNodes) {
      var _node = allNodes[nodeId];
      parentObject.add(_node);
      var node = json.nodes[nodeId];
      if (node.children) {
        var children = node.children;
        for (var i = 0, l = children.length; i < l; i++) {
          var child = children[i];
          buildNodeHierachy(child, _node, allNodes);
        }
      }
    }
    return this._withDependencies(["nodes"]).then(function (dependencies) {
      return _each(json.scenes, function (scene) {
        var _scene = new THREE.Scene();
        if (scene.name !== undefined) _scene.name = scene.name;
        if (scene.extras) _scene.userData = scene.extras;
        var nodes = scene.nodes || [];
        for (var i = 0, l = nodes.length; i < l; i++) {
          var nodeId = nodes[i];
          buildNodeHierachy(nodeId, _scene, dependencies.nodes);
        }
        _scene.traverse(function (child) {
          // Register raw material meshes with LegacyGLTFLoader.Shaders
          if (child.material && child.material.isRawShaderMaterial) {
            child.gltfShader = new GLTFShader(child, dependencies.nodes);
            child.onBeforeRender = function (renderer, scene, camera) {
              this.gltfShader.update(scene, camera);
            };
          }
        });
        return _scene;
      });
    });
  };
  return LegacyGLTFLoader;
}();
export default threeExamples.LegacyGLTFLoader;