{"version":3,"sources":["jsdelivr-header.js","/npm/three@0.182.0/examples/jsm/utils/BufferGeometryUtils.js","/npm/three@0.182.0/examples/jsm/loaders/GLTFLoader.js"],"names":[],"mappings":"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","file":"/npm/three@0.182.0/examples/jsm/loaders/GLTFLoader.js/+esm","sourceRoot":"","sourcesContent":["/**\n * Bundled by jsDelivr using Rollup v2.79.2 and Terser v5.39.0.\n * Original file: /npm/three@0.182.0/examples/jsm/loaders/GLTFLoader.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","import {\n\tBufferAttribute,\n\tBufferGeometry,\n\tFloat32BufferAttribute,\n\tInstancedBufferAttribute,\n\tInterleavedBuffer,\n\tInterleavedBufferAttribute,\n\tTriangleFanDrawMode,\n\tTriangleStripDrawMode,\n\tTrianglesDrawMode,\n\tVector3,\n} from 'three';\n\n/**\n * @module BufferGeometryUtils\n * @three_import import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js';\n */\n\n/**\n * Computes vertex tangents using the MikkTSpace algorithm. MikkTSpace generates the same tangents consistently,\n * and is used in most modelling tools and normal map bakers. Use MikkTSpace for materials with normal maps,\n * because inconsistent tangents may lead to subtle visual issues in the normal map, particularly around mirrored\n * UV seams.\n *\n * In comparison to this method, {@link BufferGeometry#computeTangents} (a custom algorithm) generates tangents that\n * probably will not match the tangents in other software. The custom algorithm is sufficient for general use with a\n * custom material, and may be faster than MikkTSpace.\n *\n * Returns the original BufferGeometry. Indexed geometries will be de-indexed. Requires position, normal, and uv attributes.\n *\n * @param {BufferGeometry} geometry - The geometry to compute tangents for.\n * @param {Object} MikkTSpace - Instance of `examples/jsm/libs/mikktspace.module.js`, or `mikktspace` npm package.\n * Await `MikkTSpace.ready` before use.\n * @param {boolean} [negateSign=true] - Whether to negate the sign component (.w) of each tangent.\n * Required for normal map conventions in some formats, including glTF.\n * @return {BufferGeometry} The updated geometry.\n */\nfunction computeMikkTSpaceTangents( geometry, MikkTSpace, negateSign = true ) {\n\n\tif ( ! MikkTSpace || ! MikkTSpace.isReady ) {\n\n\t\tthrow new Error( 'BufferGeometryUtils: Initialized MikkTSpace library required.' );\n\n\t}\n\n\tif ( ! geometry.hasAttribute( 'position' ) || ! geometry.hasAttribute( 'normal' ) || ! geometry.hasAttribute( 'uv' ) ) {\n\n\t\tthrow new Error( 'BufferGeometryUtils: Tangents require \"position\", \"normal\", and \"uv\" attributes.' );\n\n\t}\n\n\tfunction getAttributeArray( attribute ) {\n\n\t\tif ( attribute.normalized || attribute.isInterleavedBufferAttribute ) {\n\n\t\t\tconst dstArray = new Float32Array( attribute.count * attribute.itemSize );\n\n\t\t\tfor ( let i = 0, j = 0; i < attribute.count; i ++ ) {\n\n\t\t\t\tdstArray[ j ++ ] = attribute.getX( i );\n\t\t\t\tdstArray[ j ++ ] = attribute.getY( i );\n\n\t\t\t\tif ( attribute.itemSize > 2 ) {\n\n\t\t\t\t\tdstArray[ j ++ ] = attribute.getZ( i );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn dstArray;\n\n\t\t}\n\n\t\tif ( attribute.array instanceof Float32Array ) {\n\n\t\t\treturn attribute.array;\n\n\t\t}\n\n\t\treturn new Float32Array( attribute.array );\n\n\t}\n\n\t// MikkTSpace algorithm requires non-indexed input.\n\n\tconst _geometry = geometry.index ? geometry.toNonIndexed() : geometry;\n\n\t// Compute vertex tangents.\n\n\tconst tangents = MikkTSpace.generateTangents(\n\n\t\tgetAttributeArray( _geometry.attributes.position ),\n\t\tgetAttributeArray( _geometry.attributes.normal ),\n\t\tgetAttributeArray( _geometry.attributes.uv )\n\n\t);\n\n\t// Texture coordinate convention of glTF differs from the apparent\n\t// default of the MikkTSpace library; .w component must be flipped.\n\n\tif ( negateSign ) {\n\n\t\tfor ( let i = 3; i < tangents.length; i += 4 ) {\n\n\t\t\ttangents[ i ] *= - 1;\n\n\t\t}\n\n\t}\n\n\t//\n\n\t_geometry.setAttribute( 'tangent', new BufferAttribute( tangents, 4 ) );\n\n\tif ( geometry !== _geometry ) {\n\n\t\tgeometry.copy( _geometry );\n\n\t}\n\n\treturn geometry;\n\n}\n\n/**\n * Merges a set of geometries into a single instance. All geometries must have compatible attributes.\n *\n * @param {Array<BufferGeometry>} geometries - The geometries to merge.\n * @param {boolean} [useGroups=false] - Whether to use groups or not.\n * @return {?BufferGeometry} The merged geometry. Returns `null` if the merge does not succeed.\n */\nfunction mergeGeometries( geometries, useGroups = false ) {\n\n\tconst isIndexed = geometries[ 0 ].index !== null;\n\n\tconst attributesUsed = new Set( Object.keys( geometries[ 0 ].attributes ) );\n\tconst morphAttributesUsed = new Set( Object.keys( geometries[ 0 ].morphAttributes ) );\n\n\tconst attributes = {};\n\tconst morphAttributes = {};\n\n\tconst morphTargetsRelative = geometries[ 0 ].morphTargetsRelative;\n\n\tconst mergedGeometry = new BufferGeometry();\n\n\tlet offset = 0;\n\n\tfor ( let i = 0; i < geometries.length; ++ i ) {\n\n\t\tconst geometry = geometries[ i ];\n\t\tlet attributesCount = 0;\n\n\t\t// ensure that all geometries are indexed, or none\n\n\t\tif ( isIndexed !== ( geometry.index !== null ) ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\t// gather attributes, exit early if they're different\n\n\t\tfor ( const name in geometry.attributes ) {\n\n\t\t\tif ( ! attributesUsed.has( name ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. All geometries must have compatible attributes; make sure \"' + name + '\" attribute exists among all geometries, or in none of them.' );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tif ( attributes[ name ] === undefined ) attributes[ name ] = [];\n\n\t\t\tattributes[ name ].push( geometry.attributes[ name ] );\n\n\t\t\tattributesCount ++;\n\n\t\t}\n\n\t\t// ensure geometries have the same number of attributes\n\n\t\tif ( attributesCount !== attributesUsed.size ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. Make sure all geometries have the same number of attributes.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\t// gather morph attributes, exit early if they're different\n\n\t\tif ( morphTargetsRelative !== geometry.morphTargetsRelative ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. .morphTargetsRelative must be consistent throughout all geometries.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tfor ( const name in geometry.morphAttributes ) {\n\n\t\t\tif ( ! morphAttributesUsed.has( name ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '.  .morphAttributes must be consistent throughout all geometries.' );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tif ( morphAttributes[ name ] === undefined ) morphAttributes[ name ] = [];\n\n\t\t\tmorphAttributes[ name ].push( geometry.morphAttributes[ name ] );\n\n\t\t}\n\n\t\tif ( useGroups ) {\n\n\t\t\tlet count;\n\n\t\t\tif ( isIndexed ) {\n\n\t\t\t\tcount = geometry.index.count;\n\n\t\t\t} else if ( geometry.attributes.position !== undefined ) {\n\n\t\t\t\tcount = geometry.attributes.position.count;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. The geometry must have either an index or a position attribute' );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tmergedGeometry.addGroup( offset, count, i );\n\n\t\t\toffset += count;\n\n\t\t}\n\n\t}\n\n\t// merge indices\n\n\tif ( isIndexed ) {\n\n\t\tlet indexOffset = 0;\n\t\tconst mergedIndex = [];\n\n\t\tfor ( let i = 0; i < geometries.length; ++ i ) {\n\n\t\t\tconst index = geometries[ i ].index;\n\n\t\t\tfor ( let j = 0; j < index.count; ++ j ) {\n\n\t\t\t\tmergedIndex.push( index.getX( j ) + indexOffset );\n\n\t\t\t}\n\n\t\t\tindexOffset += geometries[ i ].attributes.position.count;\n\n\t\t}\n\n\t\tmergedGeometry.setIndex( mergedIndex );\n\n\t}\n\n\t// merge attributes\n\n\tfor ( const name in attributes ) {\n\n\t\tconst mergedAttribute = mergeAttributes( attributes[ name ] );\n\n\t\tif ( ! mergedAttribute ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the ' + name + ' attribute.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tmergedGeometry.setAttribute( name, mergedAttribute );\n\n\t}\n\n\t// merge morph attributes\n\n\tfor ( const name in morphAttributes ) {\n\n\t\tconst numMorphTargets = morphAttributes[ name ][ 0 ].length;\n\n\t\tif ( numMorphTargets === 0 ) break;\n\n\t\tmergedGeometry.morphAttributes = mergedGeometry.morphAttributes || {};\n\t\tmergedGeometry.morphAttributes[ name ] = [];\n\n\t\tfor ( let i = 0; i < numMorphTargets; ++ i ) {\n\n\t\t\tconst morphAttributesToMerge = [];\n\n\t\t\tfor ( let j = 0; j < morphAttributes[ name ].length; ++ j ) {\n\n\t\t\t\tmorphAttributesToMerge.push( morphAttributes[ name ][ j ][ i ] );\n\n\t\t\t}\n\n\t\t\tconst mergedMorphAttribute = mergeAttributes( morphAttributesToMerge );\n\n\t\t\tif ( ! mergedMorphAttribute ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the ' + name + ' morphAttribute.' );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tmergedGeometry.morphAttributes[ name ].push( mergedMorphAttribute );\n\n\t\t}\n\n\t}\n\n\treturn mergedGeometry;\n\n}\n\n/**\n * Merges a set of attributes into a single instance. All attributes must have compatible properties and types.\n * Instances of {@link InterleavedBufferAttribute} are not supported.\n *\n * @param {Array<BufferAttribute>} attributes - The attributes to merge.\n * @return {?BufferAttribute} The merged attribute. Returns `null` if the merge does not succeed.\n */\nfunction mergeAttributes( attributes ) {\n\n\tlet TypedArray;\n\tlet itemSize;\n\tlet normalized;\n\tlet gpuType = - 1;\n\tlet arrayLength = 0;\n\n\tfor ( let i = 0; i < attributes.length; ++ i ) {\n\n\t\tconst attribute = attributes[ i ];\n\n\t\tif ( TypedArray === undefined ) TypedArray = attribute.array.constructor;\n\t\tif ( TypedArray !== attribute.array.constructor ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.array must be of consistent array types across matching attributes.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tif ( itemSize === undefined ) itemSize = attribute.itemSize;\n\t\tif ( itemSize !== attribute.itemSize ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.itemSize must be consistent across matching attributes.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tif ( normalized === undefined ) normalized = attribute.normalized;\n\t\tif ( normalized !== attribute.normalized ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.normalized must be consistent across matching attributes.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tif ( gpuType === - 1 ) gpuType = attribute.gpuType;\n\t\tif ( gpuType !== attribute.gpuType ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.gpuType must be consistent across matching attributes.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tarrayLength += attribute.count * itemSize;\n\n\t}\n\n\tconst array = new TypedArray( arrayLength );\n\tconst result = new BufferAttribute( array, itemSize, normalized );\n\tlet offset = 0;\n\n\tfor ( let i = 0; i < attributes.length; ++ i ) {\n\n\t\tconst attribute = attributes[ i ];\n\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\tconst tupleOffset = offset / itemSize;\n\t\t\tfor ( let j = 0, l = attribute.count; j < l; j ++ ) {\n\n\t\t\t\tfor ( let c = 0; c < itemSize; c ++ ) {\n\n\t\t\t\t\tconst value = attribute.getComponent( j, c );\n\t\t\t\t\tresult.setComponent( j + tupleOffset, c, value );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tarray.set( attribute.array, offset );\n\n\t\t}\n\n\t\toffset += attribute.count * itemSize;\n\n\t}\n\n\tif ( gpuType !== undefined ) {\n\n\t\tresult.gpuType = gpuType;\n\n\t}\n\n\treturn result;\n\n}\n\n/**\n * Performs a deep clone of the given buffer attribute.\n *\n * @param {BufferAttribute} attribute - The attribute to clone.\n * @return {BufferAttribute} The cloned attribute.\n */\nfunction deepCloneAttribute( attribute ) {\n\n\tif ( attribute.isInstancedInterleavedBufferAttribute || attribute.isInterleavedBufferAttribute ) {\n\n\t\treturn deinterleaveAttribute( attribute );\n\n\t}\n\n\tif ( attribute.isInstancedBufferAttribute ) {\n\n\t\treturn new InstancedBufferAttribute().copy( attribute );\n\n\t}\n\n\treturn new BufferAttribute().copy( attribute );\n\n}\n\n/**\n * Interleaves a set of attributes and returns a new array of corresponding attributes that share a\n * single {@link InterleavedBuffer} instance. All attributes must have compatible types.\n *\n * @param {Array<BufferAttribute>} attributes - The attributes to interleave.\n * @return {?Array<InterleavedBufferAttribute>} An array of interleaved attributes. If interleave does not succeed, the method returns `null`.\n */\nfunction interleaveAttributes( attributes ) {\n\n\t// Interleaves the provided attributes into an InterleavedBuffer and returns\n\t// a set of InterleavedBufferAttributes for each attribute\n\tlet TypedArray;\n\tlet arrayLength = 0;\n\tlet stride = 0;\n\n\t// calculate the length and type of the interleavedBuffer\n\tfor ( let i = 0, l = attributes.length; i < l; ++ i ) {\n\n\t\tconst attribute = attributes[ i ];\n\n\t\tif ( TypedArray === undefined ) TypedArray = attribute.array.constructor;\n\t\tif ( TypedArray !== attribute.array.constructor ) {\n\n\t\t\tconsole.error( 'AttributeBuffers of different types cannot be interleaved' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tarrayLength += attribute.array.length;\n\t\tstride += attribute.itemSize;\n\n\t}\n\n\t// Create the set of buffer attributes\n\tconst interleavedBuffer = new InterleavedBuffer( new TypedArray( arrayLength ), stride );\n\tlet offset = 0;\n\tconst res = [];\n\tconst getters = [ 'getX', 'getY', 'getZ', 'getW' ];\n\tconst setters = [ 'setX', 'setY', 'setZ', 'setW' ];\n\n\tfor ( let j = 0, l = attributes.length; j < l; j ++ ) {\n\n\t\tconst attribute = attributes[ j ];\n\t\tconst itemSize = attribute.itemSize;\n\t\tconst count = attribute.count;\n\t\tconst iba = new InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, attribute.normalized );\n\t\tres.push( iba );\n\n\t\toffset += itemSize;\n\n\t\t// Move the data for each attribute into the new interleavedBuffer\n\t\t// at the appropriate offset\n\t\tfor ( let c = 0; c < count; c ++ ) {\n\n\t\t\tfor ( let k = 0; k < itemSize; k ++ ) {\n\n\t\t\t\tiba[ setters[ k ] ]( c, attribute[ getters[ k ] ]( c ) );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\treturn res;\n\n}\n\n/**\n * Returns a new, non-interleaved version of the given attribute.\n *\n * @param {InterleavedBufferAttribute} attribute - The interleaved attribute.\n * @return {BufferAttribute} The non-interleaved attribute.\n */\nfunction deinterleaveAttribute( attribute ) {\n\n\tconst cons = attribute.data.array.constructor;\n\tconst count = attribute.count;\n\tconst itemSize = attribute.itemSize;\n\tconst normalized = attribute.normalized;\n\n\tconst array = new cons( count * itemSize );\n\tlet newAttribute;\n\tif ( attribute.isInstancedInterleavedBufferAttribute ) {\n\n\t\tnewAttribute = new InstancedBufferAttribute( array, itemSize, normalized, attribute.meshPerAttribute );\n\n\t} else {\n\n\t\tnewAttribute = new BufferAttribute( array, itemSize, normalized );\n\n\t}\n\n\tfor ( let i = 0; i < count; i ++ ) {\n\n\t\tnewAttribute.setX( i, attribute.getX( i ) );\n\n\t\tif ( itemSize >= 2 ) {\n\n\t\t\tnewAttribute.setY( i, attribute.getY( i ) );\n\n\t\t}\n\n\t\tif ( itemSize >= 3 ) {\n\n\t\t\tnewAttribute.setZ( i, attribute.getZ( i ) );\n\n\t\t}\n\n\t\tif ( itemSize >= 4 ) {\n\n\t\t\tnewAttribute.setW( i, attribute.getW( i ) );\n\n\t\t}\n\n\t}\n\n\treturn newAttribute;\n\n}\n\n/**\n * Deinterleaves all attributes on the given geometry.\n *\n * @param {BufferGeometry} geometry - The geometry to deinterleave.\n */\nfunction deinterleaveGeometry( geometry ) {\n\n\tconst attributes = geometry.attributes;\n\tconst morphTargets = geometry.morphTargets;\n\tconst attrMap = new Map();\n\n\tfor ( const key in attributes ) {\n\n\t\tconst attr = attributes[ key ];\n\t\tif ( attr.isInterleavedBufferAttribute ) {\n\n\t\t\tif ( ! attrMap.has( attr ) ) {\n\n\t\t\t\tattrMap.set( attr, deinterleaveAttribute( attr ) );\n\n\t\t\t}\n\n\t\t\tattributes[ key ] = attrMap.get( attr );\n\n\t\t}\n\n\t}\n\n\tfor ( const key in morphTargets ) {\n\n\t\tconst attr = morphTargets[ key ];\n\t\tif ( attr.isInterleavedBufferAttribute ) {\n\n\t\t\tif ( ! attrMap.has( attr ) ) {\n\n\t\t\t\tattrMap.set( attr, deinterleaveAttribute( attr ) );\n\n\t\t\t}\n\n\t\t\tmorphTargets[ key ] = attrMap.get( attr );\n\n\t\t}\n\n\t}\n\n}\n\n/**\n * Returns the amount of bytes used by all attributes to represent the geometry.\n *\n * @param {BufferGeometry} geometry - The geometry.\n * @return {number} The estimate bytes used.\n */\nfunction estimateBytesUsed( geometry ) {\n\n\t// Return the estimated memory used by this geometry in bytes\n\t// Calculate using itemSize, count, and BYTES_PER_ELEMENT to account\n\t// for InterleavedBufferAttributes.\n\tlet mem = 0;\n\tfor ( const name in geometry.attributes ) {\n\n\t\tconst attr = geometry.getAttribute( name );\n\t\tmem += attr.count * attr.itemSize * attr.array.BYTES_PER_ELEMENT;\n\n\t}\n\n\tconst indices = geometry.getIndex();\n\tmem += indices ? indices.count * indices.itemSize * indices.array.BYTES_PER_ELEMENT : 0;\n\treturn mem;\n\n}\n\n/**\n * Returns a new geometry with vertices for which all similar vertex attributes (within tolerance) are merged.\n *\n * @param {BufferGeometry} geometry - The geometry to merge vertices for.\n * @param {number} [tolerance=1e-4] - The tolerance value.\n * @return {BufferGeometry} - The new geometry with merged vertices.\n */\nfunction mergeVertices( geometry, tolerance = 1e-4 ) {\n\n\ttolerance = Math.max( tolerance, Number.EPSILON );\n\n\t// Generate an index buffer if the geometry doesn't have one, or optimize it\n\t// if it's already available.\n\tconst hashToIndex = {};\n\tconst indices = geometry.getIndex();\n\tconst positions = geometry.getAttribute( 'position' );\n\tconst vertexCount = indices ? indices.count : positions.count;\n\n\t// next value for triangle indices\n\tlet nextIndex = 0;\n\n\t// attributes and new attribute arrays\n\tconst attributeNames = Object.keys( geometry.attributes );\n\tconst tmpAttributes = {};\n\tconst tmpMorphAttributes = {};\n\tconst newIndices = [];\n\tconst getters = [ 'getX', 'getY', 'getZ', 'getW' ];\n\tconst setters = [ 'setX', 'setY', 'setZ', 'setW' ];\n\n\t// Initialize the arrays, allocating space conservatively. Extra\n\t// space will be trimmed in the last step.\n\tfor ( let i = 0, l = attributeNames.length; i < l; i ++ ) {\n\n\t\tconst name = attributeNames[ i ];\n\t\tconst attr = geometry.attributes[ name ];\n\n\t\ttmpAttributes[ name ] = new attr.constructor(\n\t\t\tnew attr.array.constructor( attr.count * attr.itemSize ),\n\t\t\tattr.itemSize,\n\t\t\tattr.normalized\n\t\t);\n\n\t\tconst morphAttributes = geometry.morphAttributes[ name ];\n\t\tif ( morphAttributes ) {\n\n\t\t\tif ( ! tmpMorphAttributes[ name ] ) tmpMorphAttributes[ name ] = [];\n\t\t\tmorphAttributes.forEach( ( morphAttr, i ) => {\n\n\t\t\t\tconst array = new morphAttr.array.constructor( morphAttr.count * morphAttr.itemSize );\n\t\t\t\ttmpMorphAttributes[ name ][ i ] = new morphAttr.constructor( array, morphAttr.itemSize, morphAttr.normalized );\n\n\t\t\t} );\n\n\t\t}\n\n\t}\n\n\t// convert the error tolerance to an amount of decimal places to truncate to\n\tconst halfTolerance = tolerance * 0.5;\n\tconst exponent = Math.log10( 1 / tolerance );\n\tconst hashMultiplier = Math.pow( 10, exponent );\n\tconst hashAdditive = halfTolerance * hashMultiplier;\n\tfor ( let i = 0; i < vertexCount; i ++ ) {\n\n\t\tconst index = indices ? indices.getX( i ) : i;\n\n\t\t// Generate a hash for the vertex attributes at the current index 'i'\n\t\tlet hash = '';\n\t\tfor ( let j = 0, l = attributeNames.length; j < l; j ++ ) {\n\n\t\t\tconst name = attributeNames[ j ];\n\t\t\tconst attribute = geometry.getAttribute( name );\n\t\t\tconst itemSize = attribute.itemSize;\n\n\t\t\tfor ( let k = 0; k < itemSize; k ++ ) {\n\n\t\t\t\t// double tilde truncates the decimal value\n\t\t\t\thash += `${ ~ ~ ( attribute[ getters[ k ] ]( index ) * hashMultiplier + hashAdditive ) },`;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Add another reference to the vertex if it's already\n\t\t// used by another index\n\t\tif ( hash in hashToIndex ) {\n\n\t\t\tnewIndices.push( hashToIndex[ hash ] );\n\n\t\t} else {\n\n\t\t\t// copy data to the new index in the temporary attributes\n\t\t\tfor ( let j = 0, l = attributeNames.length; j < l; j ++ ) {\n\n\t\t\t\tconst name = attributeNames[ j ];\n\t\t\t\tconst attribute = geometry.getAttribute( name );\n\t\t\t\tconst morphAttributes = geometry.morphAttributes[ name ];\n\t\t\t\tconst itemSize = attribute.itemSize;\n\t\t\t\tconst newArray = tmpAttributes[ name ];\n\t\t\t\tconst newMorphArrays = tmpMorphAttributes[ name ];\n\n\t\t\t\tfor ( let k = 0; k < itemSize; k ++ ) {\n\n\t\t\t\t\tconst getterFunc = getters[ k ];\n\t\t\t\t\tconst setterFunc = setters[ k ];\n\t\t\t\t\tnewArray[ setterFunc ]( nextIndex, attribute[ getterFunc ]( index ) );\n\n\t\t\t\t\tif ( morphAttributes ) {\n\n\t\t\t\t\t\tfor ( let m = 0, ml = morphAttributes.length; m < ml; m ++ ) {\n\n\t\t\t\t\t\t\tnewMorphArrays[ m ][ setterFunc ]( nextIndex, morphAttributes[ m ][ getterFunc ]( index ) );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\thashToIndex[ hash ] = nextIndex;\n\t\t\tnewIndices.push( nextIndex );\n\t\t\tnextIndex ++;\n\n\t\t}\n\n\t}\n\n\t// generate result BufferGeometry\n\tconst result = geometry.clone();\n\tfor ( const name in geometry.attributes ) {\n\n\t\tconst tmpAttribute = tmpAttributes[ name ];\n\n\t\tresult.setAttribute( name, new tmpAttribute.constructor(\n\t\t\ttmpAttribute.array.slice( 0, nextIndex * tmpAttribute.itemSize ),\n\t\t\ttmpAttribute.itemSize,\n\t\t\ttmpAttribute.normalized,\n\t\t) );\n\n\t\tif ( ! ( name in tmpMorphAttributes ) ) continue;\n\n\t\tfor ( let j = 0; j < tmpMorphAttributes[ name ].length; j ++ ) {\n\n\t\t\tconst tmpMorphAttribute = tmpMorphAttributes[ name ][ j ];\n\n\t\t\tresult.morphAttributes[ name ][ j ] = new tmpMorphAttribute.constructor(\n\t\t\t\ttmpMorphAttribute.array.slice( 0, nextIndex * tmpMorphAttribute.itemSize ),\n\t\t\t\ttmpMorphAttribute.itemSize,\n\t\t\t\ttmpMorphAttribute.normalized,\n\t\t\t);\n\n\t\t}\n\n\t}\n\n\t// indices\n\n\tresult.setIndex( newIndices );\n\n\treturn result;\n\n}\n\n/**\n * Returns a new indexed geometry based on `TrianglesDrawMode` draw mode.\n * This mode corresponds to the `gl.TRIANGLES` primitive in WebGL.\n *\n * @param {BufferGeometry} geometry - The geometry to convert.\n * @param {number} drawMode - The current draw mode.\n * @return {BufferGeometry} The new geometry using `TrianglesDrawMode`.\n */\nfunction toTrianglesDrawMode( geometry, drawMode ) {\n\n\tif ( drawMode === TrianglesDrawMode ) {\n\n\t\tconsole.warn( 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles.' );\n\t\treturn geometry;\n\n\t}\n\n\tif ( drawMode === TriangleFanDrawMode || drawMode === TriangleStripDrawMode ) {\n\n\t\tlet index = geometry.getIndex();\n\n\t\t// generate index if not present\n\n\t\tif ( index === null ) {\n\n\t\t\tconst indices = [];\n\n\t\t\tconst position = geometry.getAttribute( 'position' );\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tfor ( let i = 0; i < position.count; i ++ ) {\n\n\t\t\t\t\tindices.push( i );\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.setIndex( indices );\n\t\t\t\tindex = geometry.getIndex();\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Undefined position attribute. Processing not possible.' );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tconst numberOfTriangles = index.count - 2;\n\t\tconst newIndices = [];\n\n\t\tif ( drawMode === TriangleFanDrawMode ) {\n\n\t\t\t// gl.TRIANGLE_FAN\n\n\t\t\tfor ( let i = 1; i <= numberOfTriangles; i ++ ) {\n\n\t\t\t\tnewIndices.push( index.getX( 0 ) );\n\t\t\t\tnewIndices.push( index.getX( i ) );\n\t\t\t\tnewIndices.push( index.getX( i + 1 ) );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// gl.TRIANGLE_STRIP\n\n\t\t\tfor ( let i = 0; i < numberOfTriangles; i ++ ) {\n\n\t\t\t\tif ( i % 2 === 0 ) {\n\n\t\t\t\t\tnewIndices.push( index.getX( i ) );\n\t\t\t\t\tnewIndices.push( index.getX( i + 1 ) );\n\t\t\t\t\tnewIndices.push( index.getX( i + 2 ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tnewIndices.push( index.getX( i + 2 ) );\n\t\t\t\t\tnewIndices.push( index.getX( i + 1 ) );\n\t\t\t\t\tnewIndices.push( index.getX( i ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( ( newIndices.length / 3 ) !== numberOfTriangles ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles.' );\n\n\t\t}\n\n\t\t// build final geometry\n\n\t\tconst newGeometry = geometry.clone();\n\t\tnewGeometry.setIndex( newIndices );\n\t\tnewGeometry.clearGroups();\n\n\t\treturn newGeometry;\n\n\t} else {\n\n\t\tconsole.error( 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unknown draw mode:', drawMode );\n\t\treturn geometry;\n\n\t}\n\n}\n\n/**\n * Calculates the morphed attributes of a morphed/skinned BufferGeometry.\n *\n * Helpful for Raytracing or Decals (i.e. a `DecalGeometry` applied to a morphed Object with a `BufferGeometry`\n * will use the original `BufferGeometry`, not the morphed/skinned one, generating an incorrect result.\n * Using this function to create a shadow `Object3`D the `DecalGeometry` can be correctly generated).\n *\n * @param {Mesh|Line|Points} object - The 3D object to compute morph attributes for.\n * @return {Object} An object with original position/normal attributes and morphed ones.\n */\nfunction computeMorphedAttributes( object ) {\n\n\tconst _vA = new Vector3();\n\tconst _vB = new Vector3();\n\tconst _vC = new Vector3();\n\n\tconst _tempA = new Vector3();\n\tconst _tempB = new Vector3();\n\tconst _tempC = new Vector3();\n\n\tconst _morphA = new Vector3();\n\tconst _morphB = new Vector3();\n\tconst _morphC = new Vector3();\n\n\tfunction _calculateMorphedAttributeData(\n\t\tobject,\n\t\tattribute,\n\t\tmorphAttribute,\n\t\tmorphTargetsRelative,\n\t\ta,\n\t\tb,\n\t\tc,\n\t\tmodifiedAttributeArray\n\t) {\n\n\t\t_vA.fromBufferAttribute( attribute, a );\n\t\t_vB.fromBufferAttribute( attribute, b );\n\t\t_vC.fromBufferAttribute( attribute, c );\n\n\t\tconst morphInfluences = object.morphTargetInfluences;\n\n\t\tif ( morphAttribute && morphInfluences ) {\n\n\t\t\t_morphA.set( 0, 0, 0 );\n\t\t\t_morphB.set( 0, 0, 0 );\n\t\t\t_morphC.set( 0, 0, 0 );\n\n\t\t\tfor ( let i = 0, il = morphAttribute.length; i < il; i ++ ) {\n\n\t\t\t\tconst influence = morphInfluences[ i ];\n\t\t\t\tconst morph = morphAttribute[ i ];\n\n\t\t\t\tif ( influence === 0 ) continue;\n\n\t\t\t\t_tempA.fromBufferAttribute( morph, a );\n\t\t\t\t_tempB.fromBufferAttribute( morph, b );\n\t\t\t\t_tempC.fromBufferAttribute( morph, c );\n\n\t\t\t\tif ( morphTargetsRelative ) {\n\n\t\t\t\t\t_morphA.addScaledVector( _tempA, influence );\n\t\t\t\t\t_morphB.addScaledVector( _tempB, influence );\n\t\t\t\t\t_morphC.addScaledVector( _tempC, influence );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_morphA.addScaledVector( _tempA.sub( _vA ), influence );\n\t\t\t\t\t_morphB.addScaledVector( _tempB.sub( _vB ), influence );\n\t\t\t\t\t_morphC.addScaledVector( _tempC.sub( _vC ), influence );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_vA.add( _morphA );\n\t\t\t_vB.add( _morphB );\n\t\t\t_vC.add( _morphC );\n\n\t\t}\n\n\t\tif ( object.isSkinnedMesh ) {\n\n\t\t\tobject.applyBoneTransform( a, _vA );\n\t\t\tobject.applyBoneTransform( b, _vB );\n\t\t\tobject.applyBoneTransform( c, _vC );\n\n\t\t}\n\n\t\tmodifiedAttributeArray[ a * 3 + 0 ] = _vA.x;\n\t\tmodifiedAttributeArray[ a * 3 + 1 ] = _vA.y;\n\t\tmodifiedAttributeArray[ a * 3 + 2 ] = _vA.z;\n\t\tmodifiedAttributeArray[ b * 3 + 0 ] = _vB.x;\n\t\tmodifiedAttributeArray[ b * 3 + 1 ] = _vB.y;\n\t\tmodifiedAttributeArray[ b * 3 + 2 ] = _vB.z;\n\t\tmodifiedAttributeArray[ c * 3 + 0 ] = _vC.x;\n\t\tmodifiedAttributeArray[ c * 3 + 1 ] = _vC.y;\n\t\tmodifiedAttributeArray[ c * 3 + 2 ] = _vC.z;\n\n\t}\n\n\tconst geometry = object.geometry;\n\tconst material = object.material;\n\n\tlet a, b, c;\n\tconst index = geometry.index;\n\tconst positionAttribute = geometry.attributes.position;\n\tconst morphPosition = geometry.morphAttributes.position;\n\tconst morphTargetsRelative = geometry.morphTargetsRelative;\n\tconst normalAttribute = geometry.attributes.normal;\n\tconst morphNormal = geometry.morphAttributes.position;\n\n\tconst groups = geometry.groups;\n\tconst drawRange = geometry.drawRange;\n\tlet i, j, il, jl;\n\tlet group;\n\tlet start, end;\n\n\tconst modifiedPosition = new Float32Array( positionAttribute.count * positionAttribute.itemSize );\n\tconst modifiedNormal = new Float32Array( normalAttribute.count * normalAttribute.itemSize );\n\n\tif ( index !== null ) {\n\n\t\t// indexed buffer geometry\n\n\t\tif ( Array.isArray( material ) ) {\n\n\t\t\tfor ( i = 0, il = groups.length; i < il; i ++ ) {\n\n\t\t\t\tgroup = groups[ i ];\n\n\t\t\t\tstart = Math.max( group.start, drawRange.start );\n\t\t\t\tend = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );\n\n\t\t\t\tfor ( j = start, jl = end; j < jl; j += 3 ) {\n\n\t\t\t\t\ta = index.getX( j );\n\t\t\t\t\tb = index.getX( j + 1 );\n\t\t\t\t\tc = index.getX( j + 2 );\n\n\t\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tpositionAttribute,\n\t\t\t\t\t\tmorphPosition,\n\t\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\t\ta, b, c,\n\t\t\t\t\t\tmodifiedPosition\n\t\t\t\t\t);\n\n\t\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tnormalAttribute,\n\t\t\t\t\t\tmorphNormal,\n\t\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\t\ta, b, c,\n\t\t\t\t\t\tmodifiedNormal\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tstart = Math.max( 0, drawRange.start );\n\t\t\tend = Math.min( index.count, ( drawRange.start + drawRange.count ) );\n\n\t\t\tfor ( i = start, il = end; i < il; i += 3 ) {\n\n\t\t\t\ta = index.getX( i );\n\t\t\t\tb = index.getX( i + 1 );\n\t\t\t\tc = index.getX( i + 2 );\n\n\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\tobject,\n\t\t\t\t\tpositionAttribute,\n\t\t\t\t\tmorphPosition,\n\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\ta, b, c,\n\t\t\t\t\tmodifiedPosition\n\t\t\t\t);\n\n\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\tobject,\n\t\t\t\t\tnormalAttribute,\n\t\t\t\t\tmorphNormal,\n\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\ta, b, c,\n\t\t\t\t\tmodifiedNormal\n\t\t\t\t);\n\n\t\t\t}\n\n\t\t}\n\n\t} else {\n\n\t\t// non-indexed buffer geometry\n\n\t\tif ( Array.isArray( material ) ) {\n\n\t\t\tfor ( i = 0, il = groups.length; i < il; i ++ ) {\n\n\t\t\t\tgroup = groups[ i ];\n\n\t\t\t\tstart = Math.max( group.start, drawRange.start );\n\t\t\t\tend = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );\n\n\t\t\t\tfor ( j = start, jl = end; j < jl; j += 3 ) {\n\n\t\t\t\t\ta = j;\n\t\t\t\t\tb = j + 1;\n\t\t\t\t\tc = j + 2;\n\n\t\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tpositionAttribute,\n\t\t\t\t\t\tmorphPosition,\n\t\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\t\ta, b, c,\n\t\t\t\t\t\tmodifiedPosition\n\t\t\t\t\t);\n\n\t\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tnormalAttribute,\n\t\t\t\t\t\tmorphNormal,\n\t\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\t\ta, b, c,\n\t\t\t\t\t\tmodifiedNormal\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tstart = Math.max( 0, drawRange.start );\n\t\t\tend = Math.min( positionAttribute.count, ( drawRange.start + drawRange.count ) );\n\n\t\t\tfor ( i = start, il = end; i < il; i += 3 ) {\n\n\t\t\t\ta = i;\n\t\t\t\tb = i + 1;\n\t\t\t\tc = i + 2;\n\n\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\tobject,\n\t\t\t\t\tpositionAttribute,\n\t\t\t\t\tmorphPosition,\n\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\ta, b, c,\n\t\t\t\t\tmodifiedPosition\n\t\t\t\t);\n\n\t\t\t\t_calculateMorphedAttributeData(\n\t\t\t\t\tobject,\n\t\t\t\t\tnormalAttribute,\n\t\t\t\t\tmorphNormal,\n\t\t\t\t\tmorphTargetsRelative,\n\t\t\t\t\ta, b, c,\n\t\t\t\t\tmodifiedNormal\n\t\t\t\t);\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tconst morphedPositionAttribute = new Float32BufferAttribute( modifiedPosition, 3 );\n\tconst morphedNormalAttribute = new Float32BufferAttribute( modifiedNormal, 3 );\n\n\treturn {\n\n\t\tpositionAttribute: positionAttribute,\n\t\tnormalAttribute: normalAttribute,\n\t\tmorphedPositionAttribute: morphedPositionAttribute,\n\t\tmorphedNormalAttribute: morphedNormalAttribute\n\n\t};\n\n}\n\n/**\n * Merges the {@link BufferGeometry#groups} for the given geometry.\n *\n * @param {BufferGeometry} geometry - The geometry to modify.\n * @return {BufferGeometry} - The updated geometry\n */\nfunction mergeGroups( geometry ) {\n\n\tif ( geometry.groups.length === 0 ) {\n\n\t\tconsole.warn( 'THREE.BufferGeometryUtils.mergeGroups(): No groups are defined. Nothing to merge.' );\n\t\treturn geometry;\n\n\t}\n\n\tlet groups = geometry.groups;\n\n\t// sort groups by material index\n\n\tgroups = groups.sort( ( a, b ) => {\n\n\t\tif ( a.materialIndex !== b.materialIndex ) return a.materialIndex - b.materialIndex;\n\n\t\treturn a.start - b.start;\n\n\t} );\n\n\t// create index for non-indexed geometries\n\n\tif ( geometry.getIndex() === null ) {\n\n\t\tconst positionAttribute = geometry.getAttribute( 'position' );\n\t\tconst indices = [];\n\n\t\tfor ( let i = 0; i < positionAttribute.count; i += 3 ) {\n\n\t\t\tindices.push( i, i + 1, i + 2 );\n\n\t\t}\n\n\t\tgeometry.setIndex( indices );\n\n\t}\n\n\t// sort index\n\n\tconst index = geometry.getIndex();\n\n\tconst newIndices = [];\n\n\tfor ( let i = 0; i < groups.length; i ++ ) {\n\n\t\tconst group = groups[ i ];\n\n\t\tconst groupStart = group.start;\n\t\tconst groupLength = groupStart + group.count;\n\n\t\tfor ( let j = groupStart; j < groupLength; j ++ ) {\n\n\t\t\tnewIndices.push( index.getX( j ) );\n\n\t\t}\n\n\t}\n\n\tgeometry.dispose(); // Required to force buffer recreation\n\tgeometry.setIndex( newIndices );\n\n\t// update groups indices\n\n\tlet start = 0;\n\n\tfor ( let i = 0; i < groups.length; i ++ ) {\n\n\t\tconst group = groups[ i ];\n\n\t\tgroup.start = start;\n\t\tstart += group.count;\n\n\t}\n\n\t// merge groups\n\n\tlet currentGroup = groups[ 0 ];\n\n\tgeometry.groups = [ currentGroup ];\n\n\tfor ( let i = 1; i < groups.length; i ++ ) {\n\n\t\tconst group = groups[ i ];\n\n\t\tif ( currentGroup.materialIndex === group.materialIndex ) {\n\n\t\t\tcurrentGroup.count += group.count;\n\n\t\t} else {\n\n\t\t\tcurrentGroup = group;\n\t\t\tgeometry.groups.push( currentGroup );\n\n\t\t}\n\n\t}\n\n\treturn geometry;\n\n}\n\n/**\n * Modifies the supplied geometry if it is non-indexed, otherwise creates a new,\n * non-indexed geometry. Returns the geometry with smooth normals everywhere except\n * faces that meet at an angle greater than the crease angle.\n *\n * @param {BufferGeometry} geometry - The geometry to modify.\n * @param {number} [creaseAngle=Math.PI/3] - The crease angle in radians.\n * @return {BufferGeometry} - The updated geometry\n */\nfunction toCreasedNormals( geometry, creaseAngle = Math.PI / 3 /* 60 degrees */ ) {\n\n\tconst creaseDot = Math.cos( creaseAngle );\n\tconst hashMultiplier = ( 1 + 1e-10 ) * 1e2;\n\n\t// reusable vectors\n\tconst verts = [ new Vector3(), new Vector3(), new Vector3() ];\n\tconst tempVec1 = new Vector3();\n\tconst tempVec2 = new Vector3();\n\tconst tempNorm = new Vector3();\n\tconst tempNorm2 = new Vector3();\n\n\t// hashes a vector\n\tfunction hashVertex( v ) {\n\n\t\tconst x = ~ ~ ( v.x * hashMultiplier );\n\t\tconst y = ~ ~ ( v.y * hashMultiplier );\n\t\tconst z = ~ ~ ( v.z * hashMultiplier );\n\t\treturn `${x},${y},${z}`;\n\n\t}\n\n\t// BufferGeometry.toNonIndexed() warns if the geometry is non-indexed\n\t// and returns the original geometry\n\tconst resultGeometry = geometry.index ? geometry.toNonIndexed() : geometry;\n\tconst posAttr = resultGeometry.attributes.position;\n\tconst vertexMap = {};\n\n\t// find all the normals shared by commonly located vertices\n\tfor ( let i = 0, l = posAttr.count / 3; i < l; i ++ ) {\n\n\t\tconst i3 = 3 * i;\n\t\tconst a = verts[ 0 ].fromBufferAttribute( posAttr, i3 + 0 );\n\t\tconst b = verts[ 1 ].fromBufferAttribute( posAttr, i3 + 1 );\n\t\tconst c = verts[ 2 ].fromBufferAttribute( posAttr, i3 + 2 );\n\n\t\ttempVec1.subVectors( c, b );\n\t\ttempVec2.subVectors( a, b );\n\n\t\t// add the normal to the map for all vertices\n\t\tconst normal = new Vector3().crossVectors( tempVec1, tempVec2 ).normalize();\n\t\tfor ( let n = 0; n < 3; n ++ ) {\n\n\t\t\tconst vert = verts[ n ];\n\t\t\tconst hash = hashVertex( vert );\n\t\t\tif ( ! ( hash in vertexMap ) ) {\n\n\t\t\t\tvertexMap[ hash ] = [];\n\n\t\t\t}\n\n\t\t\tvertexMap[ hash ].push( normal );\n\n\t\t}\n\n\t}\n\n\t// average normals from all vertices that share a common location if they are within the\n\t// provided crease threshold\n\tconst normalArray = new Float32Array( posAttr.count * 3 );\n\tconst normAttr = new BufferAttribute( normalArray, 3, false );\n\tfor ( let i = 0, l = posAttr.count / 3; i < l; i ++ ) {\n\n\t\t// get the face normal for this vertex\n\t\tconst i3 = 3 * i;\n\t\tconst a = verts[ 0 ].fromBufferAttribute( posAttr, i3 + 0 );\n\t\tconst b = verts[ 1 ].fromBufferAttribute( posAttr, i3 + 1 );\n\t\tconst c = verts[ 2 ].fromBufferAttribute( posAttr, i3 + 2 );\n\n\t\ttempVec1.subVectors( c, b );\n\t\ttempVec2.subVectors( a, b );\n\n\t\ttempNorm.crossVectors( tempVec1, tempVec2 ).normalize();\n\n\t\t// average all normals that meet the threshold and set the normal value\n\t\tfor ( let n = 0; n < 3; n ++ ) {\n\n\t\t\tconst vert = verts[ n ];\n\t\t\tconst hash = hashVertex( vert );\n\t\t\tconst otherNormals = vertexMap[ hash ];\n\t\t\ttempNorm2.set( 0, 0, 0 );\n\n\t\t\tfor ( let k = 0, lk = otherNormals.length; k < lk; k ++ ) {\n\n\t\t\t\tconst otherNorm = otherNormals[ k ];\n\t\t\t\tif ( tempNorm.dot( otherNorm ) > creaseDot ) {\n\n\t\t\t\t\ttempNorm2.add( otherNorm );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\ttempNorm2.normalize();\n\t\t\tnormAttr.setXYZ( i3 + n, tempNorm2.x, tempNorm2.y, tempNorm2.z );\n\n\t\t}\n\n\t}\n\n\tresultGeometry.setAttribute( 'normal', normAttr );\n\treturn resultGeometry;\n\n}\n\nexport {\n\tcomputeMikkTSpaceTangents,\n\tmergeGeometries,\n\tmergeAttributes,\n\tdeepCloneAttribute,\n\tdeinterleaveAttribute,\n\tdeinterleaveGeometry,\n\tinterleaveAttributes,\n\testimateBytesUsed,\n\tmergeVertices,\n\ttoTrianglesDrawMode,\n\tcomputeMorphedAttributes,\n\tmergeGroups,\n\ttoCreasedNormals\n};\n","import {\n\tAnimationClip,\n\tBone,\n\tBox3,\n\tBufferAttribute,\n\tBufferGeometry,\n\tClampToEdgeWrapping,\n\tColor,\n\tColorManagement,\n\tDirectionalLight,\n\tDoubleSide,\n\tFileLoader,\n\tFrontSide,\n\tGroup,\n\tImageBitmapLoader,\n\tInstancedMesh,\n\tInterleavedBuffer,\n\tInterleavedBufferAttribute,\n\tInterpolant,\n\tInterpolateDiscrete,\n\tInterpolateLinear,\n\tLine,\n\tLineBasicMaterial,\n\tLineLoop,\n\tLineSegments,\n\tLinearFilter,\n\tLinearMipmapLinearFilter,\n\tLinearMipmapNearestFilter,\n\tLinearSRGBColorSpace,\n\tLoader,\n\tLoaderUtils,\n\tMaterial,\n\tMathUtils,\n\tMatrix4,\n\tMesh,\n\tMeshBasicMaterial,\n\tMeshPhysicalMaterial,\n\tMeshStandardMaterial,\n\tMirroredRepeatWrapping,\n\tNearestFilter,\n\tNearestMipmapLinearFilter,\n\tNearestMipmapNearestFilter,\n\tNumberKeyframeTrack,\n\tObject3D,\n\tOrthographicCamera,\n\tPerspectiveCamera,\n\tPointLight,\n\tPoints,\n\tPointsMaterial,\n\tPropertyBinding,\n\tQuaternion,\n\tQuaternionKeyframeTrack,\n\tRepeatWrapping,\n\tSkeleton,\n\tSkinnedMesh,\n\tSphere,\n\tSpotLight,\n\tTexture,\n\tTextureLoader,\n\tTriangleFanDrawMode,\n\tTriangleStripDrawMode,\n\tVector2,\n\tVector3,\n\tVectorKeyframeTrack,\n\tSRGBColorSpace,\n\tInstancedBufferAttribute\n} from 'three';\nimport { toTrianglesDrawMode } from '../utils/BufferGeometryUtils.js';\n\n/**\n * A loader for the glTF 2.0 format.\n *\n * [glTF](https://www.khronos.org/gltf/} (GL Transmission Format) is an [open format specification]{@link https://github.com/KhronosGroup/glTF/tree/main/specification/2.0)\n * for efficient delivery and loading of 3D content. Assets may be provided either in JSON (.gltf) or binary (.glb)\n * format. External files store textures (.jpg, .png) and additional binary data (.bin). A glTF asset may deliver\n * one or more scenes, including meshes, materials, textures, skins, skeletons, morph targets, animations, lights,\n * and/or cameras.\n *\n * `GLTFLoader` uses {@link ImageBitmapLoader} whenever possible. Be advised that image bitmaps are not\n * automatically GC-collected when they are no longer referenced, and they require special handling during\n * the disposal process.\n *\n * `GLTFLoader` supports the following glTF 2.0 extensions:\n * - KHR_draco_mesh_compression\n * - KHR_materials_clearcoat\n * - KHR_materials_dispersion\n * - KHR_materials_ior\n * - KHR_materials_specular\n * - KHR_materials_transmission\n * - KHR_materials_iridescence\n * - KHR_materials_unlit\n * - KHR_materials_volume\n * - KHR_mesh_quantization\n * - KHR_lights_punctual\n * - KHR_texture_basisu\n * - KHR_texture_transform\n * - EXT_texture_webp\n * - EXT_meshopt_compression\n * - EXT_mesh_gpu_instancing\n *\n * The following glTF 2.0 extension is supported by an external user plugin:\n * - [KHR_materials_variants](https://github.com/takahirox/three-gltf-extensions)\n * - [MSFT_texture_dds](https://github.com/takahirox/three-gltf-extensions)\n * - [KHR_animation_pointer](https://github.com/needle-tools/three-animation-pointer)\n * - [NEEDLE_progressive](https://github.com/needle-tools/gltf-progressive)\n *\n * ```js\n * const loader = new GLTFLoader();\n *\n * // Optional: Provide a DRACOLoader instance to decode compressed mesh data\n * const dracoLoader = new DRACOLoader();\n * dracoLoader.setDecoderPath( '/examples/jsm/libs/draco/' );\n * loader.setDRACOLoader( dracoLoader );\n *\n * const gltf = await loader.loadAsync( 'models/gltf/duck/duck.gltf' );\n * scene.add( gltf.scene );\n * ```\n *\n * @augments Loader\n * @three_import import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\n */\nclass GLTFLoader extends Loader {\n\n\t/**\n\t * Constructs a new glTF loader.\n\t *\n\t * @param {LoadingManager} [manager] - The loading manager.\n\t */\n\tconstructor( manager ) {\n\n\t\tsuper( manager );\n\n\t\tthis.dracoLoader = null;\n\t\tthis.ktx2Loader = null;\n\t\tthis.meshoptDecoder = null;\n\n\t\tthis.pluginCallbacks = [];\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsClearcoatExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsDispersionExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFTextureBasisUExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFTextureWebPExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFTextureAVIFExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsSheenExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsTransmissionExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsVolumeExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsIorExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsEmissiveStrengthExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsSpecularExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsIridescenceExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsAnisotropyExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsBumpExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFLightsExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMeshoptCompression( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMeshGpuInstancing( parser );\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Starts loading from the given URL and passes the loaded glTF asset\n\t * to the `onLoad()` callback.\n\t *\n\t * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.\n\t * @param {function(GLTFLoader~LoadObject)} onLoad - Executed when the loading process has been finished.\n\t * @param {onProgressCallback} onProgress - Executed while the loading is in progress.\n\t * @param {onErrorCallback} onError - Executed when errors occur.\n\t */\n\tload( url, onLoad, onProgress, onError ) {\n\n\t\tconst scope = this;\n\n\t\tlet resourcePath;\n\n\t\tif ( this.resourcePath !== '' ) {\n\n\t\t\tresourcePath = this.resourcePath;\n\n\t\t} else if ( this.path !== '' ) {\n\n\t\t\t// If a base path is set, resources will be relative paths from that plus the relative path of the gltf file\n\t\t\t// Example  path = 'https://my-cnd-server.com/', url = 'assets/models/model.gltf'\n\t\t\t// resourcePath = 'https://my-cnd-server.com/assets/models/'\n\t\t\t// referenced resource 'model.bin' will be loaded from 'https://my-cnd-server.com/assets/models/model.bin'\n\t\t\t// referenced resource '../textures/texture.png' will be loaded from 'https://my-cnd-server.com/assets/textures/texture.png'\n\t\t\tconst relativeUrl = LoaderUtils.extractUrlBase( url );\n\t\t\tresourcePath = LoaderUtils.resolveURL( relativeUrl, this.path );\n\n\t\t} else {\n\n\t\t\tresourcePath = LoaderUtils.extractUrlBase( url );\n\n\t\t}\n\n\t\t// Tells the LoadingManager to track an extra item, which resolves after\n\t\t// the model is fully loaded. This means the count of items loaded will\n\t\t// be incorrect, but ensures manager.onLoad() does not fire early.\n\t\tthis.manager.itemStart( url );\n\n\t\tconst _onError = function ( e ) {\n\n\t\t\tif ( onError ) {\n\n\t\t\t\tonError( e );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( e );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemError( url );\n\t\t\tscope.manager.itemEnd( url );\n\n\t\t};\n\n\t\tconst loader = new FileLoader( this.manager );\n\n\t\tloader.setPath( this.path );\n\t\tloader.setResponseType( 'arraybuffer' );\n\t\tloader.setRequestHeader( this.requestHeader );\n\t\tloader.setWithCredentials( this.withCredentials );\n\n\t\tloader.load( url, function ( data ) {\n\n\t\t\ttry {\n\n\t\t\t\tscope.parse( data, resourcePath, function ( gltf ) {\n\n\t\t\t\t\tonLoad( gltf );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, _onError );\n\n\t\t\t} catch ( e ) {\n\n\t\t\t\t_onError( e );\n\n\t\t\t}\n\n\t\t}, onProgress, _onError );\n\n\t}\n\n\t/**\n\t * Sets the given Draco loader to this loader. Required for decoding assets\n\t * compressed with the `KHR_draco_mesh_compression` extension.\n\t *\n\t * @param {DRACOLoader} dracoLoader - The Draco loader to set.\n\t * @return {GLTFLoader} A reference to this loader.\n\t */\n\tsetDRACOLoader( dracoLoader ) {\n\n\t\tthis.dracoLoader = dracoLoader;\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Sets the given KTX2 loader to this loader. Required for loading KTX2\n\t * compressed textures.\n\t *\n\t * @param {KTX2Loader} ktx2Loader - The KTX2 loader to set.\n\t * @return {GLTFLoader} A reference to this loader.\n\t */\n\tsetKTX2Loader( ktx2Loader ) {\n\n\t\tthis.ktx2Loader = ktx2Loader;\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Sets the given meshopt decoder. Required for decoding assets\n\t * compressed with the `EXT_meshopt_compression` extension.\n\t *\n\t * @param {Object} meshoptDecoder - The meshopt decoder to set.\n\t * @return {GLTFLoader} A reference to this loader.\n\t */\n\tsetMeshoptDecoder( meshoptDecoder ) {\n\n\t\tthis.meshoptDecoder = meshoptDecoder;\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Registers a plugin callback. This API is internally used to implement the various\n\t * glTF extensions but can also used by third-party code to add additional logic\n\t * to the loader.\n\t *\n\t * @param {function(parser:GLTFParser)} callback - The callback function to register.\n\t * @return {GLTFLoader} A reference to this loader.\n\t */\n\tregister( callback ) {\n\n\t\tif ( this.pluginCallbacks.indexOf( callback ) === - 1 ) {\n\n\t\t\tthis.pluginCallbacks.push( callback );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Unregisters a plugin callback.\n\t *\n\t * @param {Function} callback - The callback function to unregister.\n\t * @return {GLTFLoader} A reference to this loader.\n\t */\n\tunregister( callback ) {\n\n\t\tif ( this.pluginCallbacks.indexOf( callback ) !== - 1 ) {\n\n\t\t\tthis.pluginCallbacks.splice( this.pluginCallbacks.indexOf( callback ), 1 );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Parses the given FBX data and returns the resulting group.\n\t *\n\t * @param {string|ArrayBuffer} data - The raw glTF data.\n\t * @param {string} path - The URL base path.\n\t * @param {function(GLTFLoader~LoadObject)} onLoad - Executed when the loading process has been finished.\n\t * @param {onErrorCallback} onError - Executed when errors occur.\n\t */\n\tparse( data, path, onLoad, onError ) {\n\n\t\tlet json;\n\t\tconst extensions = {};\n\t\tconst plugins = {};\n\t\tconst textDecoder = new TextDecoder();\n\n\t\tif ( typeof data === 'string' ) {\n\n\t\t\tjson = JSON.parse( data );\n\n\t\t} else if ( data instanceof ArrayBuffer ) {\n\n\t\t\tconst magic = textDecoder.decode( new Uint8Array( data, 0, 4 ) );\n\n\t\t\tif ( magic === BINARY_EXTENSION_HEADER_MAGIC ) {\n\n\t\t\t\ttry {\n\n\t\t\t\t\textensions[ EXTENSIONS.KHR_BINARY_GLTF ] = new GLTFBinaryExtension( data );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\tif ( onError ) onError( error );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tjson = JSON.parse( extensions[ EXTENSIONS.KHR_BINARY_GLTF ].content );\n\n\t\t\t} else {\n\n\t\t\t\tjson = JSON.parse( textDecoder.decode( data ) );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tjson = data;\n\n\t\t}\n\n\t\tif ( json.asset === undefined || json.asset.version[ 0 ] < 2 ) {\n\n\t\t\tif ( onError ) onError( new Error( 'THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported.' ) );\n\t\t\treturn;\n\n\t\t}\n\n\t\tconst parser = new GLTFParser( json, {\n\n\t\t\tpath: path || this.resourcePath || '',\n\t\t\tcrossOrigin: this.crossOrigin,\n\t\t\trequestHeader: this.requestHeader,\n\t\t\tmanager: this.manager,\n\t\t\tktx2Loader: this.ktx2Loader,\n\t\t\tmeshoptDecoder: this.meshoptDecoder\n\n\t\t} );\n\n\t\tparser.fileLoader.setRequestHeader( this.requestHeader );\n\n\t\tfor ( let i = 0; i < this.pluginCallbacks.length; i ++ ) {\n\n\t\t\tconst plugin = this.pluginCallbacks[ i ]( parser );\n\n\t\t\tif ( ! plugin.name ) console.error( 'THREE.GLTFLoader: Invalid plugin found: missing name' );\n\n\t\t\tplugins[ plugin.name ] = plugin;\n\n\t\t\t// Workaround to avoid determining as unknown extension\n\t\t\t// in addUnknownExtensionsToUserData().\n\t\t\t// Remove this workaround if we move all the existing\n\t\t\t// extension handlers to plugin system\n\t\t\textensions[ plugin.name ] = true;\n\n\t\t}\n\n\t\tif ( json.extensionsUsed ) {\n\n\t\t\tfor ( let i = 0; i < json.extensionsUsed.length; ++ i ) {\n\n\t\t\t\tconst extensionName = json.extensionsUsed[ i ];\n\t\t\t\tconst extensionsRequired = json.extensionsRequired || [];\n\n\t\t\t\tswitch ( extensionName ) {\n\n\t\t\t\t\tcase EXTENSIONS.KHR_MATERIALS_UNLIT:\n\t\t\t\t\t\textensions[ extensionName ] = new GLTFMaterialsUnlitExtension();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase EXTENSIONS.KHR_DRACO_MESH_COMPRESSION:\n\t\t\t\t\t\textensions[ extensionName ] = new GLTFDracoMeshCompressionExtension( json, this.dracoLoader );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase EXTENSIONS.KHR_TEXTURE_TRANSFORM:\n\t\t\t\t\t\textensions[ extensionName ] = new GLTFTextureTransformExtension();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase EXTENSIONS.KHR_MESH_QUANTIZATION:\n\t\t\t\t\t\textensions[ extensionName ] = new GLTFMeshQuantizationExtension();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tif ( extensionsRequired.indexOf( extensionName ) >= 0 && plugins[ extensionName ] === undefined ) {\n\n\t\t\t\t\t\t\tconsole.warn( 'THREE.GLTFLoader: Unknown extension \"' + extensionName + '\".' );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tparser.setExtensions( extensions );\n\t\tparser.setPlugins( plugins );\n\t\tparser.parse( onLoad, onError );\n\n\t}\n\n\t/**\n\t * Async version of {@link GLTFLoader#parse}.\n\t *\n\t * @async\n\t * @param {string|ArrayBuffer} data - The raw glTF data.\n\t * @param {string} path - The URL base path.\n\t * @return {Promise<GLTFLoader~LoadObject>} A Promise that resolves with the loaded glTF when the parsing has been finished.\n\t */\n\tparseAsync( data, path ) {\n\n\t\tconst scope = this;\n\n\t\treturn new Promise( function ( resolve, reject ) {\n\n\t\t\tscope.parse( data, path, resolve, reject );\n\n\t\t} );\n\n\t}\n\n}\n\n/* GLTFREGISTRY */\n\nfunction GLTFRegistry() {\n\n\tlet objects = {};\n\n\treturn\t{\n\n\t\tget: function ( key ) {\n\n\t\t\treturn objects[ key ];\n\n\t\t},\n\n\t\tadd: function ( key, object ) {\n\n\t\t\tobjects[ key ] = object;\n\n\t\t},\n\n\t\tremove: function ( key ) {\n\n\t\t\tdelete objects[ key ];\n\n\t\t},\n\n\t\tremoveAll: function () {\n\n\t\t\tobjects = {};\n\n\t\t}\n\n\t};\n\n}\n\n/*********************************/\n/********** EXTENSIONS ***********/\n/*********************************/\n\nconst EXTENSIONS = {\n\tKHR_BINARY_GLTF: 'KHR_binary_glTF',\n\tKHR_DRACO_MESH_COMPRESSION: 'KHR_draco_mesh_compression',\n\tKHR_LIGHTS_PUNCTUAL: 'KHR_lights_punctual',\n\tKHR_MATERIALS_CLEARCOAT: 'KHR_materials_clearcoat',\n\tKHR_MATERIALS_DISPERSION: 'KHR_materials_dispersion',\n\tKHR_MATERIALS_IOR: 'KHR_materials_ior',\n\tKHR_MATERIALS_SHEEN: 'KHR_materials_sheen',\n\tKHR_MATERIALS_SPECULAR: 'KHR_materials_specular',\n\tKHR_MATERIALS_TRANSMISSION: 'KHR_materials_transmission',\n\tKHR_MATERIALS_IRIDESCENCE: 'KHR_materials_iridescence',\n\tKHR_MATERIALS_ANISOTROPY: 'KHR_materials_anisotropy',\n\tKHR_MATERIALS_UNLIT: 'KHR_materials_unlit',\n\tKHR_MATERIALS_VOLUME: 'KHR_materials_volume',\n\tKHR_TEXTURE_BASISU: 'KHR_texture_basisu',\n\tKHR_TEXTURE_TRANSFORM: 'KHR_texture_transform',\n\tKHR_MESH_QUANTIZATION: 'KHR_mesh_quantization',\n\tKHR_MATERIALS_EMISSIVE_STRENGTH: 'KHR_materials_emissive_strength',\n\tEXT_MATERIALS_BUMP: 'EXT_materials_bump',\n\tEXT_TEXTURE_WEBP: 'EXT_texture_webp',\n\tEXT_TEXTURE_AVIF: 'EXT_texture_avif',\n\tEXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression',\n\tEXT_MESH_GPU_INSTANCING: 'EXT_mesh_gpu_instancing'\n};\n\n/**\n * Punctual Lights Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual\n *\n * @private\n */\nclass GLTFLightsExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_LIGHTS_PUNCTUAL;\n\n\t\t// Object3D instance caches\n\t\tthis.cache = { refs: {}, uses: {} };\n\n\t}\n\n\t_markDefs() {\n\n\t\tconst parser = this.parser;\n\t\tconst nodeDefs = this.parser.json.nodes || [];\n\n\t\tfor ( let nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex ++ ) {\n\n\t\t\tconst nodeDef = nodeDefs[ nodeIndex ];\n\n\t\t\tif ( nodeDef.extensions\n\t\t\t\t\t&& nodeDef.extensions[ this.name ]\n\t\t\t\t\t&& nodeDef.extensions[ this.name ].light !== undefined ) {\n\n\t\t\t\tparser._addNodeRef( this.cache, nodeDef.extensions[ this.name ].light );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t_loadLight( lightIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst cacheKey = 'light:' + lightIndex;\n\t\tlet dependency = parser.cache.get( cacheKey );\n\n\t\tif ( dependency ) return dependency;\n\n\t\tconst json = parser.json;\n\t\tconst extensions = ( json.extensions && json.extensions[ this.name ] ) || {};\n\t\tconst lightDefs = extensions.lights || [];\n\t\tconst lightDef = lightDefs[ lightIndex ];\n\t\tlet lightNode;\n\n\t\tconst color = new Color( 0xffffff );\n\n\t\tif ( lightDef.color !== undefined ) color.setRGB( lightDef.color[ 0 ], lightDef.color[ 1 ], lightDef.color[ 2 ], LinearSRGBColorSpace );\n\n\t\tconst range = lightDef.range !== undefined ? lightDef.range : 0;\n\n\t\tswitch ( lightDef.type ) {\n\n\t\t\tcase 'directional':\n\t\t\t\tlightNode = new DirectionalLight( color );\n\t\t\t\tlightNode.target.position.set( 0, 0, - 1 );\n\t\t\t\tlightNode.add( lightNode.target );\n\t\t\t\tbreak;\n\n\t\t\tcase 'point':\n\t\t\t\tlightNode = new PointLight( color );\n\t\t\t\tlightNode.distance = range;\n\t\t\t\tbreak;\n\n\t\t\tcase 'spot':\n\t\t\t\tlightNode = new SpotLight( color );\n\t\t\t\tlightNode.distance = range;\n\t\t\t\t// Handle spotlight properties.\n\t\t\t\tlightDef.spot = lightDef.spot || {};\n\t\t\t\tlightDef.spot.innerConeAngle = lightDef.spot.innerConeAngle !== undefined ? lightDef.spot.innerConeAngle : 0;\n\t\t\t\tlightDef.spot.outerConeAngle = lightDef.spot.outerConeAngle !== undefined ? lightDef.spot.outerConeAngle : Math.PI / 4.0;\n\t\t\t\tlightNode.angle = lightDef.spot.outerConeAngle;\n\t\t\t\tlightNode.penumbra = 1.0 - lightDef.spot.innerConeAngle / lightDef.spot.outerConeAngle;\n\t\t\t\tlightNode.target.position.set( 0, 0, - 1 );\n\t\t\t\tlightNode.add( lightNode.target );\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'THREE.GLTFLoader: Unexpected light type: ' + lightDef.type );\n\n\t\t}\n\n\t\t// Some lights (e.g. spot) default to a position other than the origin. Reset the position\n\t\t// here, because node-level parsing will only override position if explicitly specified.\n\t\tlightNode.position.set( 0, 0, 0 );\n\n\t\tassignExtrasToUserData( lightNode, lightDef );\n\n\t\tif ( lightDef.intensity !== undefined ) lightNode.intensity = lightDef.intensity;\n\n\t\tlightNode.name = parser.createUniqueName( lightDef.name || ( 'light_' + lightIndex ) );\n\n\t\tdependency = Promise.resolve( lightNode );\n\n\t\tparser.cache.add( cacheKey, dependency );\n\n\t\treturn dependency;\n\n\t}\n\n\tgetDependency( type, index ) {\n\n\t\tif ( type !== 'light' ) return;\n\n\t\treturn this._loadLight( index );\n\n\t}\n\n\tcreateNodeAttachment( nodeIndex ) {\n\n\t\tconst self = this;\n\t\tconst parser = this.parser;\n\t\tconst json = parser.json;\n\t\tconst nodeDef = json.nodes[ nodeIndex ];\n\t\tconst lightDef = ( nodeDef.extensions && nodeDef.extensions[ this.name ] ) || {};\n\t\tconst lightIndex = lightDef.light;\n\n\t\tif ( lightIndex === undefined ) return null;\n\n\t\treturn this._loadLight( lightIndex ).then( function ( light ) {\n\n\t\t\treturn parser._getNodeRef( self.cache, lightIndex, light );\n\n\t\t} );\n\n\t}\n\n}\n\n/**\n * Unlit Materials Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit\n *\n * @private\n */\nclass GLTFMaterialsUnlitExtension {\n\n\tconstructor() {\n\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_UNLIT;\n\n\t}\n\n\tgetMaterialType() {\n\n\t\treturn MeshBasicMaterial;\n\n\t}\n\n\textendParams( materialParams, materialDef, parser ) {\n\n\t\tconst pending = [];\n\n\t\tmaterialParams.color = new Color( 1.0, 1.0, 1.0 );\n\t\tmaterialParams.opacity = 1.0;\n\n\t\tconst metallicRoughness = materialDef.pbrMetallicRoughness;\n\n\t\tif ( metallicRoughness ) {\n\n\t\t\tif ( Array.isArray( metallicRoughness.baseColorFactor ) ) {\n\n\t\t\t\tconst array = metallicRoughness.baseColorFactor;\n\n\t\t\t\tmaterialParams.color.setRGB( array[ 0 ], array[ 1 ], array[ 2 ], LinearSRGBColorSpace );\n\t\t\t\tmaterialParams.opacity = array[ 3 ];\n\n\t\t\t}\n\n\t\t\tif ( metallicRoughness.baseColorTexture !== undefined ) {\n\n\t\t\t\tpending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture, SRGBColorSpace ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Materials Emissive Strength Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/blob/5768b3ce0ef32bc39cdf1bef10b948586635ead3/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md\n *\n * @private\n */\nclass GLTFMaterialsEmissiveStrengthExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_EMISSIVE_STRENGTH;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {\n\n\t\t\treturn Promise.resolve();\n\n\t\t}\n\n\t\tconst emissiveStrength = materialDef.extensions[ this.name ].emissiveStrength;\n\n\t\tif ( emissiveStrength !== undefined ) {\n\n\t\t\tmaterialParams.emissiveIntensity = emissiveStrength;\n\n\t\t}\n\n\t\treturn Promise.resolve();\n\n\t}\n\n}\n\n/**\n * Clearcoat Materials Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat\n *\n * @private\n */\nclass GLTFMaterialsClearcoatExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_CLEARCOAT;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;\n\n\t\treturn MeshPhysicalMaterial;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {\n\n\t\t\treturn Promise.resolve();\n\n\t\t}\n\n\t\tconst pending = [];\n\n\t\tconst extension = materialDef.extensions[ this.name ];\n\n\t\tif ( extension.clearcoatFactor !== undefined ) {\n\n\t\t\tmaterialParams.clearcoat = extension.clearcoatFactor;\n\n\t\t}\n\n\t\tif ( extension.clearcoatTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'clearcoatMap', extension.clearcoatTexture ) );\n\n\t\t}\n\n\t\tif ( extension.clearcoatRoughnessFactor !== undefined ) {\n\n\t\t\tmaterialParams.clearcoatRoughness = extension.clearcoatRoughnessFactor;\n\n\t\t}\n\n\t\tif ( extension.clearcoatRoughnessTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'clearcoatRoughnessMap', extension.clearcoatRoughnessTexture ) );\n\n\t\t}\n\n\t\tif ( extension.clearcoatNormalTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'clearcoatNormalMap', extension.clearcoatNormalTexture ) );\n\n\t\t\tif ( extension.clearcoatNormalTexture.scale !== undefined ) {\n\n\t\t\t\tconst scale = extension.clearcoatNormalTexture.scale;\n\n\t\t\t\tmaterialParams.clearcoatNormalScale = new Vector2( scale, scale );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Materials dispersion Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_dispersion\n *\n * @private\n */\nclass GLTFMaterialsDispersionExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_DISPERSION;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;\n\n\t\treturn MeshPhysicalMaterial;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {\n\n\t\t\treturn Promise.resolve();\n\n\t\t}\n\n\t\tconst extension = materialDef.extensions[ this.name ];\n\n\t\tmaterialParams.dispersion = extension.dispersion !== undefined ? extension.dispersion : 0;\n\n\t\treturn Promise.resolve();\n\n\t}\n\n}\n\n/**\n * Iridescence Materials Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_iridescence\n *\n * @private\n */\nclass GLTFMaterialsIridescenceExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_IRIDESCENCE;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;\n\n\t\treturn MeshPhysicalMaterial;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {\n\n\t\t\treturn Promise.resolve();\n\n\t\t}\n\n\t\tconst pending = [];\n\n\t\tconst extension = materialDef.extensions[ this.name ];\n\n\t\tif ( extension.iridescenceFactor !== undefined ) {\n\n\t\t\tmaterialParams.iridescence = extension.iridescenceFactor;\n\n\t\t}\n\n\t\tif ( extension.iridescenceTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'iridescenceMap', extension.iridescenceTexture ) );\n\n\t\t}\n\n\t\tif ( extension.iridescenceIor !== undefined ) {\n\n\t\t\tmaterialParams.iridescenceIOR = extension.iridescenceIor;\n\n\t\t}\n\n\t\tif ( materialParams.iridescenceThicknessRange === undefined ) {\n\n\t\t\tmaterialParams.iridescenceThicknessRange = [ 100, 400 ];\n\n\t\t}\n\n\t\tif ( extension.iridescenceThicknessMinimum !== undefined ) {\n\n\t\t\tmaterialParams.iridescenceThicknessRange[ 0 ] = extension.iridescenceThicknessMinimum;\n\n\t\t}\n\n\t\tif ( extension.iridescenceThicknessMaximum !== undefined ) {\n\n\t\t\tmaterialParams.iridescenceThicknessRange[ 1 ] = extension.iridescenceThicknessMaximum;\n\n\t\t}\n\n\t\tif ( extension.iridescenceThicknessTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'iridescenceThicknessMap', extension.iridescenceThicknessTexture ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Sheen Materials Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_sheen\n *\n * @private\n */\nclass GLTFMaterialsSheenExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_SHEEN;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;\n\n\t\treturn MeshPhysicalMaterial;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {\n\n\t\t\treturn Promise.resolve();\n\n\t\t}\n\n\t\tconst pending = [];\n\n\t\tmaterialParams.sheenColor = new Color( 0, 0, 0 );\n\t\tmaterialParams.sheenRoughness = 0;\n\t\tmaterialParams.sheen = 1;\n\n\t\tconst extension = materialDef.extensions[ this.name ];\n\n\t\tif ( extension.sheenColorFactor !== undefined ) {\n\n\t\t\tconst colorFactor = extension.sheenColorFactor;\n\t\t\tmaterialParams.sheenColor.setRGB( colorFactor[ 0 ], colorFactor[ 1 ], colorFactor[ 2 ], LinearSRGBColorSpace );\n\n\t\t}\n\n\t\tif ( extension.sheenRoughnessFactor !== undefined ) {\n\n\t\t\tmaterialParams.sheenRoughness = extension.sheenRoughnessFactor;\n\n\t\t}\n\n\t\tif ( extension.sheenColorTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'sheenColorMap', extension.sheenColorTexture, SRGBColorSpace ) );\n\n\t\t}\n\n\t\tif ( extension.sheenRoughnessTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'sheenRoughnessMap', extension.sheenRoughnessTexture ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Transmission Materials Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_transmission\n * Draft: https://github.com/KhronosGroup/glTF/pull/1698\n *\n * @private\n */\nclass GLTFMaterialsTransmissionExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_TRANSMISSION;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;\n\n\t\treturn MeshPhysicalMaterial;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {\n\n\t\t\treturn Promise.resolve();\n\n\t\t}\n\n\t\tconst pending = [];\n\n\t\tconst extension = materialDef.extensions[ this.name ];\n\n\t\tif ( extension.transmissionFactor !== undefined ) {\n\n\t\t\tmaterialParams.transmission = extension.transmissionFactor;\n\n\t\t}\n\n\t\tif ( extension.transmissionTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'transmissionMap', extension.transmissionTexture ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Materials Volume Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_volume\n *\n * @private\n */\nclass GLTFMaterialsVolumeExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_VOLUME;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;\n\n\t\treturn MeshPhysicalMaterial;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {\n\n\t\t\treturn Promise.resolve();\n\n\t\t}\n\n\t\tconst pending = [];\n\n\t\tconst extension = materialDef.extensions[ this.name ];\n\n\t\tmaterialParams.thickness = extension.thicknessFactor !== undefined ? extension.thicknessFactor : 0;\n\n\t\tif ( extension.thicknessTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'thicknessMap', extension.thicknessTexture ) );\n\n\t\t}\n\n\t\tmaterialParams.attenuationDistance = extension.attenuationDistance || Infinity;\n\n\t\tconst colorArray = extension.attenuationColor || [ 1, 1, 1 ];\n\t\tmaterialParams.attenuationColor = new Color().setRGB( colorArray[ 0 ], colorArray[ 1 ], colorArray[ 2 ], LinearSRGBColorSpace );\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Materials ior Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_ior\n *\n * @private\n */\nclass GLTFMaterialsIorExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_IOR;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;\n\n\t\treturn MeshPhysicalMaterial;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {\n\n\t\t\treturn Promise.resolve();\n\n\t\t}\n\n\t\tconst extension = materialDef.extensions[ this.name ];\n\n\t\tmaterialParams.ior = extension.ior !== undefined ? extension.ior : 1.5;\n\n\t\treturn Promise.resolve();\n\n\t}\n\n}\n\n/**\n * Materials specular Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_specular\n *\n * @private\n */\nclass GLTFMaterialsSpecularExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_SPECULAR;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;\n\n\t\treturn MeshPhysicalMaterial;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {\n\n\t\t\treturn Promise.resolve();\n\n\t\t}\n\n\t\tconst pending = [];\n\n\t\tconst extension = materialDef.extensions[ this.name ];\n\n\t\tmaterialParams.specularIntensity = extension.specularFactor !== undefined ? extension.specularFactor : 1.0;\n\n\t\tif ( extension.specularTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'specularIntensityMap', extension.specularTexture ) );\n\n\t\t}\n\n\t\tconst colorArray = extension.specularColorFactor || [ 1, 1, 1 ];\n\t\tmaterialParams.specularColor = new Color().setRGB( colorArray[ 0 ], colorArray[ 1 ], colorArray[ 2 ], LinearSRGBColorSpace );\n\n\t\tif ( extension.specularColorTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'specularColorMap', extension.specularColorTexture, SRGBColorSpace ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n\n/**\n * Materials bump Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/EXT_materials_bump\n *\n * @private\n */\nclass GLTFMaterialsBumpExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.EXT_MATERIALS_BUMP;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;\n\n\t\treturn MeshPhysicalMaterial;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {\n\n\t\t\treturn Promise.resolve();\n\n\t\t}\n\n\t\tconst pending = [];\n\n\t\tconst extension = materialDef.extensions[ this.name ];\n\n\t\tmaterialParams.bumpScale = extension.bumpFactor !== undefined ? extension.bumpFactor : 1.0;\n\n\t\tif ( extension.bumpTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'bumpMap', extension.bumpTexture ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Materials anisotropy Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_anisotropy\n *\n * @private\n */\nclass GLTFMaterialsAnisotropyExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_ANISOTROPY;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;\n\n\t\treturn MeshPhysicalMaterial;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {\n\n\t\t\treturn Promise.resolve();\n\n\t\t}\n\n\t\tconst pending = [];\n\n\t\tconst extension = materialDef.extensions[ this.name ];\n\n\t\tif ( extension.anisotropyStrength !== undefined ) {\n\n\t\t\tmaterialParams.anisotropy = extension.anisotropyStrength;\n\n\t\t}\n\n\t\tif ( extension.anisotropyRotation !== undefined ) {\n\n\t\t\tmaterialParams.anisotropyRotation = extension.anisotropyRotation;\n\n\t\t}\n\n\t\tif ( extension.anisotropyTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'anisotropyMap', extension.anisotropyTexture ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * BasisU Texture Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_basisu\n *\n * @private\n */\nclass GLTFTextureBasisUExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_TEXTURE_BASISU;\n\n\t}\n\n\tloadTexture( textureIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst json = parser.json;\n\n\t\tconst textureDef = json.textures[ textureIndex ];\n\n\t\tif ( ! textureDef.extensions || ! textureDef.extensions[ this.name ] ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst extension = textureDef.extensions[ this.name ];\n\t\tconst loader = parser.options.ktx2Loader;\n\n\t\tif ( ! loader ) {\n\n\t\t\tif ( json.extensionsRequired && json.extensionsRequired.indexOf( this.name ) >= 0 ) {\n\n\t\t\t\tthrow new Error( 'THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures' );\n\n\t\t\t} else {\n\n\t\t\t\t// Assumes that the extension is optional and that a fallback texture is present\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn parser.loadTextureImage( textureIndex, extension.source, loader );\n\n\t}\n\n}\n\n/**\n * WebP Texture Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_texture_webp\n *\n * @private\n */\nclass GLTFTextureWebPExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.EXT_TEXTURE_WEBP;\n\n\t}\n\n\tloadTexture( textureIndex ) {\n\n\t\tconst name = this.name;\n\t\tconst parser = this.parser;\n\t\tconst json = parser.json;\n\n\t\tconst textureDef = json.textures[ textureIndex ];\n\n\t\tif ( ! textureDef.extensions || ! textureDef.extensions[ name ] ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst extension = textureDef.extensions[ name ];\n\t\tconst source = json.images[ extension.source ];\n\n\t\tlet loader = parser.textureLoader;\n\t\tif ( source.uri ) {\n\n\t\t\tconst handler = parser.options.manager.getHandler( source.uri );\n\t\t\tif ( handler !== null ) loader = handler;\n\n\t\t}\n\n\t\treturn parser.loadTextureImage( textureIndex, extension.source, loader );\n\n\t}\n\n}\n\n/**\n * AVIF Texture Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_texture_avif\n *\n * @private\n */\nclass GLTFTextureAVIFExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.EXT_TEXTURE_AVIF;\n\n\t}\n\n\tloadTexture( textureIndex ) {\n\n\t\tconst name = this.name;\n\t\tconst parser = this.parser;\n\t\tconst json = parser.json;\n\n\t\tconst textureDef = json.textures[ textureIndex ];\n\n\t\tif ( ! textureDef.extensions || ! textureDef.extensions[ name ] ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst extension = textureDef.extensions[ name ];\n\t\tconst source = json.images[ extension.source ];\n\n\t\tlet loader = parser.textureLoader;\n\t\tif ( source.uri ) {\n\n\t\t\tconst handler = parser.options.manager.getHandler( source.uri );\n\t\t\tif ( handler !== null ) loader = handler;\n\n\t\t}\n\n\t\treturn parser.loadTextureImage( textureIndex, extension.source, loader );\n\n\t}\n\n}\n\n/**\n * meshopt BufferView Compression Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_meshopt_compression\n *\n * @private\n */\nclass GLTFMeshoptCompression {\n\n\tconstructor( parser ) {\n\n\t\tthis.name = EXTENSIONS.EXT_MESHOPT_COMPRESSION;\n\t\tthis.parser = parser;\n\n\t}\n\n\tloadBufferView( index ) {\n\n\t\tconst json = this.parser.json;\n\t\tconst bufferView = json.bufferViews[ index ];\n\n\t\tif ( bufferView.extensions && bufferView.extensions[ this.name ] ) {\n\n\t\t\tconst extensionDef = bufferView.extensions[ this.name ];\n\n\t\t\tconst buffer = this.parser.getDependency( 'buffer', extensionDef.buffer );\n\t\t\tconst decoder = this.parser.options.meshoptDecoder;\n\n\t\t\tif ( ! decoder || ! decoder.supported ) {\n\n\t\t\t\tif ( json.extensionsRequired && json.extensionsRequired.indexOf( this.name ) >= 0 ) {\n\n\t\t\t\t\tthrow new Error( 'THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files' );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Assumes that the extension is optional and that fallback buffer data is present\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn buffer.then( function ( res ) {\n\n\t\t\t\tconst byteOffset = extensionDef.byteOffset || 0;\n\t\t\t\tconst byteLength = extensionDef.byteLength || 0;\n\n\t\t\t\tconst count = extensionDef.count;\n\t\t\t\tconst stride = extensionDef.byteStride;\n\n\t\t\t\tconst source = new Uint8Array( res, byteOffset, byteLength );\n\n\t\t\t\tif ( decoder.decodeGltfBufferAsync ) {\n\n\t\t\t\t\treturn decoder.decodeGltfBufferAsync( count, stride, source, extensionDef.mode, extensionDef.filter ).then( function ( res ) {\n\n\t\t\t\t\t\treturn res.buffer;\n\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Support for MeshoptDecoder 0.18 or earlier, without decodeGltfBufferAsync\n\t\t\t\t\treturn decoder.ready.then( function () {\n\n\t\t\t\t\t\tconst result = new ArrayBuffer( count * stride );\n\t\t\t\t\t\tdecoder.decodeGltfBuffer( new Uint8Array( result ), count, stride, source, extensionDef.mode, extensionDef.filter );\n\t\t\t\t\t\treturn result;\n\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t} else {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t}\n\n}\n\n/**\n * GPU Instancing Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_mesh_gpu_instancing\n *\n * @private\n */\nclass GLTFMeshGpuInstancing {\n\n\tconstructor( parser ) {\n\n\t\tthis.name = EXTENSIONS.EXT_MESH_GPU_INSTANCING;\n\t\tthis.parser = parser;\n\n\t}\n\n\tcreateNodeMesh( nodeIndex ) {\n\n\t\tconst json = this.parser.json;\n\t\tconst nodeDef = json.nodes[ nodeIndex ];\n\n\t\tif ( ! nodeDef.extensions || ! nodeDef.extensions[ this.name ] ||\n\t\t\tnodeDef.mesh === undefined ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst meshDef = json.meshes[ nodeDef.mesh ];\n\n\t\t// No Points or Lines + Instancing support yet\n\n\t\tfor ( const primitive of meshDef.primitives ) {\n\n\t\t\tif ( primitive.mode !== WEBGL_CONSTANTS.TRIANGLES &&\n\t\t\t\t primitive.mode !== WEBGL_CONSTANTS.TRIANGLE_STRIP &&\n\t\t\t\t primitive.mode !== WEBGL_CONSTANTS.TRIANGLE_FAN &&\n\t\t\t\t primitive.mode !== undefined ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst extensionDef = nodeDef.extensions[ this.name ];\n\t\tconst attributesDef = extensionDef.attributes;\n\n\t\t// @TODO: Can we support InstancedMesh + SkinnedMesh?\n\n\t\tconst pending = [];\n\t\tconst attributes = {};\n\n\t\tfor ( const key in attributesDef ) {\n\n\t\t\tpending.push( this.parser.getDependency( 'accessor', attributesDef[ key ] ).then( accessor => {\n\n\t\t\t\tattributes[ key ] = accessor;\n\t\t\t\treturn attributes[ key ];\n\n\t\t\t} ) );\n\n\t\t}\n\n\t\tif ( pending.length < 1 ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tpending.push( this.parser.createNodeMesh( nodeIndex ) );\n\n\t\treturn Promise.all( pending ).then( results => {\n\n\t\t\tconst nodeObject = results.pop();\n\t\t\tconst meshes = nodeObject.isGroup ? nodeObject.children : [ nodeObject ];\n\t\t\tconst count = results[ 0 ].count; // All attribute counts should be same\n\t\t\tconst instancedMeshes = [];\n\n\t\t\tfor ( const mesh of meshes ) {\n\n\t\t\t\t// Temporal variables\n\t\t\t\tconst m = new Matrix4();\n\t\t\t\tconst p = new Vector3();\n\t\t\t\tconst q = new Quaternion();\n\t\t\t\tconst s = new Vector3( 1, 1, 1 );\n\n\t\t\t\tconst instancedMesh = new InstancedMesh( mesh.geometry, mesh.material, count );\n\n\t\t\t\tfor ( let i = 0; i < count; i ++ ) {\n\n\t\t\t\t\tif ( attributes.TRANSLATION ) {\n\n\t\t\t\t\t\tp.fromBufferAttribute( attributes.TRANSLATION, i );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( attributes.ROTATION ) {\n\n\t\t\t\t\t\tq.fromBufferAttribute( attributes.ROTATION, i );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( attributes.SCALE ) {\n\n\t\t\t\t\t\ts.fromBufferAttribute( attributes.SCALE, i );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tinstancedMesh.setMatrixAt( i, m.compose( p, q, s ) );\n\n\t\t\t\t}\n\n\t\t\t\t// Add instance attributes to the geometry, excluding TRS.\n\t\t\t\tfor ( const attributeName in attributes ) {\n\n\t\t\t\t\tif ( attributeName === '_COLOR_0' ) {\n\n\t\t\t\t\t\tconst attr = attributes[ attributeName ];\n\t\t\t\t\t\tinstancedMesh.instanceColor = new InstancedBufferAttribute( attr.array, attr.itemSize, attr.normalized );\n\n\t\t\t\t\t} else if ( attributeName !== 'TRANSLATION' &&\n\t\t\t\t\t\t attributeName !== 'ROTATION' &&\n\t\t\t\t\t\t attributeName !== 'SCALE' ) {\n\n\t\t\t\t\t\tmesh.geometry.setAttribute( attributeName, attributes[ attributeName ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Just in case\n\t\t\t\tObject3D.prototype.copy.call( instancedMesh, mesh );\n\n\t\t\t\tthis.parser.assignFinalMaterial( instancedMesh );\n\n\t\t\t\tinstancedMeshes.push( instancedMesh );\n\n\t\t\t}\n\n\t\t\tif ( nodeObject.isGroup ) {\n\n\t\t\t\tnodeObject.clear();\n\n\t\t\t\tnodeObject.add( ... instancedMeshes );\n\n\t\t\t\treturn nodeObject;\n\n\t\t\t}\n\n\t\t\treturn instancedMeshes[ 0 ];\n\n\t\t} );\n\n\t}\n\n}\n\n/* BINARY EXTENSION */\nconst BINARY_EXTENSION_HEADER_MAGIC = 'glTF';\nconst BINARY_EXTENSION_HEADER_LENGTH = 12;\nconst BINARY_EXTENSION_CHUNK_TYPES = { JSON: 0x4E4F534A, BIN: 0x004E4942 };\n\nclass GLTFBinaryExtension {\n\n\tconstructor( data ) {\n\n\t\tthis.name = EXTENSIONS.KHR_BINARY_GLTF;\n\t\tthis.content = null;\n\t\tthis.body = null;\n\n\t\tconst headerView = new DataView( data, 0, BINARY_EXTENSION_HEADER_LENGTH );\n\t\tconst textDecoder = new TextDecoder();\n\n\t\tthis.header = {\n\t\t\tmagic: textDecoder.decode( new Uint8Array( data.slice( 0, 4 ) ) ),\n\t\t\tversion: headerView.getUint32( 4, true ),\n\t\t\tlength: headerView.getUint32( 8, true )\n\t\t};\n\n\t\tif ( this.header.magic !== BINARY_EXTENSION_HEADER_MAGIC ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: Unsupported glTF-Binary header.' );\n\n\t\t} else if ( this.header.version < 2.0 ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: Legacy binary file detected.' );\n\n\t\t}\n\n\t\tconst chunkContentsLength = this.header.length - BINARY_EXTENSION_HEADER_LENGTH;\n\t\tconst chunkView = new DataView( data, BINARY_EXTENSION_HEADER_LENGTH );\n\t\tlet chunkIndex = 0;\n\n\t\twhile ( chunkIndex < chunkContentsLength ) {\n\n\t\t\tconst chunkLength = chunkView.getUint32( chunkIndex, true );\n\t\t\tchunkIndex += 4;\n\n\t\t\tconst chunkType = chunkView.getUint32( chunkIndex, true );\n\t\t\tchunkIndex += 4;\n\n\t\t\tif ( chunkType === BINARY_EXTENSION_CHUNK_TYPES.JSON ) {\n\n\t\t\t\tconst contentArray = new Uint8Array( data, BINARY_EXTENSION_HEADER_LENGTH + chunkIndex, chunkLength );\n\t\t\t\tthis.content = textDecoder.decode( contentArray );\n\n\t\t\t} else if ( chunkType === BINARY_EXTENSION_CHUNK_TYPES.BIN ) {\n\n\t\t\t\tconst byteOffset = BINARY_EXTENSION_HEADER_LENGTH + chunkIndex;\n\t\t\t\tthis.body = data.slice( byteOffset, byteOffset + chunkLength );\n\n\t\t\t}\n\n\t\t\t// Clients must ignore chunks with unknown types.\n\n\t\t\tchunkIndex += chunkLength;\n\n\t\t}\n\n\t\tif ( this.content === null ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: JSON content not found.' );\n\n\t\t}\n\n\t}\n\n}\n\n/**\n * DRACO Mesh Compression Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression\n *\n * @private\n */\nclass GLTFDracoMeshCompressionExtension {\n\n\tconstructor( json, dracoLoader ) {\n\n\t\tif ( ! dracoLoader ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: No DRACOLoader instance provided.' );\n\n\t\t}\n\n\t\tthis.name = EXTENSIONS.KHR_DRACO_MESH_COMPRESSION;\n\t\tthis.json = json;\n\t\tthis.dracoLoader = dracoLoader;\n\t\tthis.dracoLoader.preload();\n\n\t}\n\n\tdecodePrimitive( primitive, parser ) {\n\n\t\tconst json = this.json;\n\t\tconst dracoLoader = this.dracoLoader;\n\t\tconst bufferViewIndex = primitive.extensions[ this.name ].bufferView;\n\t\tconst gltfAttributeMap = primitive.extensions[ this.name ].attributes;\n\t\tconst threeAttributeMap = {};\n\t\tconst attributeNormalizedMap = {};\n\t\tconst attributeTypeMap = {};\n\n\t\tfor ( const attributeName in gltfAttributeMap ) {\n\n\t\t\tconst threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase();\n\n\t\t\tthreeAttributeMap[ threeAttributeName ] = gltfAttributeMap[ attributeName ];\n\n\t\t}\n\n\t\tfor ( const attributeName in primitive.attributes ) {\n\n\t\t\tconst threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase();\n\n\t\t\tif ( gltfAttributeMap[ attributeName ] !== undefined ) {\n\n\t\t\t\tconst accessorDef = json.accessors[ primitive.attributes[ attributeName ] ];\n\t\t\t\tconst componentType = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];\n\n\t\t\t\tattributeTypeMap[ threeAttributeName ] = componentType.name;\n\t\t\t\tattributeNormalizedMap[ threeAttributeName ] = accessorDef.normalized === true;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn parser.getDependency( 'bufferView', bufferViewIndex ).then( function ( bufferView ) {\n\n\t\t\treturn new Promise( function ( resolve, reject ) {\n\n\t\t\t\tdracoLoader.decodeDracoFile( bufferView, function ( geometry ) {\n\n\t\t\t\t\tfor ( const attributeName in geometry.attributes ) {\n\n\t\t\t\t\t\tconst attribute = geometry.attributes[ attributeName ];\n\t\t\t\t\t\tconst normalized = attributeNormalizedMap[ attributeName ];\n\n\t\t\t\t\t\tif ( normalized !== undefined ) attribute.normalized = normalized;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve( geometry );\n\n\t\t\t\t}, threeAttributeMap, attributeTypeMap, LinearSRGBColorSpace, reject );\n\n\t\t\t} );\n\n\t\t} );\n\n\t}\n\n}\n\n/**\n * Texture Transform Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_transform\n *\n * @private\n */\nclass GLTFTextureTransformExtension {\n\n\tconstructor() {\n\n\t\tthis.name = EXTENSIONS.KHR_TEXTURE_TRANSFORM;\n\n\t}\n\n\textendTexture( texture, transform ) {\n\n\t\tif ( ( transform.texCoord === undefined || transform.texCoord === texture.channel )\n\t\t\t&& transform.offset === undefined\n\t\t\t&& transform.rotation === undefined\n\t\t\t&& transform.scale === undefined ) {\n\n\t\t\t// See https://github.com/mrdoob/three.js/issues/21819.\n\t\t\treturn texture;\n\n\t\t}\n\n\t\ttexture = texture.clone();\n\n\t\tif ( transform.texCoord !== undefined ) {\n\n\t\t\ttexture.channel = transform.texCoord;\n\n\t\t}\n\n\t\tif ( transform.offset !== undefined ) {\n\n\t\t\ttexture.offset.fromArray( transform.offset );\n\n\t\t}\n\n\t\tif ( transform.rotation !== undefined ) {\n\n\t\t\ttexture.rotation = transform.rotation;\n\n\t\t}\n\n\t\tif ( transform.scale !== undefined ) {\n\n\t\t\ttexture.repeat.fromArray( transform.scale );\n\n\t\t}\n\n\t\ttexture.needsUpdate = true;\n\n\t\treturn texture;\n\n\t}\n\n}\n\n/**\n * Mesh Quantization Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization\n *\n * @private\n */\nclass GLTFMeshQuantizationExtension {\n\n\tconstructor() {\n\n\t\tthis.name = EXTENSIONS.KHR_MESH_QUANTIZATION;\n\n\t}\n\n}\n\n/*********************************/\n/********** INTERPOLATION ********/\n/*********************************/\n\n// Spline Interpolation\n// Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#appendix-c-spline-interpolation\nclass GLTFCubicSplineInterpolant extends Interpolant {\n\n\tconstructor( parameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tsuper( parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tcopySampleValue_( index ) {\n\n\t\t// Copies a sample value to the result buffer. See description of glTF\n\t\t// CUBICSPLINE values layout in interpolate_() function below.\n\n\t\tconst result = this.resultBuffer,\n\t\t\tvalues = this.sampleValues,\n\t\t\tvalueSize = this.valueSize,\n\t\t\toffset = index * valueSize * 3 + valueSize;\n\n\t\tfor ( let i = 0; i !== valueSize; i ++ ) {\n\n\t\t\tresult[ i ] = values[ offset + i ];\n\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n\tinterpolate_( i1, t0, t, t1 ) {\n\n\t\tconst result = this.resultBuffer;\n\t\tconst values = this.sampleValues;\n\t\tconst stride = this.valueSize;\n\n\t\tconst stride2 = stride * 2;\n\t\tconst stride3 = stride * 3;\n\n\t\tconst td = t1 - t0;\n\n\t\tconst p = ( t - t0 ) / td;\n\t\tconst pp = p * p;\n\t\tconst ppp = pp * p;\n\n\t\tconst offset1 = i1 * stride3;\n\t\tconst offset0 = offset1 - stride3;\n\n\t\tconst s2 = - 2 * ppp + 3 * pp;\n\t\tconst s3 = ppp - pp;\n\t\tconst s0 = 1 - s2;\n\t\tconst s1 = s3 - pp + p;\n\n\t\t// Layout of keyframe output values for CUBICSPLINE animations:\n\t\t//   [ inTangent_1, splineVertex_1, outTangent_1, inTangent_2, splineVertex_2, ... ]\n\t\tfor ( let i = 0; i !== stride; i ++ ) {\n\n\t\t\tconst p0 = values[ offset0 + i + stride ]; // splineVertex_k\n\t\t\tconst m0 = values[ offset0 + i + stride2 ] * td; // outTangent_k * (t_k+1 - t_k)\n\t\t\tconst p1 = values[ offset1 + i + stride ]; // splineVertex_k+1\n\t\t\tconst m1 = values[ offset1 + i ] * td; // inTangent_k+1 * (t_k+1 - t_k)\n\n\t\t\tresult[ i ] = s0 * p0 + s1 * m0 + s2 * p1 + s3 * m1;\n\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n}\n\nconst _quaternion = new Quaternion();\n\nclass GLTFCubicSplineQuaternionInterpolant extends GLTFCubicSplineInterpolant {\n\n\tinterpolate_( i1, t0, t, t1 ) {\n\n\t\tconst result = super.interpolate_( i1, t0, t, t1 );\n\n\t\t_quaternion.fromArray( result ).normalize().toArray( result );\n\n\t\treturn result;\n\n\t}\n\n}\n\n\n/*********************************/\n/********** INTERNALS ************/\n/*********************************/\n\n/* CONSTANTS */\n\nconst WEBGL_CONSTANTS = {\n\tFLOAT: 5126,\n\t//FLOAT_MAT2: 35674,\n\tFLOAT_MAT3: 35675,\n\tFLOAT_MAT4: 35676,\n\tFLOAT_VEC2: 35664,\n\tFLOAT_VEC3: 35665,\n\tFLOAT_VEC4: 35666,\n\tLINEAR: 9729,\n\tREPEAT: 10497,\n\tSAMPLER_2D: 35678,\n\tPOINTS: 0,\n\tLINES: 1,\n\tLINE_LOOP: 2,\n\tLINE_STRIP: 3,\n\tTRIANGLES: 4,\n\tTRIANGLE_STRIP: 5,\n\tTRIANGLE_FAN: 6,\n\tUNSIGNED_BYTE: 5121,\n\tUNSIGNED_SHORT: 5123\n};\n\nconst WEBGL_COMPONENT_TYPES = {\n\t5120: Int8Array,\n\t5121: Uint8Array,\n\t5122: Int16Array,\n\t5123: Uint16Array,\n\t5125: Uint32Array,\n\t5126: Float32Array\n};\n\nconst WEBGL_FILTERS = {\n\t9728: NearestFilter,\n\t9729: LinearFilter,\n\t9984: NearestMipmapNearestFilter,\n\t9985: LinearMipmapNearestFilter,\n\t9986: NearestMipmapLinearFilter,\n\t9987: LinearMipmapLinearFilter\n};\n\nconst WEBGL_WRAPPINGS = {\n\t33071: ClampToEdgeWrapping,\n\t33648: MirroredRepeatWrapping,\n\t10497: RepeatWrapping\n};\n\nconst WEBGL_TYPE_SIZES = {\n\t'SCALAR': 1,\n\t'VEC2': 2,\n\t'VEC3': 3,\n\t'VEC4': 4,\n\t'MAT2': 4,\n\t'MAT3': 9,\n\t'MAT4': 16\n};\n\nconst ATTRIBUTES = {\n\tPOSITION: 'position',\n\tNORMAL: 'normal',\n\tTANGENT: 'tangent',\n\tTEXCOORD_0: 'uv',\n\tTEXCOORD_1: 'uv1',\n\tTEXCOORD_2: 'uv2',\n\tTEXCOORD_3: 'uv3',\n\tCOLOR_0: 'color',\n\tWEIGHTS_0: 'skinWeight',\n\tJOINTS_0: 'skinIndex',\n};\n\nconst PATH_PROPERTIES = {\n\tscale: 'scale',\n\ttranslation: 'position',\n\trotation: 'quaternion',\n\tweights: 'morphTargetInfluences'\n};\n\nconst INTERPOLATION = {\n\tCUBICSPLINE: undefined, // We use a custom interpolant (GLTFCubicSplineInterpolation) for CUBICSPLINE tracks. Each\n\t\t                        // keyframe track will be initialized with a default interpolation type, then modified.\n\tLINEAR: InterpolateLinear,\n\tSTEP: InterpolateDiscrete\n};\n\nconst ALPHA_MODES = {\n\tOPAQUE: 'OPAQUE',\n\tMASK: 'MASK',\n\tBLEND: 'BLEND'\n};\n\n/**\n * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#default-material\n *\n * @private\n * @param {Object<string, Material>} cache\n * @return {Material}\n */\nfunction createDefaultMaterial( cache ) {\n\n\tif ( cache[ 'DefaultMaterial' ] === undefined ) {\n\n\t\tcache[ 'DefaultMaterial' ] = new MeshStandardMaterial( {\n\t\t\tcolor: 0xFFFFFF,\n\t\t\temissive: 0x000000,\n\t\t\tmetalness: 1,\n\t\t\troughness: 1,\n\t\t\ttransparent: false,\n\t\t\tdepthTest: true,\n\t\t\tside: FrontSide\n\t\t} );\n\n\t}\n\n\treturn cache[ 'DefaultMaterial' ];\n\n}\n\nfunction addUnknownExtensionsToUserData( knownExtensions, object, objectDef ) {\n\n\t// Add unknown glTF extensions to an object's userData.\n\n\tfor ( const name in objectDef.extensions ) {\n\n\t\tif ( knownExtensions[ name ] === undefined ) {\n\n\t\t\tobject.userData.gltfExtensions = object.userData.gltfExtensions || {};\n\t\t\tobject.userData.gltfExtensions[ name ] = objectDef.extensions[ name ];\n\n\t\t}\n\n\t}\n\n}\n\n/**\n *\n * @private\n * @param {Object3D|Material|BufferGeometry|Object|AnimationClip} object\n * @param {GLTF.definition} gltfDef\n */\nfunction assignExtrasToUserData( object, gltfDef ) {\n\n\tif ( gltfDef.extras !== undefined ) {\n\n\t\tif ( typeof gltfDef.extras === 'object' ) {\n\n\t\t\tObject.assign( object.userData, gltfDef.extras );\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.GLTFLoader: Ignoring primitive type .extras, ' + gltfDef.extras );\n\n\t\t}\n\n\t}\n\n}\n\n/**\n * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#morph-targets\n *\n * @private\n * @param {BufferGeometry} geometry\n * @param {Array<GLTF.Target>} targets\n * @param {GLTFParser} parser\n * @return {Promise<BufferGeometry>}\n */\nfunction addMorphTargets( geometry, targets, parser ) {\n\n\tlet hasMorphPosition = false;\n\tlet hasMorphNormal = false;\n\tlet hasMorphColor = false;\n\n\tfor ( let i = 0, il = targets.length; i < il; i ++ ) {\n\n\t\tconst target = targets[ i ];\n\n\t\tif ( target.POSITION !== undefined ) hasMorphPosition = true;\n\t\tif ( target.NORMAL !== undefined ) hasMorphNormal = true;\n\t\tif ( target.COLOR_0 !== undefined ) hasMorphColor = true;\n\n\t\tif ( hasMorphPosition && hasMorphNormal && hasMorphColor ) break;\n\n\t}\n\n\tif ( ! hasMorphPosition && ! hasMorphNormal && ! hasMorphColor ) return Promise.resolve( geometry );\n\n\tconst pendingPositionAccessors = [];\n\tconst pendingNormalAccessors = [];\n\tconst pendingColorAccessors = [];\n\n\tfor ( let i = 0, il = targets.length; i < il; i ++ ) {\n\n\t\tconst target = targets[ i ];\n\n\t\tif ( hasMorphPosition ) {\n\n\t\t\tconst pendingAccessor = target.POSITION !== undefined\n\t\t\t\t? parser.getDependency( 'accessor', target.POSITION )\n\t\t\t\t: geometry.attributes.position;\n\n\t\t\tpendingPositionAccessors.push( pendingAccessor );\n\n\t\t}\n\n\t\tif ( hasMorphNormal ) {\n\n\t\t\tconst pendingAccessor = target.NORMAL !== undefined\n\t\t\t\t? parser.getDependency( 'accessor', target.NORMAL )\n\t\t\t\t: geometry.attributes.normal;\n\n\t\t\tpendingNormalAccessors.push( pendingAccessor );\n\n\t\t}\n\n\t\tif ( hasMorphColor ) {\n\n\t\t\tconst pendingAccessor = target.COLOR_0 !== undefined\n\t\t\t\t? parser.getDependency( 'accessor', target.COLOR_0 )\n\t\t\t\t: geometry.attributes.color;\n\n\t\t\tpendingColorAccessors.push( pendingAccessor );\n\n\t\t}\n\n\t}\n\n\treturn Promise.all( [\n\t\tPromise.all( pendingPositionAccessors ),\n\t\tPromise.all( pendingNormalAccessors ),\n\t\tPromise.all( pendingColorAccessors )\n\t] ).then( function ( accessors ) {\n\n\t\tconst morphPositions = accessors[ 0 ];\n\t\tconst morphNormals = accessors[ 1 ];\n\t\tconst morphColors = accessors[ 2 ];\n\n\t\tif ( hasMorphPosition ) geometry.morphAttributes.position = morphPositions;\n\t\tif ( hasMorphNormal ) geometry.morphAttributes.normal = morphNormals;\n\t\tif ( hasMorphColor ) geometry.morphAttributes.color = morphColors;\n\t\tgeometry.morphTargetsRelative = true;\n\n\t\treturn geometry;\n\n\t} );\n\n}\n\n/**\n *\n * @private\n * @param {Mesh} mesh\n * @param {GLTF.Mesh} meshDef\n */\nfunction updateMorphTargets( mesh, meshDef ) {\n\n\tmesh.updateMorphTargets();\n\n\tif ( meshDef.weights !== undefined ) {\n\n\t\tfor ( let i = 0, il = meshDef.weights.length; i < il; i ++ ) {\n\n\t\t\tmesh.morphTargetInfluences[ i ] = meshDef.weights[ i ];\n\n\t\t}\n\n\t}\n\n\t// .extras has user-defined data, so check that .extras.targetNames is an array.\n\tif ( meshDef.extras && Array.isArray( meshDef.extras.targetNames ) ) {\n\n\t\tconst targetNames = meshDef.extras.targetNames;\n\n\t\tif ( mesh.morphTargetInfluences.length === targetNames.length ) {\n\n\t\t\tmesh.morphTargetDictionary = {};\n\n\t\t\tfor ( let i = 0, il = targetNames.length; i < il; i ++ ) {\n\n\t\t\t\tmesh.morphTargetDictionary[ targetNames[ i ] ] = i;\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.' );\n\n\t\t}\n\n\t}\n\n}\n\nfunction createPrimitiveKey( primitiveDef ) {\n\n\tlet geometryKey;\n\n\tconst dracoExtension = primitiveDef.extensions && primitiveDef.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ];\n\n\tif ( dracoExtension ) {\n\n\t\tgeometryKey = 'draco:' + dracoExtension.bufferView\n\t\t\t\t+ ':' + dracoExtension.indices\n\t\t\t\t+ ':' + createAttributesKey( dracoExtension.attributes );\n\n\t} else {\n\n\t\tgeometryKey = primitiveDef.indices + ':' + createAttributesKey( primitiveDef.attributes ) + ':' + primitiveDef.mode;\n\n\t}\n\n\tif ( primitiveDef.targets !== undefined ) {\n\n\t\tfor ( let i = 0, il = primitiveDef.targets.length; i < il; i ++ ) {\n\n\t\t\tgeometryKey += ':' + createAttributesKey( primitiveDef.targets[ i ] );\n\n\t\t}\n\n\t}\n\n\treturn geometryKey;\n\n}\n\nfunction createAttributesKey( attributes ) {\n\n\tlet attributesKey = '';\n\n\tconst keys = Object.keys( attributes ).sort();\n\n\tfor ( let i = 0, il = keys.length; i < il; i ++ ) {\n\n\t\tattributesKey += keys[ i ] + ':' + attributes[ keys[ i ] ] + ';';\n\n\t}\n\n\treturn attributesKey;\n\n}\n\nfunction getNormalizedComponentScale( constructor ) {\n\n\t// Reference:\n\t// https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization#encoding-quantized-data\n\n\tswitch ( constructor ) {\n\n\t\tcase Int8Array:\n\t\t\treturn 1 / 127;\n\n\t\tcase Uint8Array:\n\t\t\treturn 1 / 255;\n\n\t\tcase Int16Array:\n\t\t\treturn 1 / 32767;\n\n\t\tcase Uint16Array:\n\t\t\treturn 1 / 65535;\n\n\t\tdefault:\n\t\t\tthrow new Error( 'THREE.GLTFLoader: Unsupported normalized accessor component type.' );\n\n\t}\n\n}\n\nfunction getImageURIMimeType( uri ) {\n\n\tif ( uri.search( /\\.jpe?g($|\\?)/i ) > 0 || uri.search( /^data\\:image\\/jpeg/ ) === 0 ) return 'image/jpeg';\n\tif ( uri.search( /\\.webp($|\\?)/i ) > 0 || uri.search( /^data\\:image\\/webp/ ) === 0 ) return 'image/webp';\n\tif ( uri.search( /\\.ktx2($|\\?)/i ) > 0 || uri.search( /^data\\:image\\/ktx2/ ) === 0 ) return 'image/ktx2';\n\n\treturn 'image/png';\n\n}\n\nconst _identityMatrix = new Matrix4();\n\n/* GLTF PARSER */\n\nclass GLTFParser {\n\n\tconstructor( json = {}, options = {} ) {\n\n\t\tthis.json = json;\n\t\tthis.extensions = {};\n\t\tthis.plugins = {};\n\t\tthis.options = options;\n\n\t\t// loader object cache\n\t\tthis.cache = new GLTFRegistry();\n\n\t\t// associations between Three.js objects and glTF elements\n\t\tthis.associations = new Map();\n\n\t\t// BufferGeometry caching\n\t\tthis.primitiveCache = {};\n\n\t\t// Node cache\n\t\tthis.nodeCache = {};\n\n\t\t// Object3D instance caches\n\t\tthis.meshCache = { refs: {}, uses: {} };\n\t\tthis.cameraCache = { refs: {}, uses: {} };\n\t\tthis.lightCache = { refs: {}, uses: {} };\n\n\t\tthis.sourceCache = {};\n\t\tthis.textureCache = {};\n\n\t\t// Track node names, to ensure no duplicates\n\t\tthis.nodeNamesUsed = {};\n\n\t\t// Use an ImageBitmapLoader if imageBitmaps are supported. Moves much of the\n\t\t// expensive work of uploading a texture to the GPU off the main thread.\n\n\t\tlet isSafari = false;\n\t\tlet safariVersion = - 1;\n\t\tlet isFirefox = false;\n\t\tlet firefoxVersion = - 1;\n\n\t\tif ( typeof navigator !== 'undefined' ) {\n\n\t\t\tconst userAgent = navigator.userAgent;\n\n\t\t\tisSafari = /^((?!chrome|android).)*safari/i.test( userAgent ) === true;\n\t\t\tconst safariMatch = userAgent.match( /Version\\/(\\d+)/ );\n\t\t\tsafariVersion = isSafari && safariMatch ? parseInt( safariMatch[ 1 ], 10 ) : - 1;\n\n\t\t\tisFirefox = userAgent.indexOf( 'Firefox' ) > - 1;\n\t\t\tfirefoxVersion = isFirefox ? userAgent.match( /Firefox\\/([0-9]+)\\./ )[ 1 ] : - 1;\n\n\t\t}\n\n\t\tif ( typeof createImageBitmap === 'undefined' || ( isSafari && safariVersion < 17 ) || ( isFirefox && firefoxVersion < 98 ) ) {\n\n\t\t\tthis.textureLoader = new TextureLoader( this.options.manager );\n\n\t\t} else {\n\n\t\t\tthis.textureLoader = new ImageBitmapLoader( this.options.manager );\n\n\t\t}\n\n\t\tthis.textureLoader.setCrossOrigin( this.options.crossOrigin );\n\t\tthis.textureLoader.setRequestHeader( this.options.requestHeader );\n\n\t\tthis.fileLoader = new FileLoader( this.options.manager );\n\t\tthis.fileLoader.setResponseType( 'arraybuffer' );\n\n\t\tif ( this.options.crossOrigin === 'use-credentials' ) {\n\n\t\t\tthis.fileLoader.setWithCredentials( true );\n\n\t\t}\n\n\t}\n\n\tsetExtensions( extensions ) {\n\n\t\tthis.extensions = extensions;\n\n\t}\n\n\tsetPlugins( plugins ) {\n\n\t\tthis.plugins = plugins;\n\n\t}\n\n\tparse( onLoad, onError ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\t\tconst extensions = this.extensions;\n\n\t\t// Clear the loader cache\n\t\tthis.cache.removeAll();\n\t\tthis.nodeCache = {};\n\n\t\t// Mark the special nodes/meshes in json for efficient parse\n\t\tthis._invokeAll( function ( ext ) {\n\n\t\t\treturn ext._markDefs && ext._markDefs();\n\n\t\t} );\n\n\t\tPromise.all( this._invokeAll( function ( ext ) {\n\n\t\t\treturn ext.beforeRoot && ext.beforeRoot();\n\n\t\t} ) ).then( function () {\n\n\t\t\treturn Promise.all( [\n\n\t\t\t\tparser.getDependencies( 'scene' ),\n\t\t\t\tparser.getDependencies( 'animation' ),\n\t\t\t\tparser.getDependencies( 'camera' ),\n\n\t\t\t] );\n\n\t\t} ).then( function ( dependencies ) {\n\n\t\t\tconst result = {\n\t\t\t\tscene: dependencies[ 0 ][ json.scene || 0 ],\n\t\t\t\tscenes: dependencies[ 0 ],\n\t\t\t\tanimations: dependencies[ 1 ],\n\t\t\t\tcameras: dependencies[ 2 ],\n\t\t\t\tasset: json.asset,\n\t\t\t\tparser: parser,\n\t\t\t\tuserData: {}\n\t\t\t};\n\n\t\t\taddUnknownExtensionsToUserData( extensions, result, json );\n\n\t\t\tassignExtrasToUserData( result, json );\n\n\t\t\treturn Promise.all( parser._invokeAll( function ( ext ) {\n\n\t\t\t\treturn ext.afterRoot && ext.afterRoot( result );\n\n\t\t\t} ) ).then( function () {\n\n\t\t\t\tfor ( const scene of result.scenes ) {\n\n\t\t\t\t\tscene.updateMatrixWorld();\n\n\t\t\t\t}\n\n\t\t\t\tonLoad( result );\n\n\t\t\t} );\n\n\t\t} ).catch( onError );\n\n\t}\n\n\t/**\n\t * Marks the special nodes/meshes in json for efficient parse.\n\t *\n\t * @private\n\t */\n\t_markDefs() {\n\n\t\tconst nodeDefs = this.json.nodes || [];\n\t\tconst skinDefs = this.json.skins || [];\n\t\tconst meshDefs = this.json.meshes || [];\n\n\t\t// Nothing in the node definition indicates whether it is a Bone or an\n\t\t// Object3D. Use the skins' joint references to mark bones.\n\t\tfor ( let skinIndex = 0, skinLength = skinDefs.length; skinIndex < skinLength; skinIndex ++ ) {\n\n\t\t\tconst joints = skinDefs[ skinIndex ].joints;\n\n\t\t\tfor ( let i = 0, il = joints.length; i < il; i ++ ) {\n\n\t\t\t\tnodeDefs[ joints[ i ] ].isBone = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Iterate over all nodes, marking references to shared resources,\n\t\t// as well as skeleton joints.\n\t\tfor ( let nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex ++ ) {\n\n\t\t\tconst nodeDef = nodeDefs[ nodeIndex ];\n\n\t\t\tif ( nodeDef.mesh !== undefined ) {\n\n\t\t\t\tthis._addNodeRef( this.meshCache, nodeDef.mesh );\n\n\t\t\t\t// Nothing in the mesh definition indicates whether it is\n\t\t\t\t// a SkinnedMesh or Mesh. Use the node's mesh reference\n\t\t\t\t// to mark SkinnedMesh if node has skin.\n\t\t\t\tif ( nodeDef.skin !== undefined ) {\n\n\t\t\t\t\tmeshDefs[ nodeDef.mesh ].isSkinnedMesh = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( nodeDef.camera !== undefined ) {\n\n\t\t\t\tthis._addNodeRef( this.cameraCache, nodeDef.camera );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Counts references to shared node / Object3D resources. These resources\n\t * can be reused, or \"instantiated\", at multiple nodes in the scene\n\t * hierarchy. Mesh, Camera, and Light instances are instantiated and must\n\t * be marked. Non-scenegraph resources (like Materials, Geometries, and\n\t * Textures) can be reused directly and are not marked here.\n\t *\n\t * Example: CesiumMilkTruck sample model reuses \"Wheel\" meshes.\n\t *\n\t * @private\n\t * @param {Object} cache\n\t * @param {Object3D} index\n\t */\n\t_addNodeRef( cache, index ) {\n\n\t\tif ( index === undefined ) return;\n\n\t\tif ( cache.refs[ index ] === undefined ) {\n\n\t\t\tcache.refs[ index ] = cache.uses[ index ] = 0;\n\n\t\t}\n\n\t\tcache.refs[ index ] ++;\n\n\t}\n\n\t/**\n\t * Returns a reference to a shared resource, cloning it if necessary.\n\t *\n\t * @private\n\t * @param {Object} cache\n\t * @param {number} index\n\t * @param {Object} object\n\t * @return {Object}\n\t */\n\t_getNodeRef( cache, index, object ) {\n\n\t\tif ( cache.refs[ index ] <= 1 ) return object;\n\n\t\tconst ref = object.clone();\n\n\t\t// Propagates mappings to the cloned object, prevents mappings on the\n\t\t// original object from being lost.\n\t\tconst updateMappings = ( original, clone ) => {\n\n\t\t\tconst mappings = this.associations.get( original );\n\t\t\tif ( mappings != null ) {\n\n\t\t\t\tthis.associations.set( clone, mappings );\n\n\t\t\t}\n\n\t\t\tfor ( const [ i, child ] of original.children.entries() ) {\n\n\t\t\t\tupdateMappings( child, clone.children[ i ] );\n\n\t\t\t}\n\n\t\t};\n\n\t\tupdateMappings( object, ref );\n\n\t\tref.name += '_instance_' + ( cache.uses[ index ] ++ );\n\n\t\treturn ref;\n\n\t}\n\n\t_invokeOne( func ) {\n\n\t\tconst extensions = Object.values( this.plugins );\n\t\textensions.push( this );\n\n\t\tfor ( let i = 0; i < extensions.length; i ++ ) {\n\n\t\t\tconst result = func( extensions[ i ] );\n\n\t\t\tif ( result ) return result;\n\n\t\t}\n\n\t\treturn null;\n\n\t}\n\n\t_invokeAll( func ) {\n\n\t\tconst extensions = Object.values( this.plugins );\n\t\textensions.unshift( this );\n\n\t\tconst pending = [];\n\n\t\tfor ( let i = 0; i < extensions.length; i ++ ) {\n\n\t\t\tconst result = func( extensions[ i ] );\n\n\t\t\tif ( result ) pending.push( result );\n\n\t\t}\n\n\t\treturn pending;\n\n\t}\n\n\t/**\n\t * Requests the specified dependency asynchronously, with caching.\n\t *\n\t * @private\n\t * @param {string} type\n\t * @param {number} index\n\t * @return {Promise<Object3D|Material|Texture|AnimationClip|ArrayBuffer|Object>}\n\t */\n\tgetDependency( type, index ) {\n\n\t\tconst cacheKey = type + ':' + index;\n\t\tlet dependency = this.cache.get( cacheKey );\n\n\t\tif ( ! dependency ) {\n\n\t\t\tswitch ( type ) {\n\n\t\t\t\tcase 'scene':\n\t\t\t\t\tdependency = this.loadScene( index );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'node':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadNode && ext.loadNode( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'mesh':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadMesh && ext.loadMesh( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'accessor':\n\t\t\t\t\tdependency = this.loadAccessor( index );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'bufferView':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadBufferView && ext.loadBufferView( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'buffer':\n\t\t\t\t\tdependency = this.loadBuffer( index );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'material':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadMaterial && ext.loadMaterial( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'texture':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadTexture && ext.loadTexture( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'skin':\n\t\t\t\t\tdependency = this.loadSkin( index );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'animation':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadAnimation && ext.loadAnimation( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'camera':\n\t\t\t\t\tdependency = this.loadCamera( index );\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext != this && ext.getDependency && ext.getDependency( type, index );\n\n\t\t\t\t\t} );\n\n\t\t\t\t\tif ( ! dependency ) {\n\n\t\t\t\t\t\tthrow new Error( 'Unknown type: ' + type );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tthis.cache.add( cacheKey, dependency );\n\n\t\t}\n\n\t\treturn dependency;\n\n\t}\n\n\t/**\n\t * Requests all dependencies of the specified type asynchronously, with caching.\n\t *\n\t * @private\n\t * @param {string} type\n\t * @return {Promise<Array<Object>>}\n\t */\n\tgetDependencies( type ) {\n\n\t\tlet dependencies = this.cache.get( type );\n\n\t\tif ( ! dependencies ) {\n\n\t\t\tconst parser = this;\n\t\t\tconst defs = this.json[ type + ( type === 'mesh' ? 'es' : 's' ) ] || [];\n\n\t\t\tdependencies = Promise.all( defs.map( function ( def, index ) {\n\n\t\t\t\treturn parser.getDependency( type, index );\n\n\t\t\t} ) );\n\n\t\t\tthis.cache.add( type, dependencies );\n\n\t\t}\n\n\t\treturn dependencies;\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views\n\t *\n\t * @private\n\t * @param {number} bufferIndex\n\t * @return {Promise<ArrayBuffer>}\n\t */\n\tloadBuffer( bufferIndex ) {\n\n\t\tconst bufferDef = this.json.buffers[ bufferIndex ];\n\t\tconst loader = this.fileLoader;\n\n\t\tif ( bufferDef.type && bufferDef.type !== 'arraybuffer' ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: ' + bufferDef.type + ' buffer type is not supported.' );\n\n\t\t}\n\n\t\t// If present, GLB container is required to be the first buffer.\n\t\tif ( bufferDef.uri === undefined && bufferIndex === 0 ) {\n\n\t\t\treturn Promise.resolve( this.extensions[ EXTENSIONS.KHR_BINARY_GLTF ].body );\n\n\t\t}\n\n\t\tconst options = this.options;\n\n\t\treturn new Promise( function ( resolve, reject ) {\n\n\t\t\tloader.load( LoaderUtils.resolveURL( bufferDef.uri, options.path ), resolve, undefined, function () {\n\n\t\t\t\treject( new Error( 'THREE.GLTFLoader: Failed to load buffer \"' + bufferDef.uri + '\".' ) );\n\n\t\t\t} );\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views\n\t *\n\t * @private\n\t * @param {number} bufferViewIndex\n\t * @return {Promise<ArrayBuffer>}\n\t */\n\tloadBufferView( bufferViewIndex ) {\n\n\t\tconst bufferViewDef = this.json.bufferViews[ bufferViewIndex ];\n\n\t\treturn this.getDependency( 'buffer', bufferViewDef.buffer ).then( function ( buffer ) {\n\n\t\t\tconst byteLength = bufferViewDef.byteLength || 0;\n\t\t\tconst byteOffset = bufferViewDef.byteOffset || 0;\n\t\t\treturn buffer.slice( byteOffset, byteOffset + byteLength );\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#accessors\n\t *\n\t * @private\n\t * @param {number} accessorIndex\n\t * @return {Promise<BufferAttribute|InterleavedBufferAttribute>}\n\t */\n\tloadAccessor( accessorIndex ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\n\t\tconst accessorDef = this.json.accessors[ accessorIndex ];\n\n\t\tif ( accessorDef.bufferView === undefined && accessorDef.sparse === undefined ) {\n\n\t\t\tconst itemSize = WEBGL_TYPE_SIZES[ accessorDef.type ];\n\t\t\tconst TypedArray = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];\n\t\t\tconst normalized = accessorDef.normalized === true;\n\n\t\t\tconst array = new TypedArray( accessorDef.count * itemSize );\n\t\t\treturn Promise.resolve( new BufferAttribute( array, itemSize, normalized ) );\n\n\t\t}\n\n\t\tconst pendingBufferViews = [];\n\n\t\tif ( accessorDef.bufferView !== undefined ) {\n\n\t\t\tpendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.bufferView ) );\n\n\t\t} else {\n\n\t\t\tpendingBufferViews.push( null );\n\n\t\t}\n\n\t\tif ( accessorDef.sparse !== undefined ) {\n\n\t\t\tpendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.sparse.indices.bufferView ) );\n\t\t\tpendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.sparse.values.bufferView ) );\n\n\t\t}\n\n\t\treturn Promise.all( pendingBufferViews ).then( function ( bufferViews ) {\n\n\t\t\tconst bufferView = bufferViews[ 0 ];\n\n\t\t\tconst itemSize = WEBGL_TYPE_SIZES[ accessorDef.type ];\n\t\t\tconst TypedArray = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];\n\n\t\t\t// For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.\n\t\t\tconst elementBytes = TypedArray.BYTES_PER_ELEMENT;\n\t\t\tconst itemBytes = elementBytes * itemSize;\n\t\t\tconst byteOffset = accessorDef.byteOffset || 0;\n\t\t\tconst byteStride = accessorDef.bufferView !== undefined ? json.bufferViews[ accessorDef.bufferView ].byteStride : undefined;\n\t\t\tconst normalized = accessorDef.normalized === true;\n\t\t\tlet array, bufferAttribute;\n\n\t\t\t// The buffer is not interleaved if the stride is the item size in bytes.\n\t\t\tif ( byteStride && byteStride !== itemBytes ) {\n\n\t\t\t\t// Each \"slice\" of the buffer, as defined by 'count' elements of 'byteStride' bytes, gets its own InterleavedBuffer\n\t\t\t\t// This makes sure that IBA.count reflects accessor.count properly\n\t\t\t\tconst ibSlice = Math.floor( byteOffset / byteStride );\n\t\t\t\tconst ibCacheKey = 'InterleavedBuffer:' + accessorDef.bufferView + ':' + accessorDef.componentType + ':' + ibSlice + ':' + accessorDef.count;\n\t\t\t\tlet ib = parser.cache.get( ibCacheKey );\n\n\t\t\t\tif ( ! ib ) {\n\n\t\t\t\t\tarray = new TypedArray( bufferView, ibSlice * byteStride, accessorDef.count * byteStride / elementBytes );\n\n\t\t\t\t\t// Integer parameters to IB/IBA are in array elements, not bytes.\n\t\t\t\t\tib = new InterleavedBuffer( array, byteStride / elementBytes );\n\n\t\t\t\t\tparser.cache.add( ibCacheKey, ib );\n\n\t\t\t\t}\n\n\t\t\t\tbufferAttribute = new InterleavedBufferAttribute( ib, itemSize, ( byteOffset % byteStride ) / elementBytes, normalized );\n\n\t\t\t} else {\n\n\t\t\t\tif ( bufferView === null ) {\n\n\t\t\t\t\tarray = new TypedArray( accessorDef.count * itemSize );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tarray = new TypedArray( bufferView, byteOffset, accessorDef.count * itemSize );\n\n\t\t\t\t}\n\n\t\t\t\tbufferAttribute = new BufferAttribute( array, itemSize, normalized );\n\n\t\t\t}\n\n\t\t\t// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#sparse-accessors\n\t\t\tif ( accessorDef.sparse !== undefined ) {\n\n\t\t\t\tconst itemSizeIndices = WEBGL_TYPE_SIZES.SCALAR;\n\t\t\t\tconst TypedArrayIndices = WEBGL_COMPONENT_TYPES[ accessorDef.sparse.indices.componentType ];\n\n\t\t\t\tconst byteOffsetIndices = accessorDef.sparse.indices.byteOffset || 0;\n\t\t\t\tconst byteOffsetValues = accessorDef.sparse.values.byteOffset || 0;\n\n\t\t\t\tconst sparseIndices = new TypedArrayIndices( bufferViews[ 1 ], byteOffsetIndices, accessorDef.sparse.count * itemSizeIndices );\n\t\t\t\tconst sparseValues = new TypedArray( bufferViews[ 2 ], byteOffsetValues, accessorDef.sparse.count * itemSize );\n\n\t\t\t\tif ( bufferView !== null ) {\n\n\t\t\t\t\t// Avoid modifying the original ArrayBuffer, if the bufferView wasn't initialized with zeroes.\n\t\t\t\t\tbufferAttribute = new BufferAttribute( bufferAttribute.array.slice(), bufferAttribute.itemSize, bufferAttribute.normalized );\n\n\t\t\t\t}\n\n\t\t\t\t// Ignore normalized since we copy from sparse\n\t\t\t\tbufferAttribute.normalized = false;\n\n\t\t\t\tfor ( let i = 0, il = sparseIndices.length; i < il; i ++ ) {\n\n\t\t\t\t\tconst index = sparseIndices[ i ];\n\n\t\t\t\t\tbufferAttribute.setX( index, sparseValues[ i * itemSize ] );\n\t\t\t\t\tif ( itemSize >= 2 ) bufferAttribute.setY( index, sparseValues[ i * itemSize + 1 ] );\n\t\t\t\t\tif ( itemSize >= 3 ) bufferAttribute.setZ( index, sparseValues[ i * itemSize + 2 ] );\n\t\t\t\t\tif ( itemSize >= 4 ) bufferAttribute.setW( index, sparseValues[ i * itemSize + 3 ] );\n\t\t\t\t\tif ( itemSize >= 5 ) throw new Error( 'THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.' );\n\n\t\t\t\t}\n\n\t\t\t\tbufferAttribute.normalized = normalized;\n\n\t\t\t}\n\n\t\t\treturn bufferAttribute;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#textures\n\t *\n\t * @private\n\t * @param {number} textureIndex\n\t * @return {Promise<?Texture>}\n\t */\n\tloadTexture( textureIndex ) {\n\n\t\tconst json = this.json;\n\t\tconst options = this.options;\n\t\tconst textureDef = json.textures[ textureIndex ];\n\t\tconst sourceIndex = textureDef.source;\n\t\tconst sourceDef = json.images[ sourceIndex ];\n\n\t\tlet loader = this.textureLoader;\n\n\t\tif ( sourceDef.uri ) {\n\n\t\t\tconst handler = options.manager.getHandler( sourceDef.uri );\n\t\t\tif ( handler !== null ) loader = handler;\n\n\t\t}\n\n\t\treturn this.loadTextureImage( textureIndex, sourceIndex, loader );\n\n\t}\n\n\tloadTextureImage( textureIndex, sourceIndex, loader ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\n\t\tconst textureDef = json.textures[ textureIndex ];\n\t\tconst sourceDef = json.images[ sourceIndex ];\n\n\t\tconst cacheKey = ( sourceDef.uri || sourceDef.bufferView ) + ':' + textureDef.sampler;\n\n\t\tif ( this.textureCache[ cacheKey ] ) {\n\n\t\t\t// See https://github.com/mrdoob/three.js/issues/21559.\n\t\t\treturn this.textureCache[ cacheKey ];\n\n\t\t}\n\n\t\tconst promise = this.loadImageSource( sourceIndex, loader ).then( function ( texture ) {\n\n\t\t\ttexture.flipY = false;\n\n\t\t\ttexture.name = textureDef.name || sourceDef.name || '';\n\n\t\t\tif ( texture.name === '' && typeof sourceDef.uri === 'string' && sourceDef.uri.startsWith( 'data:image/' ) === false ) {\n\n\t\t\t\ttexture.name = sourceDef.uri;\n\n\t\t\t}\n\n\t\t\tconst samplers = json.samplers || {};\n\t\t\tconst sampler = samplers[ textureDef.sampler ] || {};\n\n\t\t\ttexture.magFilter = WEBGL_FILTERS[ sampler.magFilter ] || LinearFilter;\n\t\t\ttexture.minFilter = WEBGL_FILTERS[ sampler.minFilter ] || LinearMipmapLinearFilter;\n\t\t\ttexture.wrapS = WEBGL_WRAPPINGS[ sampler.wrapS ] || RepeatWrapping;\n\t\t\ttexture.wrapT = WEBGL_WRAPPINGS[ sampler.wrapT ] || RepeatWrapping;\n\t\t\ttexture.generateMipmaps = ! texture.isCompressedTexture && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter;\n\n\t\t\tparser.associations.set( texture, { textures: textureIndex } );\n\n\t\t\treturn texture;\n\n\t\t} ).catch( function () {\n\n\t\t\treturn null;\n\n\t\t} );\n\n\t\tthis.textureCache[ cacheKey ] = promise;\n\n\t\treturn promise;\n\n\t}\n\n\tloadImageSource( sourceIndex, loader ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\t\tconst options = this.options;\n\n\t\tif ( this.sourceCache[ sourceIndex ] !== undefined ) {\n\n\t\t\treturn this.sourceCache[ sourceIndex ].then( ( texture ) => texture.clone() );\n\n\t\t}\n\n\t\tconst sourceDef = json.images[ sourceIndex ];\n\n\t\tconst URL = self.URL || self.webkitURL;\n\n\t\tlet sourceURI = sourceDef.uri || '';\n\t\tlet isObjectURL = false;\n\n\t\tif ( sourceDef.bufferView !== undefined ) {\n\n\t\t\t// Load binary image data from bufferView, if provided.\n\n\t\t\tsourceURI = parser.getDependency( 'bufferView', sourceDef.bufferView ).then( function ( bufferView ) {\n\n\t\t\t\tisObjectURL = true;\n\t\t\t\tconst blob = new Blob( [ bufferView ], { type: sourceDef.mimeType } );\n\t\t\t\tsourceURI = URL.createObjectURL( blob );\n\t\t\t\treturn sourceURI;\n\n\t\t\t} );\n\n\t\t} else if ( sourceDef.uri === undefined ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: Image ' + sourceIndex + ' is missing URI and bufferView' );\n\n\t\t}\n\n\t\tconst promise = Promise.resolve( sourceURI ).then( function ( sourceURI ) {\n\n\t\t\treturn new Promise( function ( resolve, reject ) {\n\n\t\t\t\tlet onLoad = resolve;\n\n\t\t\t\tif ( loader.isImageBitmapLoader === true ) {\n\n\t\t\t\t\tonLoad = function ( imageBitmap ) {\n\n\t\t\t\t\t\tconst texture = new Texture( imageBitmap );\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tresolve( texture );\n\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\tloader.load( LoaderUtils.resolveURL( sourceURI, options.path ), onLoad, undefined, reject );\n\n\t\t\t} );\n\n\t\t} ).then( function ( texture ) {\n\n\t\t\t// Clean up resources and configure Texture.\n\n\t\t\tif ( isObjectURL === true ) {\n\n\t\t\t\tURL.revokeObjectURL( sourceURI );\n\n\t\t\t}\n\n\t\t\tassignExtrasToUserData( texture, sourceDef );\n\n\t\t\ttexture.userData.mimeType = sourceDef.mimeType || getImageURIMimeType( sourceDef.uri );\n\n\t\t\treturn texture;\n\n\t\t} ).catch( function ( error ) {\n\n\t\t\tconsole.error( 'THREE.GLTFLoader: Couldn\\'t load texture', sourceURI );\n\t\t\tthrow error;\n\n\t\t} );\n\n\t\tthis.sourceCache[ sourceIndex ] = promise;\n\t\treturn promise;\n\n\t}\n\n\t/**\n\t * Asynchronously assigns a texture to the given material parameters.\n\t *\n\t * @private\n\t * @param {Object} materialParams\n\t * @param {string} mapName\n\t * @param {Object} mapDef\n\t * @param {string} [colorSpace]\n\t * @return {Promise<Texture>}\n\t */\n\tassignTexture( materialParams, mapName, mapDef, colorSpace ) {\n\n\t\tconst parser = this;\n\n\t\treturn this.getDependency( 'texture', mapDef.index ).then( function ( texture ) {\n\n\t\t\tif ( ! texture ) return null;\n\n\t\t\tif ( mapDef.texCoord !== undefined && mapDef.texCoord > 0 ) {\n\n\t\t\t\ttexture = texture.clone();\n\t\t\t\ttexture.channel = mapDef.texCoord;\n\n\t\t\t}\n\n\t\t\tif ( parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] ) {\n\n\t\t\t\tconst transform = mapDef.extensions !== undefined ? mapDef.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] : undefined;\n\n\t\t\t\tif ( transform ) {\n\n\t\t\t\t\tconst gltfReference = parser.associations.get( texture );\n\t\t\t\t\ttexture = parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ].extendTexture( texture, transform );\n\t\t\t\t\tparser.associations.set( texture, gltfReference );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( colorSpace !== undefined ) {\n\n\t\t\t\ttexture.colorSpace = colorSpace;\n\n\t\t\t}\n\n\t\t\tmaterialParams[ mapName ] = texture;\n\n\t\t\treturn texture;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Assigns final material to a Mesh, Line, or Points instance. The instance\n\t * already has a material (generated from the glTF material options alone)\n\t * but reuse of the same glTF material may require multiple threejs materials\n\t * to accommodate different primitive types, defines, etc. New materials will\n\t * be created if necessary, and reused from a cache.\n\t *\n\t * @private\n\t * @param {Object3D} mesh Mesh, Line, or Points instance.\n\t */\n\tassignFinalMaterial( mesh ) {\n\n\t\tconst geometry = mesh.geometry;\n\t\tlet material = mesh.material;\n\n\t\tconst useDerivativeTangents = geometry.attributes.tangent === undefined;\n\t\tconst useVertexColors = geometry.attributes.color !== undefined;\n\t\tconst useFlatShading = geometry.attributes.normal === undefined;\n\n\t\tif ( mesh.isPoints ) {\n\n\t\t\tconst cacheKey = 'PointsMaterial:' + material.uuid;\n\n\t\t\tlet pointsMaterial = this.cache.get( cacheKey );\n\n\t\t\tif ( ! pointsMaterial ) {\n\n\t\t\t\tpointsMaterial = new PointsMaterial();\n\t\t\t\tMaterial.prototype.copy.call( pointsMaterial, material );\n\t\t\t\tpointsMaterial.color.copy( material.color );\n\t\t\t\tpointsMaterial.map = material.map;\n\t\t\t\tpointsMaterial.sizeAttenuation = false; // glTF spec says points should be 1px\n\n\t\t\t\tthis.cache.add( cacheKey, pointsMaterial );\n\n\t\t\t}\n\n\t\t\tmaterial = pointsMaterial;\n\n\t\t} else if ( mesh.isLine ) {\n\n\t\t\tconst cacheKey = 'LineBasicMaterial:' + material.uuid;\n\n\t\t\tlet lineMaterial = this.cache.get( cacheKey );\n\n\t\t\tif ( ! lineMaterial ) {\n\n\t\t\t\tlineMaterial = new LineBasicMaterial();\n\t\t\t\tMaterial.prototype.copy.call( lineMaterial, material );\n\t\t\t\tlineMaterial.color.copy( material.color );\n\t\t\t\tlineMaterial.map = material.map;\n\n\t\t\t\tthis.cache.add( cacheKey, lineMaterial );\n\n\t\t\t}\n\n\t\t\tmaterial = lineMaterial;\n\n\t\t}\n\n\t\t// Clone the material if it will be modified\n\t\tif ( useDerivativeTangents || useVertexColors || useFlatShading ) {\n\n\t\t\tlet cacheKey = 'ClonedMaterial:' + material.uuid + ':';\n\n\t\t\tif ( useDerivativeTangents ) cacheKey += 'derivative-tangents:';\n\t\t\tif ( useVertexColors ) cacheKey += 'vertex-colors:';\n\t\t\tif ( useFlatShading ) cacheKey += 'flat-shading:';\n\n\t\t\tlet cachedMaterial = this.cache.get( cacheKey );\n\n\t\t\tif ( ! cachedMaterial ) {\n\n\t\t\t\tcachedMaterial = material.clone();\n\n\t\t\t\tif ( useVertexColors ) cachedMaterial.vertexColors = true;\n\t\t\t\tif ( useFlatShading ) cachedMaterial.flatShading = true;\n\n\t\t\t\tif ( useDerivativeTangents ) {\n\n\t\t\t\t\t// https://github.com/mrdoob/three.js/issues/11438#issuecomment-507003995\n\t\t\t\t\tif ( cachedMaterial.normalScale ) cachedMaterial.normalScale.y *= - 1;\n\t\t\t\t\tif ( cachedMaterial.clearcoatNormalScale ) cachedMaterial.clearcoatNormalScale.y *= - 1;\n\n\t\t\t\t}\n\n\t\t\t\tthis.cache.add( cacheKey, cachedMaterial );\n\n\t\t\t\tthis.associations.set( cachedMaterial, this.associations.get( material ) );\n\n\t\t\t}\n\n\t\t\tmaterial = cachedMaterial;\n\n\t\t}\n\n\t\tmesh.material = material;\n\n\t}\n\n\tgetMaterialType( /* materialIndex */ ) {\n\n\t\treturn MeshStandardMaterial;\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#materials\n\t *\n\t * @private\n\t * @param {number} materialIndex\n\t * @return {Promise<Material>}\n\t */\n\tloadMaterial( materialIndex ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\t\tconst extensions = this.extensions;\n\t\tconst materialDef = json.materials[ materialIndex ];\n\n\t\tlet materialType;\n\t\tconst materialParams = {};\n\t\tconst materialExtensions = materialDef.extensions || {};\n\n\t\tconst pending = [];\n\n\t\tif ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] ) {\n\n\t\t\tconst kmuExtension = extensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ];\n\t\t\tmaterialType = kmuExtension.getMaterialType();\n\t\t\tpending.push( kmuExtension.extendParams( materialParams, materialDef, parser ) );\n\n\t\t} else {\n\n\t\t\t// Specification:\n\t\t\t// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#metallic-roughness-material\n\n\t\t\tconst metallicRoughness = materialDef.pbrMetallicRoughness || {};\n\n\t\t\tmaterialParams.color = new Color( 1.0, 1.0, 1.0 );\n\t\t\tmaterialParams.opacity = 1.0;\n\n\t\t\tif ( Array.isArray( metallicRoughness.baseColorFactor ) ) {\n\n\t\t\t\tconst array = metallicRoughness.baseColorFactor;\n\n\t\t\t\tmaterialParams.color.setRGB( array[ 0 ], array[ 1 ], array[ 2 ], LinearSRGBColorSpace );\n\t\t\t\tmaterialParams.opacity = array[ 3 ];\n\n\t\t\t}\n\n\t\t\tif ( metallicRoughness.baseColorTexture !== undefined ) {\n\n\t\t\t\tpending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture, SRGBColorSpace ) );\n\n\t\t\t}\n\n\t\t\tmaterialParams.metalness = metallicRoughness.metallicFactor !== undefined ? metallicRoughness.metallicFactor : 1.0;\n\t\t\tmaterialParams.roughness = metallicRoughness.roughnessFactor !== undefined ? metallicRoughness.roughnessFactor : 1.0;\n\n\t\t\tif ( metallicRoughness.metallicRoughnessTexture !== undefined ) {\n\n\t\t\t\tpending.push( parser.assignTexture( materialParams, 'metalnessMap', metallicRoughness.metallicRoughnessTexture ) );\n\t\t\t\tpending.push( parser.assignTexture( materialParams, 'roughnessMap', metallicRoughness.metallicRoughnessTexture ) );\n\n\t\t\t}\n\n\t\t\tmaterialType = this._invokeOne( function ( ext ) {\n\n\t\t\t\treturn ext.getMaterialType && ext.getMaterialType( materialIndex );\n\n\t\t\t} );\n\n\t\t\tpending.push( Promise.all( this._invokeAll( function ( ext ) {\n\n\t\t\t\treturn ext.extendMaterialParams && ext.extendMaterialParams( materialIndex, materialParams );\n\n\t\t\t} ) ) );\n\n\t\t}\n\n\t\tif ( materialDef.doubleSided === true ) {\n\n\t\t\tmaterialParams.side = DoubleSide;\n\n\t\t}\n\n\t\tconst alphaMode = materialDef.alphaMode || ALPHA_MODES.OPAQUE;\n\n\t\tif ( alphaMode === ALPHA_MODES.BLEND ) {\n\n\t\t\tmaterialParams.transparent = true;\n\n\t\t\t// See: https://github.com/mrdoob/three.js/issues/17706\n\t\t\tmaterialParams.depthWrite = false;\n\n\t\t} else {\n\n\t\t\tmaterialParams.transparent = false;\n\n\t\t\tif ( alphaMode === ALPHA_MODES.MASK ) {\n\n\t\t\t\tmaterialParams.alphaTest = materialDef.alphaCutoff !== undefined ? materialDef.alphaCutoff : 0.5;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( materialDef.normalTexture !== undefined && materialType !== MeshBasicMaterial ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'normalMap', materialDef.normalTexture ) );\n\n\t\t\tmaterialParams.normalScale = new Vector2( 1, 1 );\n\n\t\t\tif ( materialDef.normalTexture.scale !== undefined ) {\n\n\t\t\t\tconst scale = materialDef.normalTexture.scale;\n\n\t\t\t\tmaterialParams.normalScale.set( scale, scale );\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( materialDef.occlusionTexture !== undefined && materialType !== MeshBasicMaterial ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'aoMap', materialDef.occlusionTexture ) );\n\n\t\t\tif ( materialDef.occlusionTexture.strength !== undefined ) {\n\n\t\t\t\tmaterialParams.aoMapIntensity = materialDef.occlusionTexture.strength;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( materialDef.emissiveFactor !== undefined && materialType !== MeshBasicMaterial ) {\n\n\t\t\tconst emissiveFactor = materialDef.emissiveFactor;\n\t\t\tmaterialParams.emissive = new Color().setRGB( emissiveFactor[ 0 ], emissiveFactor[ 1 ], emissiveFactor[ 2 ], LinearSRGBColorSpace );\n\n\t\t}\n\n\t\tif ( materialDef.emissiveTexture !== undefined && materialType !== MeshBasicMaterial ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture, SRGBColorSpace ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending ).then( function () {\n\n\t\t\tconst material = new materialType( materialParams );\n\n\t\t\tif ( materialDef.name ) material.name = materialDef.name;\n\n\t\t\tassignExtrasToUserData( material, materialDef );\n\n\t\t\tparser.associations.set( material, { materials: materialIndex } );\n\n\t\t\tif ( materialDef.extensions ) addUnknownExtensionsToUserData( extensions, material, materialDef );\n\n\t\t\treturn material;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * When Object3D instances are targeted by animation, they need unique names.\n\t *\n\t * @private\n\t * @param {string} originalName\n\t * @return {string}\n\t */\n\tcreateUniqueName( originalName ) {\n\n\t\tconst sanitizedName = PropertyBinding.sanitizeNodeName( originalName || '' );\n\n\t\tif ( sanitizedName in this.nodeNamesUsed ) {\n\n\t\t\treturn sanitizedName + '_' + ( ++ this.nodeNamesUsed[ sanitizedName ] );\n\n\t\t} else {\n\n\t\t\tthis.nodeNamesUsed[ sanitizedName ] = 0;\n\n\t\t\treturn sanitizedName;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#geometry\n\t *\n\t * Creates BufferGeometries from primitives.\n\t *\n\t * @private\n\t * @param {Array<GLTF.Primitive>} primitives\n\t * @return {Promise<Array<BufferGeometry>>}\n\t */\n\tloadGeometries( primitives ) {\n\n\t\tconst parser = this;\n\t\tconst extensions = this.extensions;\n\t\tconst cache = this.primitiveCache;\n\n\t\tfunction createDracoPrimitive( primitive ) {\n\n\t\t\treturn extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ]\n\t\t\t\t.decodePrimitive( primitive, parser )\n\t\t\t\t.then( function ( geometry ) {\n\n\t\t\t\t\treturn addPrimitiveAttributes( geometry, primitive, parser );\n\n\t\t\t\t} );\n\n\t\t}\n\n\t\tconst pending = [];\n\n\t\tfor ( let i = 0, il = primitives.length; i < il; i ++ ) {\n\n\t\t\tconst primitive = primitives[ i ];\n\t\t\tconst cacheKey = createPrimitiveKey( primitive );\n\n\t\t\t// See if we've already created this geometry\n\t\t\tconst cached = cache[ cacheKey ];\n\n\t\t\tif ( cached ) {\n\n\t\t\t\t// Use the cached geometry if it exists\n\t\t\t\tpending.push( cached.promise );\n\n\t\t\t} else {\n\n\t\t\t\tlet geometryPromise;\n\n\t\t\t\tif ( primitive.extensions && primitive.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] ) {\n\n\t\t\t\t\t// Use DRACO geometry if available\n\t\t\t\t\tgeometryPromise = createDracoPrimitive( primitive );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Otherwise create a new geometry\n\t\t\t\t\tgeometryPromise = addPrimitiveAttributes( new BufferGeometry(), primitive, parser );\n\n\t\t\t\t}\n\n\t\t\t\t// Cache this geometry\n\t\t\t\tcache[ cacheKey ] = { primitive: primitive, promise: geometryPromise };\n\n\t\t\t\tpending.push( geometryPromise );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#meshes\n\t *\n\t * @private\n\t * @param {number} meshIndex\n\t * @return {Promise<Group|Mesh|SkinnedMesh|Line|Points>}\n\t */\n\tloadMesh( meshIndex ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\t\tconst extensions = this.extensions;\n\n\t\tconst meshDef = json.meshes[ meshIndex ];\n\t\tconst primitives = meshDef.primitives;\n\n\t\tconst pending = [];\n\n\t\tfor ( let i = 0, il = primitives.length; i < il; i ++ ) {\n\n\t\t\tconst material = primitives[ i ].material === undefined\n\t\t\t\t? createDefaultMaterial( this.cache )\n\t\t\t\t: this.getDependency( 'material', primitives[ i ].material );\n\n\t\t\tpending.push( material );\n\n\t\t}\n\n\t\tpending.push( parser.loadGeometries( primitives ) );\n\n\t\treturn Promise.all( pending ).then( function ( results ) {\n\n\t\t\tconst materials = results.slice( 0, results.length - 1 );\n\t\t\tconst geometries = results[ results.length - 1 ];\n\n\t\t\tconst meshes = [];\n\n\t\t\tfor ( let i = 0, il = geometries.length; i < il; i ++ ) {\n\n\t\t\t\tconst geometry = geometries[ i ];\n\t\t\t\tconst primitive = primitives[ i ];\n\n\t\t\t\t// 1. create Mesh\n\n\t\t\t\tlet mesh;\n\n\t\t\t\tconst material = materials[ i ];\n\n\t\t\t\tif ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES ||\n\t\t\t\t\t\tprimitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ||\n\t\t\t\t\t\tprimitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ||\n\t\t\t\t\t\tprimitive.mode === undefined ) {\n\n\t\t\t\t\t// .isSkinnedMesh isn't in glTF spec. See ._markDefs()\n\t\t\t\t\tmesh = meshDef.isSkinnedMesh === true\n\t\t\t\t\t\t? new SkinnedMesh( geometry, material )\n\t\t\t\t\t\t: new Mesh( geometry, material );\n\n\t\t\t\t\tif ( mesh.isSkinnedMesh === true ) {\n\n\t\t\t\t\t\t// normalize skin weights to fix malformed assets (see #15319)\n\t\t\t\t\t\tmesh.normalizeSkinWeights();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ) {\n\n\t\t\t\t\t\tmesh.geometry = toTrianglesDrawMode( mesh.geometry, TriangleStripDrawMode );\n\n\t\t\t\t\t} else if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ) {\n\n\t\t\t\t\t\tmesh.geometry = toTrianglesDrawMode( mesh.geometry, TriangleFanDrawMode );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( primitive.mode === WEBGL_CONSTANTS.LINES ) {\n\n\t\t\t\t\tmesh = new LineSegments( geometry, material );\n\n\t\t\t\t} else if ( primitive.mode === WEBGL_CONSTANTS.LINE_STRIP ) {\n\n\t\t\t\t\tmesh = new Line( geometry, material );\n\n\t\t\t\t} else if ( primitive.mode === WEBGL_CONSTANTS.LINE_LOOP ) {\n\n\t\t\t\t\tmesh = new LineLoop( geometry, material );\n\n\t\t\t\t} else if ( primitive.mode === WEBGL_CONSTANTS.POINTS ) {\n\n\t\t\t\t\tmesh = new Points( geometry, material );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow new Error( 'THREE.GLTFLoader: Primitive mode unsupported: ' + primitive.mode );\n\n\t\t\t\t}\n\n\t\t\t\tif ( Object.keys( mesh.geometry.morphAttributes ).length > 0 ) {\n\n\t\t\t\t\tupdateMorphTargets( mesh, meshDef );\n\n\t\t\t\t}\n\n\t\t\t\tmesh.name = parser.createUniqueName( meshDef.name || ( 'mesh_' + meshIndex ) );\n\n\t\t\t\tassignExtrasToUserData( mesh, meshDef );\n\n\t\t\t\tif ( primitive.extensions ) addUnknownExtensionsToUserData( extensions, mesh, primitive );\n\n\t\t\t\tparser.assignFinalMaterial( mesh );\n\n\t\t\t\tmeshes.push( mesh );\n\n\t\t\t}\n\n\t\t\tfor ( let i = 0, il = meshes.length; i < il; i ++ ) {\n\n\t\t\t\tparser.associations.set( meshes[ i ], {\n\t\t\t\t\tmeshes: meshIndex,\n\t\t\t\t\tprimitives: i\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tif ( meshes.length === 1 ) {\n\n\t\t\t\tif ( meshDef.extensions ) addUnknownExtensionsToUserData( extensions, meshes[ 0 ], meshDef );\n\n\t\t\t\treturn meshes[ 0 ];\n\n\t\t\t}\n\n\t\t\tconst group = new Group();\n\n\t\t\tif ( meshDef.extensions ) addUnknownExtensionsToUserData( extensions, group, meshDef );\n\n\t\t\tparser.associations.set( group, { meshes: meshIndex } );\n\n\t\t\tfor ( let i = 0, il = meshes.length; i < il; i ++ ) {\n\n\t\t\t\tgroup.add( meshes[ i ] );\n\n\t\t\t}\n\n\t\t\treturn group;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#cameras\n\t *\n\t * @private\n\t * @param {number} cameraIndex\n\t * @return {Promise<Camera>|undefined}\n\t */\n\tloadCamera( cameraIndex ) {\n\n\t\tlet camera;\n\t\tconst cameraDef = this.json.cameras[ cameraIndex ];\n\t\tconst params = cameraDef[ cameraDef.type ];\n\n\t\tif ( ! params ) {\n\n\t\t\tconsole.warn( 'THREE.GLTFLoader: Missing camera parameters.' );\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( cameraDef.type === 'perspective' ) {\n\n\t\t\tcamera = new PerspectiveCamera( MathUtils.radToDeg( params.yfov ), params.aspectRatio || 1, params.znear || 1, params.zfar || 2e6 );\n\n\t\t} else if ( cameraDef.type === 'orthographic' ) {\n\n\t\t\tcamera = new OrthographicCamera( - params.xmag, params.xmag, params.ymag, - params.ymag, params.znear, params.zfar );\n\n\t\t}\n\n\t\tif ( cameraDef.name ) camera.name = this.createUniqueName( cameraDef.name );\n\n\t\tassignExtrasToUserData( camera, cameraDef );\n\n\t\treturn Promise.resolve( camera );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins\n\t *\n\t * @private\n\t * @param {number} skinIndex\n\t * @return {Promise<Skeleton>}\n\t */\n\tloadSkin( skinIndex ) {\n\n\t\tconst skinDef = this.json.skins[ skinIndex ];\n\n\t\tconst pending = [];\n\n\t\tfor ( let i = 0, il = skinDef.joints.length; i < il; i ++ ) {\n\n\t\t\tpending.push( this._loadNodeShallow( skinDef.joints[ i ] ) );\n\n\t\t}\n\n\t\tif ( skinDef.inverseBindMatrices !== undefined ) {\n\n\t\t\tpending.push( this.getDependency( 'accessor', skinDef.inverseBindMatrices ) );\n\n\t\t} else {\n\n\t\t\tpending.push( null );\n\n\t\t}\n\n\t\treturn Promise.all( pending ).then( function ( results ) {\n\n\t\t\tconst inverseBindMatrices = results.pop();\n\t\t\tconst jointNodes = results;\n\n\t\t\t// Note that bones (joint nodes) may or may not be in the\n\t\t\t// scene graph at this time.\n\n\t\t\tconst bones = [];\n\t\t\tconst boneInverses = [];\n\n\t\t\tfor ( let i = 0, il = jointNodes.length; i < il; i ++ ) {\n\n\t\t\t\tconst jointNode = jointNodes[ i ];\n\n\t\t\t\tif ( jointNode ) {\n\n\t\t\t\t\tbones.push( jointNode );\n\n\t\t\t\t\tconst mat = new Matrix4();\n\n\t\t\t\t\tif ( inverseBindMatrices !== null ) {\n\n\t\t\t\t\t\tmat.fromArray( inverseBindMatrices.array, i * 16 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tboneInverses.push( mat );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( 'THREE.GLTFLoader: Joint \"%s\" could not be found.', skinDef.joints[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn new Skeleton( bones, boneInverses );\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations\n\t *\n\t * @private\n\t * @param {number} animationIndex\n\t * @return {Promise<AnimationClip>}\n\t */\n\tloadAnimation( animationIndex ) {\n\n\t\tconst json = this.json;\n\t\tconst parser = this;\n\n\t\tconst animationDef = json.animations[ animationIndex ];\n\t\tconst animationName = animationDef.name ? animationDef.name : 'animation_' + animationIndex;\n\n\t\tconst pendingNodes = [];\n\t\tconst pendingInputAccessors = [];\n\t\tconst pendingOutputAccessors = [];\n\t\tconst pendingSamplers = [];\n\t\tconst pendingTargets = [];\n\n\t\tfor ( let i = 0, il = animationDef.channels.length; i < il; i ++ ) {\n\n\t\t\tconst channel = animationDef.channels[ i ];\n\t\t\tconst sampler = animationDef.samplers[ channel.sampler ];\n\t\t\tconst target = channel.target;\n\t\t\tconst name = target.node;\n\t\t\tconst input = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.input ] : sampler.input;\n\t\t\tconst output = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.output ] : sampler.output;\n\n\t\t\tif ( target.node === undefined ) continue;\n\n\t\t\tpendingNodes.push( this.getDependency( 'node', name ) );\n\t\t\tpendingInputAccessors.push( this.getDependency( 'accessor', input ) );\n\t\t\tpendingOutputAccessors.push( this.getDependency( 'accessor', output ) );\n\t\t\tpendingSamplers.push( sampler );\n\t\t\tpendingTargets.push( target );\n\n\t\t}\n\n\t\treturn Promise.all( [\n\n\t\t\tPromise.all( pendingNodes ),\n\t\t\tPromise.all( pendingInputAccessors ),\n\t\t\tPromise.all( pendingOutputAccessors ),\n\t\t\tPromise.all( pendingSamplers ),\n\t\t\tPromise.all( pendingTargets )\n\n\t\t] ).then( function ( dependencies ) {\n\n\t\t\tconst nodes = dependencies[ 0 ];\n\t\t\tconst inputAccessors = dependencies[ 1 ];\n\t\t\tconst outputAccessors = dependencies[ 2 ];\n\t\t\tconst samplers = dependencies[ 3 ];\n\t\t\tconst targets = dependencies[ 4 ];\n\n\t\t\tconst tracks = [];\n\n\t\t\tfor ( let i = 0, il = nodes.length; i < il; i ++ ) {\n\n\t\t\t\tconst node = nodes[ i ];\n\t\t\t\tconst inputAccessor = inputAccessors[ i ];\n\t\t\t\tconst outputAccessor = outputAccessors[ i ];\n\t\t\t\tconst sampler = samplers[ i ];\n\t\t\t\tconst target = targets[ i ];\n\n\t\t\t\tif ( node === undefined ) continue;\n\n\t\t\t\tif ( node.updateMatrix ) {\n\n\t\t\t\t\tnode.updateMatrix();\n\n\t\t\t\t}\n\n\t\t\t\tconst createdTracks = parser._createAnimationTracks( node, inputAccessor, outputAccessor, sampler, target );\n\n\t\t\t\tif ( createdTracks ) {\n\n\t\t\t\t\tfor ( let k = 0; k < createdTracks.length; k ++ ) {\n\n\t\t\t\t\t\ttracks.push( createdTracks[ k ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tconst animation = new AnimationClip( animationName, undefined, tracks );\n\n\t\t\tassignExtrasToUserData( animation, animationDef );\n\n\t\t\treturn animation;\n\n\t\t} );\n\n\t}\n\n\tcreateNodeMesh( nodeIndex ) {\n\n\t\tconst json = this.json;\n\t\tconst parser = this;\n\t\tconst nodeDef = json.nodes[ nodeIndex ];\n\n\t\tif ( nodeDef.mesh === undefined ) return null;\n\n\t\treturn parser.getDependency( 'mesh', nodeDef.mesh ).then( function ( mesh ) {\n\n\t\t\tconst node = parser._getNodeRef( parser.meshCache, nodeDef.mesh, mesh );\n\n\t\t\t// if weights are provided on the node, override weights on the mesh.\n\t\t\tif ( nodeDef.weights !== undefined ) {\n\n\t\t\t\tnode.traverse( function ( o ) {\n\n\t\t\t\t\tif ( ! o.isMesh ) return;\n\n\t\t\t\t\tfor ( let i = 0, il = nodeDef.weights.length; i < il; i ++ ) {\n\n\t\t\t\t\t\to.morphTargetInfluences[ i ] = nodeDef.weights[ i ];\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn node;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#nodes-and-hierarchy\n\t *\n\t * @private\n\t * @param {number} nodeIndex\n\t * @return {Promise<Object3D>}\n\t */\n\tloadNode( nodeIndex ) {\n\n\t\tconst json = this.json;\n\t\tconst parser = this;\n\n\t\tconst nodeDef = json.nodes[ nodeIndex ];\n\n\t\tconst nodePending = parser._loadNodeShallow( nodeIndex );\n\n\t\tconst childPending = [];\n\t\tconst childrenDef = nodeDef.children || [];\n\n\t\tfor ( let i = 0, il = childrenDef.length; i < il; i ++ ) {\n\n\t\t\tchildPending.push( parser.getDependency( 'node', childrenDef[ i ] ) );\n\n\t\t}\n\n\t\tconst skeletonPending = nodeDef.skin === undefined\n\t\t\t? Promise.resolve( null )\n\t\t\t: parser.getDependency( 'skin', nodeDef.skin );\n\n\t\treturn Promise.all( [\n\t\t\tnodePending,\n\t\t\tPromise.all( childPending ),\n\t\t\tskeletonPending\n\t\t] ).then( function ( results ) {\n\n\t\t\tconst node = results[ 0 ];\n\t\t\tconst children = results[ 1 ];\n\t\t\tconst skeleton = results[ 2 ];\n\n\t\t\tif ( skeleton !== null ) {\n\n\t\t\t\t// This full traverse should be fine because\n\t\t\t\t// child glTF nodes have not been added to this node yet.\n\t\t\t\tnode.traverse( function ( mesh ) {\n\n\t\t\t\t\tif ( ! mesh.isSkinnedMesh ) return;\n\n\t\t\t\t\tmesh.bind( skeleton, _identityMatrix );\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tfor ( let i = 0, il = children.length; i < il; i ++ ) {\n\n\t\t\t\tnode.add( children[ i ] );\n\n\t\t\t}\n\n\t\t\treturn node;\n\n\t\t} );\n\n\t}\n\n\t// ._loadNodeShallow() parses a single node.\n\t// skin and child nodes are created and added in .loadNode() (no '_' prefix).\n\t_loadNodeShallow( nodeIndex ) {\n\n\t\tconst json = this.json;\n\t\tconst extensions = this.extensions;\n\t\tconst parser = this;\n\n\t\t// This method is called from .loadNode() and .loadSkin().\n\t\t// Cache a node to avoid duplication.\n\n\t\tif ( this.nodeCache[ nodeIndex ] !== undefined ) {\n\n\t\t\treturn this.nodeCache[ nodeIndex ];\n\n\t\t}\n\n\t\tconst nodeDef = json.nodes[ nodeIndex ];\n\n\t\t// reserve node's name before its dependencies, so the root has the intended name.\n\t\tconst nodeName = nodeDef.name ? parser.createUniqueName( nodeDef.name ) : '';\n\n\t\tconst pending = [];\n\n\t\tconst meshPromise = parser._invokeOne( function ( ext ) {\n\n\t\t\treturn ext.createNodeMesh && ext.createNodeMesh( nodeIndex );\n\n\t\t} );\n\n\t\tif ( meshPromise ) {\n\n\t\t\tpending.push( meshPromise );\n\n\t\t}\n\n\t\tif ( nodeDef.camera !== undefined ) {\n\n\t\t\tpending.push( parser.getDependency( 'camera', nodeDef.camera ).then( function ( camera ) {\n\n\t\t\t\treturn parser._getNodeRef( parser.cameraCache, nodeDef.camera, camera );\n\n\t\t\t} ) );\n\n\t\t}\n\n\t\tparser._invokeAll( function ( ext ) {\n\n\t\t\treturn ext.createNodeAttachment && ext.createNodeAttachment( nodeIndex );\n\n\t\t} ).forEach( function ( promise ) {\n\n\t\t\tpending.push( promise );\n\n\t\t} );\n\n\t\tthis.nodeCache[ nodeIndex ] = Promise.all( pending ).then( function ( objects ) {\n\n\t\t\tlet node;\n\n\t\t\t// .isBone isn't in glTF spec. See ._markDefs\n\t\t\tif ( nodeDef.isBone === true ) {\n\n\t\t\t\tnode = new Bone();\n\n\t\t\t} else if ( objects.length > 1 ) {\n\n\t\t\t\tnode = new Group();\n\n\t\t\t} else if ( objects.length === 1 ) {\n\n\t\t\t\tnode = objects[ 0 ];\n\n\t\t\t} else {\n\n\t\t\t\tnode = new Object3D();\n\n\t\t\t}\n\n\t\t\tif ( node !== objects[ 0 ] ) {\n\n\t\t\t\tfor ( let i = 0, il = objects.length; i < il; i ++ ) {\n\n\t\t\t\t\tnode.add( objects[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( nodeDef.name ) {\n\n\t\t\t\tnode.userData.name = nodeDef.name;\n\t\t\t\tnode.name = nodeName;\n\n\t\t\t}\n\n\t\t\tassignExtrasToUserData( node, nodeDef );\n\n\t\t\tif ( nodeDef.extensions ) addUnknownExtensionsToUserData( extensions, node, nodeDef );\n\n\t\t\tif ( nodeDef.matrix !== undefined ) {\n\n\t\t\t\tconst matrix = new Matrix4();\n\t\t\t\tmatrix.fromArray( nodeDef.matrix );\n\t\t\t\tnode.applyMatrix4( matrix );\n\n\t\t\t} else {\n\n\t\t\t\tif ( nodeDef.translation !== undefined ) {\n\n\t\t\t\t\tnode.position.fromArray( nodeDef.translation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( nodeDef.rotation !== undefined ) {\n\n\t\t\t\t\tnode.quaternion.fromArray( nodeDef.rotation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( nodeDef.scale !== undefined ) {\n\n\t\t\t\t\tnode.scale.fromArray( nodeDef.scale );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( ! parser.associations.has( node ) ) {\n\n\t\t\t\tparser.associations.set( node, {} );\n\n\t\t\t} else if ( nodeDef.mesh !== undefined && parser.meshCache.refs[ nodeDef.mesh ] > 1 ) {\n\n\t\t\t\tconst mapping = parser.associations.get( node );\n\t\t\t\tparser.associations.set( node, { ...mapping } );\n\n\t\t\t}\n\n\t\t\tparser.associations.get( node ).nodes = nodeIndex;\n\n\t\t\treturn node;\n\n\t\t} );\n\n\t\treturn this.nodeCache[ nodeIndex ];\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#scenes\n\t *\n\t * @private\n\t * @param {number} sceneIndex\n\t * @return {Promise<Group>}\n\t */\n\tloadScene( sceneIndex ) {\n\n\t\tconst extensions = this.extensions;\n\t\tconst sceneDef = this.json.scenes[ sceneIndex ];\n\t\tconst parser = this;\n\n\t\t// Loader returns Group, not Scene.\n\t\t// See: https://github.com/mrdoob/three.js/issues/18342#issuecomment-578981172\n\t\tconst scene = new Group();\n\t\tif ( sceneDef.name ) scene.name = parser.createUniqueName( sceneDef.name );\n\n\t\tassignExtrasToUserData( scene, sceneDef );\n\n\t\tif ( sceneDef.extensions ) addUnknownExtensionsToUserData( extensions, scene, sceneDef );\n\n\t\tconst nodeIds = sceneDef.nodes || [];\n\n\t\tconst pending = [];\n\n\t\tfor ( let i = 0, il = nodeIds.length; i < il; i ++ ) {\n\n\t\t\tpending.push( parser.getDependency( 'node', nodeIds[ i ] ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending ).then( function ( nodes ) {\n\n\t\t\tfor ( let i = 0, il = nodes.length; i < il; i ++ ) {\n\n\t\t\t\tscene.add( nodes[ i ] );\n\n\t\t\t}\n\n\t\t\t// Removes dangling associations, associations that reference a node that\n\t\t\t// didn't make it into the scene.\n\t\t\tconst reduceAssociations = ( node ) => {\n\n\t\t\t\tconst reducedAssociations = new Map();\n\n\t\t\t\tfor ( const [ key, value ] of parser.associations ) {\n\n\t\t\t\t\tif ( key instanceof Material || key instanceof Texture ) {\n\n\t\t\t\t\t\treducedAssociations.set( key, value );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tnode.traverse( ( node ) => {\n\n\t\t\t\t\tconst mappings = parser.associations.get( node );\n\n\t\t\t\t\tif ( mappings != null ) {\n\n\t\t\t\t\t\treducedAssociations.set( node, mappings );\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\treturn reducedAssociations;\n\n\t\t\t};\n\n\t\t\tparser.associations = reduceAssociations( scene );\n\n\t\t\treturn scene;\n\n\t\t} );\n\n\t}\n\n\t_createAnimationTracks( node, inputAccessor, outputAccessor, sampler, target ) {\n\n\t\tconst tracks = [];\n\n\t\tconst targetName = node.name ? node.name : node.uuid;\n\t\tconst targetNames = [];\n\n\t\tif ( PATH_PROPERTIES[ target.path ] === PATH_PROPERTIES.weights ) {\n\n\t\t\tnode.traverse( function ( object ) {\n\n\t\t\t\tif ( object.morphTargetInfluences ) {\n\n\t\t\t\t\ttargetNames.push( object.name ? object.name : object.uuid );\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t} else {\n\n\t\t\ttargetNames.push( targetName );\n\n\t\t}\n\n\t\tlet TypedKeyframeTrack;\n\n\t\tswitch ( PATH_PROPERTIES[ target.path ] ) {\n\n\t\t\tcase PATH_PROPERTIES.weights:\n\n\t\t\t\tTypedKeyframeTrack = NumberKeyframeTrack;\n\t\t\t\tbreak;\n\n\t\t\tcase PATH_PROPERTIES.rotation:\n\n\t\t\t\tTypedKeyframeTrack = QuaternionKeyframeTrack;\n\t\t\t\tbreak;\n\n\t\t\tcase PATH_PROPERTIES.translation:\n\t\t\tcase PATH_PROPERTIES.scale:\n\n\t\t\t\tTypedKeyframeTrack = VectorKeyframeTrack;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\n\t\t\t\tswitch ( outputAccessor.itemSize ) {\n\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tTypedKeyframeTrack = NumberKeyframeTrack;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n\t\t\t\t\tcase 3:\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tTypedKeyframeTrack = VectorKeyframeTrack;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t}\n\n\t\tconst interpolation = sampler.interpolation !== undefined ? INTERPOLATION[ sampler.interpolation ] : InterpolateLinear;\n\n\n\t\tconst outputArray = this._getArrayFromAccessor( outputAccessor );\n\n\t\tfor ( let j = 0, jl = targetNames.length; j < jl; j ++ ) {\n\n\t\t\tconst track = new TypedKeyframeTrack(\n\t\t\t\ttargetNames[ j ] + '.' + PATH_PROPERTIES[ target.path ],\n\t\t\t\tinputAccessor.array,\n\t\t\t\toutputArray,\n\t\t\t\tinterpolation\n\t\t\t);\n\n\t\t\t// Override interpolation with custom factory method.\n\t\t\tif ( sampler.interpolation === 'CUBICSPLINE' ) {\n\n\t\t\t\tthis._createCubicSplineTrackInterpolant( track );\n\n\t\t\t}\n\n\t\t\ttracks.push( track );\n\n\t\t}\n\n\t\treturn tracks;\n\n\t}\n\n\t_getArrayFromAccessor( accessor ) {\n\n\t\tlet outputArray = accessor.array;\n\n\t\tif ( accessor.normalized ) {\n\n\t\t\tconst scale = getNormalizedComponentScale( outputArray.constructor );\n\t\t\tconst scaled = new Float32Array( outputArray.length );\n\n\t\t\tfor ( let j = 0, jl = outputArray.length; j < jl; j ++ ) {\n\n\t\t\t\tscaled[ j ] = outputArray[ j ] * scale;\n\n\t\t\t}\n\n\t\t\toutputArray = scaled;\n\n\t\t}\n\n\t\treturn outputArray;\n\n\t}\n\n\t_createCubicSplineTrackInterpolant( track ) {\n\n\t\ttrack.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline( result ) {\n\n\t\t\t// A CUBICSPLINE keyframe in glTF has three output values for each input value,\n\t\t\t// representing inTangent, splineVertex, and outTangent. As a result, track.getValueSize()\n\t\t\t// must be divided by three to get the interpolant's sampleSize argument.\n\n\t\t\tconst interpolantType = ( this instanceof QuaternionKeyframeTrack ) ? GLTFCubicSplineQuaternionInterpolant : GLTFCubicSplineInterpolant;\n\n\t\t\treturn new interpolantType( this.times, this.values, this.getValueSize() / 3, result );\n\n\t\t};\n\n\t\t// Mark as CUBICSPLINE. `track.getInterpolation()` doesn't support custom interpolants.\n\t\ttrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true;\n\n\t}\n\n}\n\n/**\n *\n * @private\n * @param {BufferGeometry} geometry\n * @param {GLTF.Primitive} primitiveDef\n * @param {GLTFParser} parser\n */\nfunction computeBounds( geometry, primitiveDef, parser ) {\n\n\tconst attributes = primitiveDef.attributes;\n\n\tconst box = new Box3();\n\n\tif ( attributes.POSITION !== undefined ) {\n\n\t\tconst accessor = parser.json.accessors[ attributes.POSITION ];\n\n\t\tconst min = accessor.min;\n\t\tconst max = accessor.max;\n\n\t\t// glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement.\n\n\t\tif ( min !== undefined && max !== undefined ) {\n\n\t\t\tbox.set(\n\t\t\t\tnew Vector3( min[ 0 ], min[ 1 ], min[ 2 ] ),\n\t\t\t\tnew Vector3( max[ 0 ], max[ 1 ], max[ 2 ] )\n\t\t\t);\n\n\t\t\tif ( accessor.normalized ) {\n\n\t\t\t\tconst boxScale = getNormalizedComponentScale( WEBGL_COMPONENT_TYPES[ accessor.componentType ] );\n\t\t\t\tbox.min.multiplyScalar( boxScale );\n\t\t\t\tbox.max.multiplyScalar( boxScale );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.GLTFLoader: Missing min/max properties for accessor POSITION.' );\n\n\t\t\treturn;\n\n\t\t}\n\n\t} else {\n\n\t\treturn;\n\n\t}\n\n\tconst targets = primitiveDef.targets;\n\n\tif ( targets !== undefined ) {\n\n\t\tconst maxDisplacement = new Vector3();\n\t\tconst vector = new Vector3();\n\n\t\tfor ( let i = 0, il = targets.length; i < il; i ++ ) {\n\n\t\t\tconst target = targets[ i ];\n\n\t\t\tif ( target.POSITION !== undefined ) {\n\n\t\t\t\tconst accessor = parser.json.accessors[ target.POSITION ];\n\t\t\t\tconst min = accessor.min;\n\t\t\t\tconst max = accessor.max;\n\n\t\t\t\t// glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement.\n\n\t\t\t\tif ( min !== undefined && max !== undefined ) {\n\n\t\t\t\t\t// we need to get max of absolute components because target weight is [-1,1]\n\t\t\t\t\tvector.setX( Math.max( Math.abs( min[ 0 ] ), Math.abs( max[ 0 ] ) ) );\n\t\t\t\t\tvector.setY( Math.max( Math.abs( min[ 1 ] ), Math.abs( max[ 1 ] ) ) );\n\t\t\t\t\tvector.setZ( Math.max( Math.abs( min[ 2 ] ), Math.abs( max[ 2 ] ) ) );\n\n\n\t\t\t\t\tif ( accessor.normalized ) {\n\n\t\t\t\t\t\tconst boxScale = getNormalizedComponentScale( WEBGL_COMPONENT_TYPES[ accessor.componentType ] );\n\t\t\t\t\t\tvector.multiplyScalar( boxScale );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Note: this assumes that the sum of all weights is at most 1. This isn't quite correct - it's more conservative\n\t\t\t\t\t// to assume that each target can have a max weight of 1. However, for some use cases - notably, when morph targets\n\t\t\t\t\t// are used to implement key-frame animations and as such only two are active at a time - this results in very large\n\t\t\t\t\t// boxes. So for now we make a box that's sometimes a touch too small but is hopefully mostly of reasonable size.\n\t\t\t\t\tmaxDisplacement.max( vector );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( 'THREE.GLTFLoader: Missing min/max properties for accessor POSITION.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// As per comment above this box isn't conservative, but has a reasonable size for a very large number of morph targets.\n\t\tbox.expandByVector( maxDisplacement );\n\n\t}\n\n\tgeometry.boundingBox = box;\n\n\tconst sphere = new Sphere();\n\n\tbox.getCenter( sphere.center );\n\tsphere.radius = box.min.distanceTo( box.max ) / 2;\n\n\tgeometry.boundingSphere = sphere;\n\n}\n\n/**\n *\n * @private\n * @param {BufferGeometry} geometry\n * @param {GLTF.Primitive} primitiveDef\n * @param {GLTFParser} parser\n * @return {Promise<BufferGeometry>}\n */\nfunction addPrimitiveAttributes( geometry, primitiveDef, parser ) {\n\n\tconst attributes = primitiveDef.attributes;\n\n\tconst pending = [];\n\n\tfunction assignAttributeAccessor( accessorIndex, attributeName ) {\n\n\t\treturn parser.getDependency( 'accessor', accessorIndex )\n\t\t\t.then( function ( accessor ) {\n\n\t\t\t\tgeometry.setAttribute( attributeName, accessor );\n\n\t\t\t} );\n\n\t}\n\n\tfor ( const gltfAttributeName in attributes ) {\n\n\t\tconst threeAttributeName = ATTRIBUTES[ gltfAttributeName ] || gltfAttributeName.toLowerCase();\n\n\t\t// Skip attributes already provided by e.g. Draco extension.\n\t\tif ( threeAttributeName in geometry.attributes ) continue;\n\n\t\tpending.push( assignAttributeAccessor( attributes[ gltfAttributeName ], threeAttributeName ) );\n\n\t}\n\n\tif ( primitiveDef.indices !== undefined && ! geometry.index ) {\n\n\t\tconst accessor = parser.getDependency( 'accessor', primitiveDef.indices ).then( function ( accessor ) {\n\n\t\t\tgeometry.setIndex( accessor );\n\n\t\t} );\n\n\t\tpending.push( accessor );\n\n\t}\n\n\tif ( ColorManagement.workingColorSpace !== LinearSRGBColorSpace && 'COLOR_0' in attributes ) {\n\n\t\tconsole.warn( `THREE.GLTFLoader: Converting vertex colors from \"srgb-linear\" to \"${ColorManagement.workingColorSpace}\" not supported.` );\n\n\t}\n\n\tassignExtrasToUserData( geometry, primitiveDef );\n\n\tcomputeBounds( geometry, primitiveDef, parser );\n\n\treturn Promise.all( pending ).then( function () {\n\n\t\treturn primitiveDef.targets !== undefined\n\t\t\t? addMorphTargets( geometry, primitiveDef.targets, parser )\n\t\t\t: geometry;\n\n\t} );\n\n}\n\n/**\n * Loader result of `GLTFLoader`.\n *\n * @typedef {Object} GLTFLoader~LoadObject\n * @property {Array<AnimationClip>} animations - An array of animation clips.\n * @property {Object} asset - Meta data about the loaded asset.\n * @property {Array<Camera>} cameras - An array of cameras.\n * @property {GLTFParser} parser - A reference to the internal parser.\n * @property {Group} scene - The default scene.\n * @property {Array<Group>} scenes - glTF assets might define multiple scenes.\n * @property {Object} userData - Additional data.\n **/\n\nexport { GLTFLoader };\n"]}