{"version":3,"file":"LWOLoader.cjs","sources":["../../src/loaders/LWOLoader.js"],"sourcesContent":["/**\n * @version 1.1.1\n *\n * @desc Load files in LWO3 and LWO2 format on Three.js\n *\n * LWO3 format specification:\n * \thttp://static.lightwave3d.com/sdk/2018/html/filefmts/lwo3.html\n *\n * LWO2 format specification:\n * \thttp://static.lightwave3d.com/sdk/2018/html/filefmts/lwo2.html\n *\n **/\n\nimport {\n  AddOperation,\n  BackSide,\n  BufferAttribute,\n  BufferGeometry,\n  ClampToEdgeWrapping,\n  Color,\n  DoubleSide,\n  EquirectangularReflectionMapping,\n  EquirectangularRefractionMapping,\n  FileLoader,\n  Float32BufferAttribute,\n  FrontSide,\n  LineBasicMaterial,\n  LineSegments,\n  Loader,\n  Mesh,\n  MeshPhongMaterial,\n  MeshPhysicalMaterial,\n  MeshStandardMaterial,\n  MirroredRepeatWrapping,\n  Points,\n  PointsMaterial,\n  RepeatWrapping,\n  TextureLoader,\n  Vector2,\n} from 'three'\n\nimport { IFFParser } from './lwo/IFFParser.js'\n\nlet _lwoTree\n\nclass LWOLoader extends Loader {\n  constructor(manager, parameters = {}) {\n    super(manager)\n\n    this.resourcePath = parameters.resourcePath !== undefined ? parameters.resourcePath : ''\n  }\n\n  load(url, onLoad, onProgress, onError) {\n    const scope = this\n\n    const path = scope.path === '' ? extractParentUrl(url, 'Objects') : scope.path\n\n    // give the mesh a default name based on the filename\n    const modelName = url.split(path).pop().split('.')[0]\n\n    const loader = new FileLoader(this.manager)\n    loader.setPath(scope.path)\n    loader.setResponseType('arraybuffer')\n\n    loader.load(\n      url,\n      function (buffer) {\n        // console.time( 'Total parsing: ' );\n\n        try {\n          onLoad(scope.parse(buffer, path, modelName))\n        } catch (e) {\n          if (onError) {\n            onError(e)\n          } else {\n            console.error(e)\n          }\n\n          scope.manager.itemError(url)\n        }\n\n        // console.timeEnd( 'Total parsing: ' );\n      },\n      onProgress,\n      onError,\n    )\n  }\n\n  parse(iffBuffer, path, modelName) {\n    _lwoTree = new IFFParser().parse(iffBuffer)\n\n    // console.log( 'lwoTree', lwoTree );\n\n    const textureLoader = new TextureLoader(this.manager)\n      .setPath(this.resourcePath || path)\n      .setCrossOrigin(this.crossOrigin)\n\n    return new LWOTreeParser(textureLoader).parse(modelName)\n  }\n}\n\n// Parse the lwoTree object\nclass LWOTreeParser {\n  constructor(textureLoader) {\n    this.textureLoader = textureLoader\n  }\n\n  parse(modelName) {\n    this.materials = new MaterialParser(this.textureLoader).parse()\n    this.defaultLayerName = modelName\n\n    this.meshes = this.parseLayers()\n\n    return {\n      materials: this.materials,\n      meshes: this.meshes,\n    }\n  }\n\n  parseLayers() {\n    // array of all meshes for building hierarchy\n    const meshes = []\n\n    // final array containing meshes with scene graph hierarchy set up\n    const finalMeshes = []\n\n    const geometryParser = new GeometryParser()\n\n    const scope = this\n    _lwoTree.layers.forEach(function (layer) {\n      const geometry = geometryParser.parse(layer.geometry, layer)\n\n      const mesh = scope.parseMesh(geometry, layer)\n\n      meshes[layer.number] = mesh\n\n      if (layer.parent === -1) finalMeshes.push(mesh)\n      else meshes[layer.parent].add(mesh)\n    })\n\n    this.applyPivots(finalMeshes)\n\n    return finalMeshes\n  }\n\n  parseMesh(geometry, layer) {\n    let mesh\n\n    const materials = this.getMaterials(geometry.userData.matNames, layer.geometry.type)\n\n    this.duplicateUVs(geometry, materials)\n\n    if (layer.geometry.type === 'points') mesh = new Points(geometry, materials)\n    else if (layer.geometry.type === 'lines') mesh = new LineSegments(geometry, materials)\n    else mesh = new Mesh(geometry, materials)\n\n    if (layer.name) mesh.name = layer.name\n    else mesh.name = this.defaultLayerName + '_layer_' + layer.number\n\n    mesh.userData.pivot = layer.pivot\n\n    return mesh\n  }\n\n  // TODO: may need to be reversed in z to convert LWO to three.js coordinates\n  applyPivots(meshes) {\n    meshes.forEach(function (mesh) {\n      mesh.traverse(function (child) {\n        const pivot = child.userData.pivot\n\n        child.position.x += pivot[0]\n        child.position.y += pivot[1]\n        child.position.z += pivot[2]\n\n        if (child.parent) {\n          const parentPivot = child.parent.userData.pivot\n\n          child.position.x -= parentPivot[0]\n          child.position.y -= parentPivot[1]\n          child.position.z -= parentPivot[2]\n        }\n      })\n    })\n  }\n\n  getMaterials(namesArray, type) {\n    const materials = []\n\n    const scope = this\n\n    namesArray.forEach(function (name, i) {\n      materials[i] = scope.getMaterialByName(name)\n    })\n\n    // convert materials to line or point mats if required\n    if (type === 'points' || type === 'lines') {\n      materials.forEach(function (mat, i) {\n        const spec = {\n          color: mat.color,\n        }\n\n        if (type === 'points') {\n          spec.size = 0.1\n          spec.map = mat.map\n          spec.morphTargets = mat.morphTargets\n          materials[i] = new PointsMaterial(spec)\n        } else if (type === 'lines') {\n          materials[i] = new LineBasicMaterial(spec)\n        }\n      })\n    }\n\n    // if there is only one material, return that directly instead of array\n    const filtered = materials.filter(Boolean)\n    if (filtered.length === 1) return filtered[0]\n\n    return materials\n  }\n\n  getMaterialByName(name) {\n    return this.materials.filter(function (m) {\n      return m.name === name\n    })[0]\n  }\n\n  // If the material has an aoMap, duplicate UVs\n  duplicateUVs(geometry, materials) {\n    let duplicateUVs = false\n\n    if (!Array.isArray(materials)) {\n      if (materials.aoMap) duplicateUVs = true\n    } else {\n      materials.forEach(function (material) {\n        if (material.aoMap) duplicateUVs = true\n      })\n    }\n\n    if (!duplicateUVs) return\n\n    geometry.setAttribute('uv2', new BufferAttribute(geometry.attributes.uv.array, 2))\n  }\n}\n\nclass MaterialParser {\n  constructor(textureLoader) {\n    this.textureLoader = textureLoader\n  }\n\n  parse() {\n    const materials = []\n    this.textures = {}\n\n    for (const name in _lwoTree.materials) {\n      if (_lwoTree.format === 'LWO3') {\n        materials.push(this.parseMaterial(_lwoTree.materials[name], name, _lwoTree.textures))\n      } else if (_lwoTree.format === 'LWO2') {\n        materials.push(this.parseMaterialLwo2(_lwoTree.materials[name], name, _lwoTree.textures))\n      }\n    }\n\n    return materials\n  }\n\n  parseMaterial(materialData, name, textures) {\n    let params = {\n      name: name,\n      side: this.getSide(materialData.attributes),\n      flatShading: this.getSmooth(materialData.attributes),\n    }\n\n    const connections = this.parseConnections(materialData.connections, materialData.nodes)\n\n    const maps = this.parseTextureNodes(connections.maps)\n\n    this.parseAttributeImageMaps(connections.attributes, textures, maps, materialData.maps)\n\n    const attributes = this.parseAttributes(connections.attributes, maps)\n\n    this.parseEnvMap(connections, maps, attributes)\n\n    params = Object.assign(maps, params)\n    params = Object.assign(params, attributes)\n\n    const materialType = this.getMaterialType(connections.attributes)\n\n    return new materialType(params)\n  }\n\n  parseMaterialLwo2(materialData, name /*, textures*/) {\n    let params = {\n      name: name,\n      side: this.getSide(materialData.attributes),\n      flatShading: this.getSmooth(materialData.attributes),\n    }\n\n    const attributes = this.parseAttributes(materialData.attributes, {})\n    params = Object.assign(params, attributes)\n    return new MeshPhongMaterial(params)\n  }\n\n  // Note: converting from left to right handed coords by switching x -> -x in vertices, and\n  // then switching mat FrontSide -> BackSide\n  // NB: this means that FrontSide and BackSide have been switched!\n  getSide(attributes) {\n    if (!attributes.side) return BackSide\n\n    switch (attributes.side) {\n      case 0:\n      case 1:\n        return BackSide\n      case 2:\n        return FrontSide\n      case 3:\n        return DoubleSide\n    }\n  }\n\n  getSmooth(attributes) {\n    if (!attributes.smooth) return true\n    return !attributes.smooth\n  }\n\n  parseConnections(connections, nodes) {\n    const materialConnections = {\n      maps: {},\n    }\n\n    const inputName = connections.inputName\n    const inputNodeName = connections.inputNodeName\n    const nodeName = connections.nodeName\n\n    const scope = this\n    inputName.forEach(function (name, index) {\n      if (name === 'Material') {\n        const matNode = scope.getNodeByRefName(inputNodeName[index], nodes)\n        materialConnections.attributes = matNode.attributes\n        materialConnections.envMap = matNode.fileName\n        materialConnections.name = inputNodeName[index]\n      }\n    })\n\n    nodeName.forEach(function (name, index) {\n      if (name === materialConnections.name) {\n        materialConnections.maps[inputName[index]] = scope.getNodeByRefName(inputNodeName[index], nodes)\n      }\n    })\n\n    return materialConnections\n  }\n\n  getNodeByRefName(refName, nodes) {\n    for (const name in nodes) {\n      if (nodes[name].refName === refName) return nodes[name]\n    }\n  }\n\n  parseTextureNodes(textureNodes) {\n    const maps = {}\n\n    for (const name in textureNodes) {\n      const node = textureNodes[name]\n      const path = node.fileName\n\n      if (!path) return\n\n      const texture = this.loadTexture(path)\n\n      if (node.widthWrappingMode !== undefined) texture.wrapS = this.getWrappingType(node.widthWrappingMode)\n      if (node.heightWrappingMode !== undefined) texture.wrapT = this.getWrappingType(node.heightWrappingMode)\n\n      switch (name) {\n        case 'Color':\n          maps.map = texture\n          break\n        case 'Roughness':\n          maps.roughnessMap = texture\n          maps.roughness = 0.5\n          break\n        case 'Specular':\n          maps.specularMap = texture\n          maps.specular = 0xffffff\n          break\n        case 'Luminous':\n          maps.emissiveMap = texture\n          maps.emissive = 0x808080\n          break\n        case 'Luminous Color':\n          maps.emissive = 0x808080\n          break\n        case 'Metallic':\n          maps.metalnessMap = texture\n          maps.metalness = 0.5\n          break\n        case 'Transparency':\n        case 'Alpha':\n          maps.alphaMap = texture\n          maps.transparent = true\n          break\n        case 'Normal':\n          maps.normalMap = texture\n          if (node.amplitude !== undefined) maps.normalScale = new Vector2(node.amplitude, node.amplitude)\n          break\n        case 'Bump':\n          maps.bumpMap = texture\n          break\n      }\n    }\n\n    // LWO BSDF materials can have both spec and rough, but this is not valid in three\n    if (maps.roughnessMap && maps.specularMap) delete maps.specularMap\n\n    return maps\n  }\n\n  // maps can also be defined on individual material attributes, parse those here\n  // This occurs on Standard (Phong) surfaces\n  parseAttributeImageMaps(attributes, textures, maps) {\n    for (const name in attributes) {\n      const attribute = attributes[name]\n\n      if (attribute.maps) {\n        const mapData = attribute.maps[0]\n\n        const path = this.getTexturePathByIndex(mapData.imageIndex, textures)\n        if (!path) return\n\n        const texture = this.loadTexture(path)\n\n        if (mapData.wrap !== undefined) texture.wrapS = this.getWrappingType(mapData.wrap.w)\n        if (mapData.wrap !== undefined) texture.wrapT = this.getWrappingType(mapData.wrap.h)\n\n        switch (name) {\n          case 'Color':\n            maps.map = texture\n            break\n          case 'Diffuse':\n            maps.aoMap = texture\n            break\n          case 'Roughness':\n            maps.roughnessMap = texture\n            maps.roughness = 1\n            break\n          case 'Specular':\n            maps.specularMap = texture\n            maps.specular = 0xffffff\n            break\n          case 'Luminosity':\n            maps.emissiveMap = texture\n            maps.emissive = 0x808080\n            break\n          case 'Metallic':\n            maps.metalnessMap = texture\n            maps.metalness = 1\n            break\n          case 'Transparency':\n          case 'Alpha':\n            maps.alphaMap = texture\n            maps.transparent = true\n            break\n          case 'Normal':\n            maps.normalMap = texture\n            break\n          case 'Bump':\n            maps.bumpMap = texture\n            break\n        }\n      }\n    }\n  }\n\n  parseAttributes(attributes, maps) {\n    const params = {}\n\n    // don't use color data if color map is present\n    if (attributes.Color && !maps.map) {\n      params.color = new Color().fromArray(attributes.Color.value)\n    } else {\n      params.color = new Color()\n    }\n\n    if (attributes.Transparency && attributes.Transparency.value !== 0) {\n      params.opacity = 1 - attributes.Transparency.value\n      params.transparent = true\n    }\n\n    if (attributes['Bump Height']) params.bumpScale = attributes['Bump Height'].value * 0.1\n\n    if (attributes['Refraction Index']) params.refractionRatio = 1 / attributes['Refraction Index'].value\n\n    this.parsePhysicalAttributes(params, attributes, maps)\n    this.parseStandardAttributes(params, attributes, maps)\n    this.parsePhongAttributes(params, attributes, maps)\n\n    return params\n  }\n\n  parsePhysicalAttributes(params, attributes /*, maps*/) {\n    if (attributes.Clearcoat && attributes.Clearcoat.value > 0) {\n      params.clearcoat = attributes.Clearcoat.value\n\n      if (attributes['Clearcoat Gloss']) {\n        params.clearcoatRoughness = 0.5 * (1 - attributes['Clearcoat Gloss'].value)\n      }\n    }\n  }\n\n  parseStandardAttributes(params, attributes, maps) {\n    if (attributes.Luminous) {\n      params.emissiveIntensity = attributes.Luminous.value\n\n      if (attributes['Luminous Color'] && !maps.emissive) {\n        params.emissive = new Color().fromArray(attributes['Luminous Color'].value)\n      } else {\n        params.emissive = new Color(0x808080)\n      }\n    }\n\n    if (attributes.Roughness && !maps.roughnessMap) params.roughness = attributes.Roughness.value\n    if (attributes.Metallic && !maps.metalnessMap) params.metalness = attributes.Metallic.value\n  }\n\n  parsePhongAttributes(params, attributes, maps) {\n    if (attributes.Diffuse) params.color.multiplyScalar(attributes.Diffuse.value)\n\n    if (attributes.Reflection) {\n      params.reflectivity = attributes.Reflection.value\n      params.combine = AddOperation\n    }\n\n    if (attributes.Luminosity) {\n      params.emissiveIntensity = attributes.Luminosity.value\n\n      if (!maps.emissiveMap && !maps.map) {\n        params.emissive = params.color\n      } else {\n        params.emissive = new Color(0x808080)\n      }\n    }\n\n    // parse specular if there is no roughness - we will interpret the material as 'Phong' in this case\n    if (!attributes.Roughness && attributes.Specular && !maps.specularMap) {\n      if (attributes['Color Highlight']) {\n        params.specular = new Color()\n          .setScalar(attributes.Specular.value)\n          .lerp(params.color.clone().multiplyScalar(attributes.Specular.value), attributes['Color Highlight'].value)\n      } else {\n        params.specular = new Color().setScalar(attributes.Specular.value)\n      }\n    }\n\n    if (params.specular && attributes.Glossiness) {\n      params.shininess = 7 + Math.pow(2, attributes.Glossiness.value * 12 + 2)\n    }\n  }\n\n  parseEnvMap(connections, maps, attributes) {\n    if (connections.envMap) {\n      const envMap = this.loadTexture(connections.envMap)\n\n      if (attributes.transparent && attributes.opacity < 0.999) {\n        envMap.mapping = EquirectangularRefractionMapping\n\n        // Reflectivity and refraction mapping don't work well together in Phong materials\n        if (attributes.reflectivity !== undefined) {\n          delete attributes.reflectivity\n          delete attributes.combine\n        }\n\n        if (attributes.metalness !== undefined) {\n          delete attributes.metalness\n        }\n      } else {\n        envMap.mapping = EquirectangularReflectionMapping\n      }\n\n      maps.envMap = envMap\n    }\n  }\n\n  // get texture defined at top level by its index\n  getTexturePathByIndex(index) {\n    let fileName = ''\n\n    if (!_lwoTree.textures) return fileName\n\n    _lwoTree.textures.forEach(function (texture) {\n      if (texture.index === index) fileName = texture.fileName\n    })\n\n    return fileName\n  }\n\n  loadTexture(path) {\n    if (!path) return null\n\n    const texture = this.textureLoader.load(path, undefined, undefined, function () {\n      console.warn(\n        'LWOLoader: non-standard resource hierarchy. Use `resourcePath` parameter to specify root content directory.',\n      )\n    })\n\n    return texture\n  }\n\n  // 0 = Reset, 1 = Repeat, 2 = Mirror, 3 = Edge\n  getWrappingType(num) {\n    switch (num) {\n      case 0:\n        console.warn('LWOLoader: \"Reset\" texture wrapping type is not supported in three.js')\n        return ClampToEdgeWrapping\n      case 1:\n        return RepeatWrapping\n      case 2:\n        return MirroredRepeatWrapping\n      case 3:\n        return ClampToEdgeWrapping\n    }\n  }\n\n  getMaterialType(nodeData) {\n    if (nodeData.Clearcoat && nodeData.Clearcoat.value > 0) return MeshPhysicalMaterial\n    if (nodeData.Roughness) return MeshStandardMaterial\n    return MeshPhongMaterial\n  }\n}\n\nclass GeometryParser {\n  parse(geoData, layer) {\n    const geometry = new BufferGeometry()\n\n    geometry.setAttribute('position', new Float32BufferAttribute(geoData.points, 3))\n\n    const indices = this.splitIndices(geoData.vertexIndices, geoData.polygonDimensions)\n    geometry.setIndex(indices)\n\n    this.parseGroups(geometry, geoData)\n\n    geometry.computeVertexNormals()\n\n    this.parseUVs(geometry, layer, indices)\n    this.parseMorphTargets(geometry, layer, indices)\n\n    // TODO: z may need to be reversed to account for coordinate system change\n    geometry.translate(-layer.pivot[0], -layer.pivot[1], -layer.pivot[2])\n\n    // let userData = geometry.userData;\n    // geometry = geometry.toNonIndexed()\n    // geometry.userData = userData;\n\n    return geometry\n  }\n\n  // split quads into tris\n  splitIndices(indices, polygonDimensions) {\n    const remappedIndices = []\n\n    let i = 0\n    polygonDimensions.forEach(function (dim) {\n      if (dim < 4) {\n        for (let k = 0; k < dim; k++) remappedIndices.push(indices[i + k])\n      } else if (dim === 4) {\n        remappedIndices.push(\n          indices[i],\n          indices[i + 1],\n          indices[i + 2],\n\n          indices[i],\n          indices[i + 2],\n          indices[i + 3],\n        )\n      } else if (dim > 4) {\n        for (let k = 1; k < dim - 1; k++) {\n          remappedIndices.push(indices[i], indices[i + k], indices[i + k + 1])\n        }\n\n        console.warn('LWOLoader: polygons with greater than 4 sides are not supported')\n      }\n\n      i += dim\n    })\n\n    return remappedIndices\n  }\n\n  // NOTE: currently ignoring poly indices and assuming that they are intelligently ordered\n  parseGroups(geometry, geoData) {\n    const tags = _lwoTree.tags\n    const matNames = []\n\n    let elemSize = 3\n    if (geoData.type === 'lines') elemSize = 2\n    if (geoData.type === 'points') elemSize = 1\n\n    const remappedIndices = this.splitMaterialIndices(geoData.polygonDimensions, geoData.materialIndices)\n\n    let indexNum = 0 // create new indices in numerical order\n    const indexPairs = {} // original indices mapped to numerical indices\n\n    let prevMaterialIndex\n    let materialIndex\n\n    let prevStart = 0\n    let currentCount = 0\n\n    for (let i = 0; i < remappedIndices.length; i += 2) {\n      materialIndex = remappedIndices[i + 1]\n\n      if (i === 0) matNames[indexNum] = tags[materialIndex]\n\n      if (prevMaterialIndex === undefined) prevMaterialIndex = materialIndex\n\n      if (materialIndex !== prevMaterialIndex) {\n        let currentIndex\n        if (indexPairs[tags[prevMaterialIndex]]) {\n          currentIndex = indexPairs[tags[prevMaterialIndex]]\n        } else {\n          currentIndex = indexNum\n          indexPairs[tags[prevMaterialIndex]] = indexNum\n          matNames[indexNum] = tags[prevMaterialIndex]\n          indexNum++\n        }\n\n        geometry.addGroup(prevStart, currentCount, currentIndex)\n\n        prevStart += currentCount\n\n        prevMaterialIndex = materialIndex\n        currentCount = 0\n      }\n\n      currentCount += elemSize\n    }\n\n    // the loop above doesn't add the last group, do that here.\n    if (geometry.groups.length > 0) {\n      let currentIndex\n      if (indexPairs[tags[materialIndex]]) {\n        currentIndex = indexPairs[tags[materialIndex]]\n      } else {\n        currentIndex = indexNum\n        indexPairs[tags[materialIndex]] = indexNum\n        matNames[indexNum] = tags[materialIndex]\n      }\n\n      geometry.addGroup(prevStart, currentCount, currentIndex)\n    }\n\n    // Mat names from TAGS chunk, used to build up an array of materials for this geometry\n    geometry.userData.matNames = matNames\n  }\n\n  splitMaterialIndices(polygonDimensions, indices) {\n    const remappedIndices = []\n\n    polygonDimensions.forEach(function (dim, i) {\n      if (dim <= 3) {\n        remappedIndices.push(indices[i * 2], indices[i * 2 + 1])\n      } else if (dim === 4) {\n        remappedIndices.push(indices[i * 2], indices[i * 2 + 1], indices[i * 2], indices[i * 2 + 1])\n      } else {\n        // ignore > 4 for now\n        for (let k = 0; k < dim - 2; k++) {\n          remappedIndices.push(indices[i * 2], indices[i * 2 + 1])\n        }\n      }\n    })\n\n    return remappedIndices\n  }\n\n  // UV maps:\n  // 1: are defined via index into an array of points, not into a geometry\n  // - the geometry is also defined by an index into this array, but the indexes may not match\n  // 2: there can be any number of UV maps for a single geometry. Here these are combined,\n  // \twith preference given to the first map encountered\n  // 3: UV maps can be partial - that is, defined for only a part of the geometry\n  // 4: UV maps can be VMAP or VMAD (discontinuous, to allow for seams). In practice, most\n  // UV maps are defined as partially VMAP and partially VMAD\n  // VMADs are currently not supported\n  parseUVs(geometry, layer) {\n    // start by creating a UV map set to zero for the whole geometry\n    const remappedUVs = Array.from(Array(geometry.attributes.position.count * 2), function () {\n      return 0\n    })\n\n    for (const name in layer.uvs) {\n      const uvs = layer.uvs[name].uvs\n      const uvIndices = layer.uvs[name].uvIndices\n\n      uvIndices.forEach(function (i, j) {\n        remappedUVs[i * 2] = uvs[j * 2]\n        remappedUVs[i * 2 + 1] = uvs[j * 2 + 1]\n      })\n    }\n\n    geometry.setAttribute('uv', new Float32BufferAttribute(remappedUVs, 2))\n  }\n\n  parseMorphTargets(geometry, layer) {\n    let num = 0\n    for (const name in layer.morphTargets) {\n      const remappedPoints = geometry.attributes.position.array.slice()\n\n      if (!geometry.morphAttributes.position) geometry.morphAttributes.position = []\n\n      const morphPoints = layer.morphTargets[name].points\n      const morphIndices = layer.morphTargets[name].indices\n      const type = layer.morphTargets[name].type\n\n      morphIndices.forEach(function (i, j) {\n        if (type === 'relative') {\n          remappedPoints[i * 3] += morphPoints[j * 3]\n          remappedPoints[i * 3 + 1] += morphPoints[j * 3 + 1]\n          remappedPoints[i * 3 + 2] += morphPoints[j * 3 + 2]\n        } else {\n          remappedPoints[i * 3] = morphPoints[j * 3]\n          remappedPoints[i * 3 + 1] = morphPoints[j * 3 + 1]\n          remappedPoints[i * 3 + 2] = morphPoints[j * 3 + 2]\n        }\n      })\n\n      geometry.morphAttributes.position[num] = new Float32BufferAttribute(remappedPoints, 3)\n      geometry.morphAttributes.position[num].name = name\n\n      num++\n    }\n\n    geometry.morphTargetsRelative = false\n  }\n}\n\n// ************** UTILITY FUNCTIONS **************\n\nfunction extractParentUrl(url, dir) {\n  const index = url.indexOf(dir)\n\n  if (index === -1) return './'\n\n  return url.substr(0, index)\n}\n\nexport { LWOLoader }\n"],"names":["Loader","FileLoader","IFFParser","TextureLoader","Points","LineSegments","Mesh","PointsMaterial","LineBasicMaterial","BufferAttribute","MeshPhongMaterial","BackSide","FrontSide","DoubleSide","Vector2","Color","AddOperation","EquirectangularRefractionMapping","EquirectangularReflectionMapping","ClampToEdgeWrapping","RepeatWrapping","MirroredRepeatWrapping","MeshPhysicalMaterial","MeshStandardMaterial","BufferGeometry","Float32BufferAttribute"],"mappings":"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"}