@luma.gl/gltf 9.3.0-alpha.4 → 9.3.0-alpha.6

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.
Files changed (79) hide show
  1. package/dist/dist.dev.js +397 -220
  2. package/dist/dist.min.js +98 -46
  3. package/dist/gltf/animations/animations.d.ts +16 -4
  4. package/dist/gltf/animations/animations.d.ts.map +1 -1
  5. package/dist/gltf/animations/interpolate.d.ts +4 -3
  6. package/dist/gltf/animations/interpolate.d.ts.map +1 -1
  7. package/dist/gltf/animations/interpolate.js +27 -36
  8. package/dist/gltf/animations/interpolate.js.map +1 -1
  9. package/dist/gltf/create-gltf-model.d.ts +6 -0
  10. package/dist/gltf/create-gltf-model.d.ts.map +1 -1
  11. package/dist/gltf/create-gltf-model.js +96 -44
  12. package/dist/gltf/create-gltf-model.js.map +1 -1
  13. package/dist/gltf/create-scenegraph-from-gltf.d.ts +15 -1
  14. package/dist/gltf/create-scenegraph-from-gltf.d.ts.map +1 -1
  15. package/dist/gltf/create-scenegraph-from-gltf.js +12 -6
  16. package/dist/gltf/create-scenegraph-from-gltf.js.map +1 -1
  17. package/dist/gltf/gltf-animator.d.ts +26 -0
  18. package/dist/gltf/gltf-animator.d.ts.map +1 -1
  19. package/dist/gltf/gltf-animator.js +22 -19
  20. package/dist/gltf/gltf-animator.js.map +1 -1
  21. package/dist/index.cjs +378 -210
  22. package/dist/index.cjs.map +4 -4
  23. package/dist/index.d.ts +1 -2
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js.map +1 -1
  26. package/dist/parsers/parse-gltf-animations.d.ts +1 -0
  27. package/dist/parsers/parse-gltf-animations.d.ts.map +1 -1
  28. package/dist/parsers/parse-gltf-animations.js +46 -23
  29. package/dist/parsers/parse-gltf-animations.js.map +1 -1
  30. package/dist/parsers/parse-gltf-lights.d.ts.map +1 -1
  31. package/dist/parsers/parse-gltf-lights.js +40 -12
  32. package/dist/parsers/parse-gltf-lights.js.map +1 -1
  33. package/dist/parsers/parse-gltf.d.ts +16 -1
  34. package/dist/parsers/parse-gltf.d.ts.map +1 -1
  35. package/dist/parsers/parse-gltf.js +65 -57
  36. package/dist/parsers/parse-gltf.js.map +1 -1
  37. package/dist/parsers/parse-pbr-material.d.ts +46 -1
  38. package/dist/parsers/parse-pbr-material.d.ts.map +1 -1
  39. package/dist/parsers/parse-pbr-material.js +137 -13
  40. package/dist/parsers/parse-pbr-material.js.map +1 -1
  41. package/dist/pbr/pbr-environment.d.ts +6 -0
  42. package/dist/pbr/pbr-environment.d.ts.map +1 -1
  43. package/dist/pbr/pbr-environment.js +1 -0
  44. package/dist/pbr/pbr-environment.js.map +1 -1
  45. package/dist/pbr/pbr-material.d.ts +5 -0
  46. package/dist/pbr/pbr-material.d.ts.map +1 -1
  47. package/dist/webgl-to-webgpu/convert-webgl-attribute.d.ts +12 -1
  48. package/dist/webgl-to-webgpu/convert-webgl-attribute.d.ts.map +1 -1
  49. package/dist/webgl-to-webgpu/convert-webgl-attribute.js +3 -0
  50. package/dist/webgl-to-webgpu/convert-webgl-attribute.js.map +1 -1
  51. package/dist/webgl-to-webgpu/convert-webgl-sampler.d.ts +6 -0
  52. package/dist/webgl-to-webgpu/convert-webgl-sampler.d.ts.map +1 -1
  53. package/dist/webgl-to-webgpu/convert-webgl-sampler.js +4 -0
  54. package/dist/webgl-to-webgpu/convert-webgl-sampler.js.map +1 -1
  55. package/dist/webgl-to-webgpu/convert-webgl-topology.d.ts +2 -0
  56. package/dist/webgl-to-webgpu/convert-webgl-topology.d.ts.map +1 -1
  57. package/dist/webgl-to-webgpu/convert-webgl-topology.js +2 -0
  58. package/dist/webgl-to-webgpu/convert-webgl-topology.js.map +1 -1
  59. package/package.json +5 -5
  60. package/src/gltf/animations/animations.ts +17 -5
  61. package/src/gltf/animations/interpolate.ts +49 -68
  62. package/src/gltf/create-gltf-model.ts +101 -43
  63. package/src/gltf/create-scenegraph-from-gltf.ts +39 -11
  64. package/src/gltf/gltf-animator.ts +34 -25
  65. package/src/index.ts +1 -2
  66. package/src/parsers/parse-gltf-animations.ts +63 -26
  67. package/src/parsers/parse-gltf-lights.ts +51 -13
  68. package/src/parsers/parse-gltf.ts +90 -77
  69. package/src/parsers/parse-pbr-material.ts +204 -14
  70. package/src/pbr/pbr-environment.ts +10 -0
  71. package/src/pbr/pbr-material.ts +5 -0
  72. package/src/webgl-to-webgpu/convert-webgl-attribute.ts +12 -1
  73. package/src/webgl-to-webgpu/convert-webgl-sampler.ts +9 -0
  74. package/src/webgl-to-webgpu/convert-webgl-topology.ts +2 -0
  75. package/dist/utils/deep-copy.d.ts +0 -3
  76. package/dist/utils/deep-copy.d.ts.map +0 -1
  77. package/dist/utils/deep-copy.js +0 -21
  78. package/dist/utils/deep-copy.js.map +0 -1
  79. package/src/utils/deep-copy.ts +0 -22
