@luma.gl/gltf 9.2.6 → 9.3.0-alpha.2

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/index.cjs CHANGED
@@ -23,6 +23,7 @@ __export(dist_exports, {
23
23
  GLTFAnimator: () => GLTFAnimator,
24
24
  createScenegraphsFromGLTF: () => createScenegraphsFromGLTF,
25
25
  loadPBREnvironment: () => loadPBREnvironment,
26
+ parseGLTFLights: () => parseGLTFLights,
26
27
  parsePBRMaterial: () => parsePBRMaterial
27
28
  });
28
29
  module.exports = __toCommonJS(dist_exports);
@@ -31,7 +32,7 @@ module.exports = __toCommonJS(dist_exports);
31
32
  var import_engine = require("@luma.gl/engine");
32
33
  var import_textures = require("@loaders.gl/textures");
33
34
  function loadPBREnvironment(device, props) {
34
- const brdfLutTexture = new import_engine.AsyncTexture(device, {
35
+ const brdfLutTexture = new import_engine.DynamicTexture(device, {
35
36
  id: "brdfLUT",
36
37
  sampler: {
37
38
  addressModeU: "clamp-to-edge",
@@ -81,7 +82,7 @@ function makeCube(device, { id, getTextureForFace, sampler }) {
81
82
  FACES.forEach((face) => {
82
83
  data[String(face)] = getTextureForFace(face);
83
84
  });
84
- return new import_engine.AsyncTexture(device, {
85
+ return new import_engine.DynamicTexture(device, {
85
86
  id,
86
87
  dimension: "cube",
87
88
  mipmaps: false,
@@ -277,9 +278,74 @@ function addTexture(device, gltfTexture, uniformName, define, parsedMaterial) {
277
278
  parsedMaterial.generatedTextures.push(texture);
278
279
  }
279
280
 
281
+ // dist/parsers/parse-gltf-lights.js
282
+ var import_core2 = require("@math.gl/core");
283
+ function parseGLTFLights(gltf) {
284
+ var _a, _b, _c;
285
+ const lightDefs = (_b = (_a = gltf.extensions) == null ? void 0 : _a["KHR_lights_punctual"]) == null ? void 0 : _b["lights"];
286
+ if (!lightDefs || !Array.isArray(lightDefs) || lightDefs.length === 0) {
287
+ return [];
288
+ }
289
+ const lights = [];
290
+ for (const node of gltf.nodes || []) {
291
+ const nodeLight = (_c = node.extensions) == null ? void 0 : _c.KHR_lights_punctual;
292
+ if (!nodeLight || typeof nodeLight.light !== "number") {
293
+ continue;
294
+ }
295
+ const gltfLight = lightDefs[nodeLight.light];
296
+ if (!gltfLight) {
297
+ continue;
298
+ }
299
+ const color = gltfLight.color || [1, 1, 1];
300
+ const intensity = gltfLight.intensity ?? 1;
301
+ const range = gltfLight.range;
302
+ switch (gltfLight.type) {
303
+ case "directional":
304
+ lights.push(parseDirectionalLight(node, color, intensity));
305
+ break;
306
+ case "point":
307
+ lights.push(parsePointLight(node, color, intensity, range));
308
+ break;
309
+ case "spot":
310
+ lights.push(parsePointLight(node, color, intensity, range));
311
+ break;
312
+ default:
313
+ break;
314
+ }
315
+ }
316
+ return lights;
317
+ }
318
+ function parsePointLight(node, color, intensity, range) {
319
+ const position = node.translation ? [...node.translation] : [0, 0, 0];
320
+ let attenuation = [1, 0, 0];
321
+ if (range !== void 0 && range > 0) {
322
+ attenuation = [1, 0, 1 / (range * range)];
323
+ }
324
+ return {
325
+ type: "point",
326
+ position,
327
+ color,
328
+ intensity,
329
+ attenuation
330
+ };
331
+ }
332
+ function parseDirectionalLight(node, color, intensity) {
333
+ let direction = [0, 0, -1];
334
+ if (node.rotation) {
335
+ const orientation = new import_core2.Matrix4().fromQuaternion(node.rotation);
336
+ direction = orientation.transformDirection([0, 0, -1]);
337
+ }
338
+ return {
339
+ type: "directional",
340
+ direction,
341
+ color,
342
+ intensity
343
+ };
344
+ }
345
+
280
346
  // dist/parsers/parse-gltf.js
281
347
  var import_engine3 = require("@luma.gl/engine");
282
- var import_core3 = require("@math.gl/core");
348
+ var import_core4 = require("@math.gl/core");
283
349
 
284
350
  // dist/webgl-to-webgpu/convert-webgl-topology.js
285
351
  var GLEnum;
@@ -310,7 +376,7 @@ function convertGLDrawModeToTopology(drawMode) {
310
376
  }
311
377
 
312
378
  // dist/gltf/create-gltf-model.js
313
- var import_core2 = require("@luma.gl/core");
379
+ var import_core3 = require("@luma.gl/core");
314
380
  var import_shadertools = require("@luma.gl/shadertools");
315
381
  var import_engine2 = require("@luma.gl/engine");
316
382
  var SHADER = (
@@ -418,7 +484,7 @@ var fs = (
418
484
  );
419
485
  function createGLTFModel(device, options) {
420
486
  const { id, geometry, parsedPPBRMaterial, vertexCount, modelOptions = {} } = options;
421
- import_core2.log.info(4, "createGLTFModel defines: ", parsedPPBRMaterial.defines)();
487
+ import_core3.log.info(4, "createGLTFModel defines: ", parsedPPBRMaterial.defines)();
422
488
  const managedResources = [];
423
489
  const parameters = {
424
490
  depthWriteEnabled: true,
@@ -491,7 +557,7 @@ function createNode(device, gltfNode, gltfNodes, options) {
491
557
  node.matrix.translate(gltfNode.translation);
492
558
  }
493
559
  if (gltfNode.rotation) {
494
- const rotationMatrix = new import_core3.Matrix4().fromQuaternion(gltfNode.rotation);
560
+ const rotationMatrix = new import_core4.Matrix4().fromQuaternion(gltfNode.rotation);
495
561
  node.matrix.multiplyRight(rotationMatrix);
496
562
  }
497
563
  if (gltfNode.scale) {
@@ -550,13 +616,13 @@ function createGeometry(id, gltfPrimitive, topology) {
550
616
  }
551
617
 
552
618
  // dist/gltf/gltf-animator.js
553
- var import_core6 = require("@luma.gl/core");
554
- var import_core7 = require("@math.gl/core");
619
+ var import_core7 = require("@luma.gl/core");
620
+ var import_core8 = require("@math.gl/core");
555
621
 
556
622
  // dist/gltf/animations/interpolate.js
557
- var import_core4 = require("@luma.gl/core");
558
- var import_core5 = require("@math.gl/core");
559
- var scratchQuaternion = new import_core5.Quaternion();
623
+ var import_core5 = require("@luma.gl/core");
624
+ var import_core6 = require("@math.gl/core");
625
+ var scratchQuaternion = new import_core6.Quaternion();
560
626
  function interpolate(time, { input, interpolation, output }, target, path) {
561
627
  const maxTime = input[input.length - 1];
562
628
  const animationTime = time % maxTime;
@@ -574,7 +640,7 @@ function interpolate(time, { input, interpolation, output }, target, path) {
574
640
  target[path] = [1, 1, 1];
575
641
  break;
576
642
  default:
577
- import_core4.log.warn(`Bad animation path ${path}`)();
643
+ import_core5.log.warn(`Bad animation path ${path}`)();
578
644
  }
579
645
  }
580
646
  const previousTime = input[previousIndex];
@@ -601,7 +667,7 @@ function interpolate(time, { input, interpolation, output }, target, path) {
601
667
  }
602
668
  break;
603
669
  default:
604
- import_core4.log.warn(`Interpolation ${interpolation} not supported`)();
670
+ import_core5.log.warn(`Interpolation ${interpolation} not supported`)();
605
671
  break;
606
672
  }
607
673
  }
@@ -674,7 +740,7 @@ var GLTFAnimator = class {
674
740
  }
675
741
  /** @deprecated Use .setTime(). Will be removed (deck.gl is using this) */
676
742
  animate(time) {
677
- import_core6.log.warn("GLTFAnimator#animate is deprecated. Use GLTFAnimator#setTime instead")();
743
+ import_core7.log.warn("GLTFAnimator#animate is deprecated. Use GLTFAnimator#setTime instead")();
678
744
  this.setTime(time);
679
745
  }
680
746
  setTime(time) {
@@ -684,7 +750,7 @@ var GLTFAnimator = class {
684
750
  return this.animations;
685
751
  }
686
752
  };
687
- var scratchMatrix = new import_core7.Matrix4();
753
+ var scratchMatrix = new import_core8.Matrix4();
688
754
  function applyTranslationRotationScale(gltfNode, node) {
689
755
  node.matrix.identity();
690
756
  if (gltfNode.translation) {
@@ -785,6 +851,7 @@ function createScenegraphsFromGLTF(device, gltf, options) {
785
851
  const scenes = parseGLTF(device, gltf, options);
786
852
  const animations = parseGLTFAnimations(gltf);
787
853
  const animator = new GLTFAnimator({ animations });
788
- return { scenes, animator };
854
+ const lights = parseGLTFLights(gltf);
855
+ return { scenes, animator, lights };
789
856
  }
790
857
  //# sourceMappingURL=index.cjs.map
@@ -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/webgl-to-webgpu/convert-webgl-attribute.ts", "../src/parsers/parse-gltf-animations.ts", "../src/utils/deep-copy.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 {} 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": ["import_constants", "import_engine", "import_core", "GLEnum", "import_core", "import_engine", "import_core", "import_core"]
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-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/webgl-to-webgpu/convert-webgl-attribute.ts", "../src/parsers/parse-gltf-animations.ts", "../src/utils/deep-copy.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 {} from './pbr/pbr-environment';\nexport {parseGLTFLights} from './parsers/parse-gltf-lights';\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 {DynamicTexture} 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 diffuseEnvSampler: DynamicTexture;\n specularEnvSampler: DynamicTexture;\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 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: 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): DynamicTexture {\n const data = {};\n FACES.forEach(face => {\n // @ts-ignore TODO\n data[String(face)] = getTextureForFace(face);\n });\n return new DynamicTexture(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", "import {Matrix4} from '@math.gl/core';\nimport type {GLTFNodePostprocessed, GLTFPostprocessed} from '@loaders.gl/gltf';\nimport type {DirectionalLight, Light, PointLight} from '@luma.gl/shadertools';\n\n/** Parse KHR_lights_punctual extension into luma.gl light definitions */\nexport function parseGLTFLights(gltf: GLTFPostprocessed): Light[] {\n const lightDefs = gltf.extensions?.['KHR_lights_punctual']?.['lights'];\n if (!lightDefs || !Array.isArray(lightDefs) || lightDefs.length === 0) {\n return [];\n }\n\n const lights: Light[] = [];\n\n for (const node of gltf.nodes || []) {\n const nodeLight = node.extensions?.KHR_lights_punctual;\n if (!nodeLight || typeof nodeLight.light !== 'number') {\n // eslint-disable-next-line no-continue\n continue;\n }\n const gltfLight = lightDefs[nodeLight.light];\n if (!gltfLight) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n const color = (gltfLight.color || [1, 1, 1]) as [number, number, number];\n const intensity = gltfLight.intensity ?? 1;\n const range = gltfLight.range;\n\n switch (gltfLight.type) {\n case 'directional':\n lights.push(parseDirectionalLight(node, color, intensity));\n break;\n case 'point':\n lights.push(parsePointLight(node, color, intensity, range));\n break;\n case 'spot':\n lights.push(parsePointLight(node, color, intensity, range));\n break;\n default:\n // Unsupported light type\n break;\n }\n }\n\n return lights;\n}\n\nfunction parsePointLight(\n node: GLTFNodePostprocessed,\n color: [number, number, number],\n intensity: number,\n range?: number\n): PointLight {\n const position: Readonly<[number, number, number]> = node.translation\n ? ([...node.translation] as [number, number, number])\n : ([0, 0, 0] as [number, number, number]);\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\nfunction parseDirectionalLight(\n node: GLTFNodePostprocessed,\n color: [number, number, number],\n intensity: number\n): DirectionalLight {\n let direction: [number, number, number] = [0, 0, -1];\n\n if (node.rotation) {\n const orientation = new Matrix4().fromQuaternion(node.rotation);\n direction = orientation.transformDirection([0, 0, -1]) as [number, number, number];\n }\n\n return {\n type: 'directional',\n direction,\n color,\n intensity\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 {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 {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 lights: Light[];\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 const lights = parseGLTFLights(gltf);\n return {scenes, animator, lights};\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["import_constants", "import_core", "import_engine", "import_core", "GLEnum", "import_core", "import_engine", "import_core", "import_core"]
7
7
  }
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export { loadPBREnvironment, type PBREnvironment } from "./pbr/pbr-environment.j
2
2
  export { type ParsedPBRMaterial } from "./pbr/pbr-material.js";
3
3
  export { parsePBRMaterial, type ParsePBRMaterialOptions } from "./parsers/parse-pbr-material.js";
4
4
  export {} from "./pbr/pbr-environment.js";
5
+ export { parseGLTFLights } from "./parsers/parse-gltf-lights.js";
5
6
  export { createScenegraphsFromGLTF } from "./gltf/create-scenegraph-from-gltf.js";
6
7
  export { GLTFAnimator } from "./gltf/gltf-animator.js";
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -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,EAAE,iCAA8B;AAGvC,OAAO,EAAC,yBAAyB,EAAC,8CAA2C;AAC7E,OAAO,EAAC,YAAY,EAAC,gCAA6B"}
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,EAAE,iCAA8B;AACvC,OAAO,EAAC,eAAe,EAAC,uCAAoC;AAG5D,OAAO,EAAC,yBAAyB,EAAC,8CAA2C;AAC7E,OAAO,EAAC,YAAY,EAAC,gCAA6B"}
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
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";
6
7
  export { GLTFAnimator } from "./gltf/gltf-animator.js";
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;AAG5F,+BAA+B;AAC/B,OAAO,EAAC,yBAAyB,EAAC,8CAA2C;AAC7E,OAAO,EAAC,YAAY,EAAC,gCAA6B"}
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;AAE5F,OAAO,EAAC,eAAe,EAAC,uCAAoC;AAE5D,+BAA+B;AAC/B,OAAO,EAAC,yBAAyB,EAAC,8CAA2C;AAC7E,OAAO,EAAC,YAAY,EAAC,gCAA6B"}
@@ -0,0 +1,5 @@
1
+ import type { GLTFPostprocessed } from '@loaders.gl/gltf';
2
+ import type { Light } from '@luma.gl/shadertools';
3
+ /** Parse KHR_lights_punctual extension into luma.gl light definitions */
4
+ export declare function parseGLTFLights(gltf: GLTFPostprocessed): Light[];
5
+ //# sourceMappingURL=parse-gltf-lights.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-gltf-lights.d.ts","sourceRoot":"","sources":["../../src/parsers/parse-gltf-lights.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAwB,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AAC/E,OAAO,KAAK,EAAmB,KAAK,EAAa,MAAM,sBAAsB,CAAC;AAE9E,yEAAyE;AACzE,wBAAgB,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,KAAK,EAAE,CAyChE"}
@@ -0,0 +1,69 @@
1
+ import { Matrix4 } from '@math.gl/core';
2
+ /** Parse KHR_lights_punctual extension into luma.gl light definitions */
3
+ export function parseGLTFLights(gltf) {
4
+ const lightDefs = gltf.extensions?.['KHR_lights_punctual']?.['lights'];
5
+ if (!lightDefs || !Array.isArray(lightDefs) || lightDefs.length === 0) {
6
+ return [];
7
+ }
8
+ const lights = [];
9
+ for (const node of gltf.nodes || []) {
10
+ const nodeLight = node.extensions?.KHR_lights_punctual;
11
+ if (!nodeLight || typeof nodeLight.light !== 'number') {
12
+ // eslint-disable-next-line no-continue
13
+ continue;
14
+ }
15
+ const gltfLight = lightDefs[nodeLight.light];
16
+ if (!gltfLight) {
17
+ // eslint-disable-next-line no-continue
18
+ continue;
19
+ }
20
+ const color = (gltfLight.color || [1, 1, 1]);
21
+ const intensity = gltfLight.intensity ?? 1;
22
+ const range = gltfLight.range;
23
+ switch (gltfLight.type) {
24
+ case 'directional':
25
+ lights.push(parseDirectionalLight(node, color, intensity));
26
+ break;
27
+ case 'point':
28
+ lights.push(parsePointLight(node, color, intensity, range));
29
+ break;
30
+ case 'spot':
31
+ lights.push(parsePointLight(node, color, intensity, range));
32
+ break;
33
+ default:
34
+ // Unsupported light type
35
+ break;
36
+ }
37
+ }
38
+ return lights;
39
+ }
40
+ function parsePointLight(node, color, intensity, range) {
41
+ const position = node.translation
42
+ ? [...node.translation]
43
+ : [0, 0, 0];
44
+ let attenuation = [1, 0, 0];
45
+ if (range !== undefined && range > 0) {
46
+ attenuation = [1, 0, 1 / (range * range)];
47
+ }
48
+ return {
49
+ type: 'point',
50
+ position,
51
+ color,
52
+ intensity,
53
+ attenuation
54
+ };
55
+ }
56
+ function parseDirectionalLight(node, color, intensity) {
57
+ let direction = [0, 0, -1];
58
+ if (node.rotation) {
59
+ const orientation = new Matrix4().fromQuaternion(node.rotation);
60
+ direction = orientation.transformDirection([0, 0, -1]);
61
+ }
62
+ return {
63
+ type: 'directional',
64
+ direction,
65
+ color,
66
+ intensity
67
+ };
68
+ }
69
+ //# sourceMappingURL=parse-gltf-lights.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-gltf-lights.js","sourceRoot":"","sources":["../../src/parsers/parse-gltf-lights.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,11 @@
1
1
  import { Device } from '@luma.gl/core';
2
- import { AsyncTexture } from '@luma.gl/engine';
2
+ import { DynamicTexture } from '@luma.gl/engine';
3
3
  /** Environment textures for PBR module */
4
4
  export type PBREnvironment = {
5
5
  /** Bi-directional Reflectance Distribution Function (BRDF) lookup table */
6
- brdfLutTexture: AsyncTexture;
7
- diffuseEnvSampler: AsyncTexture;
8
- specularEnvSampler: AsyncTexture;
6
+ brdfLutTexture: DynamicTexture;
7
+ diffuseEnvSampler: DynamicTexture;
8
+ specularEnvSampler: DynamicTexture;
9
9
  };
10
10
  export type PBREnvironmentProps = {
11
11
  brdfLutUrl: string;
@@ -1 +1 @@
1
- {"version":3,"file":"pbr-environment.d.ts","sourceRoot":"","sources":["../../src/pbr/pbr-environment.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,MAAM,EAAe,MAAM,eAAe,CAAC;AACnD,OAAO,EAAC,YAAY,EAAC,MAAM,iBAAiB,CAAC;AAG7C,0CAA0C;AAC1C,MAAM,MAAM,cAAc,GAAG;IAC3B,2EAA2E;IAC3E,cAAc,EAAE,YAAY,CAAC;IAC7B,iBAAiB,EAAE,YAAY,CAAC;IAChC,kBAAkB,EAAE,YAAY,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAChE,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,yCAAyC;AACzC,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,cAAc,CA+C7F"}
1
+ {"version":3,"file":"pbr-environment.d.ts","sourceRoot":"","sources":["../../src/pbr/pbr-environment.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,MAAM,EAAe,MAAM,eAAe,CAAC;AACnD,OAAO,EAAC,cAAc,EAAC,MAAM,iBAAiB,CAAC;AAG/C,0CAA0C;AAC1C,MAAM,MAAM,cAAc,GAAG;IAC3B,2EAA2E;IAC3E,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,EAAE,cAAc,CAAC;IAClC,kBAAkB,EAAE,cAAc,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAChE,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,yCAAyC;AACzC,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,cAAc,CA+C7F"}