@plasius/gpu-shared 0.1.15 → 0.1.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/asset-url.js","../src/gltf-loader.js"],"sourcesContent":["import { INLINE_SHOWCASE_ASSET_URLS } from \"./showcase-inline-assets.js\";\n\nconst SHOWCASE_ASSET_FILES = Object.freeze({\n brigantine: \"brigantine.gltf\",\n cutter: \"cutter.gltf\",\n lighthouse: \"lighthouse.gltf\",\n \"harbor-dock\": \"harbor-dock.gltf\",\n});\n\nfunction createInlineShowcaseAssetUrl(assetName) {\n const inlineUrl = INLINE_SHOWCASE_ASSET_URLS[assetName];\n return inlineUrl ? new URL(inlineUrl) : null;\n}\n\nfunction getBrowserBaseUrl() {\n if (\n typeof document !== \"undefined\" &&\n typeof document.baseURI === \"string\" &&\n document.baseURI.length > 0\n ) {\n return document.baseURI;\n }\n if (\n typeof window !== \"undefined\" &&\n typeof window.location?.href === \"string\" &&\n window.location.href.length > 0\n ) {\n return window.location.href;\n }\n return null;\n}\n\nfunction normalizeAssetName(assetName) {\n return typeof assetName === \"string\" && assetName in SHOWCASE_ASSET_FILES\n ? assetName\n : \"brigantine\";\n}\n\nfunction parseResolveArgs(baseUrlOrAssetName, assetName) {\n if (\n typeof baseUrlOrAssetName === \"string\" &&\n baseUrlOrAssetName in SHOWCASE_ASSET_FILES &&\n typeof assetName === \"undefined\"\n ) {\n return {\n baseUrl: import.meta.url,\n assetName: baseUrlOrAssetName,\n };\n }\n\n return {\n baseUrl: baseUrlOrAssetName ?? import.meta.url,\n assetName: normalizeAssetName(assetName),\n };\n}\n\nexport function resolveShowcaseAssetUrl(baseUrlOrAssetName, assetName) {\n const resolved = parseResolveArgs(baseUrlOrAssetName, assetName);\n const fileName = SHOWCASE_ASSET_FILES[resolved.assetName];\n\n try {\n return new URL(`../assets/${fileName}`, resolved.baseUrl);\n } catch {\n const browserBaseUrl = getBrowserBaseUrl();\n if (browserBaseUrl) {\n try {\n const normalizedBaseUrl = new URL(resolved.baseUrl, browserBaseUrl);\n return new URL(`../assets/${fileName}`, normalizedBaseUrl);\n } catch {\n const inlineAsset = createInlineShowcaseAssetUrl(resolved.assetName);\n if (inlineAsset) {\n return inlineAsset;\n }\n }\n }\n\n try {\n return new URL(`../assets/${fileName}`, import.meta.url);\n } catch {\n return new URL(`assets/${fileName}`, \"file:///\");\n }\n }\n}\n\nexport function shouldUseInlineShowcaseFallback(url) {\n const href = url instanceof URL ? url.href : String(url ?? \"\");\n return href.includes(\"/assets/\");\n}\n","import { shouldUseInlineShowcaseFallback } from \"./asset-url.js\";\n\nfunction decodeDataUri(uri) {\n const match = /^data:.*?;base64,(.+)$/i.exec(uri);\n if (!match) {\n throw new Error(`Unsupported glTF buffer URI: ${uri.slice(0, 48)}`);\n }\n\n const binary = atob(match[1]);\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n return bytes.buffer;\n}\n\nfunction getComponentArray(componentType, buffer, byteOffset, count) {\n switch (componentType) {\n case 5121:\n return new Uint8Array(buffer, byteOffset, count);\n case 5123:\n return new Uint16Array(buffer, byteOffset, count);\n case 5125:\n return new Uint32Array(buffer, byteOffset, count);\n case 5126:\n return new Float32Array(buffer, byteOffset, count);\n default:\n throw new Error(`Unsupported glTF componentType: ${componentType}`);\n }\n}\n\nfunction getNormalizationScale(componentType) {\n switch (componentType) {\n case 5121:\n return 255;\n case 5123:\n return 65535;\n default:\n return 1;\n }\n}\n\nfunction getTypeSize(type) {\n switch (type) {\n case \"SCALAR\":\n return 1;\n case \"VEC2\":\n return 2;\n case \"VEC3\":\n return 3;\n case \"VEC4\":\n return 4;\n default:\n throw new Error(`Unsupported glTF accessor type: ${type}`);\n }\n}\n\nfunction getComponentByteSize(componentType) {\n switch (componentType) {\n case 5121:\n return 1;\n case 5123:\n return 2;\n case 5125:\n case 5126:\n return 4;\n default:\n throw new Error(`Unsupported glTF componentType: ${componentType}`);\n }\n}\n\nfunction readComponentValue(view, componentType, byteOffset) {\n switch (componentType) {\n case 5121:\n return view.getUint8(byteOffset);\n case 5123:\n return view.getUint16(byteOffset, true);\n case 5125:\n return view.getUint32(byteOffset, true);\n case 5126:\n return view.getFloat32(byteOffset, true);\n default:\n throw new Error(`Unsupported glTF componentType: ${componentType}`);\n }\n}\n\nfunction readAccessor(document, accessorIndex, buffers) {\n const accessor = document.accessors?.[accessorIndex];\n if (!accessor) {\n throw new Error(`glTF accessor ${accessorIndex} is missing.`);\n }\n\n const bufferView = document.bufferViews?.[accessor.bufferView];\n if (!bufferView) {\n throw new Error(`glTF bufferView ${accessor.bufferView} is missing.`);\n }\n\n const buffer = buffers[bufferView.buffer];\n const componentCount = getTypeSize(accessor.type);\n const byteOffset = (bufferView.byteOffset ?? 0) + (accessor.byteOffset ?? 0);\n const componentByteSize = getComponentByteSize(accessor.componentType);\n const packedElementByteLength = componentCount * componentByteSize;\n const byteStride = Math.max(bufferView.byteStride ?? packedElementByteLength, packedElementByteLength);\n let values;\n\n if (byteStride === packedElementByteLength) {\n const valueCount = accessor.count * componentCount;\n values = Array.from(\n getComponentArray(accessor.componentType, buffer, byteOffset, valueCount)\n );\n } else {\n const view = new DataView(buffer, byteOffset);\n values = new Array(accessor.count * componentCount);\n for (let index = 0; index < accessor.count; index += 1) {\n const elementOffset = index * byteStride;\n for (let componentIndex = 0; componentIndex < componentCount; componentIndex += 1) {\n values[index * componentCount + componentIndex] = readComponentValue(\n view,\n accessor.componentType,\n elementOffset + componentIndex * componentByteSize\n );\n }\n }\n }\n\n if (accessor.normalized) {\n const scale = getNormalizationScale(accessor.componentType);\n return values.map((value) => value / scale);\n }\n\n return values;\n}\n\nasync function decodeImagePixels(blob, urlLabel = \"glTF texture\") {\n if (typeof createImageBitmap === \"function\") {\n const bitmap = await createImageBitmap(blob);\n try {\n const canvas =\n typeof OffscreenCanvas === \"function\"\n ? new OffscreenCanvas(bitmap.width, bitmap.height)\n : typeof document !== \"undefined\"\n ? Object.assign(document.createElement(\"canvas\"), {\n width: bitmap.width,\n height: bitmap.height,\n })\n : null;\n const context = canvas?.getContext?.(\"2d\", { willReadFrequently: true });\n if (!context) {\n throw new Error(\"Unable to create 2D context for glTF texture decode.\");\n }\n context.drawImage(bitmap, 0, 0);\n const imageData = context.getImageData(0, 0, bitmap.width, bitmap.height);\n return Object.freeze({\n width: bitmap.width,\n height: bitmap.height,\n data: imageData.data,\n });\n } finally {\n bitmap.close?.();\n }\n }\n\n if (typeof document === \"undefined\") {\n throw new Error(`Unable to decode ${urlLabel}: browser image decode APIs are unavailable.`);\n }\n\n const objectUrl = URL.createObjectURL(blob);\n try {\n const image = await new Promise((resolve, reject) => {\n const element = new Image();\n element.onload = () => resolve(element);\n element.onerror = () => reject(new Error(`Failed to decode ${urlLabel}.`));\n element.src = objectUrl;\n });\n const canvas = Object.assign(document.createElement(\"canvas\"), {\n width: image.naturalWidth || image.width,\n height: image.naturalHeight || image.height,\n });\n const context = canvas.getContext(\"2d\", { willReadFrequently: true });\n if (!context) {\n throw new Error(\"Unable to create 2D context for glTF texture decode.\");\n }\n context.drawImage(image, 0, 0);\n const imageData = context.getImageData(0, 0, canvas.width, canvas.height);\n return Object.freeze({\n width: canvas.width,\n height: canvas.height,\n data: imageData.data,\n });\n } finally {\n URL.revokeObjectURL(objectUrl);\n }\n}\n\nfunction sliceBufferView(document, bufferViewIndex, buffers) {\n const bufferView = document.bufferViews?.[bufferViewIndex];\n if (!bufferView) {\n throw new Error(`glTF bufferView ${bufferViewIndex} is missing.`);\n }\n const buffer = buffers[bufferView.buffer];\n if (!buffer) {\n throw new Error(`glTF buffer ${bufferView.buffer} is missing.`);\n }\n const start = bufferView.byteOffset ?? 0;\n const end = start + (bufferView.byteLength ?? 0);\n return buffer.slice(start, end);\n}\n\nasync function loadImageResource(document, image, index, buffers, baseUrl) {\n if (typeof image?.uri === \"string\") {\n const response = await fetch(new URL(image.uri, baseUrl));\n if (!response.ok) {\n throw new Error(`Failed to load glTF texture: ${response.status} ${response.statusText}`);\n }\n return decodeImagePixels(\n await response.blob(),\n `glTF texture ${index}${image.uri ? ` (${image.uri})` : \"\"}`\n );\n }\n\n if (typeof image?.bufferView === \"number\") {\n const bytes = sliceBufferView(document, image.bufferView, buffers);\n return decodeImagePixels(\n new Blob([bytes], { type: image.mimeType ?? \"application/octet-stream\" }),\n `glTF texture ${index}`\n );\n }\n\n return null;\n}\n\nfunction normalizeTextureTransformPair(value, fallback) {\n if (!Array.isArray(value) || value.length < 2) {\n return fallback;\n }\n return [\n Number.isFinite(value[0]) ? Number(value[0]) : fallback[0],\n Number.isFinite(value[1]) ? Number(value[1]) : fallback[1],\n ];\n}\n\nfunction readTextureTransform(textureRef) {\n const transformExtension = textureRef?.extensions?.KHR_texture_transform ?? null;\n return {\n texCoord:\n typeof transformExtension?.texCoord === \"number\"\n ? transformExtension.texCoord\n : textureRef?.texCoord ?? 0,\n offset: normalizeTextureTransformPair(transformExtension?.offset, [0, 0]),\n scale: normalizeTextureTransformPair(transformExtension?.scale, [1, 1]),\n rotation: Number.isFinite(transformExtension?.rotation) ? Number(transformExtension.rotation) : 0,\n };\n}\n\nfunction wrapTextureCoordinate(value) {\n return ((value % 1) + 1) % 1;\n}\n\nfunction transformTextureCoordinate(uv, transform) {\n const scaledU = uv[0] * transform.scale[0];\n const scaledV = uv[1] * transform.scale[1];\n const cosine = Math.cos(transform.rotation);\n const sine = Math.sin(transform.rotation);\n return [\n scaledU * cosine - scaledV * sine + transform.offset[0],\n scaledU * sine + scaledV * cosine + transform.offset[1],\n ];\n}\n\nfunction readTexturePixel(data, width, height, x, y) {\n const clampedX = Math.min(width - 1, Math.max(0, x));\n const clampedY = Math.min(height - 1, Math.max(0, y));\n const offset = (clampedY * width + clampedX) * 4;\n return [\n data[offset] ?? 0,\n data[offset + 1] ?? 0,\n data[offset + 2] ?? 0,\n data[offset + 3] ?? 255,\n ];\n}\n\nfunction mixChannel(a, b, weight) {\n return a + (b - a) * weight;\n}\n\nfunction sampleTexturePixel(data, width, height, uv) {\n const u = wrapTextureCoordinate(uv[0]);\n const v = wrapTextureCoordinate(uv[1]);\n const sourceX = u * Math.max(width - 1, 0);\n const sourceY = (1 - v) * Math.max(height - 1, 0);\n const x0 = Math.floor(sourceX);\n const y0 = Math.floor(sourceY);\n const x1 = Math.min(width - 1, x0 + 1);\n const y1 = Math.min(height - 1, y0 + 1);\n const tx = sourceX - x0;\n const ty = sourceY - y0;\n const topLeft = readTexturePixel(data, width, height, x0, y0);\n const topRight = readTexturePixel(data, width, height, x1, y0);\n const bottomLeft = readTexturePixel(data, width, height, x0, y1);\n const bottomRight = readTexturePixel(data, width, height, x1, y1);\n return [0, 1, 2, 3].map((channelIndex) => {\n const top = mixChannel(topLeft[channelIndex], topRight[channelIndex], tx);\n const bottom = mixChannel(bottomLeft[channelIndex], bottomRight[channelIndex], tx);\n return mixChannel(top, bottom, ty);\n });\n}\n\nfunction applyTextureTransformToPixels(pixels, transform) {\n const isIdentityTransform =\n transform.offset[0] === 0 &&\n transform.offset[1] === 0 &&\n transform.scale[0] === 1 &&\n transform.scale[1] === 1 &&\n transform.rotation === 0;\n if (isIdentityTransform) {\n return pixels;\n }\n\n const transformedData = new Uint8ClampedArray(pixels.data.length);\n for (let y = 0; y < pixels.height; y += 1) {\n const outputV = pixels.height > 1 ? 1 - y / (pixels.height - 1) : 0;\n for (let x = 0; x < pixels.width; x += 1) {\n const outputU = pixels.width > 1 ? x / (pixels.width - 1) : 0;\n const sourcePixel = sampleTexturePixel(\n pixels.data,\n pixels.width,\n pixels.height,\n transformTextureCoordinate([outputU, outputV], transform)\n );\n const offset = (y * pixels.width + x) * 4;\n transformedData[offset] = sourcePixel[0];\n transformedData[offset + 1] = sourcePixel[1];\n transformedData[offset + 2] = sourcePixel[2];\n transformedData[offset + 3] = sourcePixel[3];\n }\n }\n\n return Object.freeze({\n width: pixels.width,\n height: pixels.height,\n data: transformedData,\n });\n}\n\nfunction getMaterialTexture(document, textureRef, imageResources) {\n if (!textureRef || typeof textureRef.index !== \"number\") {\n return null;\n }\n const texture = document.textures?.[textureRef.index] ?? null;\n const sourceIndex = texture?.source;\n if (typeof sourceIndex !== \"number\") {\n return null;\n }\n const pixels = imageResources.get(sourceIndex) ?? null;\n if (!pixels) {\n return null;\n }\n\n const transform = readTextureTransform(textureRef);\n const transformedPixels = applyTextureTransformToPixels(pixels, transform);\n return Object.freeze({\n texCoord: transform.texCoord,\n scale: textureRef.scale,\n strength: textureRef.strength,\n width: transformedPixels.width,\n height: transformedPixels.height,\n data: transformedPixels.data,\n });\n}\n\nfunction getMaterialInfo(document, primitive, imageResources) {\n const material = document.materials?.[primitive.material] ?? null;\n const pbr = material?.pbrMetallicRoughness ?? null;\n const factor = pbr?.baseColorFactor ?? [0.56, 0.33, 0.22, 1];\n const emissive = Array.isArray(material?.emissiveFactor) ? material.emissiveFactor : [0, 0, 0];\n const extensions = material?.extensions ?? {};\n const specular = extensions.KHR_materials_specular ?? null;\n const transmission = extensions.KHR_materials_transmission ?? null;\n const ior = extensions.KHR_materials_ior ?? null;\n const clearcoat = extensions.KHR_materials_clearcoat ?? null;\n const sheen = extensions.KHR_materials_sheen ?? null;\n const volume = extensions.KHR_materials_volume ?? null;\n const iridescence = extensions.KHR_materials_iridescence ?? null;\n const anisotropy = extensions.KHR_materials_anisotropy ?? null;\n const dispersion = extensions.KHR_materials_dispersion ?? null;\n\n return Object.freeze({\n name: material?.name ?? \"default-material\",\n color: Object.freeze({\n r: factor[0],\n g: factor[1],\n b: factor[2],\n a: factor[3] ?? 1,\n }),\n roughness:\n typeof pbr?.roughnessFactor === \"number\"\n ? pbr.roughnessFactor\n : 0.92,\n metallic:\n typeof pbr?.metallicFactor === \"number\"\n ? pbr.metallicFactor\n : 0.08,\n opacity: factor[3] ?? 1,\n emissive: Object.freeze({\n r: emissive[0] ?? 0,\n g: emissive[1] ?? 0,\n b: emissive[2] ?? 0,\n a: 1,\n }),\n baseColorTexture: getMaterialTexture(document, pbr?.baseColorTexture, imageResources),\n metallicRoughnessTexture: getMaterialTexture(\n document,\n pbr?.metallicRoughnessTexture,\n imageResources\n ),\n normalTexture: getMaterialTexture(document, material?.normalTexture, imageResources),\n occlusionTexture: getMaterialTexture(document, material?.occlusionTexture, imageResources),\n emissiveTexture: getMaterialTexture(document, material?.emissiveTexture, imageResources),\n specular:\n typeof specular?.specularFactor === \"number\"\n ? specular.specularFactor\n : 1,\n specularColor: Object.freeze(\n Array.isArray(specular?.specularColorFactor)\n ? [...specular.specularColorFactor]\n : [1, 1, 1]\n ),\n specularTexture: getMaterialTexture(document, specular?.specularTexture, imageResources),\n specularColorTexture: getMaterialTexture(\n document,\n specular?.specularColorTexture,\n imageResources\n ),\n transmission:\n typeof transmission?.transmissionFactor === \"number\"\n ? transmission.transmissionFactor\n : 0,\n transmissionTexture: getMaterialTexture(\n document,\n transmission?.transmissionTexture,\n imageResources\n ),\n ior: typeof ior?.ior === \"number\" ? ior.ior : 1.45,\n attenuationDistance:\n typeof volume?.attenuationDistance === \"number\"\n ? volume.attenuationDistance\n : null,\n attenuationColor: Object.freeze(\n Array.isArray(volume?.attenuationColor)\n ? [...volume.attenuationColor]\n : [1, 1, 1]\n ),\n thickness:\n typeof volume?.thicknessFactor === \"number\"\n ? volume.thicknessFactor\n : 0,\n thicknessTexture: getMaterialTexture(document, volume?.thicknessTexture, imageResources),\n clearcoat:\n typeof clearcoat?.clearcoatFactor === \"number\"\n ? clearcoat.clearcoatFactor\n : 0,\n clearcoatTexture: getMaterialTexture(document, clearcoat?.clearcoatTexture, imageResources),\n clearcoatRoughness:\n typeof clearcoat?.clearcoatRoughnessFactor === \"number\"\n ? clearcoat.clearcoatRoughnessFactor\n : 0.08,\n clearcoatRoughnessTexture: getMaterialTexture(\n document,\n clearcoat?.clearcoatRoughnessTexture,\n imageResources\n ),\n clearcoatNormalTexture: getMaterialTexture(\n document,\n clearcoat?.clearcoatNormalTexture,\n imageResources\n ),\n sheenColor: Object.freeze(\n Array.isArray(sheen?.sheenColorFactor) ? [...sheen.sheenColorFactor] : [0, 0, 0]\n ),\n sheenColorTexture: getMaterialTexture(document, sheen?.sheenColorTexture, imageResources),\n sheenRoughness:\n typeof sheen?.sheenRoughnessFactor === \"number\"\n ? sheen.sheenRoughnessFactor\n : 0,\n sheenRoughnessTexture: getMaterialTexture(\n document,\n sheen?.sheenRoughnessTexture,\n imageResources\n ),\n iridescence:\n typeof iridescence?.iridescenceFactor === \"number\"\n ? iridescence.iridescenceFactor\n : 0,\n iridescenceTexture: getMaterialTexture(\n document,\n iridescence?.iridescenceTexture,\n imageResources\n ),\n iridescenceIor:\n typeof iridescence?.iridescenceIor === \"number\"\n ? iridescence.iridescenceIor\n : 1.3,\n iridescenceThicknessMinimum:\n typeof iridescence?.iridescenceThicknessMinimum === \"number\"\n ? iridescence.iridescenceThicknessMinimum\n : 100,\n iridescenceThicknessMaximum:\n typeof iridescence?.iridescenceThicknessMaximum === \"number\"\n ? iridescence.iridescenceThicknessMaximum\n : 400,\n iridescenceThicknessTexture: getMaterialTexture(\n document,\n iridescence?.iridescenceThicknessTexture,\n imageResources\n ),\n anisotropy:\n typeof anisotropy?.anisotropyStrength === \"number\"\n ? anisotropy.anisotropyStrength\n : 0,\n anisotropyRotation:\n typeof anisotropy?.anisotropyRotation === \"number\"\n ? anisotropy.anisotropyRotation\n : 0,\n anisotropyTexture: getMaterialTexture(document, anisotropy?.anisotropyTexture, imageResources),\n dispersion:\n typeof dispersion?.dispersion === \"number\"\n ? dispersion.dispersion\n : 0,\n });\n}\n\nfunction computeBounds(positions) {\n const min = [\n Number.POSITIVE_INFINITY,\n Number.POSITIVE_INFINITY,\n Number.POSITIVE_INFINITY,\n ];\n const max = [\n Number.NEGATIVE_INFINITY,\n Number.NEGATIVE_INFINITY,\n Number.NEGATIVE_INFINITY,\n ];\n\n for (let index = 0; index < positions.length; index += 3) {\n min[0] = Math.min(min[0], positions[index]);\n min[1] = Math.min(min[1], positions[index + 1]);\n min[2] = Math.min(min[2], positions[index + 2]);\n max[0] = Math.max(max[0], positions[index]);\n max[1] = Math.max(max[1], positions[index + 1]);\n max[2] = Math.max(max[2], positions[index + 2]);\n }\n\n return Object.freeze({\n min: Object.freeze([min[0], min[1], min[2]]),\n max: Object.freeze([max[0], max[1], max[2]]),\n });\n}\n\nfunction appendValues(target, values) {\n for (let index = 0; index < values.length; index += 1) {\n target.push(values[index]);\n }\n}\n\nfunction appendIndicesWithOffset(target, values, vertexOffset) {\n for (let index = 0; index < values.length; index += 1) {\n target.push(values[index] + vertexOffset);\n }\n}\n\nfunction resolveBrowserRequestBaseUrl() {\n if (\n typeof document !== \"undefined\" &&\n typeof document.baseURI === \"string\" &&\n document.baseURI.length > 0\n ) {\n return document.baseURI;\n }\n if (\n typeof window !== \"undefined\" &&\n typeof window.location?.href === \"string\" &&\n window.location.href.length > 0\n ) {\n return window.location.href;\n }\n return null;\n}\n\nfunction resolveFetchBaseUrl(requestUrl, responseUrl) {\n if (typeof responseUrl === \"string\" && responseUrl.length > 0) {\n try {\n return new URL(responseUrl);\n } catch {\n // Keep trying the other candidates when an environment reports a malformed response URL.\n }\n }\n\n try {\n return new URL(requestUrl);\n } catch {\n const browserBaseUrl = resolveBrowserRequestBaseUrl();\n if (browserBaseUrl) {\n return new URL(requestUrl, browserBaseUrl);\n }\n throw new Error(\n `Unable to resolve a stable base URL for glTF asset loading: ${String(requestUrl)}`\n );\n }\n}\n\nfunction createIdentityMatrix() {\n return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];\n}\n\nfunction multiplyMatrices(a, b) {\n const out = new Array(16).fill(0);\n for (let column = 0; column < 4; column += 1) {\n for (let row = 0; row < 4; row += 1) {\n out[column * 4 + row] =\n a[0 * 4 + row] * b[column * 4 + 0] +\n a[1 * 4 + row] * b[column * 4 + 1] +\n a[2 * 4 + row] * b[column * 4 + 2] +\n a[3 * 4 + row] * b[column * 4 + 3];\n }\n }\n return out;\n}\n\nfunction composeNodeMatrix(node) {\n if (Array.isArray(node.matrix) && node.matrix.length === 16) {\n return [...node.matrix];\n }\n\n const translation = Array.isArray(node.translation) ? node.translation : [0, 0, 0];\n const rotation = Array.isArray(node.rotation) ? node.rotation : [0, 0, 0, 1];\n const scale = Array.isArray(node.scale) ? node.scale : [1, 1, 1];\n const [x, y, z, w] = rotation;\n const x2 = x + x;\n const y2 = y + y;\n const z2 = z + z;\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n\n return [\n (1 - (yy + zz)) * scale[0],\n (xy + wz) * scale[0],\n (xz - wy) * scale[0],\n 0,\n (xy - wz) * scale[1],\n (1 - (xx + zz)) * scale[1],\n (yz + wx) * scale[1],\n 0,\n (xz + wy) * scale[2],\n (yz - wx) * scale[2],\n (1 - (xx + yy)) * scale[2],\n 0,\n translation[0],\n translation[1],\n translation[2],\n 1,\n ];\n}\n\nfunction transformPosition(position, matrix) {\n return [\n matrix[0] * position[0] + matrix[4] * position[1] + matrix[8] * position[2] + matrix[12],\n matrix[1] * position[0] + matrix[5] * position[1] + matrix[9] * position[2] + matrix[13],\n matrix[2] * position[0] + matrix[6] * position[1] + matrix[10] * position[2] + matrix[14],\n ];\n}\n\nfunction transformNormal(normal, matrix) {\n const transformed = [\n matrix[0] * normal[0] + matrix[4] * normal[1] + matrix[8] * normal[2],\n matrix[1] * normal[0] + matrix[5] * normal[1] + matrix[9] * normal[2],\n matrix[2] * normal[0] + matrix[6] * normal[1] + matrix[10] * normal[2],\n ];\n const length = Math.hypot(transformed[0], transformed[1], transformed[2]) || 1;\n return [transformed[0] / length, transformed[1] / length, transformed[2] / length];\n}\n\nfunction collectScenePrimitives(document, buffers, imageResources) {\n const scene = document.scenes?.[document.scene ?? 0];\n if (!scene || !Array.isArray(scene.nodes) || scene.nodes.length === 0) {\n throw new Error(\"glTF demo asset must expose a default scene with at least one node.\");\n }\n\n const results = [];\n let modelName = null;\n let physics = null;\n\n function visit(nodeIndex, parentMatrix) {\n const node = document.nodes?.[nodeIndex];\n if (!node) {\n throw new Error(`glTF node ${nodeIndex} is missing.`);\n }\n\n const localMatrix = composeNodeMatrix(node);\n const worldMatrix = multiplyMatrices(parentMatrix, localMatrix);\n\n if (!modelName && typeof node.name === \"string\" && node.name.length > 0) {\n modelName = node.name;\n }\n\n if (!physics && node.extras?.physics && typeof node.extras.physics === \"object\") {\n physics = Object.freeze({ ...node.extras.physics });\n }\n\n if (typeof node.mesh === \"number\") {\n const mesh = document.meshes?.[node.mesh];\n if (!mesh || !Array.isArray(mesh.primitives)) {\n throw new Error(`glTF mesh ${node.mesh} is missing primitives.`);\n }\n\n mesh.primitives.forEach((primitive, primitiveIndex) => {\n const positions = readAccessor(document, primitive.attributes.POSITION, buffers);\n const normals =\n typeof primitive.attributes.NORMAL === \"number\"\n ? readAccessor(document, primitive.attributes.NORMAL, buffers)\n : null;\n const colors =\n typeof primitive.attributes.COLOR_0 === \"number\"\n ? readAccessor(document, primitive.attributes.COLOR_0, buffers)\n : null;\n const uvs =\n typeof primitive.attributes.TEXCOORD_0 === \"number\"\n ? readAccessor(document, primitive.attributes.TEXCOORD_0, buffers)\n : null;\n const transformedPositions = [];\n const transformedNormals = [];\n\n for (let index = 0; index < positions.length; index += 3) {\n const point = transformPosition(\n [positions[index], positions[index + 1], positions[index + 2]],\n worldMatrix\n );\n transformedPositions.push(point[0], point[1], point[2]);\n\n if (normals) {\n const normal = transformNormal(\n [normals[index], normals[index + 1], normals[index + 2]],\n worldMatrix\n );\n transformedNormals.push(normal[0], normal[1], normal[2]);\n }\n }\n\n const indices =\n typeof primitive.indices === \"number\"\n ? readAccessor(document, primitive.indices, buffers).map((value) => Number(value))\n : Array.from({ length: transformedPositions.length / 3 }, (_, index) => index);\n const material = getMaterialInfo(document, primitive, imageResources);\n const primitiveName =\n `${node.name ?? mesh.name ?? \"mesh\"}-${primitiveIndex}`;\n\n results.push(\n Object.freeze({\n name: primitiveName,\n positions: Object.freeze(transformedPositions),\n indices: Object.freeze(indices),\n normals:\n transformedNormals.length > 0\n ? Object.freeze(transformedNormals)\n : null,\n uvs: uvs ? Object.freeze(uvs) : null,\n colors: colors ? Object.freeze(colors) : null,\n material,\n bounds: computeBounds(transformedPositions),\n })\n );\n });\n }\n\n if (Array.isArray(node.children)) {\n for (const childIndex of node.children) {\n visit(childIndex, worldMatrix);\n }\n }\n }\n\n for (const rootNodeIndex of scene.nodes) {\n visit(rootNodeIndex, createIdentityMatrix());\n }\n\n if (results.length === 0) {\n throw new Error(\"glTF demo asset must contain at least one mesh primitive.\");\n }\n\n return {\n name: modelName ?? \"gltf-model\",\n physics: physics ?? Object.freeze({}),\n primitives: results,\n };\n}\n\nasync function loadGltfDocument(url) {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to load glTF asset: ${response.status} ${response.statusText}`);\n }\n\n return {\n document: await response.json(),\n baseUrl: resolveFetchBaseUrl(url, response.url),\n };\n}\n\nasync function loadInlineShowcaseDocument() {\n const module = await import(\"./showcase-inline-assets.js\");\n return loadGltfDocument(new URL(module.INLINE_SHOWCASE_ASSET_URLS.brigantine));\n}\n\nasync function buildGltfModel(document, baseUrl) {\n const buffers = await Promise.all(\n (document.buffers ?? []).map(async (buffer) => {\n if (typeof buffer.uri !== \"string\") {\n throw new Error(\"glTF buffer URI is required for demo asset loading.\");\n }\n if (buffer.uri.startsWith(\"data:\")) {\n return decodeDataUri(buffer.uri);\n }\n const nested = await fetch(new URL(buffer.uri, baseUrl));\n if (!nested.ok) {\n throw new Error(`Failed to load glTF buffer: ${nested.status} ${nested.statusText}`);\n }\n return nested.arrayBuffer();\n })\n );\n\n const imageResources = new Map();\n await Promise.all(\n (document.images ?? []).map(async (image, index) => {\n const pixels = await loadImageResource(document, image, index, buffers, baseUrl);\n if (pixels) {\n imageResources.set(index, pixels);\n }\n })\n );\n\n const scene = collectScenePrimitives(document, buffers, imageResources);\n const aggregatePositions = [];\n const aggregateIndices = [];\n\n for (const primitive of scene.primitives) {\n const vertexOffset = aggregatePositions.length / 3;\n appendValues(aggregatePositions, primitive.positions);\n appendIndicesWithOffset(aggregateIndices, primitive.indices, vertexOffset);\n }\n\n const color = scene.primitives[0]?.material?.color ?? { r: 0.56, g: 0.33, b: 0.22, a: 1 };\n\n return Object.freeze({\n name: scene.name,\n positions: Object.freeze(aggregatePositions),\n indices: Object.freeze(aggregateIndices),\n bounds: computeBounds(aggregatePositions),\n color: Object.freeze({ ...color }),\n physics: scene.physics,\n primitives: Object.freeze(scene.primitives),\n });\n}\n\nfunction shouldRetryWithInlineShowcaseFallback(url, error) {\n if (!shouldUseInlineShowcaseFallback(url)) {\n return false;\n }\n\n return error instanceof TypeError || /^Failed to load glTF asset:/u.test(error.message);\n}\n\nexport async function loadGltfModel(url) {\n try {\n const { document, baseUrl } = await loadGltfDocument(url);\n return buildGltfModel(document, baseUrl);\n } catch (error) {\n if (!shouldRetryWithInlineShowcaseFallback(url, error)) {\n throw error;\n }\n\n const { document, baseUrl } = await loadInlineShowcaseDocument();\n return buildGltfModel(document, baseUrl);\n }\n}\n"],"mappings":"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","names":["document"]}
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  loadGltfModel
3
- } from "./chunk-QVNRTWHB.js";
3
+ } from "./chunk-UKCJ2AWJ.js";
4
4
  import "./chunk-2GM64LB6.js";