@@ -1,6 +1,7 @@
1
1
  // luma.gl
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
+ /** Maps glTF accessor type strings to their component counts. */
4
5
  export const ATTRIBUTE_TYPE_TO_COMPONENTS = {
5
6
  SCALAR: 1,
6
7
  VEC2: 2,
@@ -10,6 +11,7 @@ export const ATTRIBUTE_TYPE_TO_COMPONENTS = {
10
11
  MAT3: 9,
11
12
  MAT4: 16
12
13
  };
14
+ /** Maps glTF accessor component-type enums to typed-array constructors. */
13
15
  export const ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY = {
14
16
  5120: Int8Array,
15
17
  5121: Uint8Array,
@@ -18,6 +20,7 @@ export const ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY = {
18
20
  5125: Uint32Array,
19
21
  5126: Float32Array
20
22
  };
23
+ /** Converts a glTF accessor into a typed array plus its component count. */
21
24
  export function accessorToTypedArray(accessor) {
22
25
  const ArrayType = ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY[accessor.componentType];
23
26
  const components = ATTRIBUTE_TYPE_TO_COMPONENTS[accessor.type];
@@ -1 +1 @@
1
- {"version":3,"file":"convert-webgl-attribute.js","sourceRoot":"","sources":["../../src/webgl-to-webgpu/convert-webgl-attribute.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,+BAA+B;AAC/B,oCAAoC;AAKpC,MAAM,CAAC,MAAM,4BAA4B,GAA2B;IAClE,MAAM,EAAE,CAAC;IACT,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,EAAE;CACT,CAAC;AAEF,MAAM,CAAC,MAAM,iCAAiC,GAAwB;IACpE,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,YAAY;CACnB,CAAC;AAUF,MAAM,UAAU,oBAAoB,CAAC,QAAsB;IAIzD,MAAM,SAAS,GAAG,iCAAiC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IAC5E,MAAM,UAAU,GAAG,4BAA4B,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC;IAC3C,MAAM,EAAC,MAAM,EAAE,UAAU,GAAG,CAAC,EAAC,GAAG,QAAQ,CAAC,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC;IAEjE,MAAM,UAAU,GAAG,IAAI,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,CAAC,QAAQ,CAAC,UAAU,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAE1F,OAAO,EAAC,UAAU,EAAE,UAAU,EAAC,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"convert-webgl-attribute.js","sourceRoot":"","sources":["../../src/webgl-to-webgpu/convert-webgl-attribute.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,+BAA+B;AAC/B,oCAAoC;AAKpC,iEAAiE;AACjE,MAAM,CAAC,MAAM,4BAA4B,GAA2B;IAClE,MAAM,EAAE,CAAC;IACT,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,EAAE;CACT,CAAC;AAEF,2EAA2E;AAC3E,MAAM,CAAC,MAAM,iCAAiC,GAAwB;IACpE,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,YAAY;CACnB,CAAC;AAgBF,4EAA4E;AAC5E,MAAM,UAAU,oBAAoB,CAAC,QAAsB;IAMzD,MAAM,SAAS,GAAG,iCAAiC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IAC5E,MAAM,UAAU,GAAG,4BAA4B,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC;IAC3C,MAAM,EAAC,MAAM,EAAE,UAAU,GAAG,CAAC,EAAC,GAAG,QAAQ,CAAC,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC;IAEjE,MAAM,UAAU,GAAG,IAAI,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,CAAC,QAAQ,CAAC,UAAU,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAE1F,OAAO,EAAC,UAAU,EAAE,UAAU,EAAC,CAAC;AAClC,CAAC"}
@@ -1,11 +1,17 @@
1
1
  import type { SamplerProps } from '@luma.gl/core';
2
2
  import { GL } from '@luma.gl/constants';
3
+ /** Minimal glTF sampler representation used during conversion. */
3
4
  type GLTFSampler = {
5
+ /** Horizontal wrap mode. */
4
6
  wrapS?: GL.CLAMP_TO_EDGE | GL.REPEAT | GL.MIRRORED_REPEAT;
7
+ /** Vertical wrap mode. */
5
8
  wrapT?: GL.CLAMP_TO_EDGE | GL.REPEAT | GL.MIRRORED_REPEAT;
9
+ /** Magnification filter. */
6
10
  magFilter?: GL.NEAREST | GL.LINEAR;
11
+ /** Minification and mip filter combination. */
7
12
  minFilter?: GL.NEAREST | GL.LINEAR | GL.NEAREST_MIPMAP_NEAREST | GL.LINEAR_MIPMAP_NEAREST | GL.NEAREST_MIPMAP_LINEAR | GL.LINEAR_MIPMAP_LINEAR;
8
13
  };
14
+ /** Converts a glTF sampler into luma.gl sampler props. */
9
15
  export declare function convertSampler(gltfSampler: GLTFSampler): SamplerProps;
10
16
  export {};
11
17
  //# sourceMappingURL=convert-webgl-sampler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"convert-webgl-sampler.d.ts","sourceRoot":"","sources":["../../src/webgl-to-webgpu/convert-webgl-sampler.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,eAAe,CAAC;AAChD,OAAO,EAAC,EAAE,EAAC,MAAM,oBAAoB,CAAC;AAEtC,KAAK,WAAW,GAAG;IACjB,KAAK,CAAC,EAAE,EAAE,CAAC,aAAa,GAAG,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,eAAe,CAAC;IAC1D,KAAK,CAAC,EAAE,EAAE,CAAC,aAAa,GAAG,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,eAAe,CAAC;IAC1D,SAAS,CAAC,EAAE,EAAE,CAAC,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC;IACnC,SAAS,CAAC,EACN,EAAE,CAAC,OAAO,GACV,EAAE,CAAC,MAAM,GACT,EAAE,CAAC,sBAAsB,GACzB,EAAE,CAAC,qBAAqB,GACxB,EAAE,CAAC,qBAAqB,GACxB,EAAE,CAAC,oBAAoB,CAAC;CAC7B,CAAC;AAEF,wBAAgB,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,YAAY,CAOrE"}
1
+ {"version":3,"file":"convert-webgl-sampler.d.ts","sourceRoot":"","sources":["../../src/webgl-to-webgpu/convert-webgl-sampler.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,eAAe,CAAC;AAChD,OAAO,EAAC,EAAE,EAAC,MAAM,oBAAoB,CAAC;AAEtC,kEAAkE;AAClE,KAAK,WAAW,GAAG;IACjB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,EAAE,CAAC,aAAa,GAAG,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,eAAe,CAAC;IAC1D,0BAA0B;IAC1B,KAAK,CAAC,EAAE,EAAE,CAAC,aAAa,GAAG,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,eAAe,CAAC;IAC1D,4BAA4B;IAC5B,SAAS,CAAC,EAAE,EAAE,CAAC,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC;IACnC,+CAA+C;IAC/C,SAAS,CAAC,EACN,EAAE,CAAC,OAAO,GACV,EAAE,CAAC,MAAM,GACT,EAAE,CAAC,sBAAsB,GACzB,EAAE,CAAC,qBAAqB,GACxB,EAAE,CAAC,qBAAqB,GACxB,EAAE,CAAC,oBAAoB,CAAC;CAC7B,CAAC;AAEF,0DAA0D;AAC1D,wBAAgB,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,YAAY,CAOrE"}
@@ -2,6 +2,7 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
  import { GL } from '@luma.gl/constants';
5
+ /** Converts a glTF sampler into luma.gl sampler props. */
5
6
  export function convertSampler(gltfSampler) {
6
7
  return {
7
8
  addressModeU: convertSamplerWrapMode(gltfSampler.wrapS),
@@ -10,6 +11,7 @@ export function convertSampler(gltfSampler) {
10
11
  ...convertSamplerMinFilter(gltfSampler.minFilter)
11
12
  };
12
13
  }
14
+ /** Converts a glTF wrap enum into a luma.gl address mode. */
13
15
  function convertSamplerWrapMode(mode) {
14
16
  switch (mode) {
15
17
  case 33071:
@@ -22,6 +24,7 @@ function convertSamplerWrapMode(mode) {
22
24
  return undefined;
23
25
  }
24
26
  }
27
+ /** Converts a glTF mag filter enum into a luma.gl mag filter. */
25
28
  function convertSamplerMagFilter(mode) {
26
29
  switch (mode) {
27
30
  case 9728:
@@ -32,6 +35,7 @@ function convertSamplerMagFilter(mode) {
32
35
  return undefined;
33
36
  }
34
37
  }
38
+ /** Converts a glTF min filter enum into luma.gl minification and mipmap filters. */
35
39
  function convertSamplerMinFilter(mode) {
36
40
  switch (mode) {
37
41
  case 9728:
@@ -1 +1 @@
1
- {"version":3,"file":"convert-webgl-sampler.js","sourceRoot":"","sources":["../../src/webgl-to-webgpu/convert-webgl-sampler.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,+BAA+B;AAC/B,oCAAoC;AAKpC,OAAO,EAAC,EAAE,EAAC,MAAM,oBAAoB,CAAC;AAetC,MAAM,UAAU,cAAc,CAAC,WAAwB;IACrD,OAAO;QACL,YAAY,EAAE,sBAAsB,CAAC,WAAW,CAAC,KAAK,CAAC;QACvD,YAAY,EAAE,sBAAsB,CAAC,WAAW,CAAC,KAAK,CAAC;QACvD,SAAS,EAAE,uBAAuB,CAAC,WAAW,CAAC,SAAS,CAAC;QACzD,GAAG,uBAAuB,CAAC,WAAW,CAAC,SAAS,CAAC;KAClD,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAC7B,IAAmE;IAEnE,QAAQ,IAAI,EAAE,CAAC;QACb;YACE,OAAO,eAAe,CAAC;QACzB;YACE,OAAO,QAAQ,CAAC;QAClB;YACE,OAAO,eAAe,CAAC;QACzB;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED,SAAS,uBAAuB,CAC9B,IAAwC;IAExC,QAAQ,IAAI,EAAE,CAAC;QACb;YACE,OAAO,SAAS,CAAC;QACnB;YACE,OAAO,QAAQ,CAAC;QAClB;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED,SAAS,uBAAuB,CAC9B,IAOa;IAEb,QAAQ,IAAI,EAAE,CAAC;QACb;YACE,OAAO,EAAC,SAAS,EAAE,SAAS,EAAC,CAAC;QAChC;YACE,OAAO,EAAC,SAAS,EAAE,QAAQ,EAAC,CAAC;QAC/B;YACE,OAAO,EAAC,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAC,CAAC;QACzD;YACE,OAAO,EAAC,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAC,CAAC;QACxD;YACE,OAAO,EAAC,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAC,CAAC;QACxD;YACE,OAAO,EAAC,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAC,CAAC;QACvD;YACE,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"convert-webgl-sampler.js","sourceRoot":"","sources":["../../src/webgl-to-webgpu/convert-webgl-sampler.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,+BAA+B;AAC/B,oCAAoC;AAKpC,OAAO,EAAC,EAAE,EAAC,MAAM,oBAAoB,CAAC;AAoBtC,0DAA0D;AAC1D,MAAM,UAAU,cAAc,CAAC,WAAwB;IACrD,OAAO;QACL,YAAY,EAAE,sBAAsB,CAAC,WAAW,CAAC,KAAK,CAAC;QACvD,YAAY,EAAE,sBAAsB,CAAC,WAAW,CAAC,KAAK,CAAC;QACvD,SAAS,EAAE,uBAAuB,CAAC,WAAW,CAAC,SAAS,CAAC;QACzD,GAAG,uBAAuB,CAAC,WAAW,CAAC,SAAS,CAAC;KAClD,CAAC;AACJ,CAAC;AAED,6DAA6D;AAC7D,SAAS,sBAAsB,CAC7B,IAAmE;IAEnE,QAAQ,IAAI,EAAE,CAAC;QACb;YACE,OAAO,eAAe,CAAC;QACzB;YACE,OAAO,QAAQ,CAAC;QAClB;YACE,OAAO,eAAe,CAAC;QACzB;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED,iEAAiE;AACjE,SAAS,uBAAuB,CAC9B,IAAwC;IAExC,QAAQ,IAAI,EAAE,CAAC;QACb;YACE,OAAO,SAAS,CAAC;QACnB;YACE,OAAO,QAAQ,CAAC;QAClB;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED,oFAAoF;AACpF,SAAS,uBAAuB,CAC9B,IAOa;IAEb,QAAQ,IAAI,EAAE,CAAC;QACb;YACE,OAAO,EAAC,SAAS,EAAE,SAAS,EAAC,CAAC;QAChC;YACE,OAAO,EAAC,SAAS,EAAE,QAAQ,EAAC,CAAC;QAC/B;YACE,OAAO,EAAC,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAC,CAAC;QACzD;YACE,OAAO,EAAC,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAC,CAAC;QACxD;YACE,OAAO,EAAC,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAC,CAAC;QACxD;YACE,OAAO,EAAC,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAC,CAAC;QACvD;YACE,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { PrimitiveTopology } from '@luma.gl/core';
2
+ /** Minimal WebGL draw-mode enum subset used by the glTF converter. */
2
3
  export declare enum GLEnum {
3
4
  POINTS = 0,
4
5
  LINES = 1,
@@ -8,5 +9,6 @@ export declare enum GLEnum {
8
9
  TRIANGLE_STRIP = 5,
9
10
  TRIANGLE_FAN = 6
10
11
  }
12
+ /** Converts a WebGL draw mode into a luma.gl primitive topology string. */
11
13
  export declare function convertGLDrawModeToTopology(drawMode: GLEnum.POINTS | GLEnum.LINES | GLEnum.LINE_STRIP | GLEnum.LINE_LOOP | GLEnum.TRIANGLES | GLEnum.TRIANGLE_STRIP | GLEnum.TRIANGLE_FAN): PrimitiveTopology;
12
14
  //# sourceMappingURL=convert-webgl-topology.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"convert-webgl-topology.d.ts","sourceRoot":"","sources":["../../src/webgl-to-webgpu/convert-webgl-topology.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAMhD,oBAAY,MAAM;IAChB,MAAM,IAAM;IACZ,KAAK,IAAM;IACX,SAAS,IAAM;IACf,UAAU,IAAM;IAChB,SAAS,IAAM;IACf,cAAc,IAAM;IACpB,YAAY,IAAM;CACnB;AAED,wBAAgB,2BAA2B,CACzC,QAAQ,EACJ,MAAM,CAAC,MAAM,GACb,MAAM,CAAC,KAAK,GACZ,MAAM,CAAC,UAAU,GACjB,MAAM,CAAC,SAAS,GAChB,MAAM,CAAC,SAAS,GAChB,MAAM,CAAC,cAAc,GACrB,MAAM,CAAC,YAAY,GACtB,iBAAiB,CAUnB"}
1
+ {"version":3,"file":"convert-webgl-topology.d.ts","sourceRoot":"","sources":["../../src/webgl-to-webgpu/convert-webgl-topology.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAMhD,sEAAsE;AACtE,oBAAY,MAAM;IAChB,MAAM,IAAM;IACZ,KAAK,IAAM;IACX,SAAS,IAAM;IACf,UAAU,IAAM;IAChB,SAAS,IAAM;IACf,cAAc,IAAM;IACpB,YAAY,IAAM;CACnB;AAED,2EAA2E;AAC3E,wBAAgB,2BAA2B,CACzC,QAAQ,EACJ,MAAM,CAAC,MAAM,GACb,MAAM,CAAC,KAAK,GACZ,MAAM,CAAC,UAAU,GACjB,MAAM,CAAC,SAAS,GAChB,MAAM,CAAC,SAAS,GAChB,MAAM,CAAC,cAAc,GACrB,MAAM,CAAC,YAAY,GACtB,iBAAiB,CAUnB"}
@@ -5,6 +5,7 @@
5
5
  // `@luma.gl/constants`. Locally we use `GLEnum` instead of `GL` to avoid
6
6
  // conflicts with the `babel-plugin-inline-webgl-constants` plugin.
7
7
  // eslint-disable-next-line no-shadow
8
+ /** Minimal WebGL draw-mode enum subset used by the glTF converter. */
8
9
  export var GLEnum;
9
10
  (function (GLEnum) {
10
11
  GLEnum[GLEnum["POINTS"] = 0] = "POINTS";
@@ -15,6 +16,7 @@ export var GLEnum;
15
16
  GLEnum[GLEnum["TRIANGLE_STRIP"] = 5] = "TRIANGLE_STRIP";
16
17
  GLEnum[GLEnum["TRIANGLE_FAN"] = 6] = "TRIANGLE_FAN";
17
18
  })(GLEnum || (GLEnum = {}));
19
+ /** Converts a WebGL draw mode into a luma.gl primitive topology string. */
18
20
  export function convertGLDrawModeToTopology(drawMode) {
19
21
  // prettier-ignore
20
22
  switch (drawMode) {
@@ -1 +1 @@
1
- {"version":3,"file":"convert-webgl-topology.js","sourceRoot":"","sources":["../../src/webgl-to-webgpu/convert-webgl-topology.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,+BAA+B;AAC/B,oCAAoC;AAIpC,wEAAwE;AACxE,yEAAyE;AACzE,mEAAmE;AACnE,qCAAqC;AACrC,MAAM,CAAN,IAAY,MAQX;AARD,WAAY,MAAM;IAChB,uCAAY,CAAA;IACZ,qCAAW,CAAA;IACX,6CAAe,CAAA;IACf,+CAAgB,CAAA;IAChB,6CAAe,CAAA;IACf,uDAAoB,CAAA;IACpB,mDAAkB,CAAA;AACpB,CAAC,EARW,MAAM,KAAN,MAAM,QAQjB;AAED,MAAM,UAAU,2BAA2B,CACzC,QAOuB;IAEvB,kBAAkB;IAClB,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,YAAY,CAAC;QACxC,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,WAAW,CAAC;QACtC,KAAK,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,YAAY,CAAC;QAC5C,KAAK,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,eAAe,CAAC;QAC9C,KAAK,MAAM,CAAC,cAAc,CAAC,CAAC,OAAO,gBAAgB,CAAC;QACpD,OAAO,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"convert-webgl-topology.js","sourceRoot":"","sources":["../../src/webgl-to-webgpu/convert-webgl-topology.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,+BAA+B;AAC/B,oCAAoC;AAIpC,wEAAwE;AACxE,yEAAyE;AACzE,mEAAmE;AACnE,qCAAqC;AACrC,sEAAsE;AACtE,MAAM,CAAN,IAAY,MAQX;AARD,WAAY,MAAM;IAChB,uCAAY,CAAA;IACZ,qCAAW,CAAA;IACX,6CAAe,CAAA;IACf,+CAAgB,CAAA;IAChB,6CAAe,CAAA;IACf,uDAAoB,CAAA;IACpB,mDAAkB,CAAA;AACpB,CAAC,EARW,MAAM,KAAN,MAAM,QAQjB;AAED,2EAA2E;AAC3E,MAAM,UAAU,2BAA2B,CACzC,QAOuB;IAEvB,kBAAkB;IAClB,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,YAAY,CAAC;QACxC,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,WAAW,CAAC;QACtC,KAAK,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,YAAY,CAAC;QAC5C,KAAK,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,eAAe,CAAC;QAC9C,KAAK,MAAM,CAAC,cAAc,CAAC,CAAC,OAAO,gBAAgB,CAAC;QACpD,OAAO,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luma.gl/gltf",
3
- "version": "9.3.0-alpha.4",
3
+ "version": "9.3.0-alpha.6",
4
4
  "description": "glTF support for luma.gl",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -46,10 +46,10 @@
46
46
  "@luma.gl/shadertools": "9.2.0-alpha.6"
47
47
  },
48
48
  "dependencies": {
49
- "@loaders.gl/core": "^4.2.0",
50
- "@loaders.gl/gltf": "^4.2.0",
51
- "@loaders.gl/textures": "^4.2.0",
49
+ "@loaders.gl/core": "4.4.0-alpha.18",
50
+ "@loaders.gl/gltf": "4.4.0-alpha.18",
51
+ "@loaders.gl/textures": "4.4.0-alpha.18",
52
52
  "@math.gl/core": "^4.1.0"
53
53
  },
54
- "gitHead": "7486e7b0377fb6ab961b4499828681bede60f3b1"
54
+ "gitHead": "59fda5480c4d0bb3d64545d4621175221f2b6c7c"
55
55
  }
@@ -2,21 +2,33 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import {GLTFNodePostprocessed} from '@loaders.gl/gltf';
6
-
5
+ /** Parsed glTF animation definition. */
7
6
  export type GLTFAnimation = {
7
+ /** Application-visible animation name. */
8
8
  name: string;
9
+ /** Channels that drive individual node properties. */
9
10
  channels: GLTFAnimationChannel[];
10
11
  };
11
12
 
13
+ /** Supported glTF animation target paths. */
14
+ export type GLTFAnimationPath = 'translation' | 'rotation' | 'scale' | 'weights';
15
+
16
+ /** Parsed glTF animation channel. */
12
17
  export type GLTFAnimationChannel = {
13
- path: 'translation' | 'rotation' | 'scale' | 'weights';
18
+ /** Node property written by this channel. */
19
+ path: GLTFAnimationPath;
20
+ /** Time/value sampler used to evaluate the channel. */
14
21
  sampler: GLTFAnimationSampler;
15
- target: GLTFNodePostprocessed;
22
+ /** Target node identifier in the generated scenegraph. */
23
+ targetNodeId: string;
16
24
  };
17
25
 
26
+ /** Parsed glTF animation sampler. */
18
27
  export type GLTFAnimationSampler = {
28
+ /** Keyframe times in seconds. */
19
29
  input: number[];
30
+ /** glTF interpolation mode. */
20
31
  interpolation: string;
21
- output: number[] | number[][];
32
+ /** Keyframe values, already expanded into JS arrays. */
33
+ output: number[][];
22
34
  };
@@ -1,15 +1,36 @@
1
- import {GLTFNodePostprocessed} from '@loaders.gl/gltf';
2
1
  import {log} from '@luma.gl/core';
3
2
  import {Quaternion} from '@math.gl/core';
4
- import {GLTFAnimationChannel, GLTFAnimationSampler} from './animations';
3
+ import {GLTFAnimationPath, GLTFAnimationSampler} from './animations';
4
+ import {GroupNode} from '@luma.gl/engine';
5
5
 
6
- const scratchQuaternion = new Quaternion();
6
+ /** Applies an evaluated animation value to a scenegraph node. */
7
+ function updateTargetPath(
8
+ target: GroupNode,
9
+ path: GLTFAnimationPath,
10
+ newValue: number[]
11
+ ): GroupNode | null {
12
+ switch (path) {
13
+ case 'translation':
14
+ return target.setPosition(newValue).updateMatrix();
7
15
 
16
+ case 'rotation':
17
+ return target.setRotation(newValue).updateMatrix();
18
+
19
+ case 'scale':
20
+ return target.setScale(newValue).updateMatrix();
21
+
22
+ default:
23
+ log.warn(`Bad animation path ${path}`)();
24
+ return null;
25
+ }
26
+ }
27
+
28
+ /** Evaluates a glTF animation sampler at the supplied time and applies the result to a node. */
8
29
  export function interpolate(
9
30
  time: number,
10
31
  {input, interpolation, output}: GLTFAnimationSampler,
11
- target: GLTFNodePostprocessed,
12
- path: GLTFAnimationChannel['path']
32
+ target: GroupNode,
33
+ path: GLTFAnimationPath
13
34
  ) {
14
35
  const maxTime = input[input.length - 1];
15
36
  const animationTime = time % maxTime;
@@ -17,44 +38,18 @@ export function interpolate(
17
38
  const nextIndex = input.findIndex(t => t >= animationTime);
18
39
  const previousIndex = Math.max(0, nextIndex - 1);
19
40
 
20
- if (!Array.isArray(target[path])) {
21
- switch (path) {
22
- case 'translation':
23
- target[path] = [0, 0, 0];
24
- break;
25
-
26
- case 'rotation':
27
- target[path] = [0, 0, 0, 1];
28
- break;
29
-
30
- case 'scale':
31
- target[path] = [1, 1, 1];
32
- break;
33
-
34
- default:
35
- log.warn(`Bad animation path ${path}`)();
36
- }
37
- }
38
-
39
- // assert(target[path].length === output[previousIndex].length);
40
41
  const previousTime = input[previousIndex];
41
42
  const nextTime = input[nextIndex];
42
43
 
43
44
  switch (interpolation) {
44
45
  case 'STEP':
45
- stepInterpolate(target, path, output[previousIndex] as number[]);
46
+ stepInterpolate(target, path, output[previousIndex]);
46
47
  break;
47
48
 
48
49
  case 'LINEAR':
49
50
  if (nextTime > previousTime) {
50
51
  const ratio = (animationTime - previousTime) / (nextTime - previousTime);
51
- linearInterpolate(
52
- target,
53
- path,
54
- output[previousIndex] as number[],
55
- output[nextIndex] as number[],
56
- ratio
57
- );
52
+ linearInterpolate(target, path, output[previousIndex], output[nextIndex], ratio);
58
53
  }
59
54
  break;
60
55
 
@@ -63,10 +58,10 @@ export function interpolate(
63
58
  const ratio = (animationTime - previousTime) / (nextTime - previousTime);
64
59
  const tDiff = nextTime - previousTime;
65
60
 
66
- const p0 = output[3 * previousIndex + 1] as number[];
67
- const outTangent0 = output[3 * previousIndex + 2] as number[];
68
- const inTangent1 = output[3 * nextIndex + 0] as number[];
69
- const p1 = output[3 * nextIndex + 1] as number[];
61
+ const p0 = output[3 * previousIndex + 1];
62
+ const outTangent0 = output[3 * previousIndex + 2];
63
+ const inTangent1 = output[3 * nextIndex + 0];
64
+ const p1 = output[3 * nextIndex + 1];
70
65
 
71
66
  cubicsplineInterpolate(target, path, {p0, outTangent0, inTangent1, p1, tDiff, ratio});
72
67
  }
@@ -78,34 +73,31 @@ export function interpolate(
78
73
  }
79
74
  }
80
75
 
76
+ /** Applies linear interpolation between two keyframes. */
81
77
  function linearInterpolate(
82
- target: GLTFNodePostprocessed,
83
- path: GLTFAnimationChannel['path'],
78
+ target: GroupNode,
79
+ path: GLTFAnimationPath,
84
80
  start: number[],
85
81
  stop: number[],
86
82
  ratio: number
87
83
  ) {
88
- if (!target[path]) {
89
- throw new Error();
90
- }
91
-
92
84
  if (path === 'rotation') {
93
85
  // SLERP when path is rotation
94
- scratchQuaternion.slerp({start, target: stop, ratio});
95
- for (let i = 0; i < scratchQuaternion.length; i++) {
96
- target[path][i] = scratchQuaternion[i];
97
- }
86
+ updateTargetPath(target, path, new Quaternion().slerp({start, target: stop, ratio}));
98
87
  } else {
99
88
  // regular interpolation
89
+ const newVal = [];
100
90
  for (let i = 0; i < start.length; i++) {
101
- target[path][i] = ratio * stop[i] + (1 - ratio) * start[i];
91
+ newVal[i] = ratio * stop[i] + (1 - ratio) * start[i];
102
92
  }
93
+ updateTargetPath(target, path, newVal);
103
94
  }
104
95
  }
105
96
 
97
+ /** Applies glTF cubic spline interpolation between two keyframes. */
106
98
  function cubicsplineInterpolate(
107
- target: GLTFNodePostprocessed,
108
- path: GLTFAnimationChannel['path'],
99
+ target: GroupNode,
100
+ path: GLTFAnimationPath,
109
101
  {
110
102
  p0,
111
103
  outTangent0,
@@ -122,32 +114,21 @@ function cubicsplineInterpolate(
122
114
  ratio: number;
123
115
  }
124
116
  ) {
125
- if (!target[path]) {
126
- throw new Error();
127
- }
128
-
129
117
  // TODO: Quaternion might need normalization
130
- for (let i = 0; i < target[path].length; i++) {
118
+ const newVal = [];
119
+ for (let i = 0; i < p0.length; i++) {
131
120
  const m0 = outTangent0[i] * tDiff;
132
121
  const m1 = inTangent1[i] * tDiff;
133
- target[path][i] =
122
+ newVal[i] =
134
123
  (2 * Math.pow(t, 3) - 3 * Math.pow(t, 2) + 1) * p0[i] +
135
124
  (Math.pow(t, 3) - 2 * Math.pow(t, 2) + t) * m0 +
136
125
  (-2 * Math.pow(t, 3) + 3 * Math.pow(t, 2)) * p1[i] +
137
126
  (Math.pow(t, 3) - Math.pow(t, 2)) * m1;
138
127
  }
128
+ updateTargetPath(target, path, newVal);
139
129
  }
140
130
 
141
- function stepInterpolate(
142
- target: GLTFNodePostprocessed,
143
- path: GLTFAnimationChannel['path'],
144
- value: number[]
145
- ) {
146
- if (!target[path]) {
147
- throw new Error();
148
- }
149
-
150
- for (let i = 0; i < value.length; i++) {
151
- target[path][i] = value[i];
152
- }
131
+ /** Applies step interpolation by copying the current keyframe value. */
132
+ function stepInterpolate(target: GroupNode, path: GLTFAnimationPath, value: number[]) {
133
+ updateTargetPath(target, path, value);
153
134
  }
@@ -3,55 +3,93 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
5
  import {Device, type RenderPipelineParameters, log} from '@luma.gl/core';
6
- import {pbrMaterial, ShaderModule} from '@luma.gl/shadertools';
6
+ import {pbrMaterial, skin} from '@luma.gl/shadertools';
7
7
  import {Geometry, Model, ModelNode, type ModelProps} from '@luma.gl/engine';
8
8
  import {type ParsedPBRMaterial} from '../pbr/pbr-material';
9
9
 
10
10
  const SHADER = /* WGSL */ `
11
- layout(0) positions: vec4; // in vec4 POSITION;
12
-
13
- #ifdef HAS_NORMALS
14
- in vec4 normals; // in vec4 NORMAL;
15
- #endif
16
-
17
- #ifdef HAS_TANGENTS
18
- in vec4 TANGENT;
19
- #endif
11
+ struct VertexInputs {
12
+ @location(0) positions: vec3f,
13
+ #ifdef HAS_NORMALS
14
+ @location(1) normals: vec3f,
15
+ #endif
16
+ #ifdef HAS_TANGENTS
17
+ @location(2) TANGENT: vec4f,
18
+ #endif
19
+ #ifdef HAS_UV
20
+ @location(3) texCoords: vec2f,
21
+ #endif
22
+ #ifdef HAS_SKIN
23
+ @location(4) JOINTS_0: vec4u,
24
+ @location(5) WEIGHTS_0: vec4f,
25
+ #endif
26
+ };
20
27
 
21
- #ifdef HAS_UV
22
- // in vec2 TEXCOORD_0;
23
- in vec2 texCoords;
24
- #endif
28
+ struct FragmentInputs {
29
+ @builtin(position) position: vec4f,
30
+ @location(0) pbrPosition: vec3f,
31
+ @location(1) pbrUV: vec2f,
32
+ @location(2) pbrNormal: vec3f,
33
+ #ifdef HAS_TANGENTS
34
+ @location(3) pbrTangent: vec4f,
35
+ #endif
36
+ };
25
37
 
26
38
  @vertex
27
- void main(void) {
28
- vec4 _NORMAL = vec4(0.);
29
- vec4 _TANGENT = vec4(0.);
30
- vec2 _TEXCOORD_0 = vec2(0.);
31
-
32
- #ifdef HAS_NORMALS
33
- _NORMAL = normals;
34
- #endif
35
-
36
- #ifdef HAS_TANGENTS
37
- _TANGENT = TANGENT;
38
- #endif
39
-
40
- #ifdef HAS_UV
41
- _TEXCOORD_0 = texCoords;
42
- #endif
43
-
44
- pbr_setPositionNormalTangentUV(positions, _NORMAL, _TANGENT, _TEXCOORD_0);
45
- gl_Position = u_MVPMatrix * positions;
46
- }
39
+ fn vertexMain(inputs: VertexInputs) -> FragmentInputs {
40
+ var outputs: FragmentInputs;
41
+ var position = vec4f(inputs.positions, 1.0);
42
+ var normal = vec3f(0.0, 0.0, 1.0);
43
+ var tangent = vec4f(1.0, 0.0, 0.0, 1.0);
44
+ var uv = vec2f(0.0, 0.0);
45
+
46
+ #ifdef HAS_NORMALS
47
+ normal = inputs.normals;
48
+ #endif
49
+ #ifdef HAS_UV
50
+ uv = inputs.texCoords;
51
+ #endif
52
+ #ifdef HAS_TANGENTS
53
+ tangent = inputs.TANGENT;
54
+ #endif
55
+ #ifdef HAS_SKIN
56
+ let skinMatrix = getSkinMatrix(inputs.WEIGHTS_0, inputs.JOINTS_0);
57
+ position = skinMatrix * position;
58
+ normal = normalize((skinMatrix * vec4f(normal, 0.0)).xyz);
59
+ #ifdef HAS_TANGENTS
60
+ tangent = vec4f(normalize((skinMatrix * vec4f(tangent.xyz, 0.0)).xyz), tangent.w);
61
+ #endif
62
+ #endif
63
+
64
+ let worldPosition = pbrProjection.modelMatrix * position;
65
+
66
+ #ifdef HAS_NORMALS
67
+ normal = normalize((pbrProjection.normalMatrix * vec4f(normal, 0.0)).xyz);
68
+ #endif
69
+ #ifdef HAS_TANGENTS
70
+ let worldTangent = normalize((pbrProjection.modelMatrix * vec4f(tangent.xyz, 0.0)).xyz);
71
+ outputs.pbrTangent = vec4f(worldTangent, tangent.w);
72
+ #endif
73
+
74
+ outputs.position = pbrProjection.modelViewProjectionMatrix * position;
75
+ outputs.pbrPosition = worldPosition.xyz / worldPosition.w;
76
+ outputs.pbrUV = uv;
77
+ outputs.pbrNormal = normal;
78
+ return outputs;
79
+ }
47
80
 
48
81
  @fragment
49
- out vec4 fragmentColor;
50
-
51
- void main(void) {
52
- vec3 pos = pbr_vPosition;
53
- fragmentColor = pbr_filterColor(vec4(1.0));
54
- }
82
+ fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
83
+ fragmentInputs.pbr_vPosition = inputs.pbrPosition;
84
+ fragmentInputs.pbr_vUV = inputs.pbrUV;
85
+ fragmentInputs.pbr_vNormal = inputs.pbrNormal;
86
+ #ifdef HAS_TANGENTS
87
+ let tangent = normalize(inputs.pbrTangent.xyz);
88
+ let bitangent = normalize(cross(inputs.pbrNormal, tangent)) * inputs.pbrTangent.w;
89
+ fragmentInputs.pbr_vTBN = mat3x3f(tangent, bitangent, inputs.pbrNormal);
90
+ #endif
91
+ return pbr_filterColor(vec4f(1.0));
92
+ }
55
93
  `;
56
94
 
57
95
  // TODO rename attributes to POSITION/NORMAL etc
@@ -76,6 +114,11 @@ const vs = /* glsl */ `\
76
114
  in vec2 texCoords;
77
115
  #endif
78
116
 
117
+ #ifdef HAS_SKIN
118
+ in uvec4 JOINTS_0;
119
+ in vec4 WEIGHTS_0;
120
+ #endif
121
+
79
122
  void main(void) {
80
123
  vec4 _NORMAL = vec4(0.);
81
124
  vec4 _TANGENT = vec4(0.);
@@ -93,8 +136,17 @@ const vs = /* glsl */ `\
93
136
  _TEXCOORD_0 = texCoords;
94
137
  #endif
95
138
 
96
- pbr_setPositionNormalTangentUV(positions, _NORMAL, _TANGENT, _TEXCOORD_0);
97
- gl_Position = pbrProjection.modelViewProjectionMatrix * positions;
139
+ vec4 pos = positions;
140
+
141
+ #ifdef HAS_SKIN
142
+ mat4 skinMat = getSkinMatrix(WEIGHTS_0, JOINTS_0);
143
+ pos = skinMat * pos;
144
+ _NORMAL = skinMat * _NORMAL;
145
+ _TANGENT = vec4((skinMat * vec4(_TANGENT.xyz, 0.)).xyz, _TANGENT.w);
146
+ #endif
147
+
148
+ pbr_setPositionNormalTangentUV(pos, _NORMAL, _TANGENT, _TEXCOORD_0);
149
+ gl_Position = pbrProjection.modelViewProjectionMatrix * pos;
98
150
  }
99
151
  `;
100
152
 
@@ -108,11 +160,17 @@ const fs = /* glsl */ `\
108
160
  }
109
161
  `;
110
162
 
163
+ /** Options used to instantiate a `ModelNode` for one glTF primitive. */
111
164
  export type CreateGLTFModelOptions = {
165
+ /** Optional id assigned to the generated model. */
112
166
  id?: string;
167
+ /** Vertex count override for non-indexed primitives. */
113
168
  vertexCount?: number;
169
+ /** Geometry converted from the glTF primitive. */
114
170
  geometry: Geometry;
171
+ /** Parsed PBR material state for the primitive. */
115
172
  parsedPPBRMaterial: ParsedPBRMaterial;
173
+ /** Additional model props merged into the generated model. */
116
174
  modelOptions?: Partial<ModelProps>;
117
175
  };
118
176
 
@@ -144,7 +202,7 @@ export function createGLTFModel(device: Device, options: CreateGLTFModelOptions)
144
202
  geometry,
145
203
  topology: geometry.topology,
146
204
  vertexCount,
147
- modules: [pbrMaterial as unknown as ShaderModule],
205
+ modules: [pbrMaterial, skin],
148
206
  ...modelOptions,
149
207
 
150
208
  defines: {...parsedPPBRMaterial.defines, ...modelOptions.defines},
@@ -10,22 +10,50 @@ import {parseGLTF, type ParseGLTFOptions} from '../parsers/parse-gltf';
10
10
  import {parseGLTFLights} from '../parsers/parse-gltf-lights';
11
11
  import {GLTFAnimator} from './gltf-animator';
12
12
  import {parseGLTFAnimations} from '../parsers/parse-gltf-animations';
13
- import {deepCopy} from '../utils/deep-copy';
14
13
 
14
+ /** Scenegraph bundle returned from a parsed glTF asset. */
15
+ export type GLTFScenegraphs = {
16
+ /** Scene roots produced from the glTF scenes array. */
17
+ scenes: GroupNode[];
18
+ /** Animation controller for glTF animations. */
19
+ animator: GLTFAnimator;
20
+ /** Parsed punctual lights from the asset. */
21
+ lights: Light[];
22
+
23
+ /** Map from glTF mesh ids to generated mesh group nodes. */
24
+ gltfMeshIdToNodeMap: Map<string, GroupNode>;
25
+ /** Map from glTF node indices to generated scenegraph nodes. */
26
+ gltfNodeIndexToNodeMap: Map<number, GroupNode>;
27
+ /** Map from glTF node ids to generated scenegraph nodes. */
28
+ gltfNodeIdToNodeMap: Map<string, GroupNode>;
29
+
30
+ /** Original post-processed glTF document. */
31
+ gltf: GLTFPostprocessed;
32
+ };
33
+
34
+ /** Converts a post-processed glTF asset into luma.gl scenegraph nodes and animation helpers. */
15
35
  export function createScenegraphsFromGLTF(
16
36
  device: Device,
17
37
  gltf: GLTFPostprocessed,
18
38
  options?: ParseGLTFOptions
19
- ): {
20
- scenes: GroupNode[];
21
- animator: GLTFAnimator;
22
- lights: Light[];
23
- } {
24
- gltf = deepCopy(gltf);
25
- const scenes = parseGLTF(device, gltf, options);
26
- // Note: There is a nasty dependency on injected nodes in the glTF
39
+ ): GLTFScenegraphs {
40
+ const {scenes, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap} = parseGLTF(
41
+ device,
42
+ gltf,
43
+ options
44
+ );
45
+
27
46
  const animations = parseGLTFAnimations(gltf);
28
- const animator = new GLTFAnimator({animations});
47
+ const animator = new GLTFAnimator({animations, gltfNodeIdToNodeMap});
29
48
  const lights = parseGLTFLights(gltf);
30
- return {scenes, animator, lights};
49
+
50
+ return {
51
+ scenes,
52
+ animator,
53
+ lights,
54
+ gltfMeshIdToNodeMap,
55
+ gltfNodeIdToNodeMap,
56
+ gltfNodeIndexToNodeMap,
57
+ gltf
58
+ };
31
59
  }