@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.
- package/CHANGELOG.md +9 -0
- package/README.md +3 -0
- package/dist/{chunk-6SOHFUOE.js → chunk-BXTHIQOO.js} +41 -3
- package/dist/chunk-BXTHIQOO.js.map +1 -0
- package/dist/chunk-UKCJ2AWJ.js +793 -0
- package/dist/chunk-UKCJ2AWJ.js.map +1 -0
- package/dist/{gltf-loader-B6VOWGBV.js → gltf-loader-FMRC3OEV.js} +2 -2
- package/dist/index.cjs +401 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5 -5
- package/dist/{product-studio-runtime-BYVBUWIN.js → product-studio-runtime-CTXA45RJ.js} +3 -3
- package/dist/{showcase-runtime-M6TEUYOG.js → showcase-runtime-OH3H6ZW2.js} +2 -2
- package/package.json +2 -2
- package/src/gltf-loader.js +447 -15
- package/src/index.d.ts +83 -0
- package/src/product-studio-runtime.js +53 -0
- package/dist/chunk-6SOHFUOE.js.map +0 -1
- package/dist/chunk-QVNRTWHB.js +0 -445
- package/dist/chunk-QVNRTWHB.js.map +0 -1
- /package/dist/{gltf-loader-B6VOWGBV.js.map → gltf-loader-FMRC3OEV.js.map} +0 -0
- /package/dist/{product-studio-runtime-BYVBUWIN.js.map → product-studio-runtime-CTXA45RJ.js.map} +0 -0
- /package/dist/{showcase-runtime-M6TEUYOG.js.map → showcase-runtime-OH3H6ZW2.js.map} +0 -0
|
@@ -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-
|
|
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-
|
|
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
|
|
311
|
-
const
|
|
312
|
-
|
|
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
|
|
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
|
|
323
|
-
const
|
|
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
|
|
333
|
-
metallic: typeof
|
|
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
|
|
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 = {}) {
|