@luma.gl/gltf 9.2.6 → 9.3.0-alpha.10
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/dist/dist.dev.js +1362 -313
- package/dist/dist.min.js +98 -46
- package/dist/gltf/animations/animations.d.ts +16 -4
- package/dist/gltf/animations/animations.d.ts.map +1 -1
- package/dist/gltf/animations/interpolate.d.ts +4 -3
- package/dist/gltf/animations/interpolate.d.ts.map +1 -1
- package/dist/gltf/animations/interpolate.js +27 -36
- package/dist/gltf/animations/interpolate.js.map +1 -1
- package/dist/gltf/create-gltf-model.d.ts +15 -1
- package/dist/gltf/create-gltf-model.d.ts.map +1 -1
- package/dist/gltf/create-gltf-model.js +154 -48
- package/dist/gltf/create-gltf-model.js.map +1 -1
- package/dist/gltf/create-scenegraph-from-gltf.d.ts +39 -2
- package/dist/gltf/create-scenegraph-from-gltf.d.ts.map +1 -1
- package/dist/gltf/create-scenegraph-from-gltf.js +76 -6
- package/dist/gltf/create-scenegraph-from-gltf.js.map +1 -1
- package/dist/gltf/gltf-animator.d.ts +26 -0
- package/dist/gltf/gltf-animator.d.ts.map +1 -1
- package/dist/gltf/gltf-animator.js +22 -19
- package/dist/gltf/gltf-animator.js.map +1 -1
- package/dist/gltf/gltf-extension-support.d.ts +10 -0
- package/dist/gltf/gltf-extension-support.d.ts.map +1 -0
- package/dist/gltf/gltf-extension-support.js +173 -0
- package/dist/gltf/gltf-extension-support.js.map +1 -0
- package/dist/index.cjs +1302 -276
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/parsers/parse-gltf-animations.d.ts +1 -0
- package/dist/parsers/parse-gltf-animations.d.ts.map +1 -1
- package/dist/parsers/parse-gltf-animations.js +73 -28
- package/dist/parsers/parse-gltf-animations.js.map +1 -1
- package/dist/parsers/parse-gltf-lights.d.ts +5 -0
- package/dist/parsers/parse-gltf-lights.d.ts.map +1 -0
- package/dist/parsers/parse-gltf-lights.js +163 -0
- package/dist/parsers/parse-gltf-lights.js.map +1 -0
- package/dist/parsers/parse-gltf.d.ts +19 -2
- package/dist/parsers/parse-gltf.d.ts.map +1 -1
- package/dist/parsers/parse-gltf.js +101 -61
- package/dist/parsers/parse-gltf.js.map +1 -1
- package/dist/parsers/parse-pbr-material.d.ts +115 -2
- package/dist/parsers/parse-pbr-material.d.ts.map +1 -1
- package/dist/parsers/parse-pbr-material.js +570 -54
- package/dist/parsers/parse-pbr-material.js.map +1 -1
- package/dist/pbr/pbr-environment.d.ts +10 -4
- package/dist/pbr/pbr-environment.d.ts.map +1 -1
- package/dist/pbr/pbr-environment.js +18 -15
- package/dist/pbr/pbr-environment.js.map +1 -1
- package/dist/pbr/pbr-material.d.ts +13 -3
- package/dist/pbr/pbr-material.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-attribute.d.ts +12 -1
- package/dist/webgl-to-webgpu/convert-webgl-attribute.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-attribute.js +3 -0
- package/dist/webgl-to-webgpu/convert-webgl-attribute.js.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-sampler.d.ts +11 -5
- package/dist/webgl-to-webgpu/convert-webgl-sampler.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-sampler.js +16 -12
- package/dist/webgl-to-webgpu/convert-webgl-sampler.js.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-topology.d.ts +2 -9
- package/dist/webgl-to-webgpu/convert-webgl-topology.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-topology.js +2 -14
- package/dist/webgl-to-webgpu/convert-webgl-topology.js.map +1 -1
- package/dist/webgl-to-webgpu/gltf-webgl-constants.d.ts +27 -0
- package/dist/webgl-to-webgpu/gltf-webgl-constants.d.ts.map +1 -0
- package/dist/webgl-to-webgpu/gltf-webgl-constants.js +34 -0
- package/dist/webgl-to-webgpu/gltf-webgl-constants.js.map +1 -0
- package/package.json +8 -9
- package/src/gltf/animations/animations.ts +17 -5
- package/src/gltf/animations/interpolate.ts +49 -68
- package/src/gltf/create-gltf-model.ts +214 -48
- package/src/gltf/create-scenegraph-from-gltf.ts +134 -11
- package/src/gltf/gltf-animator.ts +34 -25
- package/src/gltf/gltf-extension-support.ts +214 -0
- package/src/index.ts +11 -2
- package/src/parsers/parse-gltf-animations.ts +94 -33
- package/src/parsers/parse-gltf-lights.ts +218 -0
- package/src/parsers/parse-gltf.ts +170 -90
- package/src/parsers/parse-pbr-material.ts +870 -80
- package/src/pbr/pbr-environment.ts +44 -21
- package/src/pbr/pbr-material.ts +18 -3
- package/src/webgl-to-webgpu/convert-webgl-attribute.ts +12 -1
- package/src/webgl-to-webgpu/convert-webgl-sampler.ts +38 -29
- package/src/webgl-to-webgpu/convert-webgl-topology.ts +2 -14
- package/src/webgl-to-webgpu/gltf-webgl-constants.ts +35 -0
- package/dist/utils/deep-copy.d.ts +0 -3
- package/dist/utils/deep-copy.d.ts.map +0 -1
- package/dist/utils/deep-copy.js +0 -21
- package/dist/utils/deep-copy.js.map +0 -1
- package/src/utils/deep-copy.ts +0 -22
package/dist/index.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/index.ts", "../src/pbr/pbr-environment.ts", "../src/parsers/parse-pbr-material.ts", "../src/webgl-to-webgpu/convert-webgl-sampler.ts", "../src/parsers/parse-gltf.ts", "../src/webgl-to-webgpu/convert-webgl-topology.ts", "../src/gltf/create-gltf-model.ts", "../src/gltf/gltf-animator.ts", "../src/gltf/animations/interpolate.ts", "../src/
|
|
4
|
-
"sourcesContent": ["// luma.gl, MIT license\n\nexport {loadPBREnvironment, type PBREnvironment} from './pbr/pbr-environment';\nexport {type ParsedPBRMaterial} from './pbr/pbr-material';\nexport {parsePBRMaterial, type ParsePBRMaterialOptions} from './parsers/parse-pbr-material';\nexport {} from './pbr/pbr-environment';\n\n// glTF Scenegraph Instantiator\nexport {createScenegraphsFromGLTF} from './gltf/create-scenegraph-from-gltf';\nexport {GLTFAnimator} from './gltf/gltf-animator';\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Device, SamplerProps} from '@luma.gl/core';\nimport {AsyncTexture} from '@luma.gl/engine';\nimport {loadImageTexture} from '@loaders.gl/textures';\n\n/** Environment textures for PBR module */\nexport type PBREnvironment = {\n /** Bi-directional Reflectance Distribution Function (BRDF) lookup table */\n brdfLutTexture: AsyncTexture;\n diffuseEnvSampler: AsyncTexture;\n specularEnvSampler: AsyncTexture;\n};\n\nexport type PBREnvironmentProps = {\n brdfLutUrl: string;\n getTexUrl: (name: string, dir: number, level: number) => string;\n specularMipLevels?: number;\n};\n\n/** Loads textures for PBR environment */\nexport function loadPBREnvironment(device: Device, props: PBREnvironmentProps): PBREnvironment {\n const brdfLutTexture = new AsyncTexture(device, {\n id: 'brdfLUT',\n sampler: {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n minFilter: 'linear',\n magFilter: 'linear'\n } as const satisfies SamplerProps,\n // Texture accepts a promise that returns an image as data (Async Textures)\n data: loadImageTexture(props.brdfLutUrl)\n });\n\n const diffuseEnvSampler = makeCube(device, {\n id: 'DiffuseEnvSampler',\n getTextureForFace: dir => loadImageTexture(props.getTexUrl('diffuse', dir, 0)),\n sampler: {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n minFilter: 'linear',\n magFilter: 'linear'\n } as const satisfies SamplerProps\n });\n\n const specularEnvSampler = makeCube(device, {\n id: 'SpecularEnvSampler',\n getTextureForFace: (dir: number) => {\n const imageArray: Promise<any>[] = [];\n // @ts-ignore\n for (let lod = 0; lod <= props.specularMipLevels - 1; lod++) {\n imageArray.push(loadImageTexture(props.getTexUrl('specular', dir, lod)));\n }\n return imageArray;\n },\n sampler: {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n minFilter: 'linear', // [GL.TEXTURE_MIN_FILTER]: GL.LINEAR_MIPMAP_LINEAR,\n magFilter: 'linear'\n } as const satisfies SamplerProps\n });\n\n return {\n brdfLutTexture,\n diffuseEnvSampler,\n specularEnvSampler\n };\n}\n\n// TODO put somewhere common\nconst FACES = [0, 1, 2, 3, 4, 5];\n\nfunction makeCube(\n device: Device,\n {\n id,\n getTextureForFace,\n sampler\n }: {\n id: string;\n getTextureForFace: (dir: number) => Promise<any> | Promise<any>[];\n sampler: SamplerProps;\n }\n): AsyncTexture {\n const data = {};\n FACES.forEach(face => {\n // @ts-ignore TODO\n data[String(face)] = getTextureForFace(face);\n });\n return new AsyncTexture(device, {\n id,\n dimension: 'cube',\n mipmaps: false,\n sampler,\n // @ts-expect-error\n data\n });\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {Device, Texture} from '@luma.gl/core';\nimport {GL} from '@luma.gl/constants';\n\nimport {log} from '@luma.gl/core';\nimport {type ParsedPBRMaterial} from '../pbr/pbr-material';\nimport {type PBREnvironment} from '../pbr/pbr-environment';\nimport {type PBRMaterialBindings} from '@luma.gl/shadertools';\nimport {convertSampler} from '../webgl-to-webgpu/convert-webgl-sampler';\n\n// TODO - synchronize the GLTF... types with loaders.gl\n// TODO - remove the glParameters, use only parameters\n\n/* eslint-disable camelcase */\n\ntype GLTFTexture = {\n id: string;\n texture: {source: {image: any}; sampler: {parameters: any}};\n uniformName?: string;\n // is this on all textures?\n scale?: number;\n // is this on all textures?\n strength?: number;\n};\n\ntype GLTFPBRMetallicRoughness = {\n baseColorTexture?: GLTFTexture;\n baseColorFactor?: [number, number, number, number];\n metallicRoughnessTexture?: GLTFTexture;\n metallicFactor?: number;\n roughnessFactor?: number;\n};\n\ntype GLTFPBRMaterial = {\n unlit?: boolean;\n pbrMetallicRoughness?: GLTFPBRMetallicRoughness;\n normalTexture?: GLTFTexture;\n occlusionTexture?: GLTFTexture;\n emissiveTexture?: GLTFTexture;\n emissiveFactor?: [number, number, number];\n alphaMode?: 'MASK' | 'BLEND';\n alphaCutoff?: number;\n};\n\nexport type ParsePBRMaterialOptions = {\n /** Debug PBR shader */\n pbrDebug?: boolean;\n /** Enable lights */\n lights?: any;\n /** Use tangents */\n useTangents?: boolean;\n /** provide an image based (texture cube) lighting environment */\n imageBasedLightingEnvironment?: PBREnvironment;\n};\n\n/**\n * Parses a GLTF material definition into uniforms and parameters for the PBR shader module\n */\nexport function parsePBRMaterial(\n device: Device,\n material: GLTFPBRMaterial,\n attributes: Record<string, any>,\n options: ParsePBRMaterialOptions\n): ParsedPBRMaterial {\n const parsedMaterial: ParsedPBRMaterial = {\n defines: {\n // TODO: Use EXT_sRGB if available (Standard in WebGL 2.0)\n MANUAL_SRGB: true,\n SRGB_FAST_APPROXIMATION: true\n },\n bindings: {},\n uniforms: {\n // TODO: find better values?\n camera: [0, 0, 0], // Model should override\n\n metallicRoughnessValues: [1, 1] // Default is 1 and 1\n },\n parameters: {},\n glParameters: {},\n generatedTextures: []\n };\n\n // TODO - always available\n parsedMaterial.defines['USE_TEX_LOD'] = true;\n\n const {imageBasedLightingEnvironment} = options;\n if (imageBasedLightingEnvironment) {\n parsedMaterial.bindings.pbr_diffuseEnvSampler =\n imageBasedLightingEnvironment.diffuseEnvSampler.texture;\n parsedMaterial.bindings.pbr_specularEnvSampler =\n imageBasedLightingEnvironment.specularEnvSampler.texture;\n parsedMaterial.bindings.pbr_BrdfLUT = imageBasedLightingEnvironment.brdfLutTexture.texture;\n parsedMaterial.uniforms.scaleIBLAmbient = [1, 1];\n }\n\n if (options?.pbrDebug) {\n parsedMaterial.defines['PBR_DEBUG'] = true;\n // Override final color for reference app visualization of various parameters in the lighting equation.\n parsedMaterial.uniforms.scaleDiffBaseMR = [0, 0, 0, 0];\n parsedMaterial.uniforms.scaleFGDSpec = [0, 0, 0, 0];\n }\n\n if (attributes['NORMAL']) parsedMaterial.defines['HAS_NORMALS'] = true;\n if (attributes['TANGENT'] && options?.useTangents) parsedMaterial.defines['HAS_TANGENTS'] = true;\n if (attributes['TEXCOORD_0']) parsedMaterial.defines['HAS_UV'] = true;\n\n if (options?.imageBasedLightingEnvironment) parsedMaterial.defines['USE_IBL'] = true;\n if (options?.lights) parsedMaterial.defines['USE_LIGHTS'] = true;\n\n if (material) {\n parseMaterial(device, material, parsedMaterial);\n }\n\n return parsedMaterial;\n}\n\n/** Parse GLTF material record */\nfunction parseMaterial(\n device: Device,\n material: GLTFPBRMaterial,\n parsedMaterial: ParsedPBRMaterial\n): void {\n parsedMaterial.uniforms.unlit = Boolean(material.unlit);\n\n if (material.pbrMetallicRoughness) {\n parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial);\n }\n if (material.normalTexture) {\n addTexture(\n device,\n material.normalTexture,\n 'pbr_normalSampler',\n 'HAS_NORMALMAP',\n parsedMaterial\n );\n\n const {scale = 1} = material.normalTexture;\n parsedMaterial.uniforms.normalScale = scale;\n }\n if (material.occlusionTexture) {\n addTexture(\n device,\n material.occlusionTexture,\n 'pbr_occlusionSampler',\n 'HAS_OCCLUSIONMAP',\n parsedMaterial\n );\n\n const {strength = 1} = material.occlusionTexture;\n parsedMaterial.uniforms.occlusionStrength = strength;\n }\n if (material.emissiveTexture) {\n addTexture(\n device,\n material.emissiveTexture,\n 'pbr_emissiveSampler',\n 'HAS_EMISSIVEMAP',\n parsedMaterial\n );\n parsedMaterial.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];\n }\n\n switch (material.alphaMode || 'MASK') {\n case 'MASK':\n const {alphaCutoff = 0.5} = material;\n parsedMaterial.defines['ALPHA_CUTOFF'] = true;\n parsedMaterial.uniforms.alphaCutoff = alphaCutoff;\n break;\n case 'BLEND':\n log.warn('glTF BLEND alphaMode might not work well because it requires mesh sorting')();\n\n // WebGPU style parameters\n parsedMaterial.parameters.blend = true;\n\n parsedMaterial.parameters.blendColorOperation = 'add';\n parsedMaterial.parameters.blendColorSrcFactor = 'src-alpha';\n parsedMaterial.parameters.blendColorDstFactor = 'one-minus-src-alpha';\n\n parsedMaterial.parameters.blendAlphaOperation = 'add';\n parsedMaterial.parameters.blendAlphaSrcFactor = 'one';\n parsedMaterial.parameters.blendAlphaDstFactor = 'one-minus-src-alpha';\n\n // GL parameters\n // TODO - remove in favor of parameters\n parsedMaterial.glParameters['blend'] = true;\n parsedMaterial.glParameters['blendEquation'] = GL.FUNC_ADD;\n parsedMaterial.glParameters['blendFunc'] = [\n GL.SRC_ALPHA,\n GL.ONE_MINUS_SRC_ALPHA,\n GL.ONE,\n GL.ONE_MINUS_SRC_ALPHA\n ];\n\n break;\n }\n}\n\n/** Parse GLTF material sub record */\nfunction parsePbrMetallicRoughness(\n device: Device,\n pbrMetallicRoughness: GLTFPBRMetallicRoughness,\n parsedMaterial: ParsedPBRMaterial\n): void {\n if (pbrMetallicRoughness.baseColorTexture) {\n addTexture(\n device,\n pbrMetallicRoughness.baseColorTexture,\n 'pbr_baseColorSampler',\n 'HAS_BASECOLORMAP',\n parsedMaterial\n );\n }\n parsedMaterial.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];\n\n if (pbrMetallicRoughness.metallicRoughnessTexture) {\n addTexture(\n device,\n pbrMetallicRoughness.metallicRoughnessTexture,\n 'pbr_metallicRoughnessSampler',\n 'HAS_METALROUGHNESSMAP',\n parsedMaterial\n );\n }\n const {metallicFactor = 1, roughnessFactor = 1} = pbrMetallicRoughness;\n parsedMaterial.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];\n}\n\n/** Create a texture from a glTF texture/sampler/image combo and add it to bindings */\nfunction addTexture(\n device: Device,\n gltfTexture: GLTFTexture,\n uniformName: keyof PBRMaterialBindings,\n define: string,\n parsedMaterial: ParsedPBRMaterial\n): void {\n const image = gltfTexture.texture.source.image;\n let textureOptions;\n\n if (image.compressed) {\n textureOptions = image;\n } else {\n // Texture2D accepts a promise that returns an image as data (Async Textures)\n textureOptions = {data: image};\n }\n\n const gltfSampler = {\n wrapS: 10497, // default REPEAT S (U) wrapping mode.\n wrapT: 10497, // default REPEAT T (V) wrapping mode.\n ...gltfTexture?.texture?.sampler\n } as any;\n\n const texture: Texture = device.createTexture({\n id: gltfTexture.uniformName || gltfTexture.id,\n sampler: convertSampler(gltfSampler),\n ...textureOptions\n });\n\n parsedMaterial.bindings[uniformName] = texture;\n if (define) parsedMaterial.defines[define] = true;\n parsedMaterial.generatedTextures.push(texture);\n}\n\n/*\n/**\n * Parses a GLTF material definition into uniforms and parameters for the PBR shader module\n *\nexport class PBRMaterialParser {\n readonly device: Device;\n\n readonly defines: Record<string, boolean>;\n readonly bindings: Record<string, Binding>;\n readonly uniforms: Record<string, any>;\n readonly parameters: Record<string, any>;\n\n /** Hold on to generated textures, we destroy them in the destroy method *\n readonly generatedTextures: Texture[];\n\n constructor(device: Device, props: PBRMaterialParserProps) {\n const {attributes, material, pbrDebug, imageBasedLightingEnvironment, lights, useTangents} =\n props;\n this.device = device;\n\n this.defines = {\n // TODO: Use EXT_sRGB if available (Standard in WebGL 2.0)\n MANUAL_SRGB: true,\n SRGB_FAST_APPROXIMATION: true\n };\n\n if (this.device.features.has('glsl-texture-lod')) {\n this.defines.USE_TEX_LOD = true;\n }\n\n this.uniforms = {\n // TODO: find better values?\n camera: [0, 0, 0], // Model should override\n\n metallicRoughnessValues: [1, 1] // Default is 1 and 1\n };\n\n this.bindings = {};\n\n this.parameters = {};\n this.generatedTextures = [];\n\n if (imageBasedLightingEnvironment) {\n this.bindings.pbr_diffuseEnvSampler = imageBasedLightingEnvironment.getDiffuseEnvSampler();\n this.bindings.pbr_specularEnvSampler = imageBasedLightingEnvironment.getSpecularEnvSampler();\n this.bindings.pbr_BrdfLUT = imageBasedLightingEnvironment.getBrdfTexture();\n this.uniforms.scaleIBLAmbient = [1, 1];\n }\n\n if (pbrDebug) {\n // Override final color for reference app visualization\n // of various parameters in the lighting equation.\n this.uniforms.scaleDiffBaseMR = [0, 0, 0, 0];\n this.uniforms.scaleFGDSpec = [0, 0, 0, 0];\n }\n\n this.defineIfPresent(attributes.NORMAL, 'HAS_NORMALS');\n this.defineIfPresent(attributes.TANGENT && useTangents, 'HAS_TANGENTS');\n this.defineIfPresent(attributes.TEXCOORD_0, 'HAS_UV');\n\n this.defineIfPresent(imageBasedLightingEnvironment, 'USE_IBL');\n this.defineIfPresent(lights, 'USE_LIGHTS');\n this.defineIfPresent(pbrDebug, 'PBR_DEBUG');\n\n if (material) {\n this.parseMaterial(material);\n }\n }\n\n /**\n * Destroy all generated resources to release memory.\n *\n destroy(): void {\n this.generatedTextures.forEach(texture => texture.destroy());\n }\n\n /** Add a define if the the value is non-nullish *\n defineIfPresent(value: unknown, name: string): void {\n if (value) {\n this.defines[name] = 1;\n }\n }\n\n /** Parse GLTF material record *\n parseMaterial(material) {\n this.uniforms.unlit = Boolean(material.unlit);\n\n if (material.pbrMetallicRoughness) {\n this.parsePbrMetallicRoughness(material.pbrMetallicRoughness);\n }\n if (material.normalTexture) {\n this.addTexture(material.normalTexture, 'pbr_normalSampler', 'HAS_NORMALMAP');\n\n const {scale = 1} = material.normalTexture;\n this.uniforms.normalScale = scale;\n }\n if (material.occlusionTexture) {\n this.addTexture(material.occlusionTexture, 'pbr_occlusionSampler', 'HAS_OCCLUSIONMAP');\n\n const {strength = 1} = material.occlusionTexture;\n this.uniforms.occlusionStrength = strength;\n }\n if (material.emissiveTexture) {\n this.addTexture(material.emissiveTexture, 'pbr_emissiveSampler', 'HAS_EMISSIVEMAP');\n this.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];\n }\n if (material.alphaMode === 'MASK') {\n const {alphaCutoff = 0.5} = material;\n this.defines.ALPHA_CUTOFF = true;\n this.uniforms.u_AlphaCutoff = alphaCutoff;\n } else if (material.alphaMode === 'BLEND') {\n log.warn('BLEND alphaMode might not work well because it requires mesh sorting')();\n Object.assign(this.parameters, {\n blend: true,\n blendEquation: GL.FUNC_ADD,\n blendFunc: [GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA, GL.ONE, GL.ONE_MINUS_SRC_ALPHA]\n });\n }\n }\n\n /** Parse GLTF material sub record *\n parsePbrMetallicRoughness(pbrMetallicRoughness) {\n if (pbrMetallicRoughness.baseColorTexture) {\n this.addTexture(\n pbrMetallicRoughness.baseColorTexture,\n 'pbr_baseColorSampler',\n 'HAS_BASECOLORMAP'\n );\n }\n this.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];\n\n if (pbrMetallicRoughness.metallicRoughnessTexture) {\n this.addTexture(\n pbrMetallicRoughness.metallicRoughnessTexture,\n 'pbr_metallicRoughnessSampler',\n 'HAS_METALROUGHNESSMAP'\n );\n }\n const {metallicFactor = 1, roughnessFactor = 1} = pbrMetallicRoughness;\n this.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];\n }\n\n /** Create a texture from a glTF texture/sampler/image combo and add it to bindings *\n addTexture(gltfTexture, name, define = null) {\n const parameters = gltfTexture?.texture?.sampler?.parameters || {};\n\n const image = gltfTexture.texture.source.image;\n let textureOptions;\n let specialTextureParameters = {};\n if (image.compressed) {\n textureOptions = image;\n specialTextureParameters = {\n [GL.TEXTURE_MIN_FILTER]: image.data.length > 1 ? GL.LINEAR_MIPMAP_NEAREST : GL.LINEAR\n };\n } else {\n // Texture2D accepts a promise that returns an image as data (Async Textures)\n textureOptions = {data: image};\n }\n\n const texture: Texture = this.device.createTexture({\n id: gltfTexture.name || gltfTexture.id,\n parameters: {\n ...parameters,\n ...specialTextureParameters\n },\n pixelStore: {\n [GL.UNPACK_FLIP_Y_WEBGL]: false\n },\n ...textureOptions\n });\n this.bindings[name] = texture;\n this.defineIfPresent(define, define);\n this.generatedTextures.push(texture);\n }\n}\n*/\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// TODO: convert in loaders.gl?\n\nimport type {SamplerProps} from '@luma.gl/core';\nimport {GL} from '@luma.gl/constants';\n\ntype GLTFSampler = {\n wrapS?: GL.CLAMP_TO_EDGE | GL.REPEAT | GL.MIRRORED_REPEAT;\n wrapT?: GL.CLAMP_TO_EDGE | GL.REPEAT | GL.MIRRORED_REPEAT;\n magFilter?: GL.NEAREST | GL.LINEAR;\n minFilter?:\n | GL.NEAREST\n | GL.LINEAR\n | GL.NEAREST_MIPMAP_NEAREST\n | GL.LINEAR_MIPMAP_NEAREST\n | GL.NEAREST_MIPMAP_LINEAR\n | GL.LINEAR_MIPMAP_LINEAR;\n};\n\nexport function convertSampler(gltfSampler: GLTFSampler): SamplerProps {\n return {\n addressModeU: convertSamplerWrapMode(gltfSampler.wrapS),\n addressModeV: convertSamplerWrapMode(gltfSampler.wrapT),\n magFilter: convertSamplerMagFilter(gltfSampler.magFilter),\n ...convertSamplerMinFilter(gltfSampler.minFilter)\n };\n}\n\nfunction convertSamplerWrapMode(\n mode: GL.CLAMP_TO_EDGE | GL.REPEAT | GL.MIRRORED_REPEAT | undefined\n): 'clamp-to-edge' | 'repeat' | 'mirror-repeat' | undefined {\n switch (mode) {\n case GL.CLAMP_TO_EDGE:\n return 'clamp-to-edge';\n case GL.REPEAT:\n return 'repeat';\n case GL.MIRRORED_REPEAT:\n return 'mirror-repeat';\n default:\n return undefined;\n }\n}\n\nfunction convertSamplerMagFilter(\n mode: GL.NEAREST | GL.LINEAR | undefined\n): 'nearest' | 'linear' | undefined {\n switch (mode) {\n case GL.NEAREST:\n return 'nearest';\n case GL.LINEAR:\n return 'linear';\n default:\n return undefined;\n }\n}\n\nfunction convertSamplerMinFilter(\n mode:\n | GL.NEAREST\n | GL.LINEAR\n | GL.NEAREST_MIPMAP_NEAREST\n | GL.LINEAR_MIPMAP_NEAREST\n | GL.NEAREST_MIPMAP_LINEAR\n | GL.LINEAR_MIPMAP_LINEAR\n | undefined\n): {minFilter?: 'nearest' | 'linear'; mipmapFilter?: 'nearest' | 'linear'} {\n switch (mode) {\n case GL.NEAREST:\n return {minFilter: 'nearest'};\n case GL.LINEAR:\n return {minFilter: 'linear'};\n case GL.NEAREST_MIPMAP_NEAREST:\n return {minFilter: 'nearest', mipmapFilter: 'nearest'};\n case GL.LINEAR_MIPMAP_NEAREST:\n return {minFilter: 'linear', mipmapFilter: 'nearest'};\n case GL.NEAREST_MIPMAP_LINEAR:\n return {minFilter: 'nearest', mipmapFilter: 'linear'};\n case GL.LINEAR_MIPMAP_LINEAR:\n return {minFilter: 'linear', mipmapFilter: 'linear'};\n default:\n return {};\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Device, type PrimitiveTopology} from '@luma.gl/core';\nimport {Geometry, GeometryAttribute, GroupNode, ModelNode, type ModelProps} from '@luma.gl/engine';\nimport {Matrix4} from '@math.gl/core';\nimport {\n type GLTFMeshPostprocessed,\n type GLTFNodePostprocessed,\n type GLTFPostprocessed\n} from '@loaders.gl/gltf';\nimport {type GLTFScenePostprocessed} from '@loaders.gl/gltf/dist/lib/types/gltf-postprocessed-schema';\n\nimport {type PBREnvironment} from '../pbr/pbr-environment';\nimport {convertGLDrawModeToTopology} from '../webgl-to-webgpu/convert-webgl-topology';\nimport {createGLTFModel} from '../gltf/create-gltf-model';\n\nimport {parsePBRMaterial} from './parse-pbr-material';\n\nexport type ParseGLTFOptions = {\n modelOptions?: Partial<ModelProps>;\n pbrDebug?: boolean;\n imageBasedLightingEnvironment?: PBREnvironment;\n lights?: boolean;\n useTangents?: boolean;\n};\n\nconst defaultOptions: Required<ParseGLTFOptions> = {\n modelOptions: {},\n pbrDebug: false,\n imageBasedLightingEnvironment: undefined!,\n lights: true,\n useTangents: false\n};\n\n/**\n * GLTF instantiator for luma.gl\n * Walks the parsed and resolved glTF structure and builds a luma.gl scenegraph\n */\nexport function parseGLTF(\n device: Device,\n gltf: GLTFPostprocessed,\n options_: ParseGLTFOptions = {}\n): GroupNode[] {\n const options = {...defaultOptions, ...options_};\n const sceneNodes = gltf.scenes.map(gltfScene =>\n createScene(device, gltfScene, gltf.nodes, options)\n );\n return sceneNodes;\n}\n\nfunction createScene(\n device: Device,\n gltfScene: GLTFScenePostprocessed,\n gltfNodes: GLTFNodePostprocessed[],\n options: Required<ParseGLTFOptions>\n): GroupNode {\n const gltfSceneNodes = gltfScene.nodes || [];\n const nodes = gltfSceneNodes.map(node => createNode(device, node, gltfNodes, options));\n const sceneNode = new GroupNode({\n id: gltfScene.name || gltfScene.id,\n children: nodes\n });\n return sceneNode;\n}\n\nfunction createNode(\n device: Device,\n gltfNode: GLTFNodePostprocessed & {_node?: GroupNode},\n gltfNodes: GLTFNodePostprocessed[],\n options: Required<ParseGLTFOptions>\n): GroupNode {\n if (!gltfNode._node) {\n const gltfChildren = gltfNode.children || [];\n const children = gltfChildren.map(child => createNode(device, child, gltfNodes, options));\n\n // Node can have children nodes and meshes at the same time\n if (gltfNode.mesh) {\n children.push(createMesh(device, gltfNode.mesh, options));\n }\n\n const node = new GroupNode({\n id: gltfNode.name || gltfNode.id,\n children\n });\n\n if (gltfNode.matrix) {\n node.setMatrix(gltfNode.matrix);\n } else {\n node.matrix.identity();\n\n if (gltfNode.translation) {\n node.matrix.translate(gltfNode.translation);\n }\n\n if (gltfNode.rotation) {\n const rotationMatrix = new Matrix4().fromQuaternion(gltfNode.rotation);\n node.matrix.multiplyRight(rotationMatrix);\n }\n\n if (gltfNode.scale) {\n node.matrix.scale(gltfNode.scale);\n }\n }\n gltfNode._node = node;\n }\n\n // Copy _node so that gltf-animator can access\n const topLevelNode = gltfNodes.find(node => node.id === gltfNode.id) as any;\n topLevelNode._node = gltfNode._node;\n\n return gltfNode._node;\n}\n\nfunction createMesh(\n device: Device,\n gltfMesh: GLTFMeshPostprocessed & {_mesh?: GroupNode},\n options: Required<ParseGLTFOptions>\n): GroupNode {\n // TODO: avoid changing the gltf\n if (!gltfMesh._mesh) {\n const gltfPrimitives = gltfMesh.primitives || [];\n const primitives = gltfPrimitives.map((gltfPrimitive, i) =>\n createPrimitive(device, gltfPrimitive, i, gltfMesh, options)\n );\n const mesh = new GroupNode({\n id: gltfMesh.name || gltfMesh.id,\n children: primitives\n });\n gltfMesh._mesh = mesh;\n }\n\n return gltfMesh._mesh;\n}\n\nfunction createPrimitive(\n device: Device,\n gltfPrimitive: any,\n i: number,\n gltfMesh: GLTFMeshPostprocessed,\n options: Required<ParseGLTFOptions>\n): ModelNode {\n const id = gltfPrimitive.name || `${gltfMesh.name || gltfMesh.id}-primitive-${i}`;\n const topology = convertGLDrawModeToTopology(gltfPrimitive.mode || 4);\n const vertexCount = gltfPrimitive.indices\n ? gltfPrimitive.indices.count\n : getVertexCount(gltfPrimitive.attributes);\n\n const geometry = createGeometry(id, gltfPrimitive, topology);\n\n const parsedPPBRMaterial = parsePBRMaterial(\n device,\n gltfPrimitive.material,\n geometry.attributes,\n options\n );\n\n const modelNode = createGLTFModel(device, {\n id,\n geometry: createGeometry(id, gltfPrimitive, topology),\n parsedPPBRMaterial,\n modelOptions: options.modelOptions,\n vertexCount\n });\n\n modelNode.bounds = [gltfPrimitive.attributes.POSITION.min, gltfPrimitive.attributes.POSITION.max];\n // TODO this holds on to all the CPU side texture and attribute data\n // modelNode.material = gltfPrimitive.material;\n\n return modelNode;\n}\n\nfunction getVertexCount(attributes: any) {\n throw new Error('getVertexCount not implemented');\n}\n\nfunction createGeometry(id: string, gltfPrimitive: any, topology: PrimitiveTopology): Geometry {\n const attributes: Record<string, GeometryAttribute> = {};\n for (const [attributeName, attribute] of Object.entries(gltfPrimitive.attributes)) {\n const {components, size, value} = attribute as GeometryAttribute;\n\n attributes[attributeName] = {size: size ?? components, value};\n }\n\n return new Geometry({\n id,\n topology,\n indices: gltfPrimitive.indices.value,\n attributes\n });\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {PrimitiveTopology} from '@luma.gl/core';\n\n// NOTE: Modules other than `@luma.gl/webgl` should not import `GL` from\n// `@luma.gl/constants`. Locally we use `GLEnum` instead of `GL` to avoid\n// conflicts with the `babel-plugin-inline-webgl-constants` plugin.\n// eslint-disable-next-line no-shadow\nexport enum GLEnum {\n POINTS = 0x0,\n LINES = 0x1,\n LINE_LOOP = 0x2,\n LINE_STRIP = 0x3,\n TRIANGLES = 0x4,\n TRIANGLE_STRIP = 0x5,\n TRIANGLE_FAN = 0x6\n}\n\nexport function convertGLDrawModeToTopology(\n drawMode:\n | GLEnum.POINTS\n | GLEnum.LINES\n | GLEnum.LINE_STRIP\n | GLEnum.LINE_LOOP\n | GLEnum.TRIANGLES\n | GLEnum.TRIANGLE_STRIP\n | GLEnum.TRIANGLE_FAN\n): PrimitiveTopology {\n // prettier-ignore\n switch (drawMode) {\n case GLEnum.POINTS: return 'point-list';\n case GLEnum.LINES: return 'line-list';\n case GLEnum.LINE_STRIP: return 'line-strip';\n case GLEnum.TRIANGLES: return 'triangle-list';\n case GLEnum.TRIANGLE_STRIP: return 'triangle-strip';\n default: throw new Error(String(drawMode));\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Device, type RenderPipelineParameters, log} from '@luma.gl/core';\nimport {pbrMaterial, ShaderModule} from '@luma.gl/shadertools';\nimport {Geometry, Model, ModelNode, type ModelProps} from '@luma.gl/engine';\nimport {type ParsedPBRMaterial} from '../pbr/pbr-material';\n\nconst SHADER = /* WGSL */ `\nlayout(0) positions: vec4; // in vec4 POSITION;\n\n #ifdef HAS_NORMALS\n in vec4 normals; // in vec4 NORMAL;\n #endif\n\n #ifdef HAS_TANGENTS\n in vec4 TANGENT;\n #endif\n\n #ifdef HAS_UV\n // in vec2 TEXCOORD_0;\n in vec2 texCoords;\n #endif\n\n@vertex\n void main(void) {\n vec4 _NORMAL = vec4(0.);\n vec4 _TANGENT = vec4(0.);\n vec2 _TEXCOORD_0 = vec2(0.);\n\n #ifdef HAS_NORMALS\n _NORMAL = normals;\n #endif\n\n #ifdef HAS_TANGENTS\n _TANGENT = TANGENT;\n #endif\n\n #ifdef HAS_UV\n _TEXCOORD_0 = texCoords;\n #endif\n\n pbr_setPositionNormalTangentUV(positions, _NORMAL, _TANGENT, _TEXCOORD_0);\n gl_Position = u_MVPMatrix * positions;\n }\n\n@fragment\n out vec4 fragmentColor;\n\n void main(void) {\n vec3 pos = pbr_vPosition;\n fragmentColor = pbr_filterColor(vec4(1.0));\n }\n`;\n\n// TODO rename attributes to POSITION/NORMAL etc\n// See gpu-geometry.ts: getAttributeBuffersFromGeometry()\nconst vs = /* glsl */ `\\\n#version 300 es\n\n // in vec4 POSITION;\n in vec4 positions;\n\n #ifdef HAS_NORMALS\n // in vec4 NORMAL;\n in vec4 normals;\n #endif\n\n #ifdef HAS_TANGENTS\n in vec4 TANGENT;\n #endif\n\n #ifdef HAS_UV\n // in vec2 TEXCOORD_0;\n in vec2 texCoords;\n #endif\n\n void main(void) {\n vec4 _NORMAL = vec4(0.);\n vec4 _TANGENT = vec4(0.);\n vec2 _TEXCOORD_0 = vec2(0.);\n\n #ifdef HAS_NORMALS\n _NORMAL = normals;\n #endif\n\n #ifdef HAS_TANGENTS\n _TANGENT = TANGENT;\n #endif\n\n #ifdef HAS_UV\n _TEXCOORD_0 = texCoords;\n #endif\n\n pbr_setPositionNormalTangentUV(positions, _NORMAL, _TANGENT, _TEXCOORD_0);\n gl_Position = pbrProjection.modelViewProjectionMatrix * positions;\n }\n`;\n\nconst fs = /* glsl */ `\\\n#version 300 es\n out vec4 fragmentColor;\n\n void main(void) {\n vec3 pos = pbr_vPosition;\n fragmentColor = pbr_filterColor(vec4(1.0));\n }\n`;\n\nexport type CreateGLTFModelOptions = {\n id?: string;\n vertexCount?: number;\n geometry: Geometry;\n parsedPPBRMaterial: ParsedPBRMaterial;\n modelOptions?: Partial<ModelProps>;\n};\n\n/** Creates a luma.gl Model from GLTF data*/\nexport function createGLTFModel(device: Device, options: CreateGLTFModelOptions): ModelNode {\n const {id, geometry, parsedPPBRMaterial, vertexCount, modelOptions = {}} = options;\n\n log.info(4, 'createGLTFModel defines: ', parsedPPBRMaterial.defines)();\n\n // Calculate managedResources\n // TODO: Implement resource management logic that will\n // not deallocate resources/textures/buffers that are shared\n const managedResources: any[] = [];\n // managedResources.push(...parsedMaterial.generatedTextures);\n // managedResources.push(...Object.values(attributes).map((attribute) => attribute.buffer));\n\n const parameters: RenderPipelineParameters = {\n depthWriteEnabled: true,\n depthCompare: 'less',\n depthFormat: 'depth24plus',\n cullMode: 'back'\n };\n\n const modelProps: ModelProps = {\n id,\n source: SHADER,\n vs,\n fs,\n geometry,\n topology: geometry.topology,\n vertexCount,\n modules: [pbrMaterial as unknown as ShaderModule],\n ...modelOptions,\n\n defines: {...parsedPPBRMaterial.defines, ...modelOptions.defines},\n parameters: {...parameters, ...parsedPPBRMaterial.parameters, ...modelOptions.parameters}\n };\n\n const model = new Model(device, modelProps);\n\n const {camera, ...pbrMaterialProps} = {\n ...parsedPPBRMaterial.uniforms,\n ...modelOptions.uniforms,\n ...parsedPPBRMaterial.bindings,\n ...modelOptions.bindings\n };\n\n model.shaderInputs.setProps({pbrMaterial: pbrMaterialProps, pbrProjection: {camera}});\n return new ModelNode({managedResources, model});\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {GLTFNodePostprocessed} from '@loaders.gl/gltf';\nimport {log} from '@luma.gl/core';\nimport {GroupNode} from '@luma.gl/engine';\nimport {Matrix4} from '@math.gl/core';\nimport {GLTFAnimation} from './animations/animations';\nimport {interpolate} from './animations/interpolate';\n\ntype GLTFSingleAnimatorProps = {\n animation: GLTFAnimation;\n startTime?: number;\n playing?: boolean;\n speed?: number;\n};\n\nclass GLTFSingleAnimator {\n animation: GLTFAnimation;\n startTime: number = 0;\n playing: boolean = true;\n speed: number = 1;\n\n constructor(props: GLTFSingleAnimatorProps) {\n this.animation = props.animation;\n this.animation.name ||= 'unnamed';\n Object.assign(this, props);\n }\n\n setTime(timeMs: number) {\n if (!this.playing) {\n return;\n }\n\n const absTime = timeMs / 1000;\n const time = (absTime - this.startTime) * this.speed;\n\n this.animation.channels.forEach(({sampler, target, path}) => {\n interpolate(time, sampler, target, path);\n applyTranslationRotationScale(target, (target as any)._node as GroupNode);\n });\n }\n}\n\nexport type GLTFAnimatorProps = {\n animations: GLTFAnimation[];\n};\n\nexport class GLTFAnimator {\n animations: GLTFSingleAnimator[];\n\n constructor(props: GLTFAnimatorProps) {\n this.animations = props.animations.map((animation, index) => {\n const name = animation.name || `Animation-${index}`;\n return new GLTFSingleAnimator({\n animation: {name, channels: animation.channels}\n });\n });\n }\n\n /** @deprecated Use .setTime(). Will be removed (deck.gl is using this) */\n animate(time: number): void {\n log.warn('GLTFAnimator#animate is deprecated. Use GLTFAnimator#setTime instead')();\n this.setTime(time);\n }\n\n setTime(time: number): void {\n this.animations.forEach(animation => animation.setTime(time));\n }\n\n getAnimations() {\n return this.animations;\n }\n}\n\n// TODO: share with GLTFInstantiator\nconst scratchMatrix = new Matrix4();\n\nfunction applyTranslationRotationScale(gltfNode: GLTFNodePostprocessed, node: GroupNode) {\n node.matrix.identity();\n\n if (gltfNode.translation) {\n node.matrix.translate(gltfNode.translation);\n }\n\n if (gltfNode.rotation) {\n const rotationMatrix = scratchMatrix.fromQuaternion(gltfNode.rotation);\n node.matrix.multiplyRight(rotationMatrix);\n }\n\n if (gltfNode.scale) {\n node.matrix.scale(gltfNode.scale);\n }\n}\n", "import {GLTFNodePostprocessed} from '@loaders.gl/gltf';\nimport {log} from '@luma.gl/core';\nimport {Quaternion} from '@math.gl/core';\nimport {GLTFAnimationChannel, GLTFAnimationSampler} from './animations';\n\nconst scratchQuaternion = new Quaternion();\n\nexport function interpolate(\n time: number,\n {input, interpolation, output}: GLTFAnimationSampler,\n target: GLTFNodePostprocessed,\n path: GLTFAnimationChannel['path']\n) {\n const maxTime = input[input.length - 1];\n const animationTime = time % maxTime;\n\n const nextIndex = input.findIndex(t => t >= animationTime);\n const previousIndex = Math.max(0, nextIndex - 1);\n\n if (!Array.isArray(target[path])) {\n switch (path) {\n case 'translation':\n target[path] = [0, 0, 0];\n break;\n\n case 'rotation':\n target[path] = [0, 0, 0, 1];\n break;\n\n case 'scale':\n target[path] = [1, 1, 1];\n break;\n\n default:\n log.warn(`Bad animation path ${path}`)();\n }\n }\n\n // assert(target[path].length === output[previousIndex].length);\n const previousTime = input[previousIndex];\n const nextTime = input[nextIndex];\n\n switch (interpolation) {\n case 'STEP':\n stepInterpolate(target, path, output[previousIndex] as number[]);\n break;\n\n case 'LINEAR':\n if (nextTime > previousTime) {\n const ratio = (animationTime - previousTime) / (nextTime - previousTime);\n linearInterpolate(\n target,\n path,\n output[previousIndex] as number[],\n output[nextIndex] as number[],\n ratio\n );\n }\n break;\n\n case 'CUBICSPLINE':\n if (nextTime > previousTime) {\n const ratio = (animationTime - previousTime) / (nextTime - previousTime);\n const tDiff = nextTime - previousTime;\n\n const p0 = output[3 * previousIndex + 1] as number[];\n const outTangent0 = output[3 * previousIndex + 2] as number[];\n const inTangent1 = output[3 * nextIndex + 0] as number[];\n const p1 = output[3 * nextIndex + 1] as number[];\n\n cubicsplineInterpolate(target, path, {p0, outTangent0, inTangent1, p1, tDiff, ratio});\n }\n break;\n\n default:\n log.warn(`Interpolation ${interpolation} not supported`)();\n break;\n }\n}\n\nfunction linearInterpolate(\n target: GLTFNodePostprocessed,\n path: GLTFAnimationChannel['path'],\n start: number[],\n stop: number[],\n ratio: number\n) {\n if (!target[path]) {\n throw new Error();\n }\n\n if (path === 'rotation') {\n // SLERP when path is rotation\n scratchQuaternion.slerp({start, target: stop, ratio});\n for (let i = 0; i < scratchQuaternion.length; i++) {\n target[path][i] = scratchQuaternion[i];\n }\n } else {\n // regular interpolation\n for (let i = 0; i < start.length; i++) {\n target[path][i] = ratio * stop[i] + (1 - ratio) * start[i];\n }\n }\n}\n\nfunction cubicsplineInterpolate(\n target: GLTFNodePostprocessed,\n path: GLTFAnimationChannel['path'],\n {\n p0,\n outTangent0,\n inTangent1,\n p1,\n tDiff,\n ratio: t\n }: {\n p0: number[];\n outTangent0: number[];\n inTangent1: number[];\n p1: number[];\n tDiff: number;\n ratio: number;\n }\n) {\n if (!target[path]) {\n throw new Error();\n }\n\n // TODO: Quaternion might need normalization\n for (let i = 0; i < target[path].length; i++) {\n const m0 = outTangent0[i] * tDiff;\n const m1 = inTangent1[i] * tDiff;\n target[path][i] =\n (2 * Math.pow(t, 3) - 3 * Math.pow(t, 2) + 1) * p0[i] +\n (Math.pow(t, 3) - 2 * Math.pow(t, 2) + t) * m0 +\n (-2 * Math.pow(t, 3) + 3 * Math.pow(t, 2)) * p1[i] +\n (Math.pow(t, 3) - Math.pow(t, 2)) * m1;\n }\n}\n\nfunction stepInterpolate(\n target: GLTFNodePostprocessed,\n path: GLTFAnimationChannel['path'],\n value: number[]\n) {\n if (!target[path]) {\n throw new Error();\n }\n\n for (let i = 0; i < value.length; i++) {\n target[path][i] = value[i];\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// TODO: convert in loaders.gl?\nimport type {TypedArray} from '@math.gl/types';\n\nexport const ATTRIBUTE_TYPE_TO_COMPONENTS: Record<string, number> = {\n SCALAR: 1,\n VEC2: 2,\n VEC3: 3,\n VEC4: 4,\n MAT2: 4,\n MAT3: 9,\n MAT4: 16\n};\n\nexport const ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY: Record<number, any> = {\n 5120: Int8Array,\n 5121: Uint8Array,\n 5122: Int16Array,\n 5123: Uint16Array,\n 5125: Uint32Array,\n 5126: Float32Array\n};\n\ntype GLTFAccessor = {\n componentType: number;\n type: string;\n count: number;\n bufferView?: {data: {buffer: ArrayBuffer; byteOffset?: number}};\n byteOffset?: number;\n};\n\nexport function accessorToTypedArray(accessor: GLTFAccessor): {\n typedArray: TypedArray;\n components: number;\n} {\n const ArrayType = ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY[accessor.componentType];\n const components = ATTRIBUTE_TYPE_TO_COMPONENTS[accessor.type];\n const length = components * accessor.count;\n const {buffer, byteOffset = 0} = accessor.bufferView?.data ?? {};\n\n const typedArray = new ArrayType(buffer, byteOffset + (accessor.byteOffset || 0), length);\n\n return {typedArray, components};\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {type GLTFAccessorPostprocessed, type GLTFPostprocessed} from '@loaders.gl/gltf';\nimport {\n type GLTFAnimation,\n type GLTFAnimationChannel,\n type GLTFAnimationSampler\n} from '../gltf/animations/animations';\n\nimport {accessorToTypedArray} from '..//webgl-to-webgpu/convert-webgl-attribute';\n\nexport function parseGLTFAnimations(gltf: GLTFPostprocessed): GLTFAnimation[] {\n const gltfAnimations = gltf.animations || [];\n return gltfAnimations.map((animation, index) => {\n const name = animation.name || `Animation-${index}`;\n const samplers: GLTFAnimationSampler[] = animation.samplers.map(\n ({input, interpolation = 'LINEAR', output}) => ({\n input: accessorToJsArray(gltf.accessors[input]) as number[],\n interpolation,\n output: accessorToJsArray(gltf.accessors[output])\n })\n );\n const channels: GLTFAnimationChannel[] = animation.channels.map(({sampler, target}) => ({\n sampler: samplers[sampler],\n target: gltf.nodes[target.node ?? 0],\n path: target.path as GLTFAnimationChannel['path']\n }));\n return {name, channels};\n });\n}\n\n//\n\nfunction accessorToJsArray(\n accessor: GLTFAccessorPostprocessed & {_animation?: number[] | number[][]}\n): number[] | number[][] {\n if (!accessor._animation) {\n const {typedArray: array, components} = accessorToTypedArray(accessor);\n\n if (components === 1) {\n accessor._animation = Array.from(array);\n } else {\n // Slice array\n const slicedArray: number[][] = [];\n for (let i = 0; i < array.length; i += components) {\n slicedArray.push(Array.from(array.slice(i, i + components)));\n }\n accessor._animation = slicedArray;\n }\n }\n\n return accessor._animation;\n}\n", "/** Deeply copies a JS data structure */\nexport function deepCopy(object: any): any {\n // don't copy binary data\n if (\n ArrayBuffer.isView(object) ||\n object instanceof ArrayBuffer ||\n object instanceof ImageBitmap\n ) {\n return object;\n }\n if (Array.isArray(object)) {\n return object.map(deepCopy);\n }\n if (object && typeof object === 'object') {\n const result: typeof object = {};\n for (const key in object) {\n result[key] = deepCopy(object[key]);\n }\n return result;\n }\n return object;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Device} from '@luma.gl/core';\nimport {GroupNode} from '@luma.gl/engine';\nimport {GLTFPostprocessed} from '@loaders.gl/gltf';\nimport {parseGLTF, type ParseGLTFOptions} from '../parsers/parse-gltf';\nimport {GLTFAnimator} from './gltf-animator';\nimport {parseGLTFAnimations} from '../parsers/parse-gltf-animations';\nimport {deepCopy} from '../utils/deep-copy';\n\nexport function createScenegraphsFromGLTF(\n device: Device,\n gltf: GLTFPostprocessed,\n options?: ParseGLTFOptions\n): {\n scenes: GroupNode[];\n animator: GLTFAnimator;\n} {\n gltf = deepCopy(gltf);\n const scenes = parseGLTF(device, gltf, options);\n // Note: There is a nasty dependency on injected nodes in the glTF\n const animations = parseGLTFAnimations(gltf);\n const animator = new GLTFAnimator({animations});\n return {scenes, animator};\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["
|
|
3
|
+
"sources": ["../src/index.ts", "../src/pbr/pbr-environment.ts", "../src/parsers/parse-pbr-material.ts", "../src/webgl-to-webgpu/gltf-webgl-constants.ts", "../src/webgl-to-webgpu/convert-webgl-sampler.ts", "../src/parsers/parse-gltf-lights.ts", "../src/parsers/parse-gltf.ts", "../src/webgl-to-webgpu/convert-webgl-topology.ts", "../src/gltf/create-gltf-model.ts", "../src/gltf/gltf-animator.ts", "../src/gltf/animations/interpolate.ts", "../src/parsers/parse-gltf-animations.ts", "../src/webgl-to-webgpu/convert-webgl-attribute.ts", "../src/gltf/gltf-extension-support.ts", "../src/gltf/create-scenegraph-from-gltf.ts"],
|
|
4
|
+
"sourcesContent": ["// luma.gl, MIT license\n\nexport {loadPBREnvironment, type PBREnvironment} from './pbr/pbr-environment';\nexport {type ParsedPBRMaterial} from './pbr/pbr-material';\nexport {parsePBRMaterial, type ParsePBRMaterialOptions} from './parsers/parse-pbr-material';\nexport {parseGLTFLights} from './parsers/parse-gltf-lights';\n\n// glTF Scenegraph Instantiator\nexport {\n createScenegraphsFromGLTF,\n type GLTFScenegraphBounds,\n type GLTFScenegraphs\n} from './gltf/create-scenegraph-from-gltf';\nexport {\n getGLTFExtensionSupport,\n type GLTFExtensionSupport,\n type GLTFExtensionSupportLevel\n} from './gltf/gltf-extension-support';\nexport {GLTFAnimator} from './gltf/gltf-animator';\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Device, SamplerProps} from '@luma.gl/core';\nimport {\n DynamicTexture,\n type Texture2DData,\n type TextureCubeData,\n type TextureCubeFace\n} from '@luma.gl/engine';\nimport {loadImageTexture} from '@loaders.gl/textures';\n\n/** Environment textures for PBR module */\nexport type PBREnvironment = {\n /** Bi-directional Reflectance Distribution Function (BRDF) lookup table */\n brdfLutTexture: DynamicTexture;\n /** Diffuse irradiance cubemap. */\n diffuseEnvSampler: DynamicTexture;\n /** Specular reflection cubemap with mip chain. */\n specularEnvSampler: DynamicTexture;\n};\n\n/** Configuration used to load an image-based lighting environment. */\nexport type PBREnvironmentProps = {\n /** URL of the BRDF lookup texture. */\n brdfLutUrl: string;\n /** Callback that returns the URL for a diffuse or specular cubemap face and mip level. */\n getTexUrl: (name: string, dir: number, level: number) => string;\n /** Number of mip levels in the specular environment map. */\n specularMipLevels?: number;\n};\n\n/** Loads textures for PBR environment */\nexport function loadPBREnvironment(device: Device, props: PBREnvironmentProps): PBREnvironment {\n const specularMipLevels = props.specularMipLevels ?? 1;\n\n const brdfLutTexture = new DynamicTexture(device, {\n id: 'brdfLUT',\n sampler: {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n minFilter: 'linear',\n magFilter: 'linear'\n } as const satisfies SamplerProps,\n // Texture accepts a promise that returns an image as data (Async Textures)\n data: loadImageTexture(props.brdfLutUrl)\n });\n\n const diffuseEnvSampler = makeCube(device, {\n id: 'DiffuseEnvSampler',\n getTextureForFace: face =>\n loadImageTexture(\n props.getTexUrl('diffuse', FACES.indexOf(face), 0)\n ) as Promise<Texture2DData>,\n sampler: {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n minFilter: 'linear',\n magFilter: 'linear'\n } as const satisfies SamplerProps\n });\n\n const specularEnvSampler = makeCube(device, {\n id: 'SpecularEnvSampler',\n getTextureForFace: (face: TextureCubeFace) => {\n const imageArray: Array<Promise<unknown>> = [];\n const direction = FACES.indexOf(face);\n for (let lod = 0; lod < specularMipLevels; lod++) {\n imageArray.push(loadImageTexture(props.getTexUrl('specular', direction, lod)));\n }\n return Promise.all(imageArray) as Promise<Texture2DData>;\n },\n sampler: {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n minFilter: 'linear', // [GL.TEXTURE_MIN_FILTER]: GL.LINEAR_MIPMAP_LINEAR,\n magFilter: 'linear'\n } as const satisfies SamplerProps\n });\n\n return {\n brdfLutTexture,\n diffuseEnvSampler,\n specularEnvSampler\n };\n}\n\n// TODO put somewhere common\nconst FACES: TextureCubeFace[] = ['+X', '-X', '+Y', '-Y', '+Z', '-Z'];\n\n/** Construction props for an asynchronously loaded cubemap. */\nfunction makeCube(\n device: Device,\n {\n id,\n getTextureForFace,\n sampler\n }: {\n /** Debug id assigned to the created texture. */\n id: string;\n /** Returns the image or mip-array promise for one cubemap face. */\n getTextureForFace: (face: TextureCubeFace) => Promise<Texture2DData>;\n /** Sampler configuration shared across faces. */\n sampler: SamplerProps;\n }\n): DynamicTexture {\n const data: Promise<TextureCubeData> = Promise.all(\n FACES.map(face => getTextureForFace(face))\n ).then(faceDataArray => {\n const cubeData = {} as TextureCubeData;\n FACES.forEach((face, index) => {\n cubeData[face] = faceDataArray[index];\n });\n return cubeData;\n });\n return new DynamicTexture(device, {\n id,\n dimension: 'cube',\n mipmaps: false,\n sampler,\n data\n });\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {Device, SamplerProps, TextureFormat, TypedArray} from '@luma.gl/core';\nimport {Texture, log, textureFormatDecoder} from '@luma.gl/core';\nimport type {GLTFPostprocessed, GLTFSampler} from '@loaders.gl/gltf';\n\nimport {type ParsedPBRMaterial} from '../pbr/pbr-material';\nimport {type PBREnvironment} from '../pbr/pbr-environment';\nimport {type PBRMaterialBindings} from '@luma.gl/shadertools';\nimport {GLEnum} from '../webgl-to-webgpu/gltf-webgl-constants';\nimport {convertSampler} from '../webgl-to-webgpu/convert-webgl-sampler';\n\n// TODO - synchronize the GLTF... types with loaders.gl\n// TODO - remove the glParameters, use only parameters\n\n/* eslint-disable camelcase */\n\ntype GLTFTexture = {\n id: string;\n index?: number;\n texture: {source: {image: any}; sampler: {parameters: any}};\n uniformName?: string;\n // is this on all textures?\n scale?: number;\n // is this on all textures?\n strength?: number;\n};\n\ntype GLTFPBRMetallicRoughness = {\n baseColorTexture?: GLTFTexture;\n baseColorFactor?: [number, number, number, number];\n metallicRoughnessTexture?: GLTFTexture;\n metallicFactor?: number;\n roughnessFactor?: number;\n};\n\ntype GLTFPBRMaterial = {\n extensions?: GLTFMaterialExtensions;\n unlit?: boolean;\n pbrMetallicRoughness?: GLTFPBRMetallicRoughness;\n normalTexture?: GLTFTexture;\n occlusionTexture?: GLTFTexture;\n emissiveTexture?: GLTFTexture;\n emissiveFactor?: [number, number, number];\n alphaMode?: 'OPAQUE' | 'MASK' | 'BLEND';\n doubleSided?: boolean;\n alphaCutoff?: number;\n};\n\ntype GLTFMaterialSpecularExtension = {\n specularFactor?: number;\n specularTexture?: GLTFTexture;\n specularColorFactor?: [number, number, number];\n specularColorTexture?: GLTFTexture;\n};\n\ntype GLTFMaterialIorExtension = {\n ior?: number;\n};\n\ntype GLTFMaterialTransmissionExtension = {\n transmissionFactor?: number;\n transmissionTexture?: GLTFTexture;\n};\n\ntype GLTFMaterialVolumeExtension = {\n thicknessFactor?: number;\n thicknessTexture?: GLTFTexture;\n attenuationDistance?: number;\n attenuationColor?: [number, number, number];\n};\n\ntype GLTFMaterialClearcoatExtension = {\n clearcoatFactor?: number;\n clearcoatTexture?: GLTFTexture;\n clearcoatRoughnessFactor?: number;\n clearcoatRoughnessTexture?: GLTFTexture;\n clearcoatNormalTexture?: GLTFTexture;\n};\n\ntype GLTFMaterialSheenExtension = {\n sheenColorFactor?: [number, number, number];\n sheenColorTexture?: GLTFTexture;\n sheenRoughnessFactor?: number;\n sheenRoughnessTexture?: GLTFTexture;\n};\n\ntype GLTFMaterialIridescenceExtension = {\n iridescenceFactor?: number;\n iridescenceTexture?: GLTFTexture;\n iridescenceIor?: number;\n iridescenceThicknessMinimum?: number;\n iridescenceThicknessMaximum?: number;\n iridescenceThicknessTexture?: GLTFTexture;\n};\n\ntype GLTFMaterialAnisotropyExtension = {\n anisotropyStrength?: number;\n anisotropyRotation?: number;\n anisotropyTexture?: GLTFTexture;\n};\n\ntype GLTFMaterialEmissiveStrengthExtension = {\n emissiveStrength?: number;\n};\n\ntype GLTFMaterialExtensions = {\n KHR_materials_unlit?: Record<string, never>;\n KHR_materials_specular?: GLTFMaterialSpecularExtension;\n KHR_materials_ior?: GLTFMaterialIorExtension;\n KHR_materials_transmission?: GLTFMaterialTransmissionExtension;\n KHR_materials_volume?: GLTFMaterialVolumeExtension;\n KHR_materials_clearcoat?: GLTFMaterialClearcoatExtension;\n KHR_materials_sheen?: GLTFMaterialSheenExtension;\n KHR_materials_iridescence?: GLTFMaterialIridescenceExtension;\n KHR_materials_anisotropy?: GLTFMaterialAnisotropyExtension;\n KHR_materials_emissive_strength?: GLTFMaterialEmissiveStrengthExtension;\n};\n\ntype TextureEnabledUniformName =\n | 'baseColorMapEnabled'\n | 'normalMapEnabled'\n | 'emissiveMapEnabled'\n | 'metallicRoughnessMapEnabled'\n | 'occlusionMapEnabled'\n | 'specularColorMapEnabled'\n | 'specularIntensityMapEnabled'\n | 'transmissionMapEnabled'\n | 'clearcoatMapEnabled'\n | 'clearcoatRoughnessMapEnabled'\n | 'sheenColorMapEnabled'\n | 'sheenRoughnessMapEnabled'\n | 'iridescenceMapEnabled'\n | 'anisotropyMapEnabled';\n\ntype TextureFeatureOptions = {\n define?: string;\n enabledUniformName?: TextureEnabledUniformName;\n};\n\ntype TextureParseOptions = {\n featureOptions?: TextureFeatureOptions;\n gltf?: GLTFPostprocessed;\n};\n\nexport type ParsePBRMaterialOptions = {\n /** Debug PBR shader */\n pbrDebug?: boolean;\n /** Enable lights */\n lights?: any;\n /** Use tangents */\n useTangents?: boolean;\n /** provide an image based (texture cube) lighting environment */\n imageBasedLightingEnvironment?: PBREnvironment;\n /** parent post-processed glTF, used to resolve extension texture infos */\n gltf?: GLTFPostprocessed;\n /** run primitive-attribute diagnostics such as missing TEXCOORD_0 / NORMAL */\n validateAttributes?: boolean;\n};\n\n/**\n * Parses a GLTF material definition into uniforms and parameters for the PBR shader module\n */\nexport function parsePBRMaterial(\n device: Device,\n material: GLTFPBRMaterial,\n attributes: Record<string, any>,\n options: ParsePBRMaterialOptions\n): ParsedPBRMaterial {\n const parsedMaterial: ParsedPBRMaterial = {\n defines: {\n // TODO: Use EXT_sRGB if available (Standard in WebGL 2.0)\n MANUAL_SRGB: true,\n SRGB_FAST_APPROXIMATION: true\n },\n bindings: {},\n uniforms: {\n // TODO: find better values?\n camera: [0, 0, 0], // Model should override\n\n metallicRoughnessValues: [1, 1] // Default is 1 and 1\n },\n parameters: {},\n glParameters: {},\n generatedTextures: []\n };\n\n // TODO - always available\n parsedMaterial.defines['USE_TEX_LOD'] = true;\n\n const {imageBasedLightingEnvironment} = options;\n if (imageBasedLightingEnvironment) {\n parsedMaterial.bindings.pbr_diffuseEnvSampler =\n imageBasedLightingEnvironment.diffuseEnvSampler.texture;\n parsedMaterial.bindings.pbr_specularEnvSampler =\n imageBasedLightingEnvironment.specularEnvSampler.texture;\n parsedMaterial.bindings.pbr_brdfLUT = imageBasedLightingEnvironment.brdfLutTexture.texture;\n parsedMaterial.uniforms.IBLenabled = true;\n parsedMaterial.uniforms.scaleIBLAmbient = [1, 1];\n }\n\n if (options?.pbrDebug) {\n parsedMaterial.defines['PBR_DEBUG'] = true;\n // Override final color for reference app visualization of various parameters in the lighting equation.\n parsedMaterial.uniforms.scaleDiffBaseMR = [0, 0, 0, 0];\n parsedMaterial.uniforms.scaleFGDSpec = [0, 0, 0, 0];\n }\n\n if (attributes['NORMAL']) parsedMaterial.defines['HAS_NORMALS'] = true;\n if (attributes['TANGENT'] && options?.useTangents) parsedMaterial.defines['HAS_TANGENTS'] = true;\n if (attributes['TEXCOORD_0']) parsedMaterial.defines['HAS_UV'] = true;\n if (attributes['JOINTS_0'] && attributes['WEIGHTS_0']) parsedMaterial.defines['HAS_SKIN'] = true;\n if (attributes['COLOR_0']) parsedMaterial.defines['HAS_COLORS'] = true;\n\n if (options?.imageBasedLightingEnvironment) parsedMaterial.defines['USE_IBL'] = true;\n if (options?.lights) parsedMaterial.defines['USE_LIGHTS'] = true;\n\n if (material) {\n if (options.validateAttributes !== false) {\n warnOnMissingExpectedAttributes(material, attributes);\n }\n parseMaterial(device, material, parsedMaterial, options.gltf);\n }\n\n return parsedMaterial;\n}\n\nfunction warnOnMissingExpectedAttributes(\n material: GLTFPBRMaterial,\n attributes: Record<string, any>\n): void {\n const uvDependentTextureSlots = getUvDependentTextureSlots(material);\n if (uvDependentTextureSlots.length > 0 && !attributes['TEXCOORD_0']) {\n log.warn(\n `glTF material uses ${uvDependentTextureSlots.join(', ')} but primitive is missing TEXCOORD_0; textured shading will sample the default UV coordinates`\n )();\n }\n\n const isUnlitMaterial = Boolean(material.unlit || material.extensions?.KHR_materials_unlit);\n if (isUnlitMaterial || attributes['NORMAL']) {\n return;\n }\n\n const missingNormalReason = material.normalTexture\n ? 'lit PBR shading with normalTexture'\n : 'lit PBR shading';\n log.warn(\n `glTF primitive is missing NORMAL while using ${missingNormalReason}; shading will fall back to geometric normals`\n )();\n}\n\nfunction getUvDependentTextureSlots(material: GLTFPBRMaterial): string[] {\n const uvDependentTextureSlots: string[] = [];\n\n if (material.pbrMetallicRoughness?.baseColorTexture) {\n uvDependentTextureSlots.push('baseColorTexture');\n }\n if (material.pbrMetallicRoughness?.metallicRoughnessTexture) {\n uvDependentTextureSlots.push('metallicRoughnessTexture');\n }\n if (material.normalTexture) {\n uvDependentTextureSlots.push('normalTexture');\n }\n if (material.occlusionTexture) {\n uvDependentTextureSlots.push('occlusionTexture');\n }\n if (material.emissiveTexture) {\n uvDependentTextureSlots.push('emissiveTexture');\n }\n if (material.extensions?.KHR_materials_specular?.specularTexture) {\n uvDependentTextureSlots.push('KHR_materials_specular.specularTexture');\n }\n if (material.extensions?.KHR_materials_specular?.specularColorTexture) {\n uvDependentTextureSlots.push('KHR_materials_specular.specularColorTexture');\n }\n if (material.extensions?.KHR_materials_transmission?.transmissionTexture) {\n uvDependentTextureSlots.push('KHR_materials_transmission.transmissionTexture');\n }\n if (material.extensions?.KHR_materials_clearcoat?.clearcoatTexture) {\n uvDependentTextureSlots.push('KHR_materials_clearcoat.clearcoatTexture');\n }\n if (material.extensions?.KHR_materials_clearcoat?.clearcoatRoughnessTexture) {\n uvDependentTextureSlots.push('KHR_materials_clearcoat.clearcoatRoughnessTexture');\n }\n if (material.extensions?.KHR_materials_sheen?.sheenColorTexture) {\n uvDependentTextureSlots.push('KHR_materials_sheen.sheenColorTexture');\n }\n if (material.extensions?.KHR_materials_sheen?.sheenRoughnessTexture) {\n uvDependentTextureSlots.push('KHR_materials_sheen.sheenRoughnessTexture');\n }\n if (material.extensions?.KHR_materials_iridescence?.iridescenceTexture) {\n uvDependentTextureSlots.push('KHR_materials_iridescence.iridescenceTexture');\n }\n if (material.extensions?.KHR_materials_anisotropy?.anisotropyTexture) {\n uvDependentTextureSlots.push('KHR_materials_anisotropy.anisotropyTexture');\n }\n\n return uvDependentTextureSlots;\n}\n\n/** Parse GLTF material record */\nfunction parseMaterial(\n device: Device,\n material: GLTFPBRMaterial,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed\n): void {\n parsedMaterial.uniforms.unlit = Boolean(\n material.unlit || material.extensions?.KHR_materials_unlit\n );\n\n if (material.pbrMetallicRoughness) {\n parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial, gltf);\n }\n if (material.normalTexture) {\n addTexture(device, material.normalTexture, 'pbr_normalSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_NORMALMAP',\n enabledUniformName: 'normalMapEnabled'\n },\n gltf\n });\n\n const {scale = 1} = material.normalTexture;\n parsedMaterial.uniforms.normalScale = scale;\n }\n if (material.occlusionTexture) {\n addTexture(device, material.occlusionTexture, 'pbr_occlusionSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_OCCLUSIONMAP',\n enabledUniformName: 'occlusionMapEnabled'\n },\n gltf\n });\n\n const {strength = 1} = material.occlusionTexture;\n parsedMaterial.uniforms.occlusionStrength = strength;\n }\n parsedMaterial.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];\n if (material.emissiveTexture) {\n addTexture(device, material.emissiveTexture, 'pbr_emissiveSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_EMISSIVEMAP',\n enabledUniformName: 'emissiveMapEnabled'\n },\n gltf\n });\n }\n\n parseMaterialExtensions(device, material.extensions, parsedMaterial, gltf);\n\n switch (material.alphaMode || 'OPAQUE') {\n case 'OPAQUE':\n break;\n case 'MASK': {\n const {alphaCutoff = 0.5} = material;\n parsedMaterial.defines['ALPHA_CUTOFF'] = true;\n parsedMaterial.uniforms.alphaCutoffEnabled = true;\n parsedMaterial.uniforms.alphaCutoff = alphaCutoff;\n break;\n }\n case 'BLEND':\n log.warn('glTF BLEND alphaMode might not work well because it requires mesh sorting')();\n applyAlphaBlendParameters(parsedMaterial);\n\n break;\n }\n}\n\nfunction applyAlphaBlendParameters(parsedMaterial: ParsedPBRMaterial): void {\n parsedMaterial.parameters.blend = true;\n parsedMaterial.parameters.blendColorOperation = 'add';\n parsedMaterial.parameters.blendColorSrcFactor = 'src-alpha';\n parsedMaterial.parameters.blendColorDstFactor = 'one-minus-src-alpha';\n parsedMaterial.parameters.blendAlphaOperation = 'add';\n parsedMaterial.parameters.blendAlphaSrcFactor = 'one';\n parsedMaterial.parameters.blendAlphaDstFactor = 'one-minus-src-alpha';\n\n parsedMaterial.glParameters['blend'] = true;\n parsedMaterial.glParameters['blendEquation'] = GLEnum.FUNC_ADD;\n parsedMaterial.glParameters['blendFunc'] = [\n GLEnum.SRC_ALPHA,\n GLEnum.ONE_MINUS_SRC_ALPHA,\n GLEnum.ONE,\n GLEnum.ONE_MINUS_SRC_ALPHA\n ];\n}\n\nfunction applyTransmissionBlendApproximation(parsedMaterial: ParsedPBRMaterial): void {\n parsedMaterial.parameters.blend = true;\n parsedMaterial.parameters.depthWriteEnabled = false;\n parsedMaterial.parameters.blendColorOperation = 'add';\n parsedMaterial.parameters.blendColorSrcFactor = 'one';\n parsedMaterial.parameters.blendColorDstFactor = 'one-minus-src-alpha';\n parsedMaterial.parameters.blendAlphaOperation = 'add';\n parsedMaterial.parameters.blendAlphaSrcFactor = 'one';\n parsedMaterial.parameters.blendAlphaDstFactor = 'one-minus-src-alpha';\n\n parsedMaterial.glParameters['blend'] = true;\n parsedMaterial.glParameters['depthMask'] = false;\n parsedMaterial.glParameters['blendEquation'] = GLEnum.FUNC_ADD;\n parsedMaterial.glParameters['blendFunc'] = [\n GLEnum.ONE,\n GLEnum.ONE_MINUS_SRC_ALPHA,\n GLEnum.ONE,\n GLEnum.ONE_MINUS_SRC_ALPHA\n ];\n}\n\n/** Parse GLTF material sub record */\nfunction parsePbrMetallicRoughness(\n device: Device,\n pbrMetallicRoughness: GLTFPBRMetallicRoughness,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed\n): void {\n if (pbrMetallicRoughness.baseColorTexture) {\n addTexture(\n device,\n pbrMetallicRoughness.baseColorTexture,\n 'pbr_baseColorSampler',\n parsedMaterial,\n {\n featureOptions: {\n define: 'HAS_BASECOLORMAP',\n enabledUniformName: 'baseColorMapEnabled'\n },\n gltf\n }\n );\n }\n parsedMaterial.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];\n\n if (pbrMetallicRoughness.metallicRoughnessTexture) {\n addTexture(\n device,\n pbrMetallicRoughness.metallicRoughnessTexture,\n 'pbr_metallicRoughnessSampler',\n parsedMaterial,\n {\n featureOptions: {\n define: 'HAS_METALROUGHNESSMAP',\n enabledUniformName: 'metallicRoughnessMapEnabled'\n },\n gltf\n }\n );\n }\n const {metallicFactor = 1, roughnessFactor = 1} = pbrMetallicRoughness;\n parsedMaterial.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];\n}\n\nfunction parseMaterialExtensions(\n device: Device,\n extensions: GLTFMaterialExtensions | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed\n): void {\n if (!extensions) {\n return;\n }\n\n if (hasMaterialExtensionShading(extensions)) {\n parsedMaterial.defines['USE_MATERIAL_EXTENSIONS'] = true;\n }\n\n parseSpecularExtension(device, extensions.KHR_materials_specular, parsedMaterial, gltf);\n parseIorExtension(extensions.KHR_materials_ior, parsedMaterial);\n parseTransmissionExtension(device, extensions.KHR_materials_transmission, parsedMaterial, gltf);\n parseVolumeExtension(device, extensions.KHR_materials_volume, parsedMaterial, gltf);\n parseClearcoatExtension(device, extensions.KHR_materials_clearcoat, parsedMaterial, gltf);\n parseSheenExtension(device, extensions.KHR_materials_sheen, parsedMaterial, gltf);\n parseIridescenceExtension(device, extensions.KHR_materials_iridescence, parsedMaterial, gltf);\n parseAnisotropyExtension(device, extensions.KHR_materials_anisotropy, parsedMaterial, gltf);\n parseEmissiveStrengthExtension(extensions.KHR_materials_emissive_strength, parsedMaterial);\n}\n\nfunction hasMaterialExtensionShading(extensions: GLTFMaterialExtensions): boolean {\n return Boolean(\n extensions.KHR_materials_specular ||\n extensions.KHR_materials_ior ||\n extensions.KHR_materials_transmission ||\n extensions.KHR_materials_volume ||\n extensions.KHR_materials_clearcoat ||\n extensions.KHR_materials_sheen ||\n extensions.KHR_materials_iridescence ||\n extensions.KHR_materials_anisotropy\n );\n}\n\nfunction parseSpecularExtension(\n device: Device,\n extension: GLTFMaterialSpecularExtension | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed\n): void {\n if (!extension) {\n return;\n }\n\n if (extension.specularColorFactor) {\n parsedMaterial.uniforms.specularColorFactor = extension.specularColorFactor;\n }\n if (extension.specularFactor !== undefined) {\n parsedMaterial.uniforms.specularIntensityFactor = extension.specularFactor;\n }\n if (extension.specularColorTexture) {\n addTexture(device, extension.specularColorTexture, 'pbr_specularColorSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_SPECULARCOLORMAP',\n enabledUniformName: 'specularColorMapEnabled'\n },\n gltf\n });\n }\n if (extension.specularTexture) {\n addTexture(device, extension.specularTexture, 'pbr_specularIntensitySampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_SPECULARINTENSITYMAP',\n enabledUniformName: 'specularIntensityMapEnabled'\n },\n gltf\n });\n }\n}\n\nfunction parseIorExtension(\n extension: GLTFMaterialIorExtension | undefined,\n parsedMaterial: ParsedPBRMaterial\n): void {\n if (extension?.ior !== undefined) {\n parsedMaterial.uniforms.ior = extension.ior;\n }\n}\n\nfunction parseTransmissionExtension(\n device: Device,\n extension: GLTFMaterialTransmissionExtension | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed\n): void {\n if (!extension) {\n return;\n }\n\n if (extension.transmissionFactor !== undefined) {\n parsedMaterial.uniforms.transmissionFactor = extension.transmissionFactor;\n }\n if (extension.transmissionTexture) {\n addTexture(device, extension.transmissionTexture, 'pbr_transmissionSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_TRANSMISSIONMAP',\n enabledUniformName: 'transmissionMapEnabled'\n },\n gltf\n });\n }\n\n if ((extension.transmissionFactor ?? 0) > 0 || extension.transmissionTexture) {\n log.warn(\n 'KHR_materials_transmission uses a premultiplied-alpha blending approximation and may require mesh sorting'\n )();\n applyTransmissionBlendApproximation(parsedMaterial);\n }\n}\n\nfunction parseVolumeExtension(\n device: Device,\n extension: GLTFMaterialVolumeExtension | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed\n): void {\n if (!extension) {\n return;\n }\n\n if (extension.thicknessFactor !== undefined) {\n parsedMaterial.uniforms.thicknessFactor = extension.thicknessFactor;\n }\n if (extension.thicknessTexture) {\n addTexture(device, extension.thicknessTexture, 'pbr_thicknessSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_THICKNESSMAP'\n },\n gltf\n });\n }\n if (extension.attenuationDistance !== undefined) {\n parsedMaterial.uniforms.attenuationDistance = extension.attenuationDistance;\n }\n if (extension.attenuationColor) {\n parsedMaterial.uniforms.attenuationColor = extension.attenuationColor;\n }\n}\n\nfunction parseClearcoatExtension(\n device: Device,\n extension: GLTFMaterialClearcoatExtension | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed\n): void {\n if (!extension) {\n return;\n }\n\n if (extension.clearcoatFactor !== undefined) {\n parsedMaterial.uniforms.clearcoatFactor = extension.clearcoatFactor;\n }\n if (extension.clearcoatRoughnessFactor !== undefined) {\n parsedMaterial.uniforms.clearcoatRoughnessFactor = extension.clearcoatRoughnessFactor;\n }\n if (extension.clearcoatTexture) {\n addTexture(device, extension.clearcoatTexture, 'pbr_clearcoatSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_CLEARCOATMAP',\n enabledUniformName: 'clearcoatMapEnabled'\n },\n gltf\n });\n }\n if (extension.clearcoatRoughnessTexture) {\n addTexture(\n device,\n extension.clearcoatRoughnessTexture,\n 'pbr_clearcoatRoughnessSampler',\n parsedMaterial,\n {\n featureOptions: {\n define: 'HAS_CLEARCOATROUGHNESSMAP',\n enabledUniformName: 'clearcoatRoughnessMapEnabled'\n },\n gltf\n }\n );\n }\n if (extension.clearcoatNormalTexture) {\n addTexture(\n device,\n extension.clearcoatNormalTexture,\n 'pbr_clearcoatNormalSampler',\n parsedMaterial,\n {\n featureOptions: {\n define: 'HAS_CLEARCOATNORMALMAP'\n },\n gltf\n }\n );\n }\n}\n\nfunction parseSheenExtension(\n device: Device,\n extension: GLTFMaterialSheenExtension | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed\n): void {\n if (!extension) {\n return;\n }\n\n if (extension.sheenColorFactor) {\n parsedMaterial.uniforms.sheenColorFactor = extension.sheenColorFactor;\n }\n if (extension.sheenRoughnessFactor !== undefined) {\n parsedMaterial.uniforms.sheenRoughnessFactor = extension.sheenRoughnessFactor;\n }\n if (extension.sheenColorTexture) {\n addTexture(device, extension.sheenColorTexture, 'pbr_sheenColorSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_SHEENCOLORMAP',\n enabledUniformName: 'sheenColorMapEnabled'\n },\n gltf\n });\n }\n if (extension.sheenRoughnessTexture) {\n addTexture(\n device,\n extension.sheenRoughnessTexture,\n 'pbr_sheenRoughnessSampler',\n parsedMaterial,\n {\n featureOptions: {\n define: 'HAS_SHEENROUGHNESSMAP',\n enabledUniformName: 'sheenRoughnessMapEnabled'\n },\n gltf\n }\n );\n }\n}\n\nfunction parseIridescenceExtension(\n device: Device,\n extension: GLTFMaterialIridescenceExtension | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed\n): void {\n if (!extension) {\n return;\n }\n\n if (extension.iridescenceFactor !== undefined) {\n parsedMaterial.uniforms.iridescenceFactor = extension.iridescenceFactor;\n }\n if (extension.iridescenceIor !== undefined) {\n parsedMaterial.uniforms.iridescenceIor = extension.iridescenceIor;\n }\n if (\n extension.iridescenceThicknessMinimum !== undefined ||\n extension.iridescenceThicknessMaximum !== undefined\n ) {\n parsedMaterial.uniforms.iridescenceThicknessRange = [\n extension.iridescenceThicknessMinimum ?? 100,\n extension.iridescenceThicknessMaximum ?? 400\n ];\n }\n if (extension.iridescenceTexture) {\n addTexture(device, extension.iridescenceTexture, 'pbr_iridescenceSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_IRIDESCENCEMAP',\n enabledUniformName: 'iridescenceMapEnabled'\n },\n gltf\n });\n }\n if (extension.iridescenceThicknessTexture) {\n addTexture(\n device,\n extension.iridescenceThicknessTexture,\n 'pbr_iridescenceThicknessSampler',\n parsedMaterial,\n {\n featureOptions: {\n define: 'HAS_IRIDESCENCETHICKNESSMAP'\n },\n gltf\n }\n );\n }\n}\n\nfunction parseAnisotropyExtension(\n device: Device,\n extension: GLTFMaterialAnisotropyExtension | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed\n): void {\n if (!extension) {\n return;\n }\n\n if (extension.anisotropyStrength !== undefined) {\n parsedMaterial.uniforms.anisotropyStrength = extension.anisotropyStrength;\n }\n if (extension.anisotropyRotation !== undefined) {\n parsedMaterial.uniforms.anisotropyRotation = extension.anisotropyRotation;\n }\n if (extension.anisotropyTexture) {\n addTexture(device, extension.anisotropyTexture, 'pbr_anisotropySampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_ANISOTROPYMAP',\n enabledUniformName: 'anisotropyMapEnabled'\n },\n gltf\n });\n }\n}\n\nfunction parseEmissiveStrengthExtension(\n extension: GLTFMaterialEmissiveStrengthExtension | undefined,\n parsedMaterial: ParsedPBRMaterial\n): void {\n if (extension?.emissiveStrength !== undefined) {\n parsedMaterial.uniforms.emissiveStrength = extension.emissiveStrength;\n }\n}\n\n/** Create a texture from a glTF texture/sampler/image combo and add it to bindings */\nfunction addTexture(\n device: Device,\n gltfTexture: GLTFTexture,\n uniformName: keyof PBRMaterialBindings,\n parsedMaterial: ParsedPBRMaterial,\n textureParseOptions: TextureParseOptions = {}\n): void {\n const {featureOptions = {}, gltf} = textureParseOptions;\n const {define, enabledUniformName} = featureOptions;\n const resolvedTextureInfo = resolveTextureInfo(gltfTexture, gltf);\n const image = resolvedTextureInfo.texture?.source?.image;\n if (!image) {\n log.warn(`Skipping unresolved glTF texture for ${String(uniformName)}`)();\n return;\n }\n\n const gltfSampler = {\n wrapS: 10497, // default REPEAT S (U) wrapping mode.\n wrapT: 10497, // default REPEAT T (V) wrapping mode.\n minFilter: 9729, // default LINEAR filtering\n magFilter: 9729, // default LINEAR filtering\n ...resolvedTextureInfo?.texture?.sampler\n } as GLTFSampler;\n\n const baseOptions = {\n id: resolvedTextureInfo.uniformName || resolvedTextureInfo.id,\n sampler: convertSampler(gltfSampler)\n };\n\n let texture: Texture;\n\n if (image.compressed) {\n texture = createCompressedTexture(device, image, baseOptions);\n } else {\n const {width, height} = device.getExternalImageSize(image);\n texture = device.createTexture({\n ...baseOptions,\n width,\n height,\n data: image\n });\n }\n\n parsedMaterial.bindings[uniformName] = texture;\n if (define) parsedMaterial.defines[define] = true;\n if (enabledUniformName) {\n parsedMaterial.uniforms[enabledUniformName] = true;\n }\n parsedMaterial.generatedTextures.push(texture);\n}\n\nfunction resolveTextureInfo(gltfTexture: GLTFTexture, gltf?: GLTFPostprocessed): GLTFTexture {\n if (gltfTexture.texture || gltfTexture.index === undefined || !gltf?.textures) {\n return gltfTexture;\n }\n\n const resolvedTextureEntry = gltf.textures[gltfTexture.index] as\n | Partial<GLTFTexture>\n | GLTFTexture['texture']\n | undefined;\n if (!resolvedTextureEntry) {\n return gltfTexture;\n }\n\n if ('texture' in resolvedTextureEntry && resolvedTextureEntry.texture) {\n return {\n ...resolvedTextureEntry,\n ...gltfTexture,\n texture: resolvedTextureEntry.texture\n } as GLTFTexture;\n }\n\n if (!('source' in resolvedTextureEntry)) {\n return gltfTexture;\n }\n\n return {\n ...gltfTexture,\n texture: resolvedTextureEntry\n };\n}\n\n/** One mip level as produced by loaders.gl compressed texture parsers */\nexport type CompressedMipLevel = {\n data: TypedArray;\n width: number;\n height: number;\n textureFormat?: TextureFormat;\n};\n\n/**\n * Compressed image from current loaders.gl releases.\n * - `mipmaps` is a boolean (true), NOT an array\n * - `data` is an Array of TextureLevel-like objects\n * - Per-level `textureFormat` is already a luma.gl TextureFormat\n * - Top-level `width`/`height` may be undefined\n */\nexport type CompressedImageDataArray = {\n compressed: true;\n mipmaps?: boolean;\n width?: number;\n height?: number;\n data: CompressedMipLevel[];\n};\n\n/**\n * Hypothetical future format where `mipmaps` is an actual array.\n * Kept for forward compatibility.\n */\nexport type CompressedImageMipmapArray = {\n compressed: true;\n width?: number;\n height?: number;\n mipmaps: CompressedMipLevel[];\n};\n\n/** Union of all known loaders.gl compressed image shapes */\nexport type CompressedImage = CompressedImageDataArray | CompressedImageMipmapArray;\n\nfunction createCompressedTextureFallback(\n device: Device,\n baseOptions: {id: string; sampler: SamplerProps}\n): Texture {\n return device.createTexture({\n ...baseOptions,\n format: 'rgba8unorm',\n width: 1,\n height: 1,\n mipLevels: 1\n });\n}\n\nfunction resolveCompressedTextureFormat(level: CompressedMipLevel): TextureFormat | undefined {\n return level.textureFormat;\n}\n\n/**\n * Maximum mip levels that can be filled for a compressed texture.\n * texStorage2D allocates level i at (baseW >> i) \u00D7 (baseH >> i).\n * Compressed formats can't upload data for levels smaller than one block,\n * so we stop before either dimension drops below the block size.\n */\nfunction getMaxCompressedMipLevels(\n baseWidth: number,\n baseHeight: number,\n format: TextureFormat\n): number {\n const {blockWidth = 1, blockHeight = 1} = textureFormatDecoder.getInfo(format);\n let count = 1;\n for (let i = 1; ; i++) {\n const w = Math.max(1, baseWidth >> i);\n const h = Math.max(1, baseHeight >> i);\n if (w < blockWidth || h < blockHeight) break;\n count++;\n }\n return count;\n}\n\n/**\n * Create a texture from compressed image data produced by loaders.gl.\n * Handles current loaders.gl compressed image layouts:\n *\n * current: {compressed, mipmaps: true, data: [{data, width, height, textureFormat}, ...]}\n * forward: {compressed, mipmaps: [{data, width, height, textureFormat}, ...]}\n */\nexport function createCompressedTexture(\n device: Device,\n image: CompressedImage,\n baseOptions: {id: string; sampler: SamplerProps}\n): Texture {\n // Normalize mip levels from all known loaders.gl formats\n let levels: CompressedMipLevel[];\n\n if (Array.isArray((image as any).data) && (image as any).data[0]?.data) {\n // loaders.gl current format: image.data is Array of mip-level objects\n levels = (image as CompressedImageDataArray).data;\n } else if ('mipmaps' in image && Array.isArray((image as CompressedImageMipmapArray).mipmaps)) {\n // Hypothetical future format: image.mipmaps is an Array\n levels = (image as CompressedImageMipmapArray).mipmaps;\n } else {\n levels = [];\n }\n\n if (levels.length === 0 || !levels[0]?.data) {\n log.warn(\n 'createCompressedTexture: compressed image has no valid mip levels, creating fallback'\n )();\n return createCompressedTextureFallback(device, baseOptions);\n }\n\n const baseLevel = levels[0];\n const baseWidth = baseLevel.width ?? (image as any).width ?? 0;\n const baseHeight = baseLevel.height ?? (image as any).height ?? 0;\n\n if (baseWidth <= 0 || baseHeight <= 0) {\n log.warn('createCompressedTexture: base level has invalid dimensions, creating fallback')();\n return createCompressedTextureFallback(device, baseOptions);\n }\n\n const format = resolveCompressedTextureFormat(baseLevel);\n\n if (!format) {\n log.warn('createCompressedTexture: compressed image has no textureFormat, creating fallback')();\n return createCompressedTextureFallback(device, baseOptions);\n }\n\n // Validate mip levels: truncate chain at first invalid level.\n // Levels must be contiguous, so we stop at the first level that has\n // a format mismatch, missing data, non-positive dimensions, or\n // dimensions that don't match what texStorage2D will allocate.\n //\n // For block-compressed formats (ASTC, BC, ETC2), texStorage2D allocates\n // mip levels down to 1\u00D71 texels, but compressed data can't be smaller\n // than one block (e.g. 4\u00D74 for ASTC-4x4). Cap the chain so we never\n // try to upload data whose block-aligned size exceeds the allocated level.\n const maxMipLevels = getMaxCompressedMipLevels(baseWidth, baseHeight, format);\n const levelLimit = Math.min(levels.length, maxMipLevels);\n\n let validLevelCount = 1;\n for (let i = 1; i < levelLimit; i++) {\n const level = levels[i];\n if (!level.data || level.width <= 0 || level.height <= 0) {\n log.warn(`createCompressedTexture: mip level ${i} has invalid data/dimensions, truncating`)();\n break;\n }\n const levelFormat = resolveCompressedTextureFormat(level);\n if (levelFormat && levelFormat !== format) {\n log.warn(\n `createCompressedTexture: mip level ${i} format '${levelFormat}' differs from base '${format}', truncating`\n )();\n break;\n }\n const expectedW = Math.max(1, baseWidth >> i);\n const expectedH = Math.max(1, baseHeight >> i);\n if (level.width !== expectedW || level.height !== expectedH) {\n log.warn(\n `createCompressedTexture: mip level ${i} dimensions ${level.width}x${level.height} ` +\n `don't match expected ${expectedW}x${expectedH}, truncating`\n )();\n break;\n }\n validLevelCount++;\n }\n\n const texture = device.createTexture({\n ...baseOptions,\n format,\n usage: Texture.TEXTURE | Texture.COPY_DST,\n width: baseWidth,\n height: baseHeight,\n mipLevels: validLevelCount,\n data: baseLevel.data\n });\n\n // Upload additional validated mip levels\n for (let i = 1; i < validLevelCount; i++) {\n texture.writeData(levels[i].data, {\n width: levels[i].width,\n height: levels[i].height,\n mipLevel: i\n });\n }\n\n return texture;\n}\n\n/*\n/**\n * Parses a GLTF material definition into uniforms and parameters for the PBR shader module\n *\nexport class PBRMaterialParser {\n readonly device: Device;\n\n readonly defines: Record<string, boolean>;\n readonly bindings: Record<string, Binding>;\n readonly uniforms: Record<string, any>;\n readonly parameters: Record<string, any>;\n\n /** Hold on to generated textures, we destroy them in the destroy method *\n readonly generatedTextures: Texture[];\n\n constructor(device: Device, props: PBRMaterialParserProps) {\n const {attributes, material, pbrDebug, imageBasedLightingEnvironment, lights, useTangents} =\n props;\n this.device = device;\n\n this.defines = {\n // TODO: Use EXT_sRGB if available (Standard in WebGL 2.0)\n MANUAL_SRGB: true,\n SRGB_FAST_APPROXIMATION: true\n };\n\n if (this.device.features.has('glsl-texture-lod')) {\n this.defines.USE_TEX_LOD = true;\n }\n\n this.uniforms = {\n // TODO: find better values?\n camera: [0, 0, 0], // Model should override\n\n metallicRoughnessValues: [1, 1] // Default is 1 and 1\n };\n\n this.bindings = {};\n\n this.parameters = {};\n this.generatedTextures = [];\n\n if (imageBasedLightingEnvironment) {\n this.bindings.pbr_diffuseEnvSampler = imageBasedLightingEnvironment.getDiffuseEnvSampler();\n this.bindings.pbr_specularEnvSampler = imageBasedLightingEnvironment.getSpecularEnvSampler();\n this.bindings.pbr_brdfLUT = imageBasedLightingEnvironment.getBrdfTexture();\n this.uniforms.scaleIBLAmbient = [1, 1];\n }\n\n if (pbrDebug) {\n // Override final color for reference app visualization\n // of various parameters in the lighting equation.\n this.uniforms.scaleDiffBaseMR = [0, 0, 0, 0];\n this.uniforms.scaleFGDSpec = [0, 0, 0, 0];\n }\n\n this.defineIfPresent(attributes.NORMAL, 'HAS_NORMALS');\n this.defineIfPresent(attributes.TANGENT && useTangents, 'HAS_TANGENTS');\n this.defineIfPresent(attributes.TEXCOORD_0, 'HAS_UV');\n this.defineIfPresent(attributes.COLOR_0, 'HAS_COLORS');\n\n this.defineIfPresent(imageBasedLightingEnvironment, 'USE_IBL');\n this.defineIfPresent(lights, 'USE_LIGHTS');\n this.defineIfPresent(pbrDebug, 'PBR_DEBUG');\n\n if (material) {\n this.parseMaterial(material);\n }\n }\n\n /**\n * Destroy all generated resources to release memory.\n *\n destroy(): void {\n this.generatedTextures.forEach(texture => texture.destroy());\n }\n\n /** Add a define if the the value is non-nullish *\n defineIfPresent(value: unknown, name: string): void {\n if (value) {\n this.defines[name] = 1;\n }\n }\n\n /** Parse GLTF material record *\n parseMaterial(material) {\n this.uniforms.unlit = Boolean(material.unlit);\n\n if (material.pbrMetallicRoughness) {\n this.parsePbrMetallicRoughness(material.pbrMetallicRoughness);\n }\n if (material.normalTexture) {\n this.addTexture(material.normalTexture, 'pbr_normalSampler', 'HAS_NORMALMAP');\n\n const {scale = 1} = material.normalTexture;\n this.uniforms.normalScale = scale;\n }\n if (material.occlusionTexture) {\n this.addTexture(material.occlusionTexture, 'pbr_occlusionSampler', 'HAS_OCCLUSIONMAP');\n\n const {strength = 1} = material.occlusionTexture;\n this.uniforms.occlusionStrength = strength;\n }\n if (material.emissiveTexture) {\n this.addTexture(material.emissiveTexture, 'pbr_emissiveSampler', 'HAS_EMISSIVEMAP');\n this.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];\n }\n if (material.alphaMode === 'MASK') {\n const {alphaCutoff = 0.5} = material;\n this.defines.ALPHA_CUTOFF = true;\n this.uniforms.u_AlphaCutoff = alphaCutoff;\n } else if (material.alphaMode === 'BLEND') {\n log.warn('BLEND alphaMode might not work well because it requires mesh sorting')();\n Object.assign(this.parameters, {\n blend: true,\n blendEquation: GLEnum.FUNC_ADD,\n blendFunc: [\n GLEnum.SRC_ALPHA,\n GLEnum.ONE_MINUS_SRC_ALPHA,\n GLEnum.ONE,\n GLEnum.ONE_MINUS_SRC_ALPHA\n ]\n });\n }\n }\n\n /** Parse GLTF material sub record *\n parsePbrMetallicRoughness(pbrMetallicRoughness) {\n if (pbrMetallicRoughness.baseColorTexture) {\n this.addTexture(\n pbrMetallicRoughness.baseColorTexture,\n 'pbr_baseColorSampler',\n 'HAS_BASECOLORMAP'\n );\n }\n this.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];\n\n if (pbrMetallicRoughness.metallicRoughnessTexture) {\n this.addTexture(\n pbrMetallicRoughness.metallicRoughnessTexture,\n 'pbr_metallicRoughnessSampler',\n 'HAS_METALROUGHNESSMAP'\n );\n }\n const {metallicFactor = 1, roughnessFactor = 1} = pbrMetallicRoughness;\n this.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];\n }\n\n /** Create a texture from a glTF texture/sampler/image combo and add it to bindings *\n addTexture(gltfTexture, name, define = null) {\n const parameters = gltfTexture?.texture?.sampler?.parameters || {};\n\n const image = gltfTexture.texture.source.image;\n let textureOptions;\n let specialTextureParameters = {};\n if (image.compressed) {\n textureOptions = image;\n specialTextureParameters = {\n [GLEnum.TEXTURE_MIN_FILTER]:\n image.data.length > 1 ? GLEnum.LINEAR_MIPMAP_NEAREST : GLEnum.LINEAR\n };\n } else {\n // Texture2D accepts a promise that returns an image as data (Async Textures)\n textureOptions = {data: image};\n }\n\n const texture: Texture = this.device.createTexture({\n id: gltfTexture.name || gltfTexture.id,\n parameters: {\n ...parameters,\n ...specialTextureParameters\n },\n pixelStore: {\n [GLEnum.UNPACK_FLIP_Y_WEBGL]: false\n },\n ...textureOptions\n });\n this.bindings[name] = texture;\n this.defineIfPresent(define, define);\n this.generatedTextures.push(texture);\n }\n}\n*/\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// NOTE: `@luma.gl/gltf` intentionally keeps this as a local enum subset so it\n// does not need to depend on `@luma.gl/webgl` for a handful of stable WebGL values.\n// eslint-disable-next-line no-shadow\nexport enum GLEnum {\n POINTS = 0x0,\n LINES = 0x1,\n LINE_LOOP = 0x2,\n LINE_STRIP = 0x3,\n TRIANGLES = 0x4,\n TRIANGLE_STRIP = 0x5,\n TRIANGLE_FAN = 0x6,\n\n ONE = 1,\n SRC_ALPHA = 0x0302,\n ONE_MINUS_SRC_ALPHA = 0x0303,\n FUNC_ADD = 0x8006,\n\n LINEAR = 0x2601,\n NEAREST = 0x2600,\n NEAREST_MIPMAP_NEAREST = 0x2700,\n LINEAR_MIPMAP_NEAREST = 0x2701,\n NEAREST_MIPMAP_LINEAR = 0x2702,\n LINEAR_MIPMAP_LINEAR = 0x2703,\n TEXTURE_MIN_FILTER = 0x2801,\n TEXTURE_WRAP_S = 0x2802,\n TEXTURE_WRAP_T = 0x2803,\n REPEAT = 0x2901,\n CLAMP_TO_EDGE = 0x812f,\n MIRRORED_REPEAT = 0x8370,\n UNPACK_FLIP_Y_WEBGL = 0x9240\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// TODO: convert in loaders.gl?\n\nimport type {SamplerProps} from '@luma.gl/core';\nimport {GLEnum} from './gltf-webgl-constants';\n\n/** Minimal glTF sampler representation used during conversion. */\ntype GLTFSampler = {\n /** Horizontal wrap mode. */\n wrapS?: GLEnum.CLAMP_TO_EDGE | GLEnum.REPEAT | GLEnum.MIRRORED_REPEAT;\n /** Vertical wrap mode. */\n wrapT?: GLEnum.CLAMP_TO_EDGE | GLEnum.REPEAT | GLEnum.MIRRORED_REPEAT;\n /** Magnification filter. */\n magFilter?: GLEnum.NEAREST | GLEnum.LINEAR;\n /** Minification and mip filter combination. */\n minFilter?:\n | GLEnum.NEAREST\n | GLEnum.LINEAR\n | GLEnum.NEAREST_MIPMAP_NEAREST\n | GLEnum.LINEAR_MIPMAP_NEAREST\n | GLEnum.NEAREST_MIPMAP_LINEAR\n | GLEnum.LINEAR_MIPMAP_LINEAR;\n};\n\n/** Converts a glTF sampler into luma.gl sampler props. */\nexport function convertSampler(gltfSampler: GLTFSampler): SamplerProps {\n return {\n addressModeU: convertSamplerWrapMode(gltfSampler.wrapS),\n addressModeV: convertSamplerWrapMode(gltfSampler.wrapT),\n magFilter: convertSamplerMagFilter(gltfSampler.magFilter),\n ...convertSamplerMinFilter(gltfSampler.minFilter)\n };\n}\n\n/** Converts a glTF wrap enum into a luma.gl address mode. */\nfunction convertSamplerWrapMode(\n mode: GLEnum.CLAMP_TO_EDGE | GLEnum.REPEAT | GLEnum.MIRRORED_REPEAT | undefined\n): 'clamp-to-edge' | 'repeat' | 'mirror-repeat' | undefined {\n switch (mode) {\n case GLEnum.CLAMP_TO_EDGE:\n return 'clamp-to-edge';\n case GLEnum.REPEAT:\n return 'repeat';\n case GLEnum.MIRRORED_REPEAT:\n return 'mirror-repeat';\n default:\n return undefined;\n }\n}\n\n/** Converts a glTF mag filter enum into a luma.gl mag filter. */\nfunction convertSamplerMagFilter(\n mode: GLEnum.NEAREST | GLEnum.LINEAR | undefined\n): 'nearest' | 'linear' | undefined {\n switch (mode) {\n case GLEnum.NEAREST:\n return 'nearest';\n case GLEnum.LINEAR:\n return 'linear';\n default:\n return undefined;\n }\n}\n\n/** Converts a glTF min filter enum into luma.gl minification and mipmap filters. */\nfunction convertSamplerMinFilter(\n mode:\n | GLEnum.NEAREST\n | GLEnum.LINEAR\n | GLEnum.NEAREST_MIPMAP_NEAREST\n | GLEnum.LINEAR_MIPMAP_NEAREST\n | GLEnum.NEAREST_MIPMAP_LINEAR\n | GLEnum.LINEAR_MIPMAP_LINEAR\n | undefined\n): {minFilter?: 'nearest' | 'linear'; mipmapFilter?: 'nearest' | 'linear'} {\n switch (mode) {\n case GLEnum.NEAREST:\n return {minFilter: 'nearest'};\n case GLEnum.LINEAR:\n return {minFilter: 'linear'};\n case GLEnum.NEAREST_MIPMAP_NEAREST:\n return {minFilter: 'nearest', mipmapFilter: 'nearest'};\n case GLEnum.LINEAR_MIPMAP_NEAREST:\n return {minFilter: 'linear', mipmapFilter: 'nearest'};\n case GLEnum.NEAREST_MIPMAP_LINEAR:\n return {minFilter: 'nearest', mipmapFilter: 'linear'};\n case GLEnum.LINEAR_MIPMAP_LINEAR:\n return {minFilter: 'linear', mipmapFilter: 'linear'};\n default:\n return {};\n }\n}\n", "import {Matrix4} from '@math.gl/core';\nimport type {GLTFNodePostprocessed, GLTFPostprocessed} from '@loaders.gl/gltf';\nimport type {DirectionalLight, Light, PointLight, SpotLight} from '@luma.gl/shadertools';\n\nconst GLTF_COLOR_FACTOR = 255;\n\n/** Parse KHR_lights_punctual extension into luma.gl light definitions */\nexport function parseGLTFLights(gltf: GLTFPostprocessed): Light[] {\n const lightDefs =\n // `postProcessGLTF()` moves KHR_lights_punctual into `gltf.lights`.\n (gltf as GLTFPostprocessed & {lights?: any[]}).lights ||\n gltf.extensions?.['KHR_lights_punctual']?.['lights'];\n if (!lightDefs || !Array.isArray(lightDefs) || lightDefs.length === 0) {\n return [];\n }\n\n const lights: Light[] = [];\n const parentNodeById = createParentNodeMap(gltf.nodes || []);\n const worldMatrixByNodeId = new Map<string, Matrix4>();\n\n for (const node of gltf.nodes || []) {\n const lightIndex =\n (node as GLTFNodePostprocessed & {light?: number}).light ??\n node.extensions?.KHR_lights_punctual?.light;\n if (typeof lightIndex !== 'number') {\n // eslint-disable-next-line no-continue\n continue;\n }\n const gltfLight = lightDefs[lightIndex];\n if (!gltfLight) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n const color = normalizeGLTFLightColor(\n (gltfLight.color || [1, 1, 1]) as [number, number, number]\n );\n const intensity = gltfLight.intensity ?? 1;\n const range = gltfLight.range;\n const worldMatrix = getNodeWorldMatrix(node, parentNodeById, worldMatrixByNodeId);\n\n switch (gltfLight.type) {\n case 'directional':\n lights.push(parseDirectionalLight(worldMatrix, color, intensity));\n break;\n case 'point':\n lights.push(parsePointLight(worldMatrix, color, intensity, range));\n break;\n case 'spot':\n lights.push(parseSpotLight(worldMatrix, color, intensity, range, gltfLight.spot));\n break;\n default:\n // Unsupported light type\n break;\n }\n }\n\n return lights;\n}\n\n/**\n * Converts glTF colors from the 0-1 spec range to luma.gl's 0-255 light convention.\n */\nfunction normalizeGLTFLightColor(color: [number, number, number]): [number, number, number] {\n return color.map(component => component * GLTF_COLOR_FACTOR) as [number, number, number];\n}\n\n/**\n * Converts a glTF punctual light attached to a node into a point light.\n */\nfunction parsePointLight(\n worldMatrix: Matrix4,\n color: [number, number, number],\n intensity: number,\n range?: number\n): PointLight {\n const position = getLightPosition(worldMatrix);\n\n let attenuation: Readonly<[number, number, number]> = [1, 0, 0];\n if (range !== undefined && range > 0) {\n attenuation = [1, 0, 1 / (range * range)] as [number, number, number];\n }\n\n return {\n type: 'point',\n position,\n color,\n intensity,\n attenuation\n };\n}\n\n/**\n * Converts a glTF punctual light attached to a node into a directional light.\n */\nfunction parseDirectionalLight(\n worldMatrix: Matrix4,\n color: [number, number, number],\n intensity: number\n): DirectionalLight {\n const direction = getLightDirection(worldMatrix);\n\n return {\n type: 'directional',\n direction,\n color,\n intensity\n };\n}\n\n/**\n * Converts a glTF punctual light attached to a node into a spot light.\n */\nfunction parseSpotLight(\n worldMatrix: Matrix4,\n color: [number, number, number],\n intensity: number,\n range?: number,\n spot: {innerConeAngle?: number; outerConeAngle?: number} = {}\n): SpotLight {\n const position = getLightPosition(worldMatrix);\n const direction = getLightDirection(worldMatrix);\n\n let attenuation: Readonly<[number, number, number]> = [1, 0, 0];\n if (range !== undefined && range > 0) {\n attenuation = [1, 0, 1 / (range * range)] as [number, number, number];\n }\n\n return {\n type: 'spot',\n position,\n direction,\n color,\n intensity,\n attenuation,\n innerConeAngle: spot.innerConeAngle ?? 0,\n outerConeAngle: spot.outerConeAngle ?? Math.PI / 4\n };\n}\n\n/**\n * Builds a parent lookup so punctual lights can be resolved in world space.\n */\nfunction createParentNodeMap(nodes: GLTFNodePostprocessed[]): Map<string, GLTFNodePostprocessed> {\n const parentNodeById = new Map<string, GLTFNodePostprocessed>();\n\n for (const node of nodes) {\n for (const childNode of node.children || []) {\n parentNodeById.set(childNode.id, node);\n }\n }\n\n return parentNodeById;\n}\n\n/**\n * Resolves a glTF node's world matrix from its local transform and parent chain.\n */\nfunction getNodeWorldMatrix(\n node: GLTFNodePostprocessed,\n parentNodeById: Map<string, GLTFNodePostprocessed>,\n worldMatrixByNodeId: Map<string, Matrix4>\n): Matrix4 {\n const cachedWorldMatrix = worldMatrixByNodeId.get(node.id);\n if (cachedWorldMatrix) {\n return cachedWorldMatrix;\n }\n\n const localMatrix = getNodeLocalMatrix(node);\n const parentNode = parentNodeById.get(node.id);\n const worldMatrix = parentNode\n ? new Matrix4(\n getNodeWorldMatrix(parentNode, parentNodeById, worldMatrixByNodeId)\n ).multiplyRight(localMatrix)\n : localMatrix;\n\n worldMatrixByNodeId.set(node.id, worldMatrix);\n return worldMatrix;\n}\n\n/**\n * Resolves a glTF node's local matrix from its matrix or TRS components.\n */\nfunction getNodeLocalMatrix(node: GLTFNodePostprocessed): Matrix4 {\n if (node.matrix) {\n return new Matrix4(node.matrix);\n }\n\n const matrix = new Matrix4();\n\n if (node.translation) {\n matrix.translate(node.translation);\n }\n\n if (node.rotation) {\n matrix.multiplyRight(new Matrix4().fromQuaternion(node.rotation));\n }\n\n if (node.scale) {\n matrix.scale(node.scale);\n }\n\n return matrix;\n}\n\n/**\n * Resolves the world-space position of a glTF light node.\n */\nfunction getLightPosition(worldMatrix: Matrix4): [number, number, number] {\n return worldMatrix.transformAsPoint([0, 0, 0]) as [number, number, number];\n}\n\n/**\n * Resolves the world-space forward direction of a glTF light node.\n */\nfunction getLightDirection(worldMatrix: Matrix4): [number, number, number] {\n return worldMatrix.transformDirection([0, 0, -1]) as [number, number, number];\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Device, type PrimitiveTopology} from '@luma.gl/core';\nimport {\n Geometry,\n GeometryAttribute,\n GroupNode,\n Material,\n MaterialFactory,\n ModelNode,\n type ModelProps\n} from '@luma.gl/engine';\nimport {\n type GLTFMaterialPostprocessed,\n type GLTFMeshPostprocessed,\n type GLTFNodePostprocessed,\n type GLTFPostprocessed\n} from '@loaders.gl/gltf';\nimport {pbrMaterial} from '@luma.gl/shadertools';\n\nimport {type PBREnvironment} from '../pbr/pbr-environment';\nimport {convertGLDrawModeToTopology} from '../webgl-to-webgpu/convert-webgl-topology';\nimport {createGLTFMaterial, createGLTFModel} from '../gltf/create-gltf-model';\n\nimport {parsePBRMaterial} from './parse-pbr-material';\n\n/** Options that influence how a post-processed glTF is turned into a luma.gl scenegraph. */\nexport type ParseGLTFOptions = {\n /** Additional model props applied to each generated primitive model. */\n modelOptions?: Partial<ModelProps>;\n /** Enables shader-level PBR debug output. */\n pbrDebug?: boolean;\n /** Optional image-based lighting environment. */\n imageBasedLightingEnvironment?: PBREnvironment;\n /** Enables punctual light extraction. */\n lights?: boolean;\n /** Enables tangent usage when available. */\n useTangents?: boolean;\n};\n\nconst defaultOptions: Required<ParseGLTFOptions> = {\n modelOptions: {},\n pbrDebug: false,\n imageBasedLightingEnvironment: undefined!,\n lights: true,\n useTangents: false\n};\n\n/**\n * GLTF instantiator for luma.gl\n * Walks the parsed and resolved glTF structure and builds a luma.gl scenegraph\n */\nexport function parseGLTF(\n device: Device,\n gltf: GLTFPostprocessed,\n options: ParseGLTFOptions = {}\n): {\n /** Scene roots generated from `gltf.scenes`. */\n scenes: GroupNode[];\n /** Materials aligned with the source `gltf.materials` array. */\n materials: Material[];\n /** Map from glTF mesh ids to generated mesh group nodes. */\n gltfMeshIdToNodeMap: Map<string, GroupNode>;\n /** Map from glTF node indices to generated scenegraph nodes. */\n gltfNodeIndexToNodeMap: Map<number, GroupNode>;\n /** Map from glTF node ids to generated scenegraph nodes. */\n gltfNodeIdToNodeMap: Map<string, GroupNode>;\n} {\n const combinedOptions = {...defaultOptions, ...options};\n const materialFactory = new MaterialFactory(device, {modules: [pbrMaterial]});\n const materials = (gltf.materials || []).map((gltfMaterial, materialIndex) =>\n createGLTFMaterial(device, {\n id: getGLTFMaterialId(gltfMaterial, materialIndex),\n parsedPPBRMaterial: parsePBRMaterial(\n device,\n gltfMaterial as any,\n {},\n {\n ...combinedOptions,\n gltf,\n validateAttributes: false\n }\n ),\n materialFactory\n })\n );\n const gltfMaterialIdToMaterialMap = new Map<string, Material>();\n (gltf.materials || []).forEach((gltfMaterial, materialIndex) => {\n gltfMaterialIdToMaterialMap.set(gltfMaterial.id, materials[materialIndex]);\n });\n\n const gltfMeshIdToNodeMap = new Map<string, GroupNode>();\n gltf.meshes.forEach((gltfMesh, idx) => {\n const newMesh = createNodeForGLTFMesh(\n device,\n gltfMesh,\n gltf,\n gltfMaterialIdToMaterialMap,\n combinedOptions\n );\n gltfMeshIdToNodeMap.set(gltfMesh.id, newMesh);\n });\n\n const gltfNodeIndexToNodeMap = new Map<number, GroupNode>();\n const gltfNodeIdToNodeMap = new Map<string, GroupNode>();\n // Step 1/2: Generate a GroupNode for each gltf node. (1:1 mapping).\n gltf.nodes.forEach((gltfNode, idx) => {\n const newNode = createNodeForGLTFNode(device, gltfNode, combinedOptions);\n gltfNodeIndexToNodeMap.set(idx, newNode);\n gltfNodeIdToNodeMap.set(gltfNode.id, newNode);\n });\n\n // Step 2/2: Go though each gltf node and attach the children.\n // This guarantees that each gltf node will have exactly one luma GroupNode.\n gltf.nodes.forEach((gltfNode, idx) => {\n gltfNodeIndexToNodeMap.get(idx)!.add(\n (gltfNode.children ?? []).map(({id}) => {\n const child = gltfNodeIdToNodeMap.get(id);\n if (!child) throw new Error(`Cannot find child ${id} of node ${idx}`);\n return child;\n })\n );\n\n // Nodes can have children nodes and one optional child mesh at the same time.\n if (gltfNode.mesh) {\n const mesh = gltfMeshIdToNodeMap.get(gltfNode.mesh.id);\n if (!mesh) {\n throw new Error(`Cannot find mesh child ${gltfNode.mesh.id} of node ${idx}`);\n }\n gltfNodeIndexToNodeMap.get(idx)!.add(mesh);\n }\n });\n\n const scenes = gltf.scenes.map(gltfScene => {\n const children = (gltfScene.nodes || []).map(({id}) => {\n const child = gltfNodeIdToNodeMap.get(id);\n if (!child)\n throw new Error(`Cannot find child ${id} of scene ${gltfScene.name || gltfScene.id}`);\n return child;\n });\n return new GroupNode({\n id: gltfScene.name || gltfScene.id,\n children\n });\n });\n\n return {scenes, materials, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap};\n}\n\n/** Creates a `GroupNode` for one glTF node transform. */\nfunction createNodeForGLTFNode(\n device: Device,\n gltfNode: GLTFNodePostprocessed,\n options: Required<ParseGLTFOptions>\n): GroupNode {\n return new GroupNode({\n id: gltfNode.name || gltfNode.id,\n children: [],\n matrix: gltfNode.matrix,\n position: gltfNode.translation,\n rotation: gltfNode.rotation,\n scale: gltfNode.scale\n });\n}\n\n/** Creates a mesh group node containing one model node per glTF primitive. */\nfunction createNodeForGLTFMesh(\n device: Device,\n gltfMesh: GLTFMeshPostprocessed,\n gltf: GLTFPostprocessed,\n gltfMaterialIdToMaterialMap: Map<string, Material>,\n options: Required<ParseGLTFOptions>\n): GroupNode {\n const gltfPrimitives = gltfMesh.primitives || [];\n const primitives = gltfPrimitives.map((gltfPrimitive, i) =>\n createNodeForGLTFPrimitive({\n device,\n gltfPrimitive,\n primitiveIndex: i,\n gltfMesh,\n gltf,\n gltfMaterialIdToMaterialMap,\n options\n })\n );\n const mesh = new GroupNode({\n id: gltfMesh.name || gltfMesh.id,\n children: primitives\n });\n\n return mesh;\n}\n\n/** Input options for creating one renderable glTF primitive model node. */\ntype CreateNodeForGLTFPrimitiveOptions = {\n device: Device;\n gltfPrimitive: any;\n primitiveIndex: number;\n gltfMesh: GLTFMeshPostprocessed;\n gltf: GLTFPostprocessed;\n gltfMaterialIdToMaterialMap: Map<string, Material>;\n options: Required<ParseGLTFOptions>;\n};\n\n/** Creates a renderable model node for one glTF primitive. */\nfunction createNodeForGLTFPrimitive({\n device,\n gltfPrimitive,\n primitiveIndex,\n gltfMesh,\n gltf,\n gltfMaterialIdToMaterialMap,\n options\n}: CreateNodeForGLTFPrimitiveOptions): ModelNode {\n const id = gltfPrimitive.name || `${gltfMesh.name || gltfMesh.id}-primitive-${primitiveIndex}`;\n const topology = convertGLDrawModeToTopology(gltfPrimitive.mode || 4);\n const vertexCount = gltfPrimitive.indices\n ? gltfPrimitive.indices.count\n : getVertexCount(gltfPrimitive.attributes);\n\n const geometry = createGeometry(id, gltfPrimitive, topology);\n\n const parsedPPBRMaterial = parsePBRMaterial(device, gltfPrimitive.material, geometry.attributes, {\n ...options,\n gltf\n });\n\n const modelNode = createGLTFModel(device, {\n id,\n geometry: createGeometry(id, gltfPrimitive, topology),\n material: gltfPrimitive.material\n ? gltfMaterialIdToMaterialMap.get(gltfPrimitive.material.id) || null\n : null,\n parsedPPBRMaterial,\n modelOptions: options.modelOptions,\n vertexCount\n });\n\n modelNode.bounds = [gltfPrimitive.attributes.POSITION.min, gltfPrimitive.attributes.POSITION.max];\n // TODO this holds on to all the CPU side texture and attribute data\n // modelNode.material = gltfPrimitive.material;\n\n return modelNode;\n}\n\n/** Computes the vertex count for a primitive without indices. */\nfunction getVertexCount(attributes: any) {\n throw new Error('getVertexCount not implemented');\n}\n\n/** Converts glTF primitive attributes and indices into a luma.gl `Geometry`. */\nfunction createGeometry(id: string, gltfPrimitive: any, topology: PrimitiveTopology): Geometry {\n const attributes: Record<string, GeometryAttribute> = {};\n for (const [attributeName, attribute] of Object.entries(gltfPrimitive.attributes)) {\n const {components, size, value} = attribute as GeometryAttribute;\n\n attributes[attributeName] = {size: size ?? components, value};\n }\n\n return new Geometry({\n id,\n topology,\n indices: gltfPrimitive.indices.value,\n attributes\n });\n}\n\nfunction getGLTFMaterialId(gltfMaterial: GLTFMaterialPostprocessed, materialIndex: number): string {\n return gltfMaterial.name || gltfMaterial.id || `material-${materialIndex}`;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {PrimitiveTopology} from '@luma.gl/core';\nimport {GLEnum} from './gltf-webgl-constants';\n\n/** Converts a WebGL draw mode into a luma.gl primitive topology string. */\nexport function convertGLDrawModeToTopology(\n drawMode:\n | GLEnum.POINTS\n | GLEnum.LINES\n | GLEnum.LINE_STRIP\n | GLEnum.LINE_LOOP\n | GLEnum.TRIANGLES\n | GLEnum.TRIANGLE_STRIP\n | GLEnum.TRIANGLE_FAN\n): PrimitiveTopology {\n // prettier-ignore\n switch (drawMode) {\n case GLEnum.POINTS: return 'point-list';\n case GLEnum.LINES: return 'line-list';\n case GLEnum.LINE_STRIP: return 'line-strip';\n case GLEnum.TRIANGLES: return 'triangle-list';\n case GLEnum.TRIANGLE_STRIP: return 'triangle-strip';\n default: throw new Error(String(drawMode));\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {\n Buffer,\n Device,\n Sampler,\n Texture,\n TextureView,\n type Binding,\n type RenderPipelineParameters,\n log\n} from '@luma.gl/core';\nimport {DynamicTexture} from '@luma.gl/engine';\nimport {pbrMaterial, skin} from '@luma.gl/shadertools';\nimport {\n Geometry,\n Material,\n MaterialFactory,\n Model,\n ModelNode,\n type ModelProps\n} from '@luma.gl/engine';\nimport {type ParsedPBRMaterial} from '../pbr/pbr-material';\n\nconst SHADER = /* WGSL */ `\nstruct VertexInputs {\n @location(0) positions: vec3f,\n#ifdef HAS_NORMALS\n @location(1) normals: vec3f,\n#endif\n#ifdef HAS_TANGENTS\n @location(2) TANGENT: vec4f,\n#endif\n#ifdef HAS_UV\n @location(3) texCoords: vec2f,\n#endif\n#ifdef HAS_SKIN\n @location(4) JOINTS_0: vec4u,\n @location(5) WEIGHTS_0: vec4f,\n#endif\n};\n\nstruct FragmentInputs {\n @builtin(position) position: vec4f,\n @location(0) pbrPosition: vec3f,\n @location(1) pbrUV: vec2f,\n @location(2) pbrNormal: vec3f,\n#ifdef HAS_TANGENTS\n @location(3) pbrTangent: vec4f,\n#endif\n};\n\n@vertex\nfn vertexMain(inputs: VertexInputs) -> FragmentInputs {\n var outputs: FragmentInputs;\n var position = vec4f(inputs.positions, 1.0);\n var normal = vec3f(0.0, 0.0, 1.0);\n var tangent = vec4f(1.0, 0.0, 0.0, 1.0);\n var uv = vec2f(0.0, 0.0);\n\n#ifdef HAS_NORMALS\n normal = inputs.normals;\n#endif\n#ifdef HAS_UV\n uv = inputs.texCoords;\n#endif\n#ifdef HAS_TANGENTS\n tangent = inputs.TANGENT;\n#endif\n#ifdef HAS_SKIN\n let skinMatrix = getSkinMatrix(inputs.WEIGHTS_0, inputs.JOINTS_0);\n position = skinMatrix * position;\n normal = normalize((skinMatrix * vec4f(normal, 0.0)).xyz);\n#ifdef HAS_TANGENTS\n tangent = vec4f(normalize((skinMatrix * vec4f(tangent.xyz, 0.0)).xyz), tangent.w);\n#endif\n#endif\n\n let worldPosition = pbrProjection.modelMatrix * position;\n\n#ifdef HAS_NORMALS\n normal = normalize((pbrProjection.normalMatrix * vec4f(normal, 0.0)).xyz);\n#endif\n#ifdef HAS_TANGENTS\n let worldTangent = normalize((pbrProjection.modelMatrix * vec4f(tangent.xyz, 0.0)).xyz);\n outputs.pbrTangent = vec4f(worldTangent, tangent.w);\n#endif\n\n outputs.position = pbrProjection.modelViewProjectionMatrix * position;\n outputs.pbrPosition = worldPosition.xyz / worldPosition.w;\n outputs.pbrUV = uv;\n outputs.pbrNormal = normal;\n return outputs;\n}\n\n@fragment\nfn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {\n fragmentInputs.pbr_vPosition = inputs.pbrPosition;\n fragmentInputs.pbr_vUV = inputs.pbrUV;\n fragmentInputs.pbr_vNormal = inputs.pbrNormal;\n#ifdef HAS_TANGENTS\n let tangent = normalize(inputs.pbrTangent.xyz);\n let bitangent = normalize(cross(inputs.pbrNormal, tangent)) * inputs.pbrTangent.w;\n fragmentInputs.pbr_vTBN = mat3x3f(tangent, bitangent, inputs.pbrNormal);\n#endif\n return pbr_filterColor(vec4f(1.0));\n}\n`;\n\n// TODO rename attributes to POSITION/NORMAL etc\n// See gpu-geometry.ts: getAttributeBuffersFromGeometry()\nconst vs = /* glsl */ `\\\n#version 300 es\n\n // in vec4 POSITION;\n in vec4 positions;\n\n #ifdef HAS_NORMALS\n // in vec4 NORMAL;\n in vec4 normals;\n #endif\n\n #ifdef HAS_TANGENTS\n in vec4 TANGENT;\n #endif\n\n #ifdef HAS_UV\n // in vec2 TEXCOORD_0;\n in vec2 texCoords;\n #endif\n\n #ifdef HAS_SKIN\n in uvec4 JOINTS_0;\n in vec4 WEIGHTS_0;\n #endif\n\n void main(void) {\n vec4 _NORMAL = vec4(0.);\n vec4 _TANGENT = vec4(0.);\n vec2 _TEXCOORD_0 = vec2(0.);\n\n #ifdef HAS_NORMALS\n _NORMAL = normals;\n #endif\n\n #ifdef HAS_TANGENTS\n _TANGENT = TANGENT;\n #endif\n\n #ifdef HAS_UV\n _TEXCOORD_0 = texCoords;\n #endif\n\n vec4 pos = positions;\n\n #ifdef HAS_SKIN\n mat4 skinMat = getSkinMatrix(WEIGHTS_0, JOINTS_0);\n pos = skinMat * pos;\n _NORMAL = skinMat * _NORMAL;\n _TANGENT = vec4((skinMat * vec4(_TANGENT.xyz, 0.)).xyz, _TANGENT.w);\n #endif\n\n pbr_setPositionNormalTangentUV(pos, _NORMAL, _TANGENT, _TEXCOORD_0);\n gl_Position = pbrProjection.modelViewProjectionMatrix * pos;\n }\n`;\n\nconst fs = /* glsl */ `\\\n#version 300 es\n out vec4 fragmentColor;\n\n void main(void) {\n vec3 pos = pbr_vPosition;\n fragmentColor = pbr_filterColor(vec4(1.0));\n }\n`;\n\n/** Options used to instantiate a `ModelNode` for one glTF primitive. */\nexport type CreateGLTFModelOptions = {\n /** Optional id assigned to the generated model. */\n id?: string;\n /** Vertex count override for non-indexed primitives. */\n vertexCount?: number;\n /** Geometry converted from the glTF primitive. */\n geometry: Geometry;\n /** Parsed PBR material state for the primitive. */\n parsedPPBRMaterial: ParsedPBRMaterial;\n /** Pre-created material aligned with the source glTF material entry, when available. */\n material?: Material | null;\n /** Additional model props merged into the generated model. */\n modelOptions?: Partial<ModelProps>;\n};\n\nexport type CreateGLTFMaterialOptions = {\n id?: string;\n parsedPPBRMaterial: ParsedPBRMaterial;\n materialFactory?: MaterialFactory;\n};\n\nexport function createGLTFMaterial(device: Device, options: CreateGLTFMaterialOptions): Material {\n const materialFactory =\n options.materialFactory || new MaterialFactory(device, {modules: [pbrMaterial]});\n\n const pbrMaterialProps = {...options.parsedPPBRMaterial.uniforms};\n delete pbrMaterialProps.camera;\n const materialBindings = Object.fromEntries(\n Object.entries({\n ...pbrMaterialProps,\n ...options.parsedPPBRMaterial.bindings\n }).filter(\n ([name, value]) => materialFactory.ownsBinding(name) && isMaterialBindingResource(value)\n )\n ) as Record<string, Binding | DynamicTexture>;\n\n const material = materialFactory.createMaterial({\n id: options.id,\n bindings: materialBindings\n });\n material.setProps({pbrMaterial: pbrMaterialProps});\n\n return material;\n}\n\n/** Creates a luma.gl Model from GLTF data*/\nexport function createGLTFModel(device: Device, options: CreateGLTFModelOptions): ModelNode {\n const {id, geometry, parsedPPBRMaterial, vertexCount, modelOptions = {}} = options;\n\n log.info(4, 'createGLTFModel defines: ', parsedPPBRMaterial.defines)();\n\n // Calculate managedResources\n // TODO: Implement resource management logic that will\n // not deallocate resources/textures/buffers that are shared\n const managedResources: any[] = [];\n // managedResources.push(...parsedMaterial.generatedTextures);\n // managedResources.push(...Object.values(attributes).map((attribute) => attribute.buffer));\n\n const parameters: RenderPipelineParameters = {\n depthWriteEnabled: true,\n depthCompare: 'less',\n depthFormat: 'depth24plus',\n cullMode: 'back'\n };\n\n const modelProps: ModelProps = {\n id,\n source: SHADER,\n vs,\n fs,\n geometry,\n topology: geometry.topology,\n vertexCount,\n modules: [pbrMaterial, skin],\n ...modelOptions,\n\n defines: {...parsedPPBRMaterial.defines, ...modelOptions.defines},\n parameters: {...parameters, ...parsedPPBRMaterial.parameters, ...modelOptions.parameters}\n };\n\n const material =\n options.material ||\n createGLTFMaterial(device, {\n id: id ? `${id}-material` : undefined,\n parsedPPBRMaterial\n });\n modelProps.material = material;\n\n const model = new Model(device, modelProps);\n\n const sceneShaderInputValues = {\n ...parsedPPBRMaterial.uniforms,\n ...modelOptions.uniforms,\n ...parsedPPBRMaterial.bindings,\n ...modelOptions.bindings\n };\n const sceneShaderInputProps = getSceneShaderInputProps(\n model.shaderInputs.getModules(),\n material,\n sceneShaderInputValues\n );\n model.shaderInputs.setProps(sceneShaderInputProps);\n return new ModelNode({managedResources, model});\n}\n\nfunction isMaterialBindingResource(value: unknown): boolean {\n return (\n value instanceof Buffer ||\n value instanceof DynamicTexture ||\n value instanceof Sampler ||\n value instanceof Texture ||\n value instanceof TextureView\n );\n}\n\nfunction getSceneShaderInputProps(\n modules: Array<{\n name: string;\n uniformTypes?: Readonly<Record<string, unknown>>;\n bindingLayout?: ReadonlyArray<{name: string}>;\n }>,\n material: Material,\n shaderInputValues: Record<string, unknown>\n): Record<string, Record<string, unknown>> {\n const propertyToModuleNameMap = new Map<string, string>();\n for (const module of modules) {\n for (const uniformName of Object.keys(module.uniformTypes || {})) {\n propertyToModuleNameMap.set(uniformName, module.name);\n }\n for (const binding of module.bindingLayout || []) {\n propertyToModuleNameMap.set(binding.name, module.name);\n }\n }\n\n const sceneShaderInputProps: Record<string, Record<string, unknown>> = {};\n for (const [propertyName, value] of Object.entries(shaderInputValues)) {\n if (value === undefined) {\n continue;\n }\n\n const moduleName = propertyToModuleNameMap.get(propertyName);\n if (!moduleName || material.ownsModule(moduleName)) {\n continue;\n }\n\n sceneShaderInputProps[moduleName] ||= {};\n sceneShaderInputProps[moduleName][propertyName] = value;\n }\n\n return sceneShaderInputProps;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {log} from '@luma.gl/core';\nimport {GroupNode} from '@luma.gl/engine';\nimport {GLTFAnimation} from './animations/animations';\nimport {interpolate} from './animations/interpolate';\n\n/** Construction props for a single glTF animation controller. */\ntype GLTFSingleAnimatorProps = {\n /** Animation data to evaluate. */\n animation: GLTFAnimation;\n /** Mapping from glTF node ids to scenegraph nodes. */\n gltfNodeIdToNodeMap: Map<string, GroupNode>;\n /** Start time in seconds. */\n startTime?: number;\n /** Whether playback is active. */\n playing?: boolean;\n /** Playback speed multiplier. */\n speed?: number;\n};\n\n/** Evaluates one glTF animation against the generated scenegraph. */\nclass GLTFSingleAnimator {\n /** Animation definition being played. */\n animation: GLTFAnimation;\n /** Target scenegraph lookup table. */\n gltfNodeIdToNodeMap: Map<string, GroupNode>;\n /** Playback start time in seconds. */\n startTime: number = 0;\n /** Whether playback is currently enabled. */\n playing: boolean = true;\n /** Playback speed multiplier. */\n speed: number = 1;\n\n /** Creates a single-animation controller. */\n constructor(props: GLTFSingleAnimatorProps) {\n this.animation = props.animation;\n this.gltfNodeIdToNodeMap = props.gltfNodeIdToNodeMap;\n this.animation.name ||= 'unnamed';\n Object.assign(this, props);\n }\n\n /** Advances the animation to the supplied wall-clock time in milliseconds. */\n setTime(timeMs: number) {\n if (!this.playing) {\n return;\n }\n\n const absTime = timeMs / 1000;\n const time = (absTime - this.startTime) * this.speed;\n\n this.animation.channels.forEach(({sampler, targetNodeId, path}) => {\n const targetNode = this.gltfNodeIdToNodeMap.get(targetNodeId);\n if (!targetNode) {\n throw new Error(`Cannot find animation target node ${targetNodeId}`);\n }\n\n interpolate(time, sampler, targetNode, path);\n });\n }\n}\n\n/** Construction props for {@link GLTFAnimator}. */\nexport type GLTFAnimatorProps = {\n /** Parsed animations from the source glTF. */\n animations: GLTFAnimation[];\n /** Mapping from glTF node ids to scenegraph nodes. */\n gltfNodeIdToNodeMap: Map<string, GroupNode>;\n};\n\n/** Coordinates playback of every animation found in a glTF scene. */\nexport class GLTFAnimator {\n /** Individual animation controllers. */\n animations: GLTFSingleAnimator[];\n\n /** Creates an animator for the supplied glTF scenegraph. */\n constructor(props: GLTFAnimatorProps) {\n this.animations = props.animations.map((animation, index) => {\n const name = animation.name || `Animation-${index}`;\n return new GLTFSingleAnimator({\n gltfNodeIdToNodeMap: props.gltfNodeIdToNodeMap,\n animation: {name, channels: animation.channels}\n });\n });\n }\n\n /** @deprecated Use .setTime(). Will be removed (deck.gl is using this) */\n animate(time: number): void {\n log.warn('GLTFAnimator#animate is deprecated. Use GLTFAnimator#setTime instead')();\n this.setTime(time);\n }\n\n /** Advances every animation to the supplied wall-clock time in milliseconds. */\n setTime(time: number): void {\n this.animations.forEach(animation => animation.setTime(time));\n }\n\n /** Returns the per-animation controllers managed by this animator. */\n getAnimations() {\n return this.animations;\n }\n}\n", "import {log} from '@luma.gl/core';\nimport {Quaternion} from '@math.gl/core';\nimport {GLTFAnimationPath, GLTFAnimationSampler} from './animations';\nimport {GroupNode} from '@luma.gl/engine';\n\n/** Applies an evaluated animation value to a scenegraph node. */\nfunction updateTargetPath(\n target: GroupNode,\n path: GLTFAnimationPath,\n newValue: number[]\n): GroupNode | null {\n switch (path) {\n case 'translation':\n return target.setPosition(newValue).updateMatrix();\n\n case 'rotation':\n return target.setRotation(newValue).updateMatrix();\n\n case 'scale':\n return target.setScale(newValue).updateMatrix();\n\n default:\n log.warn(`Bad animation path ${path}`)();\n return null;\n }\n}\n\n/** Evaluates a glTF animation sampler at the supplied time and applies the result to a node. */\nexport function interpolate(\n time: number,\n {input, interpolation, output}: GLTFAnimationSampler,\n target: GroupNode,\n path: GLTFAnimationPath\n) {\n const maxTime = input[input.length - 1];\n const animationTime = time % maxTime;\n\n const nextIndex = input.findIndex(t => t >= animationTime);\n const previousIndex = Math.max(0, nextIndex - 1);\n\n const previousTime = input[previousIndex];\n const nextTime = input[nextIndex];\n\n switch (interpolation) {\n case 'STEP':\n stepInterpolate(target, path, output[previousIndex]);\n break;\n\n case 'LINEAR':\n if (nextTime > previousTime) {\n const ratio = (animationTime - previousTime) / (nextTime - previousTime);\n linearInterpolate(target, path, output[previousIndex], output[nextIndex], ratio);\n }\n break;\n\n case 'CUBICSPLINE':\n if (nextTime > previousTime) {\n const ratio = (animationTime - previousTime) / (nextTime - previousTime);\n const tDiff = nextTime - previousTime;\n\n const p0 = output[3 * previousIndex + 1];\n const outTangent0 = output[3 * previousIndex + 2];\n const inTangent1 = output[3 * nextIndex + 0];\n const p1 = output[3 * nextIndex + 1];\n\n cubicsplineInterpolate(target, path, {p0, outTangent0, inTangent1, p1, tDiff, ratio});\n }\n break;\n\n default:\n log.warn(`Interpolation ${interpolation} not supported`)();\n break;\n }\n}\n\n/** Applies linear interpolation between two keyframes. */\nfunction linearInterpolate(\n target: GroupNode,\n path: GLTFAnimationPath,\n start: number[],\n stop: number[],\n ratio: number\n) {\n if (path === 'rotation') {\n // SLERP when path is rotation\n updateTargetPath(target, path, new Quaternion().slerp({start, target: stop, ratio}));\n } else {\n // regular interpolation\n const newVal = [];\n for (let i = 0; i < start.length; i++) {\n newVal[i] = ratio * stop[i] + (1 - ratio) * start[i];\n }\n updateTargetPath(target, path, newVal);\n }\n}\n\n/** Applies glTF cubic spline interpolation between two keyframes. */\nfunction cubicsplineInterpolate(\n target: GroupNode,\n path: GLTFAnimationPath,\n {\n p0,\n outTangent0,\n inTangent1,\n p1,\n tDiff,\n ratio: t\n }: {\n p0: number[];\n outTangent0: number[];\n inTangent1: number[];\n p1: number[];\n tDiff: number;\n ratio: number;\n }\n) {\n // TODO: Quaternion might need normalization\n const newVal = [];\n for (let i = 0; i < p0.length; i++) {\n const m0 = outTangent0[i] * tDiff;\n const m1 = inTangent1[i] * tDiff;\n newVal[i] =\n (2 * Math.pow(t, 3) - 3 * Math.pow(t, 2) + 1) * p0[i] +\n (Math.pow(t, 3) - 2 * Math.pow(t, 2) + t) * m0 +\n (-2 * Math.pow(t, 3) + 3 * Math.pow(t, 2)) * p1[i] +\n (Math.pow(t, 3) - Math.pow(t, 2)) * m1;\n }\n updateTargetPath(target, path, newVal);\n}\n\n/** Applies step interpolation by copying the current keyframe value. */\nfunction stepInterpolate(target: GroupNode, path: GLTFAnimationPath, value: number[]) {\n updateTargetPath(target, path, value);\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {log} from '@luma.gl/core';\nimport {type GLTFAccessorPostprocessed, type GLTFPostprocessed} from '@loaders.gl/gltf';\nimport {\n GLTFAnimationPath,\n type GLTFAnimation,\n type GLTFAnimationChannel,\n type GLTFAnimationSampler\n} from '../gltf/animations/animations';\n\nimport {accessorToTypedArray} from '..//webgl-to-webgpu/convert-webgl-attribute';\n\n/** Parses glTF animation records into the runtime animation model used by `GLTFAnimator`. */\nexport function parseGLTFAnimations(gltf: GLTFPostprocessed): GLTFAnimation[] {\n const gltfAnimations = gltf.animations || [];\n const accessorCache1D = new Map<GLTFAccessorPostprocessed, number[]>();\n const accessorCache2D = new Map<GLTFAccessorPostprocessed, number[][]>();\n\n return gltfAnimations.flatMap((animation, index) => {\n const name = animation.name || `Animation-${index}`;\n const samplerCache = new Map<number, GLTFAnimationSampler>();\n const channels: GLTFAnimationChannel[] = animation.channels.flatMap(({sampler, target}) => {\n const path = getSupportedAnimationPath(target.path);\n if (!path) {\n return [];\n }\n\n const targetNode = gltf.nodes[target.node ?? 0];\n if (!targetNode) {\n throw new Error(`Cannot find animation target ${target.node}`);\n }\n\n let parsedSampler = samplerCache.get(sampler);\n if (!parsedSampler) {\n const gltfSampler = animation.samplers[sampler];\n if (!gltfSampler) {\n throw new Error(`Cannot find animation sampler ${sampler}`);\n }\n const {input, interpolation = 'LINEAR', output} = gltfSampler;\n parsedSampler = {\n input: accessorToJsArray1D(gltf.accessors[input], accessorCache1D),\n interpolation,\n output: accessorToJsArray2D(gltf.accessors[output], accessorCache2D)\n };\n samplerCache.set(sampler, parsedSampler);\n }\n\n return {\n sampler: parsedSampler,\n targetNodeId: targetNode.id,\n path\n };\n });\n\n return channels.length ? [{name, channels}] : [];\n });\n}\n\nfunction getSupportedAnimationPath(path: string): GLTFAnimationPath | null {\n if (path === 'pointer') {\n log.warn('KHR_animation_pointer channels are not supported and will be skipped')();\n return null;\n }\n\n return path as GLTFAnimationPath;\n}\n\n/** Converts a scalar accessor into a cached JavaScript number array. */\nfunction accessorToJsArray1D(\n accessor: GLTFAccessorPostprocessed,\n accessorCache: Map<GLTFAccessorPostprocessed, number[]>\n): number[] {\n if (accessorCache.has(accessor)) {\n return accessorCache.get(accessor)!;\n }\n\n const {typedArray: array, components} = accessorToTypedArray(accessor);\n assert(components === 1, 'accessorToJsArray1D must have exactly 1 component');\n const result = Array.from(array);\n\n accessorCache.set(accessor, result);\n return result;\n}\n\n/** Converts a scalar, vector, or matrix accessor into a cached JavaScript array-of-arrays. */\nfunction accessorToJsArray2D(\n accessor: GLTFAccessorPostprocessed,\n accessorCache: Map<GLTFAccessorPostprocessed, number[][]>\n): number[][] {\n if (accessorCache.has(accessor)) {\n return accessorCache.get(accessor)!;\n }\n\n const {typedArray: array, components} = accessorToTypedArray(accessor);\n assert(components >= 1, 'accessorToJsArray2D must have at least 1 component');\n\n const result = [];\n\n // Slice array\n for (let i = 0; i < array.length; i += components) {\n result.push(Array.from(array.slice(i, i + components)));\n }\n\n accessorCache.set(accessor, result);\n return result;\n}\n\n/** Throws when the supplied condition is false. */\nfunction assert(condition: boolean, message?: string): asserts condition {\n if (!condition) {\n throw new Error(message);\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// TODO: convert in loaders.gl?\nimport type {TypedArray} from '@math.gl/types';\n\n/** Maps glTF accessor type strings to their component counts. */\nexport const ATTRIBUTE_TYPE_TO_COMPONENTS: Record<string, number> = {\n SCALAR: 1,\n VEC2: 2,\n VEC3: 3,\n VEC4: 4,\n MAT2: 4,\n MAT3: 9,\n MAT4: 16\n};\n\n/** Maps glTF accessor component-type enums to typed-array constructors. */\nexport const ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY: Record<number, any> = {\n 5120: Int8Array,\n 5121: Uint8Array,\n 5122: Int16Array,\n 5123: Uint16Array,\n 5125: Uint32Array,\n 5126: Float32Array\n};\n\n/** Minimal accessor shape required to materialize a typed array. */\ntype GLTFAccessor = {\n /** Numeric component type enum. */\n componentType: number;\n /** Accessor type string such as `VEC3` or `SCALAR`. */\n type: string;\n /** Number of logical elements in the accessor. */\n count: number;\n /** Buffer view carrying the raw bytes. */\n bufferView?: {data: {buffer: ArrayBufferLike; byteOffset?: number}};\n /** Byte offset into the buffer view. */\n byteOffset?: number;\n};\n\n/** Converts a glTF accessor into a typed array plus its component count. */\nexport function accessorToTypedArray(accessor: GLTFAccessor): {\n /** Typed array view over the accessor data. */\n typedArray: TypedArray;\n /** Number of scalar components per element. */\n components: number;\n} {\n const ArrayType = ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY[accessor.componentType];\n const components = ATTRIBUTE_TYPE_TO_COMPONENTS[accessor.type];\n const length = components * accessor.count;\n const {buffer, byteOffset = 0} = accessor.bufferView?.data ?? {};\n\n const typedArray = new ArrayType(buffer, byteOffset + (accessor.byteOffset || 0), length);\n\n return {typedArray, components};\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {GLTFPostprocessed} from '@loaders.gl/gltf';\n\nexport type GLTFExtensionSupportLevel = 'built-in' | 'parsed-and-wired' | 'loader-only' | 'none';\n\nexport type GLTFExtensionSupport = {\n extensionName: string;\n supported: boolean;\n supportLevel: GLTFExtensionSupportLevel;\n comment: string;\n};\n\ntype GLTFExtensionSupportDefinition = Omit<GLTFExtensionSupport, 'extensionName' | 'supported'>;\n\ntype GLTFPostprocessedWithRemovedExtensions = GLTFPostprocessed & {\n extensionsRemoved?: string[];\n lights?: unknown[];\n};\n\nconst UNKNOWN_EXTENSION_SUPPORT: GLTFExtensionSupportDefinition = {\n supportLevel: 'none',\n comment: 'Not currently listed in the luma.gl glTF extension support registry.'\n};\n\nconst GLTF_EXTENSION_SUPPORT_REGISTRY: Record<string, GLTFExtensionSupportDefinition> = {\n KHR_draco_mesh_compression: {\n supportLevel: 'built-in',\n comment: 'Decoded by loaders.gl before luma.gl builds the scenegraph.'\n },\n EXT_meshopt_compression: {\n supportLevel: 'built-in',\n comment: 'Meshopt-compressed primitives are decoded during load.'\n },\n KHR_mesh_quantization: {\n supportLevel: 'built-in',\n comment: 'Quantized accessors are unpacked before geometry creation.'\n },\n KHR_lights_punctual: {\n supportLevel: 'built-in',\n comment: 'Parsed into luma.gl Light objects.'\n },\n KHR_materials_unlit: {\n supportLevel: 'built-in',\n comment: 'Unlit materials bypass the default lighting path.'\n },\n KHR_materials_emissive_strength: {\n supportLevel: 'built-in',\n comment: 'Applied by the stock PBR shader.'\n },\n KHR_texture_basisu: {\n supportLevel: 'built-in',\n comment: 'BasisU / KTX2 textures pass through when the device supports them.'\n },\n KHR_texture_transform: {\n supportLevel: 'built-in',\n comment: 'UV transforms are applied during load.'\n },\n EXT_texture_webp: {\n supportLevel: 'loader-only',\n comment:\n 'Texture source is resolved during load; final support depends on browser and device decode support.'\n },\n EXT_texture_avif: {\n supportLevel: 'loader-only',\n comment:\n 'Texture source is resolved during load; final support depends on browser and device decode support.'\n },\n KHR_materials_specular: {\n supportLevel: 'built-in',\n comment: 'The stock shader now applies specular factors and textures to the dielectric F0 term.'\n },\n KHR_materials_ior: {\n supportLevel: 'built-in',\n comment: 'The stock shader now drives dielectric reflectance from the glTF IOR value.'\n },\n KHR_materials_transmission: {\n supportLevel: 'built-in',\n comment:\n 'The stock shader now applies transmission to the base layer and exposes transparency through alpha, without a scene-color refraction buffer.'\n },\n KHR_materials_volume: {\n supportLevel: 'built-in',\n comment: 'Thickness and attenuation now tint transmitted light in the stock shader.'\n },\n KHR_materials_clearcoat: {\n supportLevel: 'built-in',\n comment: 'The stock shader now adds a secondary clearcoat specular lobe.'\n },\n KHR_materials_sheen: {\n supportLevel: 'built-in',\n comment: 'The stock shader now adds a sheen lobe for cloth-like materials.'\n },\n KHR_materials_iridescence: {\n supportLevel: 'built-in',\n comment:\n 'The stock shader now tints specular response with a view-dependent thin-film iridescence approximation.'\n },\n KHR_materials_anisotropy: {\n supportLevel: 'built-in',\n comment:\n 'The stock shader now shapes highlights and IBL response with an anisotropy-direction approximation.'\n },\n KHR_materials_pbrSpecularGlossiness: {\n supportLevel: 'loader-only',\n comment:\n 'Extension data can be loaded, but it is not translated into the default metallic-roughness material path.'\n },\n KHR_materials_variants: {\n supportLevel: 'loader-only',\n comment: 'Variant metadata can be loaded, but applications must choose and apply variants.'\n },\n EXT_mesh_gpu_instancing: {\n supportLevel: 'none',\n comment: 'GPU instancing data is not yet converted into luma.gl instanced draw setup.'\n },\n KHR_node_visibility: {\n supportLevel: 'none',\n comment: 'Node-visibility animations and toggles are not mapped onto runtime scenegraph state.'\n },\n KHR_animation_pointer: {\n supportLevel: 'none',\n comment: 'Animation pointers are not mapped onto runtime scenegraph updates.'\n },\n KHR_materials_diffuse_transmission: {\n supportLevel: 'none',\n comment: 'Diffuse-transmission shading is not implemented in the stock PBR shader.'\n },\n KHR_materials_dispersion: {\n supportLevel: 'none',\n comment: 'Chromatic dispersion is not implemented in the stock PBR shader.'\n },\n KHR_materials_volume_scatter: {\n supportLevel: 'none',\n comment: 'Volume scattering is not implemented in the stock PBR shader.'\n },\n KHR_xmp: {\n supportLevel: 'none',\n comment: 'Metadata payloads remain in the loaded glTF, but luma.gl does not interpret them.'\n },\n KHR_xmp_json_ld: {\n supportLevel: 'none',\n comment: 'Metadata is preserved in the glTF, but luma.gl does not interpret it.'\n },\n EXT_lights_image_based: {\n supportLevel: 'none',\n comment: 'Use loadPBREnvironment() or custom environment setup instead.'\n },\n EXT_texture_video: {\n supportLevel: 'none',\n comment: 'Video textures are not created automatically by the stock pipeline.'\n },\n MSFT_lod: {\n supportLevel: 'none',\n comment: 'Level-of-detail switching is not implemented in the stock scenegraph loader.'\n }\n};\n\nexport function getGLTFExtensionSupport(\n gltf: GLTFPostprocessed\n): Map<string, GLTFExtensionSupport> {\n const extensionNames = Array.from(collectGLTFExtensionNames(gltf)).sort();\n const extensionSupportEntries: [string, GLTFExtensionSupport][] = extensionNames.map(\n extensionName => {\n const extensionSupportDefinition =\n GLTF_EXTENSION_SUPPORT_REGISTRY[extensionName] || UNKNOWN_EXTENSION_SUPPORT;\n\n return [\n extensionName,\n {\n extensionName,\n supported: extensionSupportDefinition.supportLevel === 'built-in',\n supportLevel: extensionSupportDefinition.supportLevel,\n comment: extensionSupportDefinition.comment\n }\n ];\n }\n );\n\n return new Map(extensionSupportEntries);\n}\n\nfunction collectGLTFExtensionNames(gltf: GLTFPostprocessed): Set<string> {\n const gltfWithRemovedExtensions = gltf as GLTFPostprocessedWithRemovedExtensions;\n const extensionNames = new Set<string>();\n\n addExtensionNames(extensionNames, gltf.extensionsUsed);\n addExtensionNames(extensionNames, gltf.extensionsRequired);\n addExtensionNames(extensionNames, gltfWithRemovedExtensions.extensionsRemoved);\n addExtensionNames(extensionNames, Object.keys(gltf.extensions || {}));\n\n if (gltfWithRemovedExtensions.lights?.length || gltf.nodes.some(node => 'light' in node)) {\n extensionNames.add('KHR_lights_punctual');\n }\n\n if (\n gltf.materials.some(material => {\n const gltfMaterial = material as typeof material & {unlit?: boolean};\n return gltfMaterial.unlit || gltfMaterial.extensions?.KHR_materials_unlit;\n })\n ) {\n extensionNames.add('KHR_materials_unlit');\n }\n\n return extensionNames;\n}\n\nfunction addExtensionNames(extensionNames: Set<string>, newExtensionNames: string[] = []): void {\n for (const extensionName of newExtensionNames) {\n extensionNames.add(extensionName);\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Device} from '@luma.gl/core';\nimport {GroupNode, Material} from '@luma.gl/engine';\nimport {GLTFPostprocessed} from '@loaders.gl/gltf';\nimport {Light} from '@luma.gl/shadertools';\nimport {parseGLTF, type ParseGLTFOptions} from '../parsers/parse-gltf';\nimport {parseGLTFLights} from '../parsers/parse-gltf-lights';\nimport {GLTFAnimator} from './gltf-animator';\nimport {parseGLTFAnimations} from '../parsers/parse-gltf-animations';\nimport {getGLTFExtensionSupport, type GLTFExtensionSupport} from './gltf-extension-support';\n\nexport type GLTFScenegraphBounds = {\n /** World-space axis-aligned bounds for the scene or model. */\n bounds: [[number, number, number], [number, number, number]] | null;\n /** World-space center of the bounds. */\n center: [number, number, number];\n /** World-space bounds size on each axis. */\n size: [number, number, number];\n /** Half of the world-space bounds diagonal, clamped to a small practical minimum. */\n radius: number;\n /** Suggested orbit distance for a 60-degree field of view camera. */\n recommendedOrbitDistance: number;\n};\n\n/** Scenegraph bundle returned from a parsed glTF asset. */\nexport type GLTFScenegraphs = {\n /** Scene roots produced from the glTF scenes array. */\n scenes: GroupNode[];\n /** Materials aligned with the source glTF `materials` array. */\n materials: Material[];\n /** Animation controller for glTF animations. */\n animator: GLTFAnimator;\n /** Parsed punctual lights from the asset. */\n lights: Light[];\n /** Extensions reported by the asset and whether luma.gl supports them. */\n extensionSupport: Map<string, GLTFExtensionSupport>;\n /** Camera-friendly bounds for each scene in `scenes`, in matching order. */\n sceneBounds: GLTFScenegraphBounds[];\n /** Combined camera-friendly bounds for the entire loaded asset. */\n modelBounds: GLTFScenegraphBounds;\n\n /** Map from glTF mesh ids to generated mesh group nodes. */\n gltfMeshIdToNodeMap: Map<string, GroupNode>;\n /** Map from glTF node indices to generated scenegraph nodes. */\n gltfNodeIndexToNodeMap: Map<number, GroupNode>;\n /** Map from glTF node ids to generated scenegraph nodes. */\n gltfNodeIdToNodeMap: Map<string, GroupNode>;\n\n /** Original post-processed glTF document. */\n gltf: GLTFPostprocessed;\n};\n\n/** Converts a post-processed glTF asset into luma.gl scenegraph nodes and animation helpers. */\nexport function createScenegraphsFromGLTF(\n device: Device,\n gltf: GLTFPostprocessed,\n options?: ParseGLTFOptions\n): GLTFScenegraphs {\n const {scenes, materials, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap} =\n parseGLTF(device, gltf, options);\n\n const animations = parseGLTFAnimations(gltf);\n const animator = new GLTFAnimator({animations, gltfNodeIdToNodeMap});\n const lights = parseGLTFLights(gltf);\n const extensionSupport = getGLTFExtensionSupport(gltf);\n const sceneBounds = scenes.map(scene => getScenegraphBounds(scene.getBounds()));\n const modelBounds = getCombinedScenegraphBounds(sceneBounds);\n\n return {\n scenes,\n materials,\n animator,\n lights,\n extensionSupport,\n sceneBounds,\n modelBounds,\n gltfMeshIdToNodeMap,\n gltfNodeIdToNodeMap,\n gltfNodeIndexToNodeMap,\n gltf\n };\n}\n\nfunction getScenegraphBounds(bounds: [number[], number[]] | null): GLTFScenegraphBounds {\n if (!bounds) {\n return {\n bounds: null,\n center: [0, 0, 0],\n size: [0, 0, 0],\n radius: 0.5,\n recommendedOrbitDistance: 1\n };\n }\n\n const normalizedBounds: [[number, number, number], [number, number, number]] = [\n [bounds[0][0], bounds[0][1], bounds[0][2]],\n [bounds[1][0], bounds[1][1], bounds[1][2]]\n ];\n const size: [number, number, number] = [\n normalizedBounds[1][0] - normalizedBounds[0][0],\n normalizedBounds[1][1] - normalizedBounds[0][1],\n normalizedBounds[1][2] - normalizedBounds[0][2]\n ];\n const center: [number, number, number] = [\n normalizedBounds[0][0] + size[0] * 0.5,\n normalizedBounds[0][1] + size[1] * 0.5,\n normalizedBounds[0][2] + size[2] * 0.5\n ];\n const maxHalfExtent = Math.max(size[0], size[1], size[2]) * 0.5;\n const radius = Math.max(0.5 * Math.hypot(size[0], size[1], size[2]), 0.001);\n\n return {\n bounds: normalizedBounds,\n center,\n size,\n radius,\n recommendedOrbitDistance: Math.max(\n (Math.max(maxHalfExtent, 0.001) / Math.tan(Math.PI / 6)) * 1.15,\n radius * 1.1\n )\n };\n}\n\nfunction getCombinedScenegraphBounds(sceneBounds: GLTFScenegraphBounds[]): GLTFScenegraphBounds {\n let combinedBounds: [[number, number, number], [number, number, number]] | null = null;\n\n for (const sceneBoundInfo of sceneBounds) {\n if (!sceneBoundInfo.bounds) {\n continue;\n }\n\n if (!combinedBounds) {\n combinedBounds = [\n [...sceneBoundInfo.bounds[0]] as [number, number, number],\n [...sceneBoundInfo.bounds[1]] as [number, number, number]\n ];\n continue;\n }\n\n for (let axis = 0; axis < 3; axis++) {\n combinedBounds[0][axis] = Math.min(combinedBounds[0][axis], sceneBoundInfo.bounds[0][axis]);\n combinedBounds[1][axis] = Math.max(combinedBounds[1][axis], sceneBoundInfo.bounds[1][axis]);\n }\n }\n\n return getScenegraphBounds(combinedBounds);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["GLEnum", "import_core", "import_engine", "import_shadertools", "import_core", "import_engine", "module", "import_core", "import_core", "import_core", "_a"]
|
|
7
7
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export { loadPBREnvironment, type PBREnvironment } from "./pbr/pbr-environment.js";
|
|
2
2
|
export { type ParsedPBRMaterial } from "./pbr/pbr-material.js";
|
|
3
3
|
export { parsePBRMaterial, type ParsePBRMaterialOptions } from "./parsers/parse-pbr-material.js";
|
|
4
|
-
export {} from "./
|
|
5
|
-
export { createScenegraphsFromGLTF } from "./gltf/create-scenegraph-from-gltf.js";
|
|
4
|
+
export { parseGLTFLights } from "./parsers/parse-gltf-lights.js";
|
|
5
|
+
export { createScenegraphsFromGLTF, type GLTFScenegraphBounds, type GLTFScenegraphs } from "./gltf/create-scenegraph-from-gltf.js";
|
|
6
|
+
export { getGLTFExtensionSupport, type GLTFExtensionSupport, type GLTFExtensionSupportLevel } from "./gltf/gltf-extension-support.js";
|
|
6
7
|
export { GLTFAnimator } from "./gltf/gltf-animator.js";
|
|
7
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,kBAAkB,EAAE,KAAK,cAAc,EAAC,iCAA8B;AAC9E,OAAO,EAAC,KAAK,iBAAiB,EAAC,8BAA2B;AAC1D,OAAO,EAAC,gBAAgB,EAAE,KAAK,uBAAuB,EAAC,wCAAqC;AAC5F,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,kBAAkB,EAAE,KAAK,cAAc,EAAC,iCAA8B;AAC9E,OAAO,EAAC,KAAK,iBAAiB,EAAC,8BAA2B;AAC1D,OAAO,EAAC,gBAAgB,EAAE,KAAK,uBAAuB,EAAC,wCAAqC;AAC5F,OAAO,EAAC,eAAe,EAAC,uCAAoC;AAG5D,OAAO,EACL,yBAAyB,EACzB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACrB,8CAA2C;AAC5C,OAAO,EACL,uBAAuB,EACvB,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC/B,yCAAsC;AACvC,OAAO,EAAC,YAAY,EAAC,gCAA6B"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
// luma.gl, MIT license
|
|
2
2
|
export { loadPBREnvironment } from "./pbr/pbr-environment.js";
|
|
3
3
|
export { parsePBRMaterial } from "./parsers/parse-pbr-material.js";
|
|
4
|
+
export { parseGLTFLights } from "./parsers/parse-gltf-lights.js";
|
|
4
5
|
// glTF Scenegraph Instantiator
|
|
5
6
|
export { createScenegraphsFromGLTF } from "./gltf/create-scenegraph-from-gltf.js";
|
|
7
|
+
export { getGLTFExtensionSupport } from "./gltf/gltf-extension-support.js";
|
|
6
8
|
export { GLTFAnimator } from "./gltf/gltf-animator.js";
|
|
7
9
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uBAAuB;AAEvB,OAAO,EAAC,kBAAkB,EAAsB,iCAA8B;AAE9E,OAAO,EAAC,gBAAgB,EAA+B,wCAAqC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uBAAuB;AAEvB,OAAO,EAAC,kBAAkB,EAAsB,iCAA8B;AAE9E,OAAO,EAAC,gBAAgB,EAA+B,wCAAqC;AAC5F,OAAO,EAAC,eAAe,EAAC,uCAAoC;AAE5D,+BAA+B;AAC/B,OAAO,EACL,yBAAyB,EAG1B,8CAA2C;AAC5C,OAAO,EACL,uBAAuB,EAGxB,yCAAsC;AACvC,OAAO,EAAC,YAAY,EAAC,gCAA6B"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type GLTFPostprocessed } from '@loaders.gl/gltf';
|
|
2
2
|
import { type GLTFAnimation } from "../gltf/animations/animations.js";
|
|
3
|
+
/** Parses glTF animation records into the runtime animation model used by `GLTFAnimator`. */
|
|
3
4
|
export declare function parseGLTFAnimations(gltf: GLTFPostprocessed): GLTFAnimation[];
|
|
4
5
|
//# sourceMappingURL=parse-gltf-animations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-gltf-animations.d.ts","sourceRoot":"","sources":["../../src/parsers/parse-gltf-animations.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"parse-gltf-animations.d.ts","sourceRoot":"","sources":["../../src/parsers/parse-gltf-animations.ts"],"names":[],"mappings":"AAKA,OAAO,EAAiC,KAAK,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AACxF,OAAO,EAEL,KAAK,aAAa,EAGnB,yCAAsC;AAIvC,6FAA6F;AAC7F,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,GAAG,aAAa,EAAE,CA2C5E"}
|