UNPKG

three-stdlib

Version:

stand-alone library of threejs examples

1 lines 23.1 kB
{"version":3,"file":"USDZExporter.cjs","sources":["../../src/exporters/USDZExporter.ts"],"sourcesContent":["import { zipSync, strToU8, Zippable } from 'fflate'\nimport {\n BufferGeometry,\n Color,\n Matrix4,\n Mesh,\n MeshPhysicalMaterial,\n MeshStandardMaterial,\n Object3D,\n Texture,\n Vector2,\n} from 'three'\nimport { Nullable } from '../types/utils'\n\ntype MaterialRepresentaion = MeshStandardMaterial | MeshPhysicalMaterial\n\nclass USDZExporter {\n private readonly PRECISION = 7\n\n private materials: { [key: string]: MaterialRepresentaion }\n private textures: { [key: string]: Texture }\n\n private files: Nullable<Zippable>\n\n constructor() {\n this.materials = {}\n this.textures = {}\n\n this.files = {}\n }\n\n public async parse(scene: Object3D): Promise<Uint8Array> {\n const modelFileName = 'model.usda'\n\n // model file should be first in USDZ archive so we init it here\n this.files[modelFileName] = null\n\n let output: string | null = this.buildHeader()\n\n scene.traverseVisible((object) => {\n if (object instanceof Mesh && object.isMesh && object.material.isMeshStandardMaterial) {\n const geometry: BufferGeometry = object.geometry\n const material: MaterialRepresentaion = object.material\n\n const geometryFileName = 'geometries/Geometry_' + geometry.id + '.usd'\n\n if (!(geometryFileName in this.files)) {\n const meshObject = this.buildMeshObject(geometry)\n this.files[geometryFileName] = this.buildUSDFileAsString(meshObject)\n }\n\n if (!(material.uuid in this.materials)) {\n this.materials[material.uuid] = material\n }\n\n output += this.buildXform(object, geometry, material)\n }\n })\n\n output += this.buildMaterials(this.materials)\n\n this.files[modelFileName] = strToU8(output)\n output = null\n\n for (const id in this.textures) {\n const texture = this.textures[id]\n const color = id.split('_')[1]\n const isRGBA = texture.format === 1023\n\n const canvas = this.imageToCanvas(texture.image, color)\n const blob = await new Promise<Blob | null>((resolve) =>\n canvas?.toBlob(resolve, isRGBA ? 'image/png' : 'image/jpeg', 1),\n )\n\n if (blob) {\n this.files[`textures/Texture_${id}.${isRGBA ? 'png' : 'jpg'}`] = new Uint8Array(await blob.arrayBuffer())\n }\n }\n\n // 64 byte alignment\n // https://github.com/101arrowz/fflate/issues/39#issuecomment-777263109\n\n let offset = 0\n\n for (const filename in this.files) {\n const file = this.files[filename]\n const headerSize = 34 + filename.length\n\n offset += headerSize\n\n const offsetMod64 = offset & 63\n\n if (offsetMod64 !== 4 && file !== null && file instanceof Uint8Array) {\n const padLength = 64 - offsetMod64\n const padding = new Uint8Array(padLength)\n\n this.files[filename] = [file, { extra: { 12345: padding } }]\n }\n\n if (file && typeof file.length === 'number') {\n offset = file.length\n }\n }\n\n return zipSync(this.files as Zippable, { level: 0 })\n }\n\n private imageToCanvas(\n image: HTMLImageElement | HTMLCanvasElement | OffscreenCanvas | ImageBitmap,\n color: string,\n ): HTMLCanvasElement | undefined {\n if (\n (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement) ||\n (typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement) ||\n (typeof OffscreenCanvas !== 'undefined' && image instanceof OffscreenCanvas) ||\n (typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap)\n ) {\n const scale = 1024 / Math.max(image.width, image.height)\n\n const canvas = document.createElement('canvas')\n canvas.width = image.width * Math.min(1, scale)\n canvas.height = image.height * Math.min(1, scale)\n\n const context = canvas.getContext('2d')\n context?.drawImage(image, 0, 0, canvas.width, canvas.height)\n\n if (color !== undefined) {\n const hex = parseInt(color, 16)\n\n const r = ((hex >> 16) & 255) / 255\n const g = ((hex >> 8) & 255) / 255\n const b = (hex & 255) / 255\n\n const imagedata = context?.getImageData(0, 0, canvas.width, canvas.height)\n if (imagedata) {\n const data = imagedata?.data\n\n for (let i = 0; i < data.length; i += 4) {\n data[i + 0] = data[i + 0] * r\n data[i + 1] = data[i + 1] * g\n data[i + 2] = data[i + 2] * b\n }\n\n context?.putImageData(imagedata, 0, 0)\n }\n }\n\n return canvas\n }\n }\n\n private buildHeader(): string {\n return `#usda 1.0\n(\n customLayerData = {\n string creator = \"Three.js USDZExporter\"\n }\n metersPerUnit = 1\n upAxis = \"Y\"\n)\n`\n }\n\n private buildUSDFileAsString(dataToInsert: string): Uint8Array {\n let output = this.buildHeader()\n output += dataToInsert\n return strToU8(output)\n }\n\n // Xform\n private buildXform(object: Object3D, geometry: BufferGeometry, material: MaterialRepresentaion): string {\n const name = 'Object_' + object.id\n const transform = this.buildMatrix(object.matrixWorld)\n\n if (object.matrixWorld.determinant() < 0) {\n console.warn('THREE.USDZExporter: USDZ does not support negative scales', object)\n }\n\n return `def Xform \"${name}\" (\n prepend references = @./geometries/Geometry_${geometry.id}.usd@</Geometry>\n)\n{\n matrix4d xformOp:transform = ${transform}\n uniform token[] xformOpOrder = [\"xformOp:transform\"]\n rel material:binding = </Materials/Material_${material.id}>\n}\n`\n }\n\n private buildMatrix(matrix: Matrix4): string {\n const array = matrix.elements\n\n return `( ${this.buildMatrixRow(array, 0)}, ${this.buildMatrixRow(array, 4)}, ${this.buildMatrixRow(\n array,\n 8,\n )}, ${this.buildMatrixRow(array, 12)} )`\n }\n\n private buildMatrixRow(array: number[], offset: number): string {\n return `(${array[offset + 0]}, ${array[offset + 1]}, ${array[offset + 2]}, ${array[offset + 3]})`\n }\n\n // Mesh\n private buildMeshObject(geometry: BufferGeometry): string {\n const mesh = this.buildMesh(geometry)\n return `\ndef \"Geometry\"\n{\n ${mesh}\n}\n`\n }\n\n private buildMesh(geometry: BufferGeometry): string {\n const name = 'Geometry'\n const attributes = geometry.attributes\n const count = attributes.position.count\n\n return `\n def Mesh \"${name}\"\n {\n int[] faceVertexCounts = [${this.buildMeshVertexCount(geometry)}]\n int[] faceVertexIndices = [${this.buildMeshVertexIndices(geometry)}]\n normal3f[] normals = [${this.buildVector3Array(attributes.normal, count)}] (\n interpolation = \"vertex\"\n )\n point3f[] points = [${this.buildVector3Array(attributes.position, count)}]\n float2[] primvars:st = [${this.buildVector2Array(attributes.uv, count)}] (\n interpolation = \"vertex\"\n )\n uniform token subdivisionScheme = \"none\"\n }\n`\n }\n\n private buildMeshVertexCount(geometry: BufferGeometry): string {\n const count = geometry.index !== null ? geometry.index.array.length : geometry.attributes.position.count\n\n return Array(count / 3)\n .fill(3)\n .join(', ')\n }\n\n private buildMeshVertexIndices(geometry: BufferGeometry): string {\n if (geometry.index !== null) {\n // @ts-ignore\n return geometry.index.array.join(', ')\n }\n\n const array: number[] = []\n const length = geometry.attributes.position.count\n\n for (let i = 0; i < length; i++) {\n array.push(i)\n }\n\n return array.join(', ')\n }\n\n private buildVector3Array(attribute: BufferGeometry['attributes'][number], count: number): string {\n if (attribute === undefined) {\n console.warn('USDZExporter: Normals missing.')\n return Array(count).fill('(0, 0, 0)').join(', ')\n }\n\n const array: string[] = []\n const data = attribute.array\n\n for (let i = 0; i < data.length; i += 3) {\n array.push(\n `(${data[i + 0].toPrecision(this.PRECISION)}, ${data[i + 1].toPrecision(this.PRECISION)}, ${data[\n i + 2\n ].toPrecision(this.PRECISION)})`,\n )\n }\n\n return array.join(', ')\n }\n\n private buildVector2Array(attribute: BufferGeometry['attributes'][number], count: number): string {\n if (attribute === undefined) {\n console.warn('USDZExporter: UVs missing.')\n return Array(count).fill('(0, 0)').join(', ')\n }\n\n const array: string[] = []\n const data = attribute.array\n\n for (let i = 0; i < data.length; i += 2) {\n // @ts-ignore\n array.push(`(${data[i + 0].toPrecision(this.PRECISION)}, ${1 - data[i + 1].toPrecision(this.PRECISION)})`)\n }\n\n return array.join(', ')\n }\n\n // Materials\n private buildMaterials(materials: USDZExporter['materials']): string {\n const array: string[] = []\n\n for (const uuid in materials) {\n const material = materials[uuid]\n\n array.push(this.buildMaterial(material))\n }\n\n return `def \"Materials\"\n{\n${array.join('')}\n}\n`\n }\n\n private buildMaterial(material: MaterialRepresentaion): string {\n // https://graphics.pixar.com/usd/docs/UsdPreviewSurface-Proposal.html\n\n const pad = ' '\n const inputs = []\n const samplers = []\n\n if (material.map !== null) {\n inputs.push(\n `${pad}color3f inputs:diffuseColor.connect = </Materials/Material_${material.id}/Texture_${material.map.id}_diffuse.outputs:rgb>`,\n )\n\n // Include alpha input\n if (material.transparent || material.alphaTest > 0.0) {\n inputs.push(`${pad}float inputs:opacity.connect = </Materials/Material_${material.id}/Texture_${material.map.id}_diffuse.outputs:a>`);\n }\n\n // Check if alpha test is bigger than minimum of 0.01, if not and it is transparent still apply a 0.01 alpha clip in order to remove white blur in transparent place.\n if (material.alphaTest > 0.01) {\n inputs.push(`${pad}float inputs:opacityThreshold = ${material.alphaTest}`);\n }\n else if(material.transparent || material.alphaTest > 0.0) {\n inputs.push(`${pad}float inputs:opacityThreshold = 0.01`);\n }\n \n samplers.push(this.buildTexture(material, material.map, 'diffuse', material.color))\n } else {\n inputs.push(`${pad}color3f inputs:diffuseColor = ${this.buildColor(material.color)}`)\n }\n\n if (material.emissiveMap !== null) {\n inputs.push(\n `${pad}color3f inputs:emissiveColor.connect = </Materials/Material_${material.id}/Texture_${material.emissiveMap.id}_emissive.outputs:rgb>`,\n )\n\n samplers.push(this.buildTexture(material, material.emissiveMap, 'emissive'))\n } else if (material.emissive.getHex() > 0) {\n inputs.push(`${pad}color3f inputs:emissiveColor = ${this.buildColor(material.emissive)}`)\n }\n\n if (material.normalMap !== null) {\n inputs.push(\n `${pad}normal3f inputs:normal.connect = </Materials/Material_${material.id}/Texture_${material.normalMap.id}_normal.outputs:rgb>`,\n )\n\n samplers.push(this.buildTexture(material, material.normalMap, 'normal'))\n }\n\n if (material.aoMap !== null) {\n inputs.push(\n `${pad}float inputs:occlusion.connect = </Materials/Material_${material.id}/Texture_${material.aoMap.id}_occlusion.outputs:r>`,\n )\n\n samplers.push(this.buildTexture(material, material.aoMap, 'occlusion'))\n }\n\n if (material.roughnessMap !== null && material.roughness === 1) {\n inputs.push(\n `${pad}float inputs:roughness.connect = </Materials/Material_${material.id}/Texture_${material.roughnessMap.id}_roughness.outputs:g>`,\n )\n\n samplers.push(this.buildTexture(material, material.roughnessMap, 'roughness'))\n } else {\n inputs.push(`${pad}float inputs:roughness = ${material.roughness}`)\n }\n\n if (material.metalnessMap !== null && material.metalness === 1) {\n inputs.push(\n `${pad}float inputs:metallic.connect = </Materials/Material_${material.id}/Texture_${material.metalnessMap.id}_metallic.outputs:b>`,\n )\n\n samplers.push(this.buildTexture(material, material.metalnessMap, 'metallic'))\n } else {\n inputs.push(`${pad}float inputs:metallic = ${material.metalness}`)\n }\n\n inputs.push(`${pad}float inputs:opacity = ${material.opacity}`)\n\n if (material instanceof MeshPhysicalMaterial) {\n inputs.push(`${pad}float inputs:clearcoat = ${material.clearcoat}`)\n inputs.push(`${pad}float inputs:clearcoatRoughness = ${material.clearcoatRoughness}`)\n inputs.push(`${pad}float inputs:ior = ${material.ior}`)\n }\n\n return `\n def Material \"Material_${material.id}\"\n {\n def Shader \"PreviewSurface\"\n {\n uniform token info:id = \"UsdPreviewSurface\"\n${inputs.join('\\n')}\n int inputs:useSpecularWorkflow = 0\n token outputs:surface\n }\n token outputs:surface.connect = </Materials/Material_${material.id}/PreviewSurface.outputs:surface>\n token inputs:frame:stPrimvarName = \"st\"\n def Shader \"uvReader_st\"\n {\n uniform token info:id = \"UsdPrimvarReader_float2\"\n token inputs:varname.connect = </Materials/Material_${material.id}.inputs:frame:stPrimvarName>\n float2 inputs:fallback = (0.0, 0.0)\n float2 outputs:result\n }\n${samplers.join('\\n')}\n }\n`\n }\n\n private buildTexture(material: MaterialRepresentaion, texture: Texture, mapType: string, color?: Color): string {\n const id = texture.id + (color ? '_' + color.getHexString() : '')\n const isRGBA = texture.format === 1023\n\n this.textures[id] = texture\n\n // Add the alpha output for when transparency is set or the alpha test is above 0\n return `\n def Shader \"Transform2d_${mapType}\" (\n sdrMetadata = {\n string role = \"math\"\n }\n )\n {\n uniform token info:id = \"UsdTransform2d\"\n float2 inputs:in.connect = </Materials/Material_${material.id}/uvReader_st.outputs:result>\n float2 inputs:scale = ${this.buildVector2(texture.repeat)}\n float2 inputs:translation = ${this.buildVector2(texture.offset)}\n float2 outputs:result\n }\n def Shader \"Texture_${texture.id}_${mapType}\"\n {\n uniform token info:id = \"UsdUVTexture\"\n asset inputs:file = @textures/Texture_${id}.${isRGBA ? 'png' : 'jpg'}@\n float2 inputs:st.connect = </Materials/Material_${material.id}/Transform2d_${mapType}.outputs:result>\n token inputs:wrapS = \"repeat\"\n token inputs:wrapT = \"repeat\"\n float outputs:r\n float outputs:g\n float outputs:b\n float3 outputs:rgb\n ${material.transparent || material.alphaTest > 0.0 ? 'float outputs:a' : ''}\n }`\n }\n\n private buildColor(color: Color): string {\n return `(${color.r}, ${color.g}, ${color.b})`\n }\n\n private buildVector2(vector: Vector2): string {\n return `(${vector.x}, ${vector.y})`\n }\n}\n\nexport { USDZExporter }\n"],"names":["Mesh","strToU8","zipSync","MeshPhysicalMaterial"],"mappings":"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"}