three-stdlib 2.31.0 → 2.32.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/_polyfill/uv1.cjs +6 -0
  2. package/_polyfill/uv1.cjs.map +1 -0
  3. package/_polyfill/uv1.d.ts +5 -0
  4. package/_polyfill/uv1.js +6 -0
  5. package/_polyfill/uv1.js.map +1 -0
  6. package/controls/ArcballControls.cjs.map +1 -1
  7. package/controls/ArcballControls.d.ts +2 -2
  8. package/controls/ArcballControls.js.map +1 -1
  9. package/controls/FirstPersonControls.cjs.map +1 -1
  10. package/controls/FirstPersonControls.d.ts +1 -1
  11. package/controls/FirstPersonControls.js.map +1 -1
  12. package/exporters/ColladaExporter.cjs +3 -2
  13. package/exporters/ColladaExporter.cjs.map +1 -1
  14. package/exporters/ColladaExporter.js +3 -2
  15. package/exporters/ColladaExporter.js.map +1 -1
  16. package/lines/LineSegments2.cjs +3 -2
  17. package/lines/LineSegments2.cjs.map +1 -1
  18. package/lines/LineSegments2.js +3 -2
  19. package/lines/LineSegments2.js.map +1 -1
  20. package/loaders/ColladaLoader.cjs +7 -6
  21. package/loaders/ColladaLoader.cjs.map +1 -1
  22. package/loaders/ColladaLoader.js +7 -6
  23. package/loaders/ColladaLoader.js.map +1 -1
  24. package/loaders/FBXLoader.cjs +4 -4
  25. package/loaders/FBXLoader.cjs.map +1 -1
  26. package/loaders/FBXLoader.js +4 -4
  27. package/loaders/FBXLoader.js.map +1 -1
  28. package/loaders/LWOLoader.cjs +3 -1
  29. package/loaders/LWOLoader.cjs.map +1 -1
  30. package/loaders/LWOLoader.js +3 -1
  31. package/loaders/LWOLoader.js.map +1 -1
  32. package/misc/ProgressiveLightmap.cjs +12 -10
  33. package/misc/ProgressiveLightmap.cjs.map +1 -1
  34. package/misc/ProgressiveLightmap.js +12 -10
  35. package/misc/ProgressiveLightmap.js.map +1 -1
  36. package/modifiers/TessellateModifier.cjs +20 -19
  37. package/modifiers/TessellateModifier.cjs.map +1 -1
  38. package/modifiers/TessellateModifier.js +20 -19
  39. package/modifiers/TessellateModifier.js.map +1 -1
  40. package/package.json +1 -1
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const THREE = require("three");
4
4
  const IFFParser = require("./lwo/IFFParser.cjs");
5
+ const uv1 = require("../_polyfill/uv1.cjs");
5
6
  let _lwoTree;
6
7
  class LWOLoader extends THREE.Loader {
7
8
  constructor(manager, parameters = {}) {
@@ -72,7 +73,8 @@ class LWOTreeParser {
72
73
  parseMesh(geometry, layer) {
73
74
  let mesh;
74
75
  const materials = this.getMaterials(geometry.userData.matNames, layer.geometry.type);
75
- this.duplicateUVs(geometry, materials);
76
+ if (uv1.UV1 === "uv2")
77
+ this.duplicateUVs(geometry, materials);
76
78
  if (layer.geometry.type === "points")
77
79
  mesh = new THREE.Points(geometry, materials);
78
80
  else if (layer.geometry.type === "lines")
@@ -1 +1 @@
1
- {"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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"}
1
+ {"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'\nimport { UV1 } from '../_polyfill/uv1.ts'\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 if (UV1 === 'uv2') 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","UV1","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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"}
@@ -1,5 +1,6 @@
1
1
  import { Loader, FileLoader, TextureLoader, Points, LineSegments, Mesh, PointsMaterial, LineBasicMaterial, BufferAttribute, MeshPhongMaterial, BackSide, DoubleSide, FrontSide, Vector2, Color, AddOperation, EquirectangularRefractionMapping, EquirectangularReflectionMapping, ClampToEdgeWrapping, MirroredRepeatWrapping, RepeatWrapping, MeshPhysicalMaterial, MeshStandardMaterial, BufferGeometry, Float32BufferAttribute } from "three";
2
2
  import { IFFParser } from "./lwo/IFFParser.js";
3
+ import { UV1 } from "../_polyfill/uv1.js";
3
4
  let _lwoTree;
4
5
  class LWOLoader extends Loader {
5
6
  constructor(manager, parameters = {}) {
@@ -70,7 +71,8 @@ class LWOTreeParser {
70
71
  parseMesh(geometry, layer) {
71
72
  let mesh;
72
73
  const materials = this.getMaterials(geometry.userData.matNames, layer.geometry.type);
73
- this.duplicateUVs(geometry, materials);
74
+ if (UV1 === "uv2")
75
+ this.duplicateUVs(geometry, materials);
74
76
  if (layer.geometry.type === "points")
75
77
  mesh = new Points(geometry, materials);
76
78
  else if (layer.geometry.type === "lines")
@@ -1 +1 @@
1
- {"version":3,"file":"LWOLoader.js","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":[],"mappings":"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"}
1
+ {"version":3,"file":"LWOLoader.js","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'\nimport { UV1 } from '../_polyfill/uv1.ts'\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 if (UV1 === 'uv2') 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":[],"mappings":"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"}
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const THREE = require("three");
4
4
  const potpack = require("potpack");
5
+ const uv1 = require("../_polyfill/uv1.cjs");
5
6
  class ProgressiveLightMap {
6
7
  constructor(renderer, res = 1024) {
7
8
  this.renderer = renderer;
@@ -20,10 +21,11 @@ class ProgressiveLightMap {
20
21
  this.uvMat = new THREE.MeshPhongMaterial();
21
22
  this.uvMat.uniforms = {};
22
23
  this.uvMat.onBeforeCompile = (shader) => {
23
- shader.vertexShader = "#define USE_LIGHTMAP\n" + shader.vertexShader.slice(0, -1) + " gl_Position = vec4((uv2 - 0.5) * 2.0, 1.0, 1.0); }";
24
+ shader.vertexShader = "#define USE_LIGHTMAP\n" + shader.vertexShader.slice(0, -1) + ` gl_Position = vec4((${uv1.UV1} - 0.5) * 2.0, 1.0, 1.0); }`;
24
25
  const bodyStart = shader.fragmentShader.indexOf("void main() {");
25
- shader.fragmentShader = "varying vec2 vUv2;\n" + shader.fragmentShader.slice(0, bodyStart) + " uniform sampler2D previousShadowMap;\n uniform float averagingWindow;\n" + shader.fragmentShader.slice(bodyStart - 1, -1) + `
26
- vec3 texelOld = texture2D(previousShadowMap, vUv2).rgb;
26
+ shader.fragmentShader = `varying vec2 v${uv1.UV1 === "uv1" ? uv1.UV1 : "Uv2"};
27
+ ` + shader.fragmentShader.slice(0, bodyStart) + " uniform sampler2D previousShadowMap;\n uniform float averagingWindow;\n" + shader.fragmentShader.slice(bodyStart - 1, -1) + `
28
+ vec3 texelOld = texture2D(previousShadowMap, v${uv1.UV1 === "uv1" ? uv1.UV1 : "Uv2"}).rgb;
27
29
  gl_FragColor.rgb = mix(texelOld, gl_FragColor.rgb, 1.0/averagingWindow);
28
30
  }`;
29
31
  shader.uniforms.previousShadowMap = { value: this.progressiveLightMap1.texture };
@@ -34,7 +36,7 @@ vec3 texelOld = texture2D(previousShadowMap, vUv2).rgb;
34
36
  };
35
37
  }
36
38
  /**
37
- * Sets these objects' materials' lightmaps and modifies their uv2's.
39
+ * Sets these objects' materials' lightmaps and modifies their uv1's.
38
40
  * @param {Object3D} objects An array of objects and lights to set up your lightmap.
39
41
  */
40
42
  addObjectsToLightMap(objects) {
@@ -64,13 +66,13 @@ vec3 texelOld = texture2D(previousShadowMap, vUv2).rgb;
64
66
  }
65
67
  const dimensions = potpack(this.uv_boxes);
66
68
  this.uv_boxes.forEach((box) => {
67
- const uv2 = objects[box.index].geometry.getAttribute("uv").clone();
68
- for (let i = 0; i < uv2.array.length; i += uv2.itemSize) {
69
- uv2.array[i] = (uv2.array[i] + box.x + padding) / dimensions.w;
70
- uv2.array[i + 1] = (uv2.array[i + 1] + box.y + padding) / dimensions.h;
69
+ const uv1$1 = objects[box.index].geometry.getAttribute("uv").clone();
70
+ for (let i = 0; i < uv1$1.array.length; i += uv1$1.itemSize) {
71
+ uv1$1.array[i] = (uv1$1.array[i] + box.x + padding) / dimensions.w;
72
+ uv1$1.array[i + 1] = (uv1$1.array[i + 1] + box.y + padding) / dimensions.h;
71
73
  }
72
- objects[box.index].geometry.setAttribute("uv2", uv2);
73
- objects[box.index].geometry.getAttribute("uv2").needsUpdate = true;
74
+ objects[box.index].geometry.setAttribute(uv1.UV1, uv1$1);
75
+ objects[box.index].geometry.getAttribute(uv1.UV1).needsUpdate = true;
74
76
  });
75
77
  }
76
78
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ProgressiveLightmap.cjs","sources":["../../src/misc/ProgressiveLightmap.js"],"sourcesContent":["import {\n Scene,\n WebGLRenderTarget,\n FloatType,\n MeshBasicMaterial,\n MeshPhongMaterial,\n DoubleSide,\n PlaneGeometry,\n Mesh,\n} from 'three'\nimport potpack from 'potpack'\n\n/**\n * Progressive Light Map Accumulator, by [zalo](https://github.com/zalo/)\n *\n * To use, simply construct a `ProgressiveLightMap` object,\n * `plmap.addObjectsToLightMap(object)` an array of semi-static\n * objects and lights to the class once, and then call\n * `plmap.update(camera)` every frame to begin accumulating\n * lighting samples.\n *\n * This should begin accumulating lightmaps which apply to\n * your objects, so you can start jittering lighting to achieve\n * the texture-space effect you're looking for.\n *\n * @param {WebGLRenderer} renderer A WebGL Rendering Context\n * @param {number} res The side-long dimension of you total lightmap\n */\nclass ProgressiveLightMap {\n constructor(renderer, res = 1024) {\n this.renderer = renderer\n this.res = res\n this.lightMapContainers = []\n this.compiled = false\n this.scene = new Scene()\n this.scene.background = null\n this.tinyTarget = new WebGLRenderTarget(1, 1)\n this.buffer1Active = false\n this.firstUpdate = true\n this.warned = false\n\n // Create the Progressive LightMap Texture\n const format = /(Android|iPad|iPhone|iPod)/g.test(navigator.userAgent) ? alfFloatType : FloatType\n this.progressiveLightMap1 = new WebGLRenderTarget(this.res, this.res, { type: format })\n this.progressiveLightMap2 = new WebGLRenderTarget(this.res, this.res, { type: format })\n\n // Inject some spicy new logic into a standard phong material\n this.uvMat = new MeshPhongMaterial()\n this.uvMat.uniforms = {}\n this.uvMat.onBeforeCompile = (shader) => {\n // Vertex Shader: Set Vertex Positions to the Unwrapped UV Positions\n shader.vertexShader =\n '#define USE_LIGHTMAP\\n' +\n shader.vertexShader.slice(0, -1) +\n '\tgl_Position = vec4((uv2 - 0.5) * 2.0, 1.0, 1.0); }'\n\n // Fragment Shader: Set Pixels to average in the Previous frame's Shadows\n const bodyStart = shader.fragmentShader.indexOf('void main() {')\n shader.fragmentShader =\n 'varying vec2 vUv2;\\n' +\n shader.fragmentShader.slice(0, bodyStart) +\n '\tuniform sampler2D previousShadowMap;\\n\tuniform float averagingWindow;\\n' +\n shader.fragmentShader.slice(bodyStart - 1, -1) +\n `\\nvec3 texelOld = texture2D(previousShadowMap, vUv2).rgb;\n\t\t\t\tgl_FragColor.rgb = mix(texelOld, gl_FragColor.rgb, 1.0/averagingWindow);\n\t\t\t}`\n\n // Set the Previous Frame's Texture Buffer and Averaging Window\n shader.uniforms.previousShadowMap = { value: this.progressiveLightMap1.texture }\n shader.uniforms.averagingWindow = { value: 100 }\n\n this.uvMat.uniforms = shader.uniforms\n\n // Set the new Shader to this\n this.uvMat.userData.shader = shader\n\n this.compiled = true\n }\n }\n\n /**\n * Sets these objects' materials' lightmaps and modifies their uv2's.\n * @param {Object3D} objects An array of objects and lights to set up your lightmap.\n */\n addObjectsToLightMap(objects) {\n // Prepare list of UV bounding boxes for packing later...\n this.uv_boxes = []\n const padding = 3 / this.res\n\n for (let ob = 0; ob < objects.length; ob++) {\n const object = objects[ob]\n\n // If this object is a light, simply add it to the internal scene\n if (object.isLight) {\n this.scene.attach(object)\n continue\n }\n\n if (!object.geometry.hasAttribute('uv')) {\n console.warn('All lightmap objects need UVs!')\n continue\n }\n\n if (this.blurringPlane == null) {\n this._initializeBlurPlane(this.res, this.progressiveLightMap1)\n }\n\n // Apply the lightmap to the object\n object.material.lightMap = this.progressiveLightMap2.texture\n object.material.dithering = true\n object.castShadow = true\n object.receiveShadow = true\n object.renderOrder = 1000 + ob\n\n // Prepare UV boxes for potpack\n // TODO: Size these by object surface area\n this.uv_boxes.push({ w: 1 + padding * 2, h: 1 + padding * 2, index: ob })\n\n this.lightMapContainers.push({ basicMat: object.material, object: object })\n\n this.compiled = false\n }\n\n // Pack the objects' lightmap UVs into the same global space\n const dimensions = potpack(this.uv_boxes)\n this.uv_boxes.forEach((box) => {\n const uv2 = objects[box.index].geometry.getAttribute('uv').clone()\n for (let i = 0; i < uv2.array.length; i += uv2.itemSize) {\n uv2.array[i] = (uv2.array[i] + box.x + padding) / dimensions.w\n uv2.array[i + 1] = (uv2.array[i + 1] + box.y + padding) / dimensions.h\n }\n\n objects[box.index].geometry.setAttribute('uv2', uv2)\n objects[box.index].geometry.getAttribute('uv2').needsUpdate = true\n })\n }\n\n /**\n * This function renders each mesh one at a time into their respective surface maps\n * @param {Camera} camera Standard Rendering Camera\n * @param {number} blendWindow When >1, samples will accumulate over time.\n * @param {boolean} blurEdges Whether to fix UV Edges via blurring\n */\n update(camera, blendWindow = 100, blurEdges = true) {\n if (this.blurringPlane == null) {\n return\n }\n\n // Store the original Render Target\n const oldTarget = this.renderer.getRenderTarget()\n\n // The blurring plane applies blur to the seams of the lightmap\n this.blurringPlane.visible = blurEdges\n\n // Steal the Object3D from the real world to our special dimension\n for (let l = 0; l < this.lightMapContainers.length; l++) {\n this.lightMapContainers[l].object.oldScene = this.lightMapContainers[l].object.parent\n this.scene.attach(this.lightMapContainers[l].object)\n }\n\n // Render once normally to initialize everything\n if (this.firstUpdate) {\n this.renderer.setRenderTarget(this.tinyTarget) // Tiny for Speed\n this.renderer.render(this.scene, camera)\n this.firstUpdate = false\n }\n\n // Set each object's material to the UV Unwrapped Surface Mapping Version\n for (let l = 0; l < this.lightMapContainers.length; l++) {\n this.uvMat.uniforms.averagingWindow = { value: blendWindow }\n this.lightMapContainers[l].object.material = this.uvMat\n this.lightMapContainers[l].object.oldFrustumCulled = this.lightMapContainers[l].object.frustumCulled\n this.lightMapContainers[l].object.frustumCulled = false\n }\n\n // Ping-pong two surface buffers for reading/writing\n const activeMap = this.buffer1Active ? this.progressiveLightMap1 : this.progressiveLightMap2\n const inactiveMap = this.buffer1Active ? this.progressiveLightMap2 : this.progressiveLightMap1\n\n // Render the object's surface maps\n this.renderer.setRenderTarget(activeMap)\n this.uvMat.uniforms.previousShadowMap = { value: inactiveMap.texture }\n this.blurringPlane.material.uniforms.previousShadowMap = { value: inactiveMap.texture }\n this.buffer1Active = !this.buffer1Active\n this.renderer.render(this.scene, camera)\n\n // Restore the object's Real-time Material and add it back to the original world\n for (let l = 0; l < this.lightMapContainers.length; l++) {\n this.lightMapContainers[l].object.frustumCulled = this.lightMapContainers[l].object.oldFrustumCulled\n this.lightMapContainers[l].object.material = this.lightMapContainers[l].basicMat\n this.lightMapContainers[l].object.oldScene.attach(this.lightMapContainers[l].object)\n }\n\n // Restore the original Render Target\n this.renderer.setRenderTarget(oldTarget)\n }\n\n /** DEBUG\n * Draw the lightmap in the main scene. Call this after adding the objects to it.\n * @param {boolean} visible Whether the debug plane should be visible\n * @param {Vector3} position Where the debug plane should be drawn\n */\n showDebugLightmap(visible, position = undefined) {\n if (this.lightMapContainers.length == 0) {\n if (!this.warned) {\n console.warn('Call this after adding the objects!')\n this.warned = true\n }\n\n return\n }\n\n if (this.labelMesh == null) {\n this.labelMaterial = new MeshBasicMaterial({\n map: this.progressiveLightMap1.texture,\n side: DoubleSide,\n })\n this.labelPlane = new PlaneGeometry(100, 100)\n this.labelMesh = new Mesh(this.labelPlane, this.labelMaterial)\n this.labelMesh.position.y = 250\n this.lightMapContainers[0].object.parent.add(this.labelMesh)\n }\n\n if (position != undefined) {\n this.labelMesh.position.copy(position)\n }\n\n this.labelMesh.visible = visible\n }\n\n /**\n * INTERNAL Creates the Blurring Plane\n * @param {number} res The square resolution of this object's lightMap.\n * @param {WebGLRenderTexture} lightMap The lightmap to initialize the plane with.\n */\n _initializeBlurPlane(res, lightMap = null) {\n const blurMaterial = new MeshBasicMaterial()\n blurMaterial.uniforms = {\n previousShadowMap: { value: null },\n pixelOffset: { value: 1.0 / res },\n polygonOffset: true,\n polygonOffsetFactor: -1,\n polygonOffsetUnits: 3.0,\n }\n blurMaterial.onBeforeCompile = (shader) => {\n // Vertex Shader: Set Vertex Positions to the Unwrapped UV Positions\n shader.vertexShader =\n '#define USE_UV\\n' + shader.vertexShader.slice(0, -1) + '\tgl_Position = vec4((uv - 0.5) * 2.0, 1.0, 1.0); }'\n\n // Fragment Shader: Set Pixels to 9-tap box blur the current frame's Shadows\n const bodyStart = shader.fragmentShader.indexOf('void main() {')\n shader.fragmentShader =\n '#define USE_UV\\n' +\n shader.fragmentShader.slice(0, bodyStart) +\n '\tuniform sampler2D previousShadowMap;\\n\tuniform float pixelOffset;\\n' +\n shader.fragmentShader.slice(bodyStart - 1, -1) +\n `\tgl_FragColor.rgb = (\n\t\t\t texture2D(previousShadowMap, vUv + vec2( pixelOffset, 0.0 )).rgb +\n\t\t\t texture2D(previousShadowMap, vUv + vec2( 0.0 , pixelOffset)).rgb +\n\t\t\t texture2D(previousShadowMap, vUv + vec2( 0.0 , -pixelOffset)).rgb +\n\t\t\t texture2D(previousShadowMap, vUv + vec2(-pixelOffset, 0.0 )).rgb +\n\t\t\t texture2D(previousShadowMap, vUv + vec2( pixelOffset, pixelOffset)).rgb +\n\t\t\t texture2D(previousShadowMap, vUv + vec2(-pixelOffset, pixelOffset)).rgb +\n\t\t\t texture2D(previousShadowMap, vUv + vec2( pixelOffset, -pixelOffset)).rgb +\n\t\t\t texture2D(previousShadowMap, vUv + vec2(-pixelOffset, -pixelOffset)).rgb)/8.0;\n\t\t}`\n\n // Set the LightMap Accumulation Buffer\n shader.uniforms.previousShadowMap = { value: lightMap.texture }\n shader.uniforms.pixelOffset = { value: 0.5 / res }\n blurMaterial.uniforms = shader.uniforms\n\n // Set the new Shader to this\n blurMaterial.userData.shader = shader\n\n this.compiled = true\n }\n\n this.blurringPlane = new Mesh(new PlaneGeometry(1, 1), blurMaterial)\n this.blurringPlane.name = 'Blurring Plane'\n this.blurringPlane.frustumCulled = false\n this.blurringPlane.renderOrder = 0\n this.blurringPlane.material.depthWrite = false\n this.scene.add(this.blurringPlane)\n }\n}\n\nexport { ProgressiveLightMap }\n"],"names":["Scene","WebGLRenderTarget","FloatType","MeshPhongMaterial","MeshBasicMaterial","DoubleSide","PlaneGeometry","Mesh"],"mappings":"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"}
1
+ {"version":3,"file":"ProgressiveLightmap.cjs","sources":["../../src/misc/ProgressiveLightmap.js"],"sourcesContent":["import {\n Scene,\n WebGLRenderTarget,\n FloatType,\n MeshBasicMaterial,\n MeshPhongMaterial,\n DoubleSide,\n PlaneGeometry,\n Mesh,\n} from 'three'\nimport potpack from 'potpack'\nimport { UV1 } from '../_polyfill/uv1'\n\n/**\n * Progressive Light Map Accumulator, by [zalo](https://github.com/zalo/)\n *\n * To use, simply construct a `ProgressiveLightMap` object,\n * `plmap.addObjectsToLightMap(object)` an array of semi-static\n * objects and lights to the class once, and then call\n * `plmap.update(camera)` every frame to begin accumulating\n * lighting samples.\n *\n * This should begin accumulating lightmaps which apply to\n * your objects, so you can start jittering lighting to achieve\n * the texture-space effect you're looking for.\n *\n * @param {WebGLRenderer} renderer A WebGL Rendering Context\n * @param {number} res The side-long dimension of you total lightmap\n */\nclass ProgressiveLightMap {\n constructor(renderer, res = 1024) {\n this.renderer = renderer\n this.res = res\n this.lightMapContainers = []\n this.compiled = false\n this.scene = new Scene()\n this.scene.background = null\n this.tinyTarget = new WebGLRenderTarget(1, 1)\n this.buffer1Active = false\n this.firstUpdate = true\n this.warned = false\n\n // Create the Progressive LightMap Texture\n const format = /(Android|iPad|iPhone|iPod)/g.test(navigator.userAgent) ? alfFloatType : FloatType\n this.progressiveLightMap1 = new WebGLRenderTarget(this.res, this.res, { type: format })\n this.progressiveLightMap2 = new WebGLRenderTarget(this.res, this.res, { type: format })\n\n // Inject some spicy new logic into a standard phong material\n this.uvMat = new MeshPhongMaterial()\n this.uvMat.uniforms = {}\n this.uvMat.onBeforeCompile = (shader) => {\n // Vertex Shader: Set Vertex Positions to the Unwrapped UV Positions\n shader.vertexShader =\n '#define USE_LIGHTMAP\\n' +\n shader.vertexShader.slice(0, -1) +\n `\tgl_Position = vec4((${UV1} - 0.5) * 2.0, 1.0, 1.0); }`\n\n // Fragment Shader: Set Pixels to average in the Previous frame's Shadows\n const bodyStart = shader.fragmentShader.indexOf('void main() {')\n shader.fragmentShader =\n `varying vec2 v${UV1 === 'uv1' ? UV1 : 'Uv2'};\\n` +\n shader.fragmentShader.slice(0, bodyStart) +\n '\tuniform sampler2D previousShadowMap;\\n\tuniform float averagingWindow;\\n' +\n shader.fragmentShader.slice(bodyStart - 1, -1) +\n `\\nvec3 texelOld = texture2D(previousShadowMap, v${UV1 === 'uv1' ? UV1 : 'Uv2'}).rgb;\n\t\t\t\tgl_FragColor.rgb = mix(texelOld, gl_FragColor.rgb, 1.0/averagingWindow);\n\t\t\t}`\n\n // Set the Previous Frame's Texture Buffer and Averaging Window\n shader.uniforms.previousShadowMap = { value: this.progressiveLightMap1.texture }\n shader.uniforms.averagingWindow = { value: 100 }\n\n this.uvMat.uniforms = shader.uniforms\n\n // Set the new Shader to this\n this.uvMat.userData.shader = shader\n\n this.compiled = true\n }\n }\n\n /**\n * Sets these objects' materials' lightmaps and modifies their uv1's.\n * @param {Object3D} objects An array of objects and lights to set up your lightmap.\n */\n addObjectsToLightMap(objects) {\n // Prepare list of UV bounding boxes for packing later...\n this.uv_boxes = []\n const padding = 3 / this.res\n\n for (let ob = 0; ob < objects.length; ob++) {\n const object = objects[ob]\n\n // If this object is a light, simply add it to the internal scene\n if (object.isLight) {\n this.scene.attach(object)\n continue\n }\n\n if (!object.geometry.hasAttribute('uv')) {\n console.warn('All lightmap objects need UVs!')\n continue\n }\n\n if (this.blurringPlane == null) {\n this._initializeBlurPlane(this.res, this.progressiveLightMap1)\n }\n\n // Apply the lightmap to the object\n object.material.lightMap = this.progressiveLightMap2.texture\n object.material.dithering = true\n object.castShadow = true\n object.receiveShadow = true\n object.renderOrder = 1000 + ob\n\n // Prepare UV boxes for potpack\n // TODO: Size these by object surface area\n this.uv_boxes.push({ w: 1 + padding * 2, h: 1 + padding * 2, index: ob })\n\n this.lightMapContainers.push({ basicMat: object.material, object: object })\n\n this.compiled = false\n }\n\n // Pack the objects' lightmap UVs into the same global space\n const dimensions = potpack(this.uv_boxes)\n this.uv_boxes.forEach((box) => {\n const uv1 = objects[box.index].geometry.getAttribute('uv').clone()\n for (let i = 0; i < uv1.array.length; i += uv1.itemSize) {\n uv1.array[i] = (uv1.array[i] + box.x + padding) / dimensions.w\n uv1.array[i + 1] = (uv1.array[i + 1] + box.y + padding) / dimensions.h\n }\n\n objects[box.index].geometry.setAttribute(UV1, uv1)\n objects[box.index].geometry.getAttribute(UV1).needsUpdate = true\n })\n }\n\n /**\n * This function renders each mesh one at a time into their respective surface maps\n * @param {Camera} camera Standard Rendering Camera\n * @param {number} blendWindow When >1, samples will accumulate over time.\n * @param {boolean} blurEdges Whether to fix UV Edges via blurring\n */\n update(camera, blendWindow = 100, blurEdges = true) {\n if (this.blurringPlane == null) {\n return\n }\n\n // Store the original Render Target\n const oldTarget = this.renderer.getRenderTarget()\n\n // The blurring plane applies blur to the seams of the lightmap\n this.blurringPlane.visible = blurEdges\n\n // Steal the Object3D from the real world to our special dimension\n for (let l = 0; l < this.lightMapContainers.length; l++) {\n this.lightMapContainers[l].object.oldScene = this.lightMapContainers[l].object.parent\n this.scene.attach(this.lightMapContainers[l].object)\n }\n\n // Render once normally to initialize everything\n if (this.firstUpdate) {\n this.renderer.setRenderTarget(this.tinyTarget) // Tiny for Speed\n this.renderer.render(this.scene, camera)\n this.firstUpdate = false\n }\n\n // Set each object's material to the UV Unwrapped Surface Mapping Version\n for (let l = 0; l < this.lightMapContainers.length; l++) {\n this.uvMat.uniforms.averagingWindow = { value: blendWindow }\n this.lightMapContainers[l].object.material = this.uvMat\n this.lightMapContainers[l].object.oldFrustumCulled = this.lightMapContainers[l].object.frustumCulled\n this.lightMapContainers[l].object.frustumCulled = false\n }\n\n // Ping-pong two surface buffers for reading/writing\n const activeMap = this.buffer1Active ? this.progressiveLightMap1 : this.progressiveLightMap2\n const inactiveMap = this.buffer1Active ? this.progressiveLightMap2 : this.progressiveLightMap1\n\n // Render the object's surface maps\n this.renderer.setRenderTarget(activeMap)\n this.uvMat.uniforms.previousShadowMap = { value: inactiveMap.texture }\n this.blurringPlane.material.uniforms.previousShadowMap = { value: inactiveMap.texture }\n this.buffer1Active = !this.buffer1Active\n this.renderer.render(this.scene, camera)\n\n // Restore the object's Real-time Material and add it back to the original world\n for (let l = 0; l < this.lightMapContainers.length; l++) {\n this.lightMapContainers[l].object.frustumCulled = this.lightMapContainers[l].object.oldFrustumCulled\n this.lightMapContainers[l].object.material = this.lightMapContainers[l].basicMat\n this.lightMapContainers[l].object.oldScene.attach(this.lightMapContainers[l].object)\n }\n\n // Restore the original Render Target\n this.renderer.setRenderTarget(oldTarget)\n }\n\n /** DEBUG\n * Draw the lightmap in the main scene. Call this after adding the objects to it.\n * @param {boolean} visible Whether the debug plane should be visible\n * @param {Vector3} position Where the debug plane should be drawn\n */\n showDebugLightmap(visible, position = undefined) {\n if (this.lightMapContainers.length == 0) {\n if (!this.warned) {\n console.warn('Call this after adding the objects!')\n this.warned = true\n }\n\n return\n }\n\n if (this.labelMesh == null) {\n this.labelMaterial = new MeshBasicMaterial({\n map: this.progressiveLightMap1.texture,\n side: DoubleSide,\n })\n this.labelPlane = new PlaneGeometry(100, 100)\n this.labelMesh = new Mesh(this.labelPlane, this.labelMaterial)\n this.labelMesh.position.y = 250\n this.lightMapContainers[0].object.parent.add(this.labelMesh)\n }\n\n if (position != undefined) {\n this.labelMesh.position.copy(position)\n }\n\n this.labelMesh.visible = visible\n }\n\n /**\n * INTERNAL Creates the Blurring Plane\n * @param {number} res The square resolution of this object's lightMap.\n * @param {WebGLRenderTexture} lightMap The lightmap to initialize the plane with.\n */\n _initializeBlurPlane(res, lightMap = null) {\n const blurMaterial = new MeshBasicMaterial()\n blurMaterial.uniforms = {\n previousShadowMap: { value: null },\n pixelOffset: { value: 1.0 / res },\n polygonOffset: true,\n polygonOffsetFactor: -1,\n polygonOffsetUnits: 3.0,\n }\n blurMaterial.onBeforeCompile = (shader) => {\n // Vertex Shader: Set Vertex Positions to the Unwrapped UV Positions\n shader.vertexShader =\n '#define USE_UV\\n' + shader.vertexShader.slice(0, -1) + '\tgl_Position = vec4((uv - 0.5) * 2.0, 1.0, 1.0); }'\n\n // Fragment Shader: Set Pixels to 9-tap box blur the current frame's Shadows\n const bodyStart = shader.fragmentShader.indexOf('void main() {')\n shader.fragmentShader =\n '#define USE_UV\\n' +\n shader.fragmentShader.slice(0, bodyStart) +\n '\tuniform sampler2D previousShadowMap;\\n\tuniform float pixelOffset;\\n' +\n shader.fragmentShader.slice(bodyStart - 1, -1) +\n `\tgl_FragColor.rgb = (\n\t\t\t texture2D(previousShadowMap, vUv + vec2( pixelOffset, 0.0 )).rgb +\n\t\t\t texture2D(previousShadowMap, vUv + vec2( 0.0 , pixelOffset)).rgb +\n\t\t\t texture2D(previousShadowMap, vUv + vec2( 0.0 , -pixelOffset)).rgb +\n\t\t\t texture2D(previousShadowMap, vUv + vec2(-pixelOffset, 0.0 )).rgb +\n\t\t\t texture2D(previousShadowMap, vUv + vec2( pixelOffset, pixelOffset)).rgb +\n\t\t\t texture2D(previousShadowMap, vUv + vec2(-pixelOffset, pixelOffset)).rgb +\n\t\t\t texture2D(previousShadowMap, vUv + vec2( pixelOffset, -pixelOffset)).rgb +\n\t\t\t texture2D(previousShadowMap, vUv + vec2(-pixelOffset, -pixelOffset)).rgb)/8.0;\n\t\t}`\n\n // Set the LightMap Accumulation Buffer\n shader.uniforms.previousShadowMap = { value: lightMap.texture }\n shader.uniforms.pixelOffset = { value: 0.5 / res }\n blurMaterial.uniforms = shader.uniforms\n\n // Set the new Shader to this\n blurMaterial.userData.shader = shader\n\n this.compiled = true\n }\n\n this.blurringPlane = new Mesh(new PlaneGeometry(1, 1), blurMaterial)\n this.blurringPlane.name = 'Blurring Plane'\n this.blurringPlane.frustumCulled = false\n this.blurringPlane.renderOrder = 0\n this.blurringPlane.material.depthWrite = false\n this.scene.add(this.blurringPlane)\n }\n}\n\nexport { ProgressiveLightMap }\n"],"names":["Scene","WebGLRenderTarget","FloatType","MeshPhongMaterial","UV1","uv1","MeshBasicMaterial","DoubleSide","PlaneGeometry","Mesh"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { Scene, WebGLRenderTarget, FloatType, MeshPhongMaterial, MeshBasicMaterial, DoubleSide, PlaneGeometry, Mesh } from "three";
2
2
  import potpack from "potpack";
3
+ import { UV1 } from "../_polyfill/uv1.js";
3
4
  class ProgressiveLightMap {
4
5
  constructor(renderer, res = 1024) {
5
6
  this.renderer = renderer;
@@ -18,10 +19,11 @@ class ProgressiveLightMap {
18
19
  this.uvMat = new MeshPhongMaterial();
19
20
  this.uvMat.uniforms = {};
20
21
  this.uvMat.onBeforeCompile = (shader) => {
21
- shader.vertexShader = "#define USE_LIGHTMAP\n" + shader.vertexShader.slice(0, -1) + " gl_Position = vec4((uv2 - 0.5) * 2.0, 1.0, 1.0); }";
22
+ shader.vertexShader = "#define USE_LIGHTMAP\n" + shader.vertexShader.slice(0, -1) + ` gl_Position = vec4((${UV1} - 0.5) * 2.0, 1.0, 1.0); }`;
22
23
  const bodyStart = shader.fragmentShader.indexOf("void main() {");
23
- shader.fragmentShader = "varying vec2 vUv2;\n" + shader.fragmentShader.slice(0, bodyStart) + " uniform sampler2D previousShadowMap;\n uniform float averagingWindow;\n" + shader.fragmentShader.slice(bodyStart - 1, -1) + `
24
- vec3 texelOld = texture2D(previousShadowMap, vUv2).rgb;
24
+ shader.fragmentShader = `varying vec2 v${UV1 === "uv1" ? UV1 : "Uv2"};
25
+ ` + shader.fragmentShader.slice(0, bodyStart) + " uniform sampler2D previousShadowMap;\n uniform float averagingWindow;\n" + shader.fragmentShader.slice(bodyStart - 1, -1) + `
26
+ vec3 texelOld = texture2D(previousShadowMap, v${UV1 === "uv1" ? UV1 : "Uv2"}).rgb;
25
27
  gl_FragColor.rgb = mix(texelOld, gl_FragColor.rgb, 1.0/averagingWindow);
26
28
  }`;
27
29
  shader.uniforms.previousShadowMap = { value: this.progressiveLightMap1.texture };
@@ -32,7 +34,7 @@ vec3 texelOld = texture2D(previousShadowMap, vUv2).rgb;
32
34
  };
33
35
  }
34
36
  /**
35
- * Sets these objects' materials' lightmaps and modifies their uv2's.
37
+ * Sets these objects' materials' lightmaps and modifies their uv1's.
36
38
  * @param {Object3D} objects An array of objects and lights to set up your lightmap.
37
39
  */
38
40
  addObjectsToLightMap(objects) {
@@ -62,13 +64,13 @@ vec3 texelOld = texture2D(previousShadowMap, vUv2).rgb;
62
64
  }
63
65
  const dimensions = potpack(this.uv_boxes);
64
66
  this.uv_boxes.forEach((box) => {
65
- const uv2 = objects[box.index].geometry.getAttribute("uv").clone();
66
- for (let i = 0; i < uv2.array.length; i += uv2.itemSize) {
67
- uv2.array[i] = (uv2.array[i] + box.x + padding) / dimensions.w;
68
- uv2.array[i + 1] = (uv2.array[i + 1] + box.y + padding) / dimensions.h;
67
+ const uv1 = objects[box.index].geometry.getAttribute("uv").clone();
68
+ for (let i = 0; i < uv1.array.length; i += uv1.itemSize) {
69
+ uv1.array[i] = (uv1.array[i] + box.x + padding) / dimensions.w;
70
+ uv1.array[i + 1] = (uv1.array[i + 1] + box.y + padding) / dimensions.h;
69
71
  }
70
- objects[box.index].geometry.setAttribute("uv2", uv2);
71
- objects[box.index].geometry.getAttribute("uv2").needsUpdate = true;
72
+ objects[box.index].geometry.setAttribute(UV1, uv1);
73
+ objects[box.index].geometry.getAttribute(UV1).needsUpdate = true;
72
74
  });
73
75
  }
74
76
  /**