5
5
  import "./chunk-DGUM43GV.js";
6
6
  export {
7
7
  loadGltfModel
8
8
  };
9
- //# sourceMappingURL=gltf-loader-B6VOWGBV.js.map
9
+ //# sourceMappingURL=gltf-loader-FMRC3OEV.js.map
package/dist/index.cjs CHANGED
@@ -295,6 +295,33 @@ function getTypeSize(type) {
295
295
  throw new Error(`Unsupported glTF accessor type: ${type}`);
296
296
  }
297
297
  }
298
+ function getComponentByteSize(componentType) {
299
+ switch (componentType) {
300
+ case 5121:
301
+ return 1;
302
+ case 5123:
303
+ return 2;
304
+ case 5125:
305
+ case 5126:
306
+ return 4;
307
+ default:
308
+ throw new Error(`Unsupported glTF componentType: ${componentType}`);
309
+ }
310
+ }
311
+ function readComponentValue(view, componentType, byteOffset) {
312
+ switch (componentType) {
313
+ case 5121:
314
+ return view.getUint8(byteOffset);
315
+ case 5123:
316
+ return view.getUint16(byteOffset, true);
317
+ case 5125:
318
+ return view.getUint32(byteOffset, true);
319
+ case 5126:
320
+ return view.getFloat32(byteOffset, true);
321
+ default:
322
+ throw new Error(`Unsupported glTF componentType: ${componentType}`);
323
+ }
324
+ }
298
325
  function readAccessor(document2, accessorIndex, buffers) {
299
326
  const accessor = document2.accessors?.[accessorIndex];
300
327
  if (!accessor) {
@@ -307,20 +334,255 @@ function readAccessor(document2, accessorIndex, buffers) {
307
334
  const buffer = buffers[bufferView.buffer];
308
335
  const componentCount = getTypeSize(accessor.type);
309
336
  const byteOffset = (bufferView.byteOffset ?? 0) + (accessor.byteOffset ?? 0);
310
- const valueCount = accessor.count * componentCount;
311
- const values = Array.from(
312
- getComponentArray(accessor.componentType, buffer, byteOffset, valueCount)
313
- );
337
+ const componentByteSize = getComponentByteSize(accessor.componentType);
338
+ const packedElementByteLength = componentCount * componentByteSize;
339
+ const byteStride = Math.max(bufferView.byteStride ?? packedElementByteLength, packedElementByteLength);
340
+ let values;
341
+ if (byteStride === packedElementByteLength) {
342
+ const valueCount = accessor.count * componentCount;
343
+ values = Array.from(
344
+ getComponentArray(accessor.componentType, buffer, byteOffset, valueCount)
345
+ );
346
+ } else {
347
+ const view = new DataView(buffer, byteOffset);
348
+ values = new Array(accessor.count * componentCount);
349
+ for (let index = 0; index < accessor.count; index += 1) {
350
+ const elementOffset = index * byteStride;
351
+ for (let componentIndex = 0; componentIndex < componentCount; componentIndex += 1) {
352
+ values[index * componentCount + componentIndex] = readComponentValue(
353
+ view,
354
+ accessor.componentType,
355
+ elementOffset + componentIndex * componentByteSize
356
+ );
357
+ }
358
+ }
359
+ }
314
360
  if (accessor.normalized) {
315
361
  const scale = getNormalizationScale(accessor.componentType);
316
362
  return values.map((value) => value / scale);
317
363
  }
318
364
  return values;
319
365
  }
320
- function getMaterialInfo(document2, primitive) {
366
+ async function decodeImagePixels(blob, urlLabel = "glTF texture") {
367
+ if (typeof createImageBitmap === "function") {
368
+ const bitmap = await createImageBitmap(blob);
369
+ try {
370
+ const canvas = typeof OffscreenCanvas === "function" ? new OffscreenCanvas(bitmap.width, bitmap.height) : typeof document !== "undefined" ? Object.assign(document.createElement("canvas"), {
371
+ width: bitmap.width,
372
+ height: bitmap.height
373
+ }) : null;
374
+ const context = canvas?.getContext?.("2d", { willReadFrequently: true });
375
+ if (!context) {
376
+ throw new Error("Unable to create 2D context for glTF texture decode.");
377
+ }
378
+ context.drawImage(bitmap, 0, 0);
379
+ const imageData = context.getImageData(0, 0, bitmap.width, bitmap.height);
380
+ return Object.freeze({
381
+ width: bitmap.width,
382
+ height: bitmap.height,
383
+ data: imageData.data
384
+ });
385
+ } finally {
386
+ bitmap.close?.();
387
+ }
388
+ }
389
+ if (typeof document === "undefined") {
390
+ throw new Error(`Unable to decode ${urlLabel}: browser image decode APIs are unavailable.`);
391
+ }
392
+ const objectUrl = URL.createObjectURL(blob);
393
+ try {
394
+ const image = await new Promise((resolve, reject) => {
395
+ const element = new Image();
396
+ element.onload = () => resolve(element);
397
+ element.onerror = () => reject(new Error(`Failed to decode ${urlLabel}.`));
398
+ element.src = objectUrl;
399
+ });
400
+ const canvas = Object.assign(document.createElement("canvas"), {
401
+ width: image.naturalWidth || image.width,
402
+ height: image.naturalHeight || image.height
403
+ });
404
+ const context = canvas.getContext("2d", { willReadFrequently: true });
405
+ if (!context) {
406
+ throw new Error("Unable to create 2D context for glTF texture decode.");
407
+ }
408
+ context.drawImage(image, 0, 0);
409
+ const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
410
+ return Object.freeze({
411
+ width: canvas.width,
412
+ height: canvas.height,
413
+ data: imageData.data
414
+ });
415
+ } finally {
416
+ URL.revokeObjectURL(objectUrl);
417
+ }
418
+ }
419
+ function sliceBufferView(document2, bufferViewIndex, buffers) {
420
+ const bufferView = document2.bufferViews?.[bufferViewIndex];
421
+ if (!bufferView) {
422
+ throw new Error(`glTF bufferView ${bufferViewIndex} is missing.`);
423
+ }
424
+ const buffer = buffers[bufferView.buffer];
425
+ if (!buffer) {
426
+ throw new Error(`glTF buffer ${bufferView.buffer} is missing.`);
427
+ }
428
+ const start = bufferView.byteOffset ?? 0;
429
+ const end = start + (bufferView.byteLength ?? 0);
430
+ return buffer.slice(start, end);
431
+ }
432
+ async function loadImageResource(document2, image, index, buffers, baseUrl2) {
433
+ if (typeof image?.uri === "string") {
434
+ const response = await fetch(new URL(image.uri, baseUrl2));
435
+ if (!response.ok) {
436
+ throw new Error(`Failed to load glTF texture: ${response.status} ${response.statusText}`);
437
+ }
438
+ return decodeImagePixels(
439
+ await response.blob(),
440
+ `glTF texture ${index}${image.uri ? ` (${image.uri})` : ""}`
441
+ );
442
+ }
443
+ if (typeof image?.bufferView === "number") {
444
+ const bytes = sliceBufferView(document2, image.bufferView, buffers);
445
+ return decodeImagePixels(
446
+ new Blob([bytes], { type: image.mimeType ?? "application/octet-stream" }),
447
+ `glTF texture ${index}`
448
+ );
449
+ }
450
+ return null;
451
+ }
452
+ function normalizeTextureTransformPair(value, fallback) {
453
+ if (!Array.isArray(value) || value.length < 2) {
454
+ return fallback;
455
+ }
456
+ return [
457
+ Number.isFinite(value[0]) ? Number(value[0]) : fallback[0],
458
+ Number.isFinite(value[1]) ? Number(value[1]) : fallback[1]
459
+ ];
460
+ }
461
+ function readTextureTransform(textureRef) {
462
+ const transformExtension = textureRef?.extensions?.KHR_texture_transform ?? null;
463
+ return {
464
+ texCoord: typeof transformExtension?.texCoord === "number" ? transformExtension.texCoord : textureRef?.texCoord ?? 0,
465
+ offset: normalizeTextureTransformPair(transformExtension?.offset, [0, 0]),
466
+ scale: normalizeTextureTransformPair(transformExtension?.scale, [1, 1]),
467
+ rotation: Number.isFinite(transformExtension?.rotation) ? Number(transformExtension.rotation) : 0
468
+ };
469
+ }
470
+ function wrapTextureCoordinate(value) {
471
+ return (value % 1 + 1) % 1;
472
+ }
473
+ function transformTextureCoordinate(uv, transform) {
474
+ const scaledU = uv[0] * transform.scale[0];
475
+ const scaledV = uv[1] * transform.scale[1];
476
+ const cosine = Math.cos(transform.rotation);
477
+ const sine = Math.sin(transform.rotation);
478
+ return [
479
+ scaledU * cosine - scaledV * sine + transform.offset[0],
480
+ scaledU * sine + scaledV * cosine + transform.offset[1]
481
+ ];
482
+ }
483
+ function readTexturePixel(data, width, height, x, y) {
484
+ const clampedX = Math.min(width - 1, Math.max(0, x));
485
+ const clampedY = Math.min(height - 1, Math.max(0, y));
486
+ const offset = (clampedY * width + clampedX) * 4;
487
+ return [
488
+ data[offset] ?? 0,
489
+ data[offset + 1] ?? 0,
490
+ data[offset + 2] ?? 0,
491
+ data[offset + 3] ?? 255
492
+ ];
493
+ }
494
+ function mixChannel(a, b, weight) {
495
+ return a + (b - a) * weight;
496
+ }
497
+ function sampleTexturePixel(data, width, height, uv) {
498
+ const u = wrapTextureCoordinate(uv[0]);
499
+ const v = wrapTextureCoordinate(uv[1]);
500
+ const sourceX = u * Math.max(width - 1, 0);
501
+ const sourceY = (1 - v) * Math.max(height - 1, 0);
502
+ const x0 = Math.floor(sourceX);
503
+ const y0 = Math.floor(sourceY);
504
+ const x1 = Math.min(width - 1, x0 + 1);
505
+ const y1 = Math.min(height - 1, y0 + 1);
506
+ const tx = sourceX - x0;
507
+ const ty = sourceY - y0;
508
+ const topLeft = readTexturePixel(data, width, height, x0, y0);
509
+ const topRight = readTexturePixel(data, width, height, x1, y0);
510
+ const bottomLeft = readTexturePixel(data, width, height, x0, y1);
511
+ const bottomRight = readTexturePixel(data, width, height, x1, y1);
512
+ return [0, 1, 2, 3].map((channelIndex) => {
513
+ const top = mixChannel(topLeft[channelIndex], topRight[channelIndex], tx);
514
+ const bottom = mixChannel(bottomLeft[channelIndex], bottomRight[channelIndex], tx);
515
+ return mixChannel(top, bottom, ty);
516
+ });
517
+ }
518
+ function applyTextureTransformToPixels(pixels, transform) {
519
+ const isIdentityTransform = transform.offset[0] === 0 && transform.offset[1] === 0 && transform.scale[0] === 1 && transform.scale[1] === 1 && transform.rotation === 0;
520
+ if (isIdentityTransform) {
521
+ return pixels;
522
+ }
523
+ const transformedData = new Uint8ClampedArray(pixels.data.length);
524
+ for (let y = 0; y < pixels.height; y += 1) {
525
+ const outputV = pixels.height > 1 ? 1 - y / (pixels.height - 1) : 0;
526
+ for (let x = 0; x < pixels.width; x += 1) {
527
+ const outputU = pixels.width > 1 ? x / (pixels.width - 1) : 0;
528
+ const sourcePixel = sampleTexturePixel(
529
+ pixels.data,
530
+ pixels.width,
531
+ pixels.height,
532
+ transformTextureCoordinate([outputU, outputV], transform)
533
+ );
534
+ const offset = (y * pixels.width + x) * 4;
535
+ transformedData[offset] = sourcePixel[0];
536
+ transformedData[offset + 1] = sourcePixel[1];
537
+ transformedData[offset + 2] = sourcePixel[2];
538
+ transformedData[offset + 3] = sourcePixel[3];
539
+ }
540
+ }
541
+ return Object.freeze({
542
+ width: pixels.width,
543
+ height: pixels.height,
544
+ data: transformedData
545
+ });
546
+ }
547
+ function getMaterialTexture(document2, textureRef, imageResources) {
548
+ if (!textureRef || typeof textureRef.index !== "number") {
549
+ return null;
550
+ }
551
+ const texture = document2.textures?.[textureRef.index] ?? null;
552
+ const sourceIndex = texture?.source;
553
+ if (typeof sourceIndex !== "number") {
554
+ return null;
555
+ }
556
+ const pixels = imageResources.get(sourceIndex) ?? null;
557
+ if (!pixels) {
558
+ return null;
559
+ }
560
+ const transform = readTextureTransform(textureRef);
561
+ const transformedPixels = applyTextureTransformToPixels(pixels, transform);
562
+ return Object.freeze({
563
+ texCoord: transform.texCoord,
564
+ scale: textureRef.scale,
565
+ strength: textureRef.strength,
566
+ width: transformedPixels.width,
567
+ height: transformedPixels.height,
568
+ data: transformedPixels.data
569
+ });
570
+ }
571
+ function getMaterialInfo(document2, primitive, imageResources) {
321
572
  const material = document2.materials?.[primitive.material] ?? null;
322
- const factor = material?.pbrMetallicRoughness?.baseColorFactor ?? [0.56, 0.33, 0.22, 1];
323
- const emissive = material?.emissiveFactor ?? [0, 0, 0];
573
+ const pbr = material?.pbrMetallicRoughness ?? null;
574
+ const factor = pbr?.baseColorFactor ?? [0.56, 0.33, 0.22, 1];
575
+ const emissive = Array.isArray(material?.emissiveFactor) ? material.emissiveFactor : [0, 0, 0];
576
+ const extensions = material?.extensions ?? {};
577
+ const specular = extensions.KHR_materials_specular ?? null;
578
+ const transmission = extensions.KHR_materials_transmission ?? null;
579
+ const ior = extensions.KHR_materials_ior ?? null;
580
+ const clearcoat = extensions.KHR_materials_clearcoat ?? null;
581
+ const sheen = extensions.KHR_materials_sheen ?? null;
582
+ const volume = extensions.KHR_materials_volume ?? null;
583
+ const iridescence = extensions.KHR_materials_iridescence ?? null;
584
+ const anisotropy = extensions.KHR_materials_anisotropy ?? null;
585
+ const dispersion = extensions.KHR_materials_dispersion ?? null;
324
586
  return Object.freeze({
325
587
  name: material?.name ?? "default-material",
326
588
  color: Object.freeze({
@@ -329,13 +591,88 @@ function getMaterialInfo(document2, primitive) {
329
591
  b: factor[2],
330
592
  a: factor[3] ?? 1
331
593
  }),
332
- roughness: typeof material?.pbrMetallicRoughness?.roughnessFactor === "number" ? material.pbrMetallicRoughness.roughnessFactor : 0.92,
333
- metallic: typeof material?.pbrMetallicRoughness?.metallicFactor === "number" ? material.pbrMetallicRoughness.metallicFactor : 0.08,
594
+ roughness: typeof pbr?.roughnessFactor === "number" ? pbr.roughnessFactor : 0.92,
595
+ metallic: typeof pbr?.metallicFactor === "number" ? pbr.metallicFactor : 0.08,
596
+ opacity: factor[3] ?? 1,
334
597
  emissive: Object.freeze({
335
598
  r: emissive[0] ?? 0,
336
599
  g: emissive[1] ?? 0,
337
- b: emissive[2] ?? 0
338
- })
600
+ b: emissive[2] ?? 0,
601
+ a: 1
602
+ }),
603
+ baseColorTexture: getMaterialTexture(document2, pbr?.baseColorTexture, imageResources),
604
+ metallicRoughnessTexture: getMaterialTexture(
605
+ document2,
606
+ pbr?.metallicRoughnessTexture,
607
+ imageResources
608
+ ),
609
+ normalTexture: getMaterialTexture(document2, material?.normalTexture, imageResources),
610
+ occlusionTexture: getMaterialTexture(document2, material?.occlusionTexture, imageResources),
611
+ emissiveTexture: getMaterialTexture(document2, material?.emissiveTexture, imageResources),
612
+ specular: typeof specular?.specularFactor === "number" ? specular.specularFactor : 1,
613
+ specularColor: Object.freeze(
614
+ Array.isArray(specular?.specularColorFactor) ? [...specular.specularColorFactor] : [1, 1, 1]
615
+ ),
616
+ specularTexture: getMaterialTexture(document2, specular?.specularTexture, imageResources),
617
+ specularColorTexture: getMaterialTexture(
618
+ document2,
619
+ specular?.specularColorTexture,
620
+ imageResources
621
+ ),
622
+ transmission: typeof transmission?.transmissionFactor === "number" ? transmission.transmissionFactor : 0,
623
+ transmissionTexture: getMaterialTexture(
624
+ document2,
625
+ transmission?.transmissionTexture,
626
+ imageResources
627
+ ),
628
+ ior: typeof ior?.ior === "number" ? ior.ior : 1.45,
629
+ attenuationDistance: typeof volume?.attenuationDistance === "number" ? volume.attenuationDistance : null,
630
+ attenuationColor: Object.freeze(
631
+ Array.isArray(volume?.attenuationColor) ? [...volume.attenuationColor] : [1, 1, 1]
632
+ ),
633
+ thickness: typeof volume?.thicknessFactor === "number" ? volume.thicknessFactor : 0,
634
+ thicknessTexture: getMaterialTexture(document2, volume?.thicknessTexture, imageResources),
635
+ clearcoat: typeof clearcoat?.clearcoatFactor === "number" ? clearcoat.clearcoatFactor : 0,
636
+ clearcoatTexture: getMaterialTexture(document2, clearcoat?.clearcoatTexture, imageResources),
637
+ clearcoatRoughness: typeof clearcoat?.clearcoatRoughnessFactor === "number" ? clearcoat.clearcoatRoughnessFactor : 0.08,
638
+ clearcoatRoughnessTexture: getMaterialTexture(
639
+ document2,
640
+ clearcoat?.clearcoatRoughnessTexture,
641
+ imageResources
642
+ ),
643
+ clearcoatNormalTexture: getMaterialTexture(
644
+ document2,
645
+ clearcoat?.clearcoatNormalTexture,
646
+ imageResources
647
+ ),
648
+ sheenColor: Object.freeze(
649
+ Array.isArray(sheen?.sheenColorFactor) ? [...sheen.sheenColorFactor] : [0, 0, 0]
650
+ ),
651
+ sheenColorTexture: getMaterialTexture(document2, sheen?.sheenColorTexture, imageResources),
652
+ sheenRoughness: typeof sheen?.sheenRoughnessFactor === "number" ? sheen.sheenRoughnessFactor : 0,
653
+ sheenRoughnessTexture: getMaterialTexture(
654
+ document2,
655
+ sheen?.sheenRoughnessTexture,
656
+ imageResources
657
+ ),
658
+ iridescence: typeof iridescence?.iridescenceFactor === "number" ? iridescence.iridescenceFactor : 0,
659
+ iridescenceTexture: getMaterialTexture(
660
+ document2,
661
+ iridescence?.iridescenceTexture,
662
+ imageResources
663
+ ),
664
+ iridescenceIor: typeof iridescence?.iridescenceIor === "number" ? iridescence.iridescenceIor : 1.3,
665
+ iridescenceThicknessMinimum: typeof iridescence?.iridescenceThicknessMinimum === "number" ? iridescence.iridescenceThicknessMinimum : 100,
666
+ iridescenceThicknessMaximum: typeof iridescence?.iridescenceThicknessMaximum === "number" ? iridescence.iridescenceThicknessMaximum : 400,
667
+ iridescenceThicknessTexture: getMaterialTexture(
668
+ document2,
669
+ iridescence?.iridescenceThicknessTexture,
670
+ imageResources
671
+ ),
672
+ anisotropy: typeof anisotropy?.anisotropyStrength === "number" ? anisotropy.anisotropyStrength : 0,
673
+ anisotropyRotation: typeof anisotropy?.anisotropyRotation === "number" ? anisotropy.anisotropyRotation : 0,
674
+ anisotropyTexture: getMaterialTexture(document2, anisotropy?.anisotropyTexture, imageResources),
675
+ dispersion: typeof dispersion?.dispersion === "number" ? dispersion.dispersion : 0
339
676
  });
340
677
  }
341
678
  function computeBounds(positions) {
@@ -467,7 +804,7 @@ function transformNormal(normal, matrix) {
467
804
  const length = Math.hypot(transformed[0], transformed[1], transformed[2]) || 1;
468
805
  return [transformed[0] / length, transformed[1] / length, transformed[2] / length];
469
806
  }
470
- function collectScenePrimitives(document2, buffers) {
807
+ function collectScenePrimitives(document2, buffers, imageResources) {
471
808
  const scene = document2.scenes?.[document2.scene ?? 0];
472
809
  if (!scene || !Array.isArray(scene.nodes) || scene.nodes.length === 0) {
473
810
  throw new Error("glTF demo asset must expose a default scene with at least one node.");
@@ -497,6 +834,7 @@ function collectScenePrimitives(document2, buffers) {
497
834
  const positions = readAccessor(document2, primitive.attributes.POSITION, buffers);
498
835
  const normals = typeof primitive.attributes.NORMAL === "number" ? readAccessor(document2, primitive.attributes.NORMAL, buffers) : null;
499
836
  const colors = typeof primitive.attributes.COLOR_0 === "number" ? readAccessor(document2, primitive.attributes.COLOR_0, buffers) : null;
837
+ const uvs = typeof primitive.attributes.TEXCOORD_0 === "number" ? readAccessor(document2, primitive.attributes.TEXCOORD_0, buffers) : null;
500
838
  const transformedPositions = [];
501
839
  const transformedNormals = [];
502
840
  for (let index = 0; index < positions.length; index += 3) {
@@ -514,7 +852,7 @@ function collectScenePrimitives(document2, buffers) {
514
852
  }
515
853
  }
516
854
  const indices = typeof primitive.indices === "number" ? readAccessor(document2, primitive.indices, buffers).map((value) => Number(value)) : Array.from({ length: transformedPositions.length / 3 }, (_, index) => index);
517
- const material = getMaterialInfo(document2, primitive);
855
+ const material = getMaterialInfo(document2, primitive, imageResources);
518
856
  const primitiveName = `${node.name ?? mesh.name ?? "mesh"}-${primitiveIndex}`;
519
857
  results.push(
520
858
  Object.freeze({
@@ -522,6 +860,7 @@ function collectScenePrimitives(document2, buffers) {
522
860
  positions: Object.freeze(transformedPositions),
523
861
  indices: Object.freeze(indices),
524
862
  normals: transformedNormals.length > 0 ? Object.freeze(transformedNormals) : null,
863
+ uvs: uvs ? Object.freeze(uvs) : null,
525
864
  colors: colors ? Object.freeze(colors) : null,
526
865
  material,
527
866
  bounds: computeBounds(transformedPositions)
@@ -577,7 +916,16 @@ async function buildGltfModel(document2, baseUrl2) {
577
916
  return nested.arrayBuffer();
578
917
  })
579
918
  );
580
- const scene = collectScenePrimitives(document2, buffers);
919
+ const imageResources = /* @__PURE__ */ new Map();
920
+ await Promise.all(
921
+ (document2.images ?? []).map(async (image, index) => {
922
+ const pixels = await loadImageResource(document2, image, index, buffers, baseUrl2);
923
+ if (pixels) {
924
+ imageResources.set(index, pixels);
925
+ }
926
+ })
927
+ );
928
+ const scene = collectScenePrimitives(document2, buffers, imageResources);
581
929
  const aggregatePositions = [];
582
930
  const aggregateIndices = [];
583
931
  for (const primitive of scene.primitives) {
@@ -2253,18 +2601,56 @@ function createProductStudioMeshFromPrimitive(primitive, primitiveIndex, transfo
2253
2601
  const indices = Array.isArray(primitive.indices) && primitive.indices.length >= 3 ? [...primitive.indices] : Array.from({ length: positions.length / 3 }, (_, index) => index);
2254
2602
  const material = primitive.material ?? {};
2255
2603
  const color = readMaterialColor(material);
2604
+ const uvs = Array.isArray(primitive.uvs) ? [...primitive.uvs] : null;
2256
2605
  return Object.freeze({
2257
2606
  id: 1e3 + primitiveIndex,
2258
2607
  positions: Object.freeze(positions),
2259
2608
  indices: Object.freeze(indices),
2260
2609
  normals: Array.isArray(primitive.normals) ? Object.freeze([...primitive.normals]) : null,
2610
+ uvs: uvs ? Object.freeze(uvs) : null,
2611
+ material: Object.freeze({ ...material }),
2261
2612
  color: Object.freeze(color),
2262
2613
  emission: Object.freeze(readEmission(material)),
2263
2614
  materialKind: readMaterialKind(material),
2264
2615
  materialRefId: 1e3 + primitiveIndex,
2265
2616
  roughness: Number.isFinite(material.roughness) ? material.roughness : 0.72,
2266
2617
  metallic: Number.isFinite(material.metallic) ? material.metallic : 0,
2267
- opacity: color[3]
2618
+ opacity: color[3],
2619
+ baseColorTexture: material.baseColorTexture ?? null,
2620
+ metallicRoughnessTexture: material.metallicRoughnessTexture ?? null,
2621
+ normalTexture: material.normalTexture ?? null,
2622
+ occlusionTexture: material.occlusionTexture ?? null,
2623
+ emissiveTexture: material.emissiveTexture ?? null,
2624
+ specular: Number.isFinite(material.specular) ? material.specular : 1,
2625
+ specularColor: Array.isArray(material.specularColor) ? Object.freeze([...material.specularColor]) : void 0,
2626
+ specularTexture: material.specularTexture ?? null,
2627
+ specularColorTexture: material.specularColorTexture ?? null,
2628
+ transmission: Number.isFinite(material.transmission) ? material.transmission : 0,
2629
+ transmissionTexture: material.transmissionTexture ?? null,
2630
+ ior: Number.isFinite(material.ior) ? material.ior : void 0,
2631
+ thickness: Number.isFinite(material.thickness) ? material.thickness : void 0,
2632
+ thicknessTexture: material.thicknessTexture ?? null,
2633
+ attenuationDistance: Number.isFinite(material.attenuationDistance) ? material.attenuationDistance : null,
2634
+ attenuationColor: Array.isArray(material.attenuationColor) ? Object.freeze([...material.attenuationColor]) : void 0,
2635
+ clearcoat: Number.isFinite(material.clearcoat) ? material.clearcoat : void 0,
2636
+ clearcoatTexture: material.clearcoatTexture ?? null,
2637
+ clearcoatRoughness: Number.isFinite(material.clearcoatRoughness) ? material.clearcoatRoughness : void 0,
2638
+ clearcoatRoughnessTexture: material.clearcoatRoughnessTexture ?? null,
2639
+ clearcoatNormalTexture: material.clearcoatNormalTexture ?? null,
2640
+ sheenColor: Array.isArray(material.sheenColor) ? Object.freeze([...material.sheenColor]) : void 0,
2641
+ sheenColorTexture: material.sheenColorTexture ?? null,
2642
+ sheenRoughness: Number.isFinite(material.sheenRoughness) ? material.sheenRoughness : void 0,
2643
+ sheenRoughnessTexture: material.sheenRoughnessTexture ?? null,
2644
+ iridescence: Number.isFinite(material.iridescence) ? material.iridescence : void 0,
2645
+ iridescenceTexture: material.iridescenceTexture ?? null,
2646
+ iridescenceIor: Number.isFinite(material.iridescenceIor) ? material.iridescenceIor : void 0,
2647
+ iridescenceThicknessMinimum: Number.isFinite(material.iridescenceThicknessMinimum) ? material.iridescenceThicknessMinimum : void 0,
2648
+ iridescenceThicknessMaximum: Number.isFinite(material.iridescenceThicknessMaximum) ? material.iridescenceThicknessMaximum : void 0,
2649
+ iridescenceThicknessTexture: material.iridescenceThicknessTexture ?? null,
2650
+ anisotropy: Number.isFinite(material.anisotropy) ? material.anisotropy : void 0,
2651
+ anisotropyRotation: Number.isFinite(material.anisotropyRotation) ? material.anisotropyRotation : void 0,
2652
+ anisotropyTexture: material.anisotropyTexture ?? null,
2653
+ dispersion: Number.isFinite(material.dispersion) ? material.dispersion : void 0
2268
2654
  });
2269
2655
  }
2270
2656
  function createProductStudioMeshes(model, options = {}) {