three-stdlib 2.31.0 → 2.32.1
Sign up to get free protection for your applications and to get access to all the features.
- package/_polyfill/uv1.cjs +6 -0
- package/_polyfill/uv1.cjs.map +1 -0
- package/_polyfill/uv1.d.ts +5 -0
- package/_polyfill/uv1.js +6 -0
- package/_polyfill/uv1.js.map +1 -0
- package/controls/ArcballControls.cjs.map +1 -1
- package/controls/ArcballControls.d.ts +2 -2
- package/controls/ArcballControls.js.map +1 -1
- package/controls/FirstPersonControls.cjs.map +1 -1
- package/controls/FirstPersonControls.d.ts +1 -1
- package/controls/FirstPersonControls.js.map +1 -1
- package/exporters/ColladaExporter.cjs +3 -2
- package/exporters/ColladaExporter.cjs.map +1 -1
- package/exporters/ColladaExporter.js +3 -2
- package/exporters/ColladaExporter.js.map +1 -1
- package/lines/LineSegments2.cjs +3 -2
- package/lines/LineSegments2.cjs.map +1 -1
- package/lines/LineSegments2.js +3 -2
- package/lines/LineSegments2.js.map +1 -1
- package/loaders/ColladaLoader.cjs +7 -6
- package/loaders/ColladaLoader.cjs.map +1 -1
- package/loaders/ColladaLoader.js +7 -6
- package/loaders/ColladaLoader.js.map +1 -1
- package/loaders/FBXLoader.cjs +4 -4
- package/loaders/FBXLoader.cjs.map +1 -1
- package/loaders/FBXLoader.js +4 -4
- package/loaders/FBXLoader.js.map +1 -1
- package/loaders/LWOLoader.cjs +3 -1
- package/loaders/LWOLoader.cjs.map +1 -1
- package/loaders/LWOLoader.js +3 -1
- package/loaders/LWOLoader.js.map +1 -1
- package/misc/ProgressiveLightmap.cjs +12 -10
- package/misc/ProgressiveLightmap.cjs.map +1 -1
- package/misc/ProgressiveLightmap.js +12 -10
- package/misc/ProgressiveLightmap.js.map +1 -1
- package/modifiers/TessellateModifier.cjs +20 -19
- package/modifiers/TessellateModifier.cjs.map +1 -1
- package/modifiers/TessellateModifier.js +20 -19
- package/modifiers/TessellateModifier.js.map +1 -1
- package/package.json +1 -1
package/loaders/LWOLoader.cjs
CHANGED
@@ -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
|
-
|
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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"}
|
package/loaders/LWOLoader.js
CHANGED
@@ -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
|
-
|
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")
|
package/loaders/LWOLoader.js.map
CHANGED
@@ -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) +
|
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 =
|
26
|
-
|
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
|
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
|
68
|
-
for (let i = 0; i <
|
69
|
-
|
70
|
-
|
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(
|
73
|
-
objects[box.index].geometry.getAttribute(
|
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":";;;;AA4BA,MAAM,oBAAoB;AAAA,EACxB,YAAY,UAAU,MAAM,MAAM;AAChC,SAAK,WAAW;AAChB,SAAK,MAAM;AACX,SAAK,qBAAqB,CAAE;AAC5B,SAAK,WAAW;AAChB,SAAK,QAAQ,IAAIA,YAAO;AACxB,SAAK,MAAM,aAAa;AACxB,SAAK,aAAa,IAAIC,wBAAkB,GAAG,CAAC;AAC5C,SAAK,gBAAgB;AACrB,SAAK,cAAc;AACnB,SAAK,SAAS;AAGd,UAAM,SAAS,8BAA8B,KAAK,UAAU,SAAS,IAAI,eAAeC,MAAS;AACjG,SAAK,uBAAuB,IAAID,MAAiB,kBAAC,KAAK,KAAK,KAAK,KAAK,EAAE,MAAM,QAAQ;AACtF,SAAK,uBAAuB,IAAIA,MAAiB,kBAAC,KAAK,KAAK,KAAK,KAAK,EAAE,MAAM,QAAQ;AAGtF,SAAK,QAAQ,IAAIE,wBAAmB;AACpC,SAAK,MAAM,WAAW,CAAE;AACxB,SAAK,MAAM,kBAAkB,CAAC,WAAW;AAEvC,aAAO,eACL,2BACA,OAAO,aAAa,MAAM,GAAG,EAAE,IAC/B;AAGF,YAAM,YAAY,OAAO,eAAe,QAAQ,eAAe;AAC/D,aAAO,iBACL,yBACA,OAAO,eAAe,MAAM,GAAG,SAAS,IACxC,6EACA,OAAO,eAAe,MAAM,YAAY,GAAG,EAAE,IAC7C;AAAA;AAAA;AAAA;AAKF,aAAO,SAAS,oBAAoB,EAAE,OAAO,KAAK,qBAAqB,QAAS;AAChF,aAAO,SAAS,kBAAkB,EAAE,OAAO,IAAK;AAEhD,WAAK,MAAM,WAAW,OAAO;AAG7B,WAAK,MAAM,SAAS,SAAS;AAE7B,WAAK,WAAW;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMD,qBAAqB,SAAS;AAE5B,SAAK,WAAW,CAAE;AAClB,UAAM,UAAU,IAAI,KAAK;AAEzB,aAAS,KAAK,GAAG,KAAK,QAAQ,QAAQ,MAAM;AAC1C,YAAM,SAAS,QAAQ,EAAE;AAGzB,UAAI,OAAO,SAAS;AAClB,aAAK,MAAM,OAAO,MAAM;AACxB;AAAA,MACD;AAED,UAAI,CAAC,OAAO,SAAS,aAAa,IAAI,GAAG;AACvC,gBAAQ,KAAK,gCAAgC;AAC7C;AAAA,MACD;AAED,UAAI,KAAK,iBAAiB,MAAM;AAC9B,aAAK,qBAAqB,KAAK,KAAK,KAAK,oBAAoB;AAAA,MAC9D;AAGD,aAAO,SAAS,WAAW,KAAK,qBAAqB;AACrD,aAAO,SAAS,YAAY;AAC5B,aAAO,aAAa;AACpB,aAAO,gBAAgB;AACvB,aAAO,cAAc,MAAO;AAI5B,WAAK,SAAS,KAAK,EAAE,GAAG,IAAI,UAAU,GAAG,GAAG,IAAI,UAAU,GAAG,OAAO,GAAE,CAAE;AAExE,WAAK,mBAAmB,KAAK,EAAE,UAAU,OAAO,UAAU,QAAgB;AAE1E,WAAK,WAAW;AAAA,IACjB;AAGD,UAAM,aAAa,QAAQ,KAAK,QAAQ;AACxC,SAAK,SAAS,QAAQ,CAAC,QAAQ;AAC7B,YAAM,MAAM,QAAQ,IAAI,KAAK,EAAE,SAAS,aAAa,IAAI,EAAE,MAAO;AAClE,eAAS,IAAI,GAAG,IAAI,IAAI,MAAM,QAAQ,KAAK,IAAI,UAAU;AACvD,YAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,IAAI,IAAI,WAAW,WAAW;AAC7D,YAAI,MAAM,IAAI,CAAC,KAAK,IAAI,MAAM,IAAI,CAAC,IAAI,IAAI,IAAI,WAAW,WAAW;AAAA,MACtE;AAED,cAAQ,IAAI,KAAK,EAAE,SAAS,aAAa,OAAO,GAAG;AACnD,cAAQ,IAAI,KAAK,EAAE,SAAS,aAAa,KAAK,EAAE,cAAc;AAAA,IACpE,CAAK;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQD,OAAO,QAAQ,cAAc,KAAK,YAAY,MAAM;AAClD,QAAI,KAAK,iBAAiB,MAAM;AAC9B;AAAA,IACD;AAGD,UAAM,YAAY,KAAK,SAAS,gBAAiB;AAGjD,SAAK,cAAc,UAAU;AAG7B,aAAS,IAAI,GAAG,IAAI,KAAK,mBAAmB,QAAQ,KAAK;AACvD,WAAK,mBAAmB,CAAC,EAAE,OAAO,WAAW,KAAK,mBAAmB,CAAC,EAAE,OAAO;AAC/E,WAAK,MAAM,OAAO,KAAK,mBAAmB,CAAC,EAAE,MAAM;AAAA,IACpD;AAGD,QAAI,KAAK,aAAa;AACpB,WAAK,SAAS,gBAAgB,KAAK,UAAU;AAC7C,WAAK,SAAS,OAAO,KAAK,OAAO,MAAM;AACvC,WAAK,cAAc;AAAA,IACpB;AAGD,aAAS,IAAI,GAAG,IAAI,KAAK,mBAAmB,QAAQ,KAAK;AACvD,WAAK,MAAM,SAAS,kBAAkB,EAAE,OAAO,YAAa;AAC5D,WAAK,mBAAmB,CAAC,EAAE,OAAO,WAAW,KAAK;AAClD,WAAK,mBAAmB,CAAC,EAAE,OAAO,mBAAmB,KAAK,mBAAmB,CAAC,EAAE,OAAO;AACvF,WAAK,mBAAmB,CAAC,EAAE,OAAO,gBAAgB;AAAA,IACnD;AAGD,UAAM,YAAY,KAAK,gBAAgB,KAAK,uBAAuB,KAAK;AACxE,UAAM,cAAc,KAAK,gBAAgB,KAAK,uBAAuB,KAAK;AAG1E,SAAK,SAAS,gBAAgB,SAAS;AACvC,SAAK,MAAM,SAAS,oBAAoB,EAAE,OAAO,YAAY,QAAS;AACtE,SAAK,cAAc,SAAS,SAAS,oBAAoB,EAAE,OAAO,YAAY,QAAS;AACvF,SAAK,gBAAgB,CAAC,KAAK;AAC3B,SAAK,SAAS,OAAO,KAAK,OAAO,MAAM;AAGvC,aAAS,IAAI,GAAG,IAAI,KAAK,mBAAmB,QAAQ,KAAK;AACvD,WAAK,mBAAmB,CAAC,EAAE,OAAO,gBAAgB,KAAK,mBAAmB,CAAC,EAAE,OAAO;AACpF,WAAK,mBAAmB,CAAC,EAAE,OAAO,WAAW,KAAK,mBAAmB,CAAC,EAAE;AACxE,WAAK,mBAAmB,CAAC,EAAE,OAAO,SAAS,OAAO,KAAK,mBAAmB,CAAC,EAAE,MAAM;AAAA,IACpF;AAGD,SAAK,SAAS,gBAAgB,SAAS;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOD,kBAAkB,SAAS,WAAW,QAAW;AAC/C,QAAI,KAAK,mBAAmB,UAAU,GAAG;AACvC,UAAI,CAAC,KAAK,QAAQ;AAChB,gBAAQ,KAAK,qCAAqC;AAClD,aAAK,SAAS;AAAA,MACf;AAED;AAAA,IACD;AAED,QAAI,KAAK,aAAa,MAAM;AAC1B,WAAK,gBAAgB,IAAIC,wBAAkB;AAAA,QACzC,KAAK,KAAK,qBAAqB;AAAA,QAC/B,MAAMC,MAAU;AAAA,MACxB,CAAO;AACD,WAAK,aAAa,IAAIC,oBAAc,KAAK,GAAG;AAC5C,WAAK,YAAY,IAAIC,MAAI,KAAC,KAAK,YAAY,KAAK,aAAa;AAC7D,WAAK,UAAU,SAAS,IAAI;AAC5B,WAAK,mBAAmB,CAAC,EAAE,OAAO,OAAO,IAAI,KAAK,SAAS;AAAA,IAC5D;AAED,QAAI,YAAY,QAAW;AACzB,WAAK,UAAU,SAAS,KAAK,QAAQ;AAAA,IACtC;AAED,SAAK,UAAU,UAAU;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOD,qBAAqB,KAAK,WAAW,MAAM;AACzC,UAAM,eAAe,IAAIH,wBAAmB;AAC5C,iBAAa,WAAW;AAAA,MACtB,mBAAmB,EAAE,OAAO,KAAM;AAAA,MAClC,aAAa,EAAE,OAAO,IAAM,IAAK;AAAA,MACjC,eAAe;AAAA,MACf,qBAAqB;AAAA,MACrB,oBAAoB;AAAA,IACrB;AACD,iBAAa,kBAAkB,CAAC,WAAW;AAEzC,aAAO,eACL,qBAAqB,OAAO,aAAa,MAAM,GAAG,EAAE,IAAI;AAG1D,YAAM,YAAY,OAAO,eAAe,QAAQ,eAAe;AAC/D,aAAO,iBACL,qBACA,OAAO,eAAe,MAAM,GAAG,SAAS,IACxC,yEACA,OAAO,eAAe,MAAM,YAAY,GAAG,EAAE,IAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYF,aAAO,SAAS,oBAAoB,EAAE,OAAO,SAAS,QAAS;AAC/D,aAAO,SAAS,cAAc,EAAE,OAAO,MAAM,IAAK;AAClD,mBAAa,WAAW,OAAO;AAG/B,mBAAa,SAAS,SAAS;AAE/B,WAAK,WAAW;AAAA,IACjB;AAED,SAAK,gBAAgB,IAAIG,WAAK,IAAID,MAAa,cAAC,GAAG,CAAC,GAAG,YAAY;AACnE,SAAK,cAAc,OAAO;AAC1B,SAAK,cAAc,gBAAgB;AACnC,SAAK,cAAc,cAAc;AACjC,SAAK,cAAc,SAAS,aAAa;AACzC,SAAK,MAAM,IAAI,KAAK,aAAa;AAAA,EAClC;AACH;;"}
|
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":";;;;;AA6BA,MAAM,oBAAoB;AAAA,EACxB,YAAY,UAAU,MAAM,MAAM;AAChC,SAAK,WAAW;AAChB,SAAK,MAAM;AACX,SAAK,qBAAqB,CAAE;AAC5B,SAAK,WAAW;AAChB,SAAK,QAAQ,IAAIA,YAAO;AACxB,SAAK,MAAM,aAAa;AACxB,SAAK,aAAa,IAAIC,wBAAkB,GAAG,CAAC;AAC5C,SAAK,gBAAgB;AACrB,SAAK,cAAc;AACnB,SAAK,SAAS;AAGd,UAAM,SAAS,8BAA8B,KAAK,UAAU,SAAS,IAAI,eAAeC,MAAS;AACjG,SAAK,uBAAuB,IAAID,MAAiB,kBAAC,KAAK,KAAK,KAAK,KAAK,EAAE,MAAM,QAAQ;AACtF,SAAK,uBAAuB,IAAIA,MAAiB,kBAAC,KAAK,KAAK,KAAK,KAAK,EAAE,MAAM,QAAQ;AAGtF,SAAK,QAAQ,IAAIE,wBAAmB;AACpC,SAAK,MAAM,WAAW,CAAE;AACxB,SAAK,MAAM,kBAAkB,CAAC,WAAW;AAEvC,aAAO,eACL,2BACA,OAAO,aAAa,MAAM,GAAG,EAAE,IAC/B,wBAAwBC,IAAG;AAG7B,YAAM,YAAY,OAAO,eAAe,QAAQ,eAAe;AAC/D,aAAO,iBACL,iBAAiBA,IAAAA,QAAQ,QAAQA,IAAAA,MAAM;AAAA,IACvC,OAAO,eAAe,MAAM,GAAG,SAAS,IACxC,6EACA,OAAO,eAAe,MAAM,YAAY,GAAG,EAAE,IAC7C;AAAA,gDAAmDA,IAAG,QAAK,QAAQA,IAAAA,MAAM;AAAA;AAAA;AAK3E,aAAO,SAAS,oBAAoB,EAAE,OAAO,KAAK,qBAAqB,QAAS;AAChF,aAAO,SAAS,kBAAkB,EAAE,OAAO,IAAK;AAEhD,WAAK,MAAM,WAAW,OAAO;AAG7B,WAAK,MAAM,SAAS,SAAS;AAE7B,WAAK,WAAW;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMD,qBAAqB,SAAS;AAE5B,SAAK,WAAW,CAAE;AAClB,UAAM,UAAU,IAAI,KAAK;AAEzB,aAAS,KAAK,GAAG,KAAK,QAAQ,QAAQ,MAAM;AAC1C,YAAM,SAAS,QAAQ,EAAE;AAGzB,UAAI,OAAO,SAAS;AAClB,aAAK,MAAM,OAAO,MAAM;AACxB;AAAA,MACD;AAED,UAAI,CAAC,OAAO,SAAS,aAAa,IAAI,GAAG;AACvC,gBAAQ,KAAK,gCAAgC;AAC7C;AAAA,MACD;AAED,UAAI,KAAK,iBAAiB,MAAM;AAC9B,aAAK,qBAAqB,KAAK,KAAK,KAAK,oBAAoB;AAAA,MAC9D;AAGD,aAAO,SAAS,WAAW,KAAK,qBAAqB;AACrD,aAAO,SAAS,YAAY;AAC5B,aAAO,aAAa;AACpB,aAAO,gBAAgB;AACvB,aAAO,cAAc,MAAO;AAI5B,WAAK,SAAS,KAAK,EAAE,GAAG,IAAI,UAAU,GAAG,GAAG,IAAI,UAAU,GAAG,OAAO,GAAE,CAAE;AAExE,WAAK,mBAAmB,KAAK,EAAE,UAAU,OAAO,UAAU,QAAgB;AAE1E,WAAK,WAAW;AAAA,IACjB;AAGD,UAAM,aAAa,QAAQ,KAAK,QAAQ;AACxC,SAAK,SAAS,QAAQ,CAAC,QAAQ;AAC7B,YAAMC,QAAM,QAAQ,IAAI,KAAK,EAAE,SAAS,aAAa,IAAI,EAAE,MAAO;AAClE,eAAS,IAAI,GAAG,IAAIA,MAAI,MAAM,QAAQ,KAAKA,MAAI,UAAU;AACvDA,cAAI,MAAM,CAAC,KAAKA,MAAI,MAAM,CAAC,IAAI,IAAI,IAAI,WAAW,WAAW;AAC7DA,cAAI,MAAM,IAAI,CAAC,KAAKA,MAAI,MAAM,IAAI,CAAC,IAAI,IAAI,IAAI,WAAW,WAAW;AAAA,MACtE;AAED,cAAQ,IAAI,KAAK,EAAE,SAAS,aAAaD,IAAG,KAAEC,KAAG;AACjD,cAAQ,IAAI,KAAK,EAAE,SAAS,aAAaD,IAAG,GAAA,EAAE,cAAc;AAAA,IAClE,CAAK;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQD,OAAO,QAAQ,cAAc,KAAK,YAAY,MAAM;AAClD,QAAI,KAAK,iBAAiB,MAAM;AAC9B;AAAA,IACD;AAGD,UAAM,YAAY,KAAK,SAAS,gBAAiB;AAGjD,SAAK,cAAc,UAAU;AAG7B,aAAS,IAAI,GAAG,IAAI,KAAK,mBAAmB,QAAQ,KAAK;AACvD,WAAK,mBAAmB,CAAC,EAAE,OAAO,WAAW,KAAK,mBAAmB,CAAC,EAAE,OAAO;AAC/E,WAAK,MAAM,OAAO,KAAK,mBAAmB,CAAC,EAAE,MAAM;AAAA,IACpD;AAGD,QAAI,KAAK,aAAa;AACpB,WAAK,SAAS,gBAAgB,KAAK,UAAU;AAC7C,WAAK,SAAS,OAAO,KAAK,OAAO,MAAM;AACvC,WAAK,cAAc;AAAA,IACpB;AAGD,aAAS,IAAI,GAAG,IAAI,KAAK,mBAAmB,QAAQ,KAAK;AACvD,WAAK,MAAM,SAAS,kBAAkB,EAAE,OAAO,YAAa;AAC5D,WAAK,mBAAmB,CAAC,EAAE,OAAO,WAAW,KAAK;AAClD,WAAK,mBAAmB,CAAC,EAAE,OAAO,mBAAmB,KAAK,mBAAmB,CAAC,EAAE,OAAO;AACvF,WAAK,mBAAmB,CAAC,EAAE,OAAO,gBAAgB;AAAA,IACnD;AAGD,UAAM,YAAY,KAAK,gBAAgB,KAAK,uBAAuB,KAAK;AACxE,UAAM,cAAc,KAAK,gBAAgB,KAAK,uBAAuB,KAAK;AAG1E,SAAK,SAAS,gBAAgB,SAAS;AACvC,SAAK,MAAM,SAAS,oBAAoB,EAAE,OAAO,YAAY,QAAS;AACtE,SAAK,cAAc,SAAS,SAAS,oBAAoB,EAAE,OAAO,YAAY,QAAS;AACvF,SAAK,gBAAgB,CAAC,KAAK;AAC3B,SAAK,SAAS,OAAO,KAAK,OAAO,MAAM;AAGvC,aAAS,IAAI,GAAG,IAAI,KAAK,mBAAmB,QAAQ,KAAK;AACvD,WAAK,mBAAmB,CAAC,EAAE,OAAO,gBAAgB,KAAK,mBAAmB,CAAC,EAAE,OAAO;AACpF,WAAK,mBAAmB,CAAC,EAAE,OAAO,WAAW,KAAK,mBAAmB,CAAC,EAAE;AACxE,WAAK,mBAAmB,CAAC,EAAE,OAAO,SAAS,OAAO,KAAK,mBAAmB,CAAC,EAAE,MAAM;AAAA,IACpF;AAGD,SAAK,SAAS,gBAAgB,SAAS;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOD,kBAAkB,SAAS,WAAW,QAAW;AAC/C,QAAI,KAAK,mBAAmB,UAAU,GAAG;AACvC,UAAI,CAAC,KAAK,QAAQ;AAChB,gBAAQ,KAAK,qCAAqC;AAClD,aAAK,SAAS;AAAA,MACf;AAED;AAAA,IACD;AAED,QAAI,KAAK,aAAa,MAAM;AAC1B,WAAK,gBAAgB,IAAIE,wBAAkB;AAAA,QACzC,KAAK,KAAK,qBAAqB;AAAA,QAC/B,MAAMC,MAAU;AAAA,MACxB,CAAO;AACD,WAAK,aAAa,IAAIC,oBAAc,KAAK,GAAG;AAC5C,WAAK,YAAY,IAAIC,MAAI,KAAC,KAAK,YAAY,KAAK,aAAa;AAC7D,WAAK,UAAU,SAAS,IAAI;AAC5B,WAAK,mBAAmB,CAAC,EAAE,OAAO,OAAO,IAAI,KAAK,SAAS;AAAA,IAC5D;AAED,QAAI,YAAY,QAAW;AACzB,WAAK,UAAU,SAAS,KAAK,QAAQ;AAAA,IACtC;AAED,SAAK,UAAU,UAAU;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOD,qBAAqB,KAAK,WAAW,MAAM;AACzC,UAAM,eAAe,IAAIH,wBAAmB;AAC5C,iBAAa,WAAW;AAAA,MACtB,mBAAmB,EAAE,OAAO,KAAM;AAAA,MAClC,aAAa,EAAE,OAAO,IAAM,IAAK;AAAA,MACjC,eAAe;AAAA,MACf,qBAAqB;AAAA,MACrB,oBAAoB;AAAA,IACrB;AACD,iBAAa,kBAAkB,CAAC,WAAW;AAEzC,aAAO,eACL,qBAAqB,OAAO,aAAa,MAAM,GAAG,EAAE,IAAI;AAG1D,YAAM,YAAY,OAAO,eAAe,QAAQ,eAAe;AAC/D,aAAO,iBACL,qBACA,OAAO,eAAe,MAAM,GAAG,SAAS,IACxC,yEACA,OAAO,eAAe,MAAM,YAAY,GAAG,EAAE,IAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYF,aAAO,SAAS,oBAAoB,EAAE,OAAO,SAAS,QAAS;AAC/D,aAAO,SAAS,cAAc,EAAE,OAAO,MAAM,IAAK;AAClD,mBAAa,WAAW,OAAO;AAG/B,mBAAa,SAAS,SAAS;AAE/B,WAAK,WAAW;AAAA,IACjB;AAED,SAAK,gBAAgB,IAAIG,WAAK,IAAID,MAAa,cAAC,GAAG,CAAC,GAAG,YAAY;AACnE,SAAK,cAAc,OAAO;AAC1B,SAAK,cAAc,gBAAgB;AACnC,SAAK,cAAc,cAAc;AACjC,SAAK,cAAc,SAAS,aAAa;AACzC,SAAK,MAAM,IAAI,KAAK,aAAa;AAAA,EAClC;AACH;;"}
|
@@ -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) +
|
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 =
|
24
|
-
|
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
|
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
|
66
|
-
for (let i = 0; i <
|
67
|
-
|
68
|
-
|
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(
|
71
|
-
objects[box.index].geometry.getAttribute(
|
72
|
+
objects[box.index].geometry.setAttribute(UV1, uv1);
|
73
|
+
objects[box.index].geometry.getAttribute(UV1).needsUpdate = true;
|
72
74
|
});
|
73
75
|
}
|
74
76
|
/**
|