@luma.gl/gltf 9.3.0-alpha.4 → 9.3.0-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +1305 -327
- package/dist/dist.min.js +98 -46
- package/dist/gltf/animations/animations.d.ts +16 -4
- package/dist/gltf/animations/animations.d.ts.map +1 -1
- package/dist/gltf/animations/interpolate.d.ts +4 -3
- package/dist/gltf/animations/interpolate.d.ts.map +1 -1
- package/dist/gltf/animations/interpolate.js +27 -36
- package/dist/gltf/animations/interpolate.js.map +1 -1
- package/dist/gltf/create-gltf-model.d.ts +15 -1
- package/dist/gltf/create-gltf-model.d.ts.map +1 -1
- package/dist/gltf/create-gltf-model.js +154 -48
- package/dist/gltf/create-gltf-model.js.map +1 -1
- package/dist/gltf/create-scenegraph-from-gltf.d.ts +37 -2
- package/dist/gltf/create-scenegraph-from-gltf.d.ts.map +1 -1
- package/dist/gltf/create-scenegraph-from-gltf.js +74 -6
- package/dist/gltf/create-scenegraph-from-gltf.js.map +1 -1
- package/dist/gltf/gltf-animator.d.ts +26 -0
- package/dist/gltf/gltf-animator.d.ts.map +1 -1
- package/dist/gltf/gltf-animator.js +22 -19
- package/dist/gltf/gltf-animator.js.map +1 -1
- package/dist/gltf/gltf-extension-support.d.ts +10 -0
- package/dist/gltf/gltf-extension-support.d.ts.map +1 -0
- package/dist/gltf/gltf-extension-support.js +173 -0
- package/dist/gltf/gltf-extension-support.js.map +1 -0
- package/dist/index.cjs +1247 -294
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/parsers/parse-gltf-animations.d.ts +1 -0
- package/dist/parsers/parse-gltf-animations.d.ts.map +1 -1
- package/dist/parsers/parse-gltf-animations.js +73 -28
- package/dist/parsers/parse-gltf-animations.js.map +1 -1
- package/dist/parsers/parse-gltf-lights.d.ts.map +1 -1
- package/dist/parsers/parse-gltf-lights.js +112 -18
- package/dist/parsers/parse-gltf-lights.js.map +1 -1
- package/dist/parsers/parse-gltf.d.ts +19 -2
- package/dist/parsers/parse-gltf.d.ts.map +1 -1
- package/dist/parsers/parse-gltf.js +101 -61
- package/dist/parsers/parse-gltf.js.map +1 -1
- package/dist/parsers/parse-pbr-material.d.ts +115 -2
- package/dist/parsers/parse-pbr-material.d.ts.map +1 -1
- package/dist/parsers/parse-pbr-material.js +565 -54
- package/dist/parsers/parse-pbr-material.js.map +1 -1
- package/dist/pbr/pbr-environment.d.ts +6 -0
- package/dist/pbr/pbr-environment.d.ts.map +1 -1
- package/dist/pbr/pbr-environment.js +15 -12
- package/dist/pbr/pbr-environment.js.map +1 -1
- package/dist/pbr/pbr-material.d.ts +13 -3
- package/dist/pbr/pbr-material.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-attribute.d.ts +12 -1
- package/dist/webgl-to-webgpu/convert-webgl-attribute.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-attribute.js +3 -0
- package/dist/webgl-to-webgpu/convert-webgl-attribute.js.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-sampler.d.ts +11 -5
- package/dist/webgl-to-webgpu/convert-webgl-sampler.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-sampler.js +16 -12
- package/dist/webgl-to-webgpu/convert-webgl-sampler.js.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-topology.d.ts +2 -9
- package/dist/webgl-to-webgpu/convert-webgl-topology.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-topology.js +2 -14
- package/dist/webgl-to-webgpu/convert-webgl-topology.js.map +1 -1
- package/dist/webgl-to-webgpu/gltf-webgl-constants.d.ts +27 -0
- package/dist/webgl-to-webgpu/gltf-webgl-constants.d.ts.map +1 -0
- package/dist/webgl-to-webgpu/gltf-webgl-constants.js +34 -0
- package/dist/webgl-to-webgpu/gltf-webgl-constants.js.map +1 -0
- package/package.json +8 -9
- package/src/gltf/animations/animations.ts +17 -5
- package/src/gltf/animations/interpolate.ts +49 -68
- package/src/gltf/create-gltf-model.ts +214 -48
- package/src/gltf/create-scenegraph-from-gltf.ts +131 -12
- package/src/gltf/gltf-animator.ts +34 -25
- package/src/gltf/gltf-extension-support.ts +214 -0
- package/src/index.ts +10 -2
- package/src/parsers/parse-gltf-animations.ts +94 -33
- package/src/parsers/parse-gltf-lights.ts +147 -20
- package/src/parsers/parse-gltf.ts +170 -90
- package/src/parsers/parse-pbr-material.ts +865 -80
- package/src/pbr/pbr-environment.ts +38 -15
- package/src/pbr/pbr-material.ts +18 -3
- package/src/webgl-to-webgpu/convert-webgl-attribute.ts +12 -1
- package/src/webgl-to-webgpu/convert-webgl-sampler.ts +38 -29
- package/src/webgl-to-webgpu/convert-webgl-topology.ts +2 -14
- package/src/webgl-to-webgpu/gltf-webgl-constants.ts +35 -0
- package/dist/utils/deep-copy.d.ts +0 -3
- package/dist/utils/deep-copy.d.ts.map +0 -1
- package/dist/utils/deep-copy.js +0 -21
- package/dist/utils/deep-copy.js.map +0 -1
- package/src/utils/deep-copy.ts +0 -22
package/dist/dist.dev.js
CHANGED
|
@@ -52,13 +52,6 @@ var __exports__ = (() => {
|
|
|
52
52
|
}
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
-
// external-global-plugin:@luma.gl/constants
|
|
56
|
-
var require_constants = __commonJS({
|
|
57
|
-
"external-global-plugin:@luma.gl/constants"(exports, module) {
|
|
58
|
-
module.exports = globalThis.luma;
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
|
|
62
55
|
// external-global-plugin:@luma.gl/shadertools
|
|
63
56
|
var require_shadertools = __commonJS({
|
|
64
57
|
"external-global-plugin:@luma.gl/shadertools"(exports, module) {
|
|
@@ -71,6 +64,7 @@ var __exports__ = (() => {
|
|
|
71
64
|
__export(bundle_exports, {
|
|
72
65
|
GLTFAnimator: () => GLTFAnimator,
|
|
73
66
|
createScenegraphsFromGLTF: () => createScenegraphsFromGLTF,
|
|
67
|
+
getGLTFExtensionSupport: () => getGLTFExtensionSupport,
|
|
74
68
|
loadPBREnvironment: () => loadPBREnvironment,
|
|
75
69
|
parseGLTFLights: () => parseGLTFLights,
|
|
76
70
|
parsePBRMaterial: () => parsePBRMaterial
|
|
@@ -122,7 +116,7 @@ var __exports__ = (() => {
|
|
|
122
116
|
}
|
|
123
117
|
|
|
124
118
|
// ../../node_modules/@loaders.gl/images/dist/lib/utils/version.js
|
|
125
|
-
var VERSION = true ? "4.
|
|
119
|
+
var VERSION = true ? "4.4.0-alpha.18" : "latest";
|
|
126
120
|
|
|
127
121
|
// ../../node_modules/@loaders.gl/images/dist/lib/category-api/image-type.js
|
|
128
122
|
var parseImageNode = globalThis.loaders?.parseImageNode;
|
|
@@ -263,7 +257,6 @@ var __exports__ = (() => {
|
|
|
263
257
|
}
|
|
264
258
|
|
|
265
259
|
// ../../node_modules/@loaders.gl/images/dist/lib/parsers/parse-to-image-bitmap.js
|
|
266
|
-
var EMPTY_OBJECT = {};
|
|
267
260
|
var imagebitmapOptionsSupported = true;
|
|
268
261
|
async function parseToImageBitmap(arrayBuffer, options, url) {
|
|
269
262
|
let blob;
|
|
@@ -291,8 +284,13 @@ var __exports__ = (() => {
|
|
|
291
284
|
return await createImageBitmap(blob);
|
|
292
285
|
}
|
|
293
286
|
function isEmptyObject(object) {
|
|
294
|
-
|
|
295
|
-
return
|
|
287
|
+
if (!object) {
|
|
288
|
+
return true;
|
|
289
|
+
}
|
|
290
|
+
for (const key in object) {
|
|
291
|
+
if (Object.prototype.hasOwnProperty.call(object, key)) {
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
296
294
|
}
|
|
297
295
|
return true;
|
|
298
296
|
}
|
|
@@ -616,6 +614,7 @@ var __exports__ = (() => {
|
|
|
616
614
|
|
|
617
615
|
// src/pbr/pbr-environment.ts
|
|
618
616
|
function loadPBREnvironment(device, props) {
|
|
617
|
+
const specularMipLevels = props.specularMipLevels ?? 1;
|
|
619
618
|
const brdfLutTexture = new import_engine.DynamicTexture(device, {
|
|
620
619
|
id: "brdfLUT",
|
|
621
620
|
sampler: {
|
|
@@ -629,7 +628,9 @@ var __exports__ = (() => {
|
|
|
629
628
|
});
|
|
630
629
|
const diffuseEnvSampler = makeCube(device, {
|
|
631
630
|
id: "DiffuseEnvSampler",
|
|
632
|
-
getTextureForFace: (
|
|
631
|
+
getTextureForFace: (face) => loadImageTexture(
|
|
632
|
+
props.getTexUrl("diffuse", FACES.indexOf(face), 0)
|
|
633
|
+
),
|
|
633
634
|
sampler: {
|
|
634
635
|
addressModeU: "clamp-to-edge",
|
|
635
636
|
addressModeV: "clamp-to-edge",
|
|
@@ -639,12 +640,13 @@ var __exports__ = (() => {
|
|
|
639
640
|
});
|
|
640
641
|
const specularEnvSampler = makeCube(device, {
|
|
641
642
|
id: "SpecularEnvSampler",
|
|
642
|
-
getTextureForFace: (
|
|
643
|
+
getTextureForFace: (face) => {
|
|
643
644
|
const imageArray = [];
|
|
644
|
-
|
|
645
|
-
|
|
645
|
+
const direction = FACES.indexOf(face);
|
|
646
|
+
for (let lod = 0; lod < specularMipLevels; lod++) {
|
|
647
|
+
imageArray.push(loadImageTexture(props.getTexUrl("specular", direction, lod)));
|
|
646
648
|
}
|
|
647
|
-
return imageArray;
|
|
649
|
+
return Promise.all(imageArray);
|
|
648
650
|
},
|
|
649
651
|
sampler: {
|
|
650
652
|
addressModeU: "clamp-to-edge",
|
|
@@ -660,32 +662,34 @@ var __exports__ = (() => {
|
|
|
660
662
|
specularEnvSampler
|
|
661
663
|
};
|
|
662
664
|
}
|
|
663
|
-
var FACES = [
|
|
665
|
+
var FACES = ["+X", "-X", "+Y", "-Y", "+Z", "-Z"];
|
|
664
666
|
function makeCube(device, {
|
|
665
667
|
id,
|
|
666
668
|
getTextureForFace,
|
|
667
669
|
sampler
|
|
668
670
|
}) {
|
|
669
|
-
const data =
|
|
670
|
-
|
|
671
|
-
|
|
671
|
+
const data = Promise.all(
|
|
672
|
+
FACES.map((face) => getTextureForFace(face))
|
|
673
|
+
).then((faceDataArray) => {
|
|
674
|
+
const cubeData = {};
|
|
675
|
+
FACES.forEach((face, index) => {
|
|
676
|
+
cubeData[face] = faceDataArray[index];
|
|
677
|
+
});
|
|
678
|
+
return cubeData;
|
|
672
679
|
});
|
|
673
680
|
return new import_engine.DynamicTexture(device, {
|
|
674
681
|
id,
|
|
675
682
|
dimension: "cube",
|
|
676
683
|
mipmaps: false,
|
|
677
684
|
sampler,
|
|
678
|
-
// @ts-expect-error
|
|
679
685
|
data
|
|
680
686
|
});
|
|
681
687
|
}
|
|
682
688
|
|
|
683
689
|
// src/parsers/parse-pbr-material.ts
|
|
684
|
-
var import_constants2 = __toESM(require_constants(), 1);
|
|
685
690
|
var import_core = __toESM(require_core(), 1);
|
|
686
691
|
|
|
687
692
|
// src/webgl-to-webgpu/convert-webgl-sampler.ts
|
|
688
|
-
var import_constants = __toESM(require_constants(), 1);
|
|
689
693
|
function convertSampler(gltfSampler) {
|
|
690
694
|
return {
|
|
691
695
|
addressModeU: convertSamplerWrapMode(gltfSampler.wrapS),
|
|
@@ -696,11 +700,11 @@ var __exports__ = (() => {
|
|
|
696
700
|
}
|
|
697
701
|
function convertSamplerWrapMode(mode) {
|
|
698
702
|
switch (mode) {
|
|
699
|
-
case
|
|
703
|
+
case 33071 /* CLAMP_TO_EDGE */:
|
|
700
704
|
return "clamp-to-edge";
|
|
701
|
-
case
|
|
705
|
+
case 10497 /* REPEAT */:
|
|
702
706
|
return "repeat";
|
|
703
|
-
case
|
|
707
|
+
case 33648 /* MIRRORED_REPEAT */:
|
|
704
708
|
return "mirror-repeat";
|
|
705
709
|
default:
|
|
706
710
|
return void 0;
|
|
@@ -708,9 +712,9 @@ var __exports__ = (() => {
|
|
|
708
712
|
}
|
|
709
713
|
function convertSamplerMagFilter(mode) {
|
|
710
714
|
switch (mode) {
|
|
711
|
-
case
|
|
715
|
+
case 9728 /* NEAREST */:
|
|
712
716
|
return "nearest";
|
|
713
|
-
case
|
|
717
|
+
case 9729 /* LINEAR */:
|
|
714
718
|
return "linear";
|
|
715
719
|
default:
|
|
716
720
|
return void 0;
|
|
@@ -718,17 +722,17 @@ var __exports__ = (() => {
|
|
|
718
722
|
}
|
|
719
723
|
function convertSamplerMinFilter(mode) {
|
|
720
724
|
switch (mode) {
|
|
721
|
-
case
|
|
725
|
+
case 9728 /* NEAREST */:
|
|
722
726
|
return { minFilter: "nearest" };
|
|
723
|
-
case
|
|
727
|
+
case 9729 /* LINEAR */:
|
|
724
728
|
return { minFilter: "linear" };
|
|
725
|
-
case
|
|
729
|
+
case 9984 /* NEAREST_MIPMAP_NEAREST */:
|
|
726
730
|
return { minFilter: "nearest", mipmapFilter: "nearest" };
|
|
727
|
-
case
|
|
731
|
+
case 9985 /* LINEAR_MIPMAP_NEAREST */:
|
|
728
732
|
return { minFilter: "linear", mipmapFilter: "nearest" };
|
|
729
|
-
case
|
|
733
|
+
case 9986 /* NEAREST_MIPMAP_LINEAR */:
|
|
730
734
|
return { minFilter: "nearest", mipmapFilter: "linear" };
|
|
731
|
-
case
|
|
735
|
+
case 9987 /* LINEAR_MIPMAP_LINEAR */:
|
|
732
736
|
return { minFilter: "linear", mipmapFilter: "linear" };
|
|
733
737
|
default:
|
|
734
738
|
return {};
|
|
@@ -760,7 +764,8 @@ var __exports__ = (() => {
|
|
|
760
764
|
if (imageBasedLightingEnvironment) {
|
|
761
765
|
parsedMaterial.bindings.pbr_diffuseEnvSampler = imageBasedLightingEnvironment.diffuseEnvSampler.texture;
|
|
762
766
|
parsedMaterial.bindings.pbr_specularEnvSampler = imageBasedLightingEnvironment.specularEnvSampler.texture;
|
|
763
|
-
parsedMaterial.bindings.
|
|
767
|
+
parsedMaterial.bindings.pbr_brdfLUT = imageBasedLightingEnvironment.brdfLutTexture.texture;
|
|
768
|
+
parsedMaterial.uniforms.IBLenabled = true;
|
|
764
769
|
parsedMaterial.uniforms.scaleIBLAmbient = [1, 1];
|
|
765
770
|
}
|
|
766
771
|
if (options?.pbrDebug) {
|
|
@@ -774,6 +779,8 @@ var __exports__ = (() => {
|
|
|
774
779
|
parsedMaterial.defines["HAS_TANGENTS"] = true;
|
|
775
780
|
if (attributes["TEXCOORD_0"])
|
|
776
781
|
parsedMaterial.defines["HAS_UV"] = true;
|
|
782
|
+
if (attributes["JOINTS_0"] && attributes["WEIGHTS_0"])
|
|
783
|
+
parsedMaterial.defines["HAS_SKIN"] = true;
|
|
777
784
|
if (attributes["COLOR_0"])
|
|
778
785
|
parsedMaterial.defines["HAS_COLORS"] = true;
|
|
779
786
|
if (options?.imageBasedLightingEnvironment)
|
|
@@ -781,81 +788,181 @@ var __exports__ = (() => {
|
|
|
781
788
|
if (options?.lights)
|
|
782
789
|
parsedMaterial.defines["USE_LIGHTS"] = true;
|
|
783
790
|
if (material) {
|
|
784
|
-
|
|
791
|
+
if (options.validateAttributes !== false) {
|
|
792
|
+
warnOnMissingExpectedAttributes(material, attributes);
|
|
793
|
+
}
|
|
794
|
+
parseMaterial(device, material, parsedMaterial, options.gltf);
|
|
785
795
|
}
|
|
786
796
|
return parsedMaterial;
|
|
787
797
|
}
|
|
788
|
-
function
|
|
789
|
-
|
|
798
|
+
function warnOnMissingExpectedAttributes(material, attributes) {
|
|
799
|
+
const uvDependentTextureSlots = getUvDependentTextureSlots(material);
|
|
800
|
+
if (uvDependentTextureSlots.length > 0 && !attributes["TEXCOORD_0"]) {
|
|
801
|
+
import_core.log.warn(
|
|
802
|
+
`glTF material uses ${uvDependentTextureSlots.join(", ")} but primitive is missing TEXCOORD_0; textured shading will sample the default UV coordinates`
|
|
803
|
+
)();
|
|
804
|
+
}
|
|
805
|
+
const isUnlitMaterial = Boolean(material.unlit || material.extensions?.KHR_materials_unlit);
|
|
806
|
+
if (isUnlitMaterial || attributes["NORMAL"]) {
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
const missingNormalReason = material.normalTexture ? "lit PBR shading with normalTexture" : "lit PBR shading";
|
|
810
|
+
import_core.log.warn(
|
|
811
|
+
`glTF primitive is missing NORMAL while using ${missingNormalReason}; shading will fall back to geometric normals`
|
|
812
|
+
)();
|
|
813
|
+
}
|
|
814
|
+
function getUvDependentTextureSlots(material) {
|
|
815
|
+
const uvDependentTextureSlots = [];
|
|
816
|
+
if (material.pbrMetallicRoughness?.baseColorTexture) {
|
|
817
|
+
uvDependentTextureSlots.push("baseColorTexture");
|
|
818
|
+
}
|
|
819
|
+
if (material.pbrMetallicRoughness?.metallicRoughnessTexture) {
|
|
820
|
+
uvDependentTextureSlots.push("metallicRoughnessTexture");
|
|
821
|
+
}
|
|
822
|
+
if (material.normalTexture) {
|
|
823
|
+
uvDependentTextureSlots.push("normalTexture");
|
|
824
|
+
}
|
|
825
|
+
if (material.occlusionTexture) {
|
|
826
|
+
uvDependentTextureSlots.push("occlusionTexture");
|
|
827
|
+
}
|
|
828
|
+
if (material.emissiveTexture) {
|
|
829
|
+
uvDependentTextureSlots.push("emissiveTexture");
|
|
830
|
+
}
|
|
831
|
+
if (material.extensions?.KHR_materials_specular?.specularTexture) {
|
|
832
|
+
uvDependentTextureSlots.push("KHR_materials_specular.specularTexture");
|
|
833
|
+
}
|
|
834
|
+
if (material.extensions?.KHR_materials_specular?.specularColorTexture) {
|
|
835
|
+
uvDependentTextureSlots.push("KHR_materials_specular.specularColorTexture");
|
|
836
|
+
}
|
|
837
|
+
if (material.extensions?.KHR_materials_transmission?.transmissionTexture) {
|
|
838
|
+
uvDependentTextureSlots.push("KHR_materials_transmission.transmissionTexture");
|
|
839
|
+
}
|
|
840
|
+
if (material.extensions?.KHR_materials_clearcoat?.clearcoatTexture) {
|
|
841
|
+
uvDependentTextureSlots.push("KHR_materials_clearcoat.clearcoatTexture");
|
|
842
|
+
}
|
|
843
|
+
if (material.extensions?.KHR_materials_clearcoat?.clearcoatRoughnessTexture) {
|
|
844
|
+
uvDependentTextureSlots.push("KHR_materials_clearcoat.clearcoatRoughnessTexture");
|
|
845
|
+
}
|
|
846
|
+
if (material.extensions?.KHR_materials_sheen?.sheenColorTexture) {
|
|
847
|
+
uvDependentTextureSlots.push("KHR_materials_sheen.sheenColorTexture");
|
|
848
|
+
}
|
|
849
|
+
if (material.extensions?.KHR_materials_sheen?.sheenRoughnessTexture) {
|
|
850
|
+
uvDependentTextureSlots.push("KHR_materials_sheen.sheenRoughnessTexture");
|
|
851
|
+
}
|
|
852
|
+
if (material.extensions?.KHR_materials_iridescence?.iridescenceTexture) {
|
|
853
|
+
uvDependentTextureSlots.push("KHR_materials_iridescence.iridescenceTexture");
|
|
854
|
+
}
|
|
855
|
+
if (material.extensions?.KHR_materials_anisotropy?.anisotropyTexture) {
|
|
856
|
+
uvDependentTextureSlots.push("KHR_materials_anisotropy.anisotropyTexture");
|
|
857
|
+
}
|
|
858
|
+
return uvDependentTextureSlots;
|
|
859
|
+
}
|
|
860
|
+
function parseMaterial(device, material, parsedMaterial, gltf) {
|
|
861
|
+
parsedMaterial.uniforms.unlit = Boolean(
|
|
862
|
+
material.unlit || material.extensions?.KHR_materials_unlit
|
|
863
|
+
);
|
|
790
864
|
if (material.pbrMetallicRoughness) {
|
|
791
|
-
parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial);
|
|
865
|
+
parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial, gltf);
|
|
792
866
|
}
|
|
793
867
|
if (material.normalTexture) {
|
|
794
|
-
addTexture(
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
);
|
|
868
|
+
addTexture(device, material.normalTexture, "pbr_normalSampler", parsedMaterial, {
|
|
869
|
+
featureOptions: {
|
|
870
|
+
define: "HAS_NORMALMAP",
|
|
871
|
+
enabledUniformName: "normalMapEnabled"
|
|
872
|
+
},
|
|
873
|
+
gltf
|
|
874
|
+
});
|
|
801
875
|
const { scale: scale4 = 1 } = material.normalTexture;
|
|
802
876
|
parsedMaterial.uniforms.normalScale = scale4;
|
|
803
877
|
}
|
|
804
878
|
if (material.occlusionTexture) {
|
|
805
|
-
addTexture(
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
);
|
|
879
|
+
addTexture(device, material.occlusionTexture, "pbr_occlusionSampler", parsedMaterial, {
|
|
880
|
+
featureOptions: {
|
|
881
|
+
define: "HAS_OCCLUSIONMAP",
|
|
882
|
+
enabledUniformName: "occlusionMapEnabled"
|
|
883
|
+
},
|
|
884
|
+
gltf
|
|
885
|
+
});
|
|
812
886
|
const { strength = 1 } = material.occlusionTexture;
|
|
813
887
|
parsedMaterial.uniforms.occlusionStrength = strength;
|
|
814
888
|
}
|
|
889
|
+
parsedMaterial.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];
|
|
815
890
|
if (material.emissiveTexture) {
|
|
816
|
-
addTexture(
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
);
|
|
823
|
-
parsedMaterial.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];
|
|
891
|
+
addTexture(device, material.emissiveTexture, "pbr_emissiveSampler", parsedMaterial, {
|
|
892
|
+
featureOptions: {
|
|
893
|
+
define: "HAS_EMISSIVEMAP",
|
|
894
|
+
enabledUniformName: "emissiveMapEnabled"
|
|
895
|
+
},
|
|
896
|
+
gltf
|
|
897
|
+
});
|
|
824
898
|
}
|
|
825
|
-
|
|
826
|
-
|
|
899
|
+
parseMaterialExtensions(device, material.extensions, parsedMaterial, gltf);
|
|
900
|
+
switch (material.alphaMode || "OPAQUE") {
|
|
901
|
+
case "OPAQUE":
|
|
902
|
+
break;
|
|
903
|
+
case "MASK": {
|
|
827
904
|
const { alphaCutoff = 0.5 } = material;
|
|
828
905
|
parsedMaterial.defines["ALPHA_CUTOFF"] = true;
|
|
906
|
+
parsedMaterial.uniforms.alphaCutoffEnabled = true;
|
|
829
907
|
parsedMaterial.uniforms.alphaCutoff = alphaCutoff;
|
|
830
908
|
break;
|
|
909
|
+
}
|
|
831
910
|
case "BLEND":
|
|
832
911
|
import_core.log.warn("glTF BLEND alphaMode might not work well because it requires mesh sorting")();
|
|
833
|
-
parsedMaterial
|
|
834
|
-
parsedMaterial.parameters.blendColorOperation = "add";
|
|
835
|
-
parsedMaterial.parameters.blendColorSrcFactor = "src-alpha";
|
|
836
|
-
parsedMaterial.parameters.blendColorDstFactor = "one-minus-src-alpha";
|
|
837
|
-
parsedMaterial.parameters.blendAlphaOperation = "add";
|
|
838
|
-
parsedMaterial.parameters.blendAlphaSrcFactor = "one";
|
|
839
|
-
parsedMaterial.parameters.blendAlphaDstFactor = "one-minus-src-alpha";
|
|
840
|
-
parsedMaterial.glParameters["blend"] = true;
|
|
841
|
-
parsedMaterial.glParameters["blendEquation"] = import_constants2.GL.FUNC_ADD;
|
|
842
|
-
parsedMaterial.glParameters["blendFunc"] = [
|
|
843
|
-
import_constants2.GL.SRC_ALPHA,
|
|
844
|
-
import_constants2.GL.ONE_MINUS_SRC_ALPHA,
|
|
845
|
-
import_constants2.GL.ONE,
|
|
846
|
-
import_constants2.GL.ONE_MINUS_SRC_ALPHA
|
|
847
|
-
];
|
|
912
|
+
applyAlphaBlendParameters(parsedMaterial);
|
|
848
913
|
break;
|
|
849
914
|
}
|
|
850
915
|
}
|
|
851
|
-
function
|
|
916
|
+
function applyAlphaBlendParameters(parsedMaterial) {
|
|
917
|
+
parsedMaterial.parameters.blend = true;
|
|
918
|
+
parsedMaterial.parameters.blendColorOperation = "add";
|
|
919
|
+
parsedMaterial.parameters.blendColorSrcFactor = "src-alpha";
|
|
920
|
+
parsedMaterial.parameters.blendColorDstFactor = "one-minus-src-alpha";
|
|
921
|
+
parsedMaterial.parameters.blendAlphaOperation = "add";
|
|
922
|
+
parsedMaterial.parameters.blendAlphaSrcFactor = "one";
|
|
923
|
+
parsedMaterial.parameters.blendAlphaDstFactor = "one-minus-src-alpha";
|
|
924
|
+
parsedMaterial.glParameters["blend"] = true;
|
|
925
|
+
parsedMaterial.glParameters["blendEquation"] = 32774 /* FUNC_ADD */;
|
|
926
|
+
parsedMaterial.glParameters["blendFunc"] = [
|
|
927
|
+
770 /* SRC_ALPHA */,
|
|
928
|
+
771 /* ONE_MINUS_SRC_ALPHA */,
|
|
929
|
+
1 /* ONE */,
|
|
930
|
+
771 /* ONE_MINUS_SRC_ALPHA */
|
|
931
|
+
];
|
|
932
|
+
}
|
|
933
|
+
function applyTransmissionBlendApproximation(parsedMaterial) {
|
|
934
|
+
parsedMaterial.parameters.blend = true;
|
|
935
|
+
parsedMaterial.parameters.depthWriteEnabled = false;
|
|
936
|
+
parsedMaterial.parameters.blendColorOperation = "add";
|
|
937
|
+
parsedMaterial.parameters.blendColorSrcFactor = "one";
|
|
938
|
+
parsedMaterial.parameters.blendColorDstFactor = "one-minus-src-alpha";
|
|
939
|
+
parsedMaterial.parameters.blendAlphaOperation = "add";
|
|
940
|
+
parsedMaterial.parameters.blendAlphaSrcFactor = "one";
|
|
941
|
+
parsedMaterial.parameters.blendAlphaDstFactor = "one-minus-src-alpha";
|
|
942
|
+
parsedMaterial.glParameters["blend"] = true;
|
|
943
|
+
parsedMaterial.glParameters["depthMask"] = false;
|
|
944
|
+
parsedMaterial.glParameters["blendEquation"] = 32774 /* FUNC_ADD */;
|
|
945
|
+
parsedMaterial.glParameters["blendFunc"] = [
|
|
946
|
+
1 /* ONE */,
|
|
947
|
+
771 /* ONE_MINUS_SRC_ALPHA */,
|
|
948
|
+
1 /* ONE */,
|
|
949
|
+
771 /* ONE_MINUS_SRC_ALPHA */
|
|
950
|
+
];
|
|
951
|
+
}
|
|
952
|
+
function parsePbrMetallicRoughness(device, pbrMetallicRoughness, parsedMaterial, gltf) {
|
|
852
953
|
if (pbrMetallicRoughness.baseColorTexture) {
|
|
853
954
|
addTexture(
|
|
854
955
|
device,
|
|
855
956
|
pbrMetallicRoughness.baseColorTexture,
|
|
856
957
|
"pbr_baseColorSampler",
|
|
857
|
-
|
|
858
|
-
|
|
958
|
+
parsedMaterial,
|
|
959
|
+
{
|
|
960
|
+
featureOptions: {
|
|
961
|
+
define: "HAS_BASECOLORMAP",
|
|
962
|
+
enabledUniformName: "baseColorMapEnabled"
|
|
963
|
+
},
|
|
964
|
+
gltf
|
|
965
|
+
}
|
|
859
966
|
);
|
|
860
967
|
}
|
|
861
968
|
parsedMaterial.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];
|
|
@@ -864,20 +971,277 @@ var __exports__ = (() => {
|
|
|
864
971
|
device,
|
|
865
972
|
pbrMetallicRoughness.metallicRoughnessTexture,
|
|
866
973
|
"pbr_metallicRoughnessSampler",
|
|
867
|
-
|
|
868
|
-
|
|
974
|
+
parsedMaterial,
|
|
975
|
+
{
|
|
976
|
+
featureOptions: {
|
|
977
|
+
define: "HAS_METALROUGHNESSMAP",
|
|
978
|
+
enabledUniformName: "metallicRoughnessMapEnabled"
|
|
979
|
+
},
|
|
980
|
+
gltf
|
|
981
|
+
}
|
|
869
982
|
);
|
|
870
983
|
}
|
|
871
984
|
const { metallicFactor = 1, roughnessFactor = 1 } = pbrMetallicRoughness;
|
|
872
985
|
parsedMaterial.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];
|
|
873
986
|
}
|
|
874
|
-
function
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
987
|
+
function parseMaterialExtensions(device, extensions, parsedMaterial, gltf) {
|
|
988
|
+
if (!extensions) {
|
|
989
|
+
return;
|
|
990
|
+
}
|
|
991
|
+
if (hasMaterialExtensionShading(extensions)) {
|
|
992
|
+
parsedMaterial.defines["USE_MATERIAL_EXTENSIONS"] = true;
|
|
993
|
+
}
|
|
994
|
+
parseSpecularExtension(device, extensions.KHR_materials_specular, parsedMaterial, gltf);
|
|
995
|
+
parseIorExtension(extensions.KHR_materials_ior, parsedMaterial);
|
|
996
|
+
parseTransmissionExtension(device, extensions.KHR_materials_transmission, parsedMaterial, gltf);
|
|
997
|
+
parseVolumeExtension(device, extensions.KHR_materials_volume, parsedMaterial, gltf);
|
|
998
|
+
parseClearcoatExtension(device, extensions.KHR_materials_clearcoat, parsedMaterial, gltf);
|
|
999
|
+
parseSheenExtension(device, extensions.KHR_materials_sheen, parsedMaterial, gltf);
|
|
1000
|
+
parseIridescenceExtension(device, extensions.KHR_materials_iridescence, parsedMaterial, gltf);
|
|
1001
|
+
parseAnisotropyExtension(device, extensions.KHR_materials_anisotropy, parsedMaterial, gltf);
|
|
1002
|
+
parseEmissiveStrengthExtension(extensions.KHR_materials_emissive_strength, parsedMaterial);
|
|
1003
|
+
}
|
|
1004
|
+
function hasMaterialExtensionShading(extensions) {
|
|
1005
|
+
return Boolean(
|
|
1006
|
+
extensions.KHR_materials_specular || extensions.KHR_materials_ior || extensions.KHR_materials_transmission || extensions.KHR_materials_volume || extensions.KHR_materials_clearcoat || extensions.KHR_materials_sheen || extensions.KHR_materials_iridescence || extensions.KHR_materials_anisotropy
|
|
1007
|
+
);
|
|
1008
|
+
}
|
|
1009
|
+
function parseSpecularExtension(device, extension, parsedMaterial, gltf) {
|
|
1010
|
+
if (!extension) {
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
1013
|
+
if (extension.specularColorFactor) {
|
|
1014
|
+
parsedMaterial.uniforms.specularColorFactor = extension.specularColorFactor;
|
|
1015
|
+
}
|
|
1016
|
+
if (extension.specularFactor !== void 0) {
|
|
1017
|
+
parsedMaterial.uniforms.specularIntensityFactor = extension.specularFactor;
|
|
1018
|
+
}
|
|
1019
|
+
if (extension.specularColorTexture) {
|
|
1020
|
+
addTexture(device, extension.specularColorTexture, "pbr_specularColorSampler", parsedMaterial, {
|
|
1021
|
+
featureOptions: {
|
|
1022
|
+
define: "HAS_SPECULARCOLORMAP",
|
|
1023
|
+
enabledUniformName: "specularColorMapEnabled"
|
|
1024
|
+
},
|
|
1025
|
+
gltf
|
|
1026
|
+
});
|
|
1027
|
+
}
|
|
1028
|
+
if (extension.specularTexture) {
|
|
1029
|
+
addTexture(device, extension.specularTexture, "pbr_specularIntensitySampler", parsedMaterial, {
|
|
1030
|
+
featureOptions: {
|
|
1031
|
+
define: "HAS_SPECULARINTENSITYMAP",
|
|
1032
|
+
enabledUniformName: "specularIntensityMapEnabled"
|
|
1033
|
+
},
|
|
1034
|
+
gltf
|
|
1035
|
+
});
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
function parseIorExtension(extension, parsedMaterial) {
|
|
1039
|
+
if (extension?.ior !== void 0) {
|
|
1040
|
+
parsedMaterial.uniforms.ior = extension.ior;
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
function parseTransmissionExtension(device, extension, parsedMaterial, gltf) {
|
|
1044
|
+
if (!extension) {
|
|
1045
|
+
return;
|
|
1046
|
+
}
|
|
1047
|
+
if (extension.transmissionFactor !== void 0) {
|
|
1048
|
+
parsedMaterial.uniforms.transmissionFactor = extension.transmissionFactor;
|
|
1049
|
+
}
|
|
1050
|
+
if (extension.transmissionTexture) {
|
|
1051
|
+
addTexture(device, extension.transmissionTexture, "pbr_transmissionSampler", parsedMaterial, {
|
|
1052
|
+
featureOptions: {
|
|
1053
|
+
define: "HAS_TRANSMISSIONMAP",
|
|
1054
|
+
enabledUniformName: "transmissionMapEnabled"
|
|
1055
|
+
},
|
|
1056
|
+
gltf
|
|
1057
|
+
});
|
|
1058
|
+
}
|
|
1059
|
+
if ((extension.transmissionFactor ?? 0) > 0 || extension.transmissionTexture) {
|
|
1060
|
+
import_core.log.warn(
|
|
1061
|
+
"KHR_materials_transmission uses a premultiplied-alpha blending approximation and may require mesh sorting"
|
|
1062
|
+
)();
|
|
1063
|
+
applyTransmissionBlendApproximation(parsedMaterial);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
function parseVolumeExtension(device, extension, parsedMaterial, gltf) {
|
|
1067
|
+
if (!extension) {
|
|
1068
|
+
return;
|
|
1069
|
+
}
|
|
1070
|
+
if (extension.thicknessFactor !== void 0) {
|
|
1071
|
+
parsedMaterial.uniforms.thicknessFactor = extension.thicknessFactor;
|
|
1072
|
+
}
|
|
1073
|
+
if (extension.thicknessTexture) {
|
|
1074
|
+
addTexture(device, extension.thicknessTexture, "pbr_thicknessSampler", parsedMaterial, {
|
|
1075
|
+
featureOptions: {
|
|
1076
|
+
define: "HAS_THICKNESSMAP"
|
|
1077
|
+
},
|
|
1078
|
+
gltf
|
|
1079
|
+
});
|
|
1080
|
+
}
|
|
1081
|
+
if (extension.attenuationDistance !== void 0) {
|
|
1082
|
+
parsedMaterial.uniforms.attenuationDistance = extension.attenuationDistance;
|
|
1083
|
+
}
|
|
1084
|
+
if (extension.attenuationColor) {
|
|
1085
|
+
parsedMaterial.uniforms.attenuationColor = extension.attenuationColor;
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
function parseClearcoatExtension(device, extension, parsedMaterial, gltf) {
|
|
1089
|
+
if (!extension) {
|
|
1090
|
+
return;
|
|
1091
|
+
}
|
|
1092
|
+
if (extension.clearcoatFactor !== void 0) {
|
|
1093
|
+
parsedMaterial.uniforms.clearcoatFactor = extension.clearcoatFactor;
|
|
1094
|
+
}
|
|
1095
|
+
if (extension.clearcoatRoughnessFactor !== void 0) {
|
|
1096
|
+
parsedMaterial.uniforms.clearcoatRoughnessFactor = extension.clearcoatRoughnessFactor;
|
|
1097
|
+
}
|
|
1098
|
+
if (extension.clearcoatTexture) {
|
|
1099
|
+
addTexture(device, extension.clearcoatTexture, "pbr_clearcoatSampler", parsedMaterial, {
|
|
1100
|
+
featureOptions: {
|
|
1101
|
+
define: "HAS_CLEARCOATMAP",
|
|
1102
|
+
enabledUniformName: "clearcoatMapEnabled"
|
|
1103
|
+
},
|
|
1104
|
+
gltf
|
|
1105
|
+
});
|
|
1106
|
+
}
|
|
1107
|
+
if (extension.clearcoatRoughnessTexture) {
|
|
1108
|
+
addTexture(
|
|
1109
|
+
device,
|
|
1110
|
+
extension.clearcoatRoughnessTexture,
|
|
1111
|
+
"pbr_clearcoatRoughnessSampler",
|
|
1112
|
+
parsedMaterial,
|
|
1113
|
+
{
|
|
1114
|
+
featureOptions: {
|
|
1115
|
+
define: "HAS_CLEARCOATROUGHNESSMAP",
|
|
1116
|
+
enabledUniformName: "clearcoatRoughnessMapEnabled"
|
|
1117
|
+
},
|
|
1118
|
+
gltf
|
|
1119
|
+
}
|
|
1120
|
+
);
|
|
1121
|
+
}
|
|
1122
|
+
if (extension.clearcoatNormalTexture) {
|
|
1123
|
+
addTexture(
|
|
1124
|
+
device,
|
|
1125
|
+
extension.clearcoatNormalTexture,
|
|
1126
|
+
"pbr_clearcoatNormalSampler",
|
|
1127
|
+
parsedMaterial,
|
|
1128
|
+
{
|
|
1129
|
+
featureOptions: {
|
|
1130
|
+
define: "HAS_CLEARCOATNORMALMAP"
|
|
1131
|
+
},
|
|
1132
|
+
gltf
|
|
1133
|
+
}
|
|
1134
|
+
);
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
function parseSheenExtension(device, extension, parsedMaterial, gltf) {
|
|
1138
|
+
if (!extension) {
|
|
1139
|
+
return;
|
|
1140
|
+
}
|
|
1141
|
+
if (extension.sheenColorFactor) {
|
|
1142
|
+
parsedMaterial.uniforms.sheenColorFactor = extension.sheenColorFactor;
|
|
1143
|
+
}
|
|
1144
|
+
if (extension.sheenRoughnessFactor !== void 0) {
|
|
1145
|
+
parsedMaterial.uniforms.sheenRoughnessFactor = extension.sheenRoughnessFactor;
|
|
1146
|
+
}
|
|
1147
|
+
if (extension.sheenColorTexture) {
|
|
1148
|
+
addTexture(device, extension.sheenColorTexture, "pbr_sheenColorSampler", parsedMaterial, {
|
|
1149
|
+
featureOptions: {
|
|
1150
|
+
define: "HAS_SHEENCOLORMAP",
|
|
1151
|
+
enabledUniformName: "sheenColorMapEnabled"
|
|
1152
|
+
},
|
|
1153
|
+
gltf
|
|
1154
|
+
});
|
|
1155
|
+
}
|
|
1156
|
+
if (extension.sheenRoughnessTexture) {
|
|
1157
|
+
addTexture(
|
|
1158
|
+
device,
|
|
1159
|
+
extension.sheenRoughnessTexture,
|
|
1160
|
+
"pbr_sheenRoughnessSampler",
|
|
1161
|
+
parsedMaterial,
|
|
1162
|
+
{
|
|
1163
|
+
featureOptions: {
|
|
1164
|
+
define: "HAS_SHEENROUGHNESSMAP",
|
|
1165
|
+
enabledUniformName: "sheenRoughnessMapEnabled"
|
|
1166
|
+
},
|
|
1167
|
+
gltf
|
|
1168
|
+
}
|
|
1169
|
+
);
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
function parseIridescenceExtension(device, extension, parsedMaterial, gltf) {
|
|
1173
|
+
if (!extension) {
|
|
1174
|
+
return;
|
|
1175
|
+
}
|
|
1176
|
+
if (extension.iridescenceFactor !== void 0) {
|
|
1177
|
+
parsedMaterial.uniforms.iridescenceFactor = extension.iridescenceFactor;
|
|
1178
|
+
}
|
|
1179
|
+
if (extension.iridescenceIor !== void 0) {
|
|
1180
|
+
parsedMaterial.uniforms.iridescenceIor = extension.iridescenceIor;
|
|
1181
|
+
}
|
|
1182
|
+
if (extension.iridescenceThicknessMinimum !== void 0 || extension.iridescenceThicknessMaximum !== void 0) {
|
|
1183
|
+
parsedMaterial.uniforms.iridescenceThicknessRange = [
|
|
1184
|
+
extension.iridescenceThicknessMinimum ?? 100,
|
|
1185
|
+
extension.iridescenceThicknessMaximum ?? 400
|
|
1186
|
+
];
|
|
1187
|
+
}
|
|
1188
|
+
if (extension.iridescenceTexture) {
|
|
1189
|
+
addTexture(device, extension.iridescenceTexture, "pbr_iridescenceSampler", parsedMaterial, {
|
|
1190
|
+
featureOptions: {
|
|
1191
|
+
define: "HAS_IRIDESCENCEMAP",
|
|
1192
|
+
enabledUniformName: "iridescenceMapEnabled"
|
|
1193
|
+
},
|
|
1194
|
+
gltf
|
|
1195
|
+
});
|
|
1196
|
+
}
|
|
1197
|
+
if (extension.iridescenceThicknessTexture) {
|
|
1198
|
+
addTexture(
|
|
1199
|
+
device,
|
|
1200
|
+
extension.iridescenceThicknessTexture,
|
|
1201
|
+
"pbr_iridescenceThicknessSampler",
|
|
1202
|
+
parsedMaterial,
|
|
1203
|
+
{
|
|
1204
|
+
featureOptions: {
|
|
1205
|
+
define: "HAS_IRIDESCENCETHICKNESSMAP"
|
|
1206
|
+
},
|
|
1207
|
+
gltf
|
|
1208
|
+
}
|
|
1209
|
+
);
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
function parseAnisotropyExtension(device, extension, parsedMaterial, gltf) {
|
|
1213
|
+
if (!extension) {
|
|
1214
|
+
return;
|
|
1215
|
+
}
|
|
1216
|
+
if (extension.anisotropyStrength !== void 0) {
|
|
1217
|
+
parsedMaterial.uniforms.anisotropyStrength = extension.anisotropyStrength;
|
|
1218
|
+
}
|
|
1219
|
+
if (extension.anisotropyRotation !== void 0) {
|
|
1220
|
+
parsedMaterial.uniforms.anisotropyRotation = extension.anisotropyRotation;
|
|
1221
|
+
}
|
|
1222
|
+
if (extension.anisotropyTexture) {
|
|
1223
|
+
addTexture(device, extension.anisotropyTexture, "pbr_anisotropySampler", parsedMaterial, {
|
|
1224
|
+
featureOptions: {
|
|
1225
|
+
define: "HAS_ANISOTROPYMAP",
|
|
1226
|
+
enabledUniformName: "anisotropyMapEnabled"
|
|
1227
|
+
},
|
|
1228
|
+
gltf
|
|
1229
|
+
});
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
function parseEmissiveStrengthExtension(extension, parsedMaterial) {
|
|
1233
|
+
if (extension?.emissiveStrength !== void 0) {
|
|
1234
|
+
parsedMaterial.uniforms.emissiveStrength = extension.emissiveStrength;
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
function addTexture(device, gltfTexture, uniformName, parsedMaterial, textureParseOptions = {}) {
|
|
1238
|
+
const { featureOptions = {}, gltf } = textureParseOptions;
|
|
1239
|
+
const { define, enabledUniformName } = featureOptions;
|
|
1240
|
+
const resolvedTextureInfo = resolveTextureInfo(gltfTexture, gltf);
|
|
1241
|
+
const image = resolvedTextureInfo.texture?.source?.image;
|
|
1242
|
+
if (!image) {
|
|
1243
|
+
import_core.log.warn(`Skipping unresolved glTF texture for ${String(uniformName)}`)();
|
|
1244
|
+
return;
|
|
881
1245
|
}
|
|
882
1246
|
const gltfSampler = {
|
|
883
1247
|
wrapS: 10497,
|
|
@@ -888,18 +1252,150 @@ var __exports__ = (() => {
|
|
|
888
1252
|
// default LINEAR filtering
|
|
889
1253
|
magFilter: 9729,
|
|
890
1254
|
// default LINEAR filtering
|
|
891
|
-
...
|
|
1255
|
+
...resolvedTextureInfo?.texture?.sampler
|
|
892
1256
|
};
|
|
893
|
-
const
|
|
894
|
-
id:
|
|
895
|
-
sampler: convertSampler(gltfSampler)
|
|
896
|
-
|
|
897
|
-
|
|
1257
|
+
const baseOptions = {
|
|
1258
|
+
id: resolvedTextureInfo.uniformName || resolvedTextureInfo.id,
|
|
1259
|
+
sampler: convertSampler(gltfSampler)
|
|
1260
|
+
};
|
|
1261
|
+
let texture;
|
|
1262
|
+
if (image.compressed) {
|
|
1263
|
+
texture = createCompressedTexture(device, image, baseOptions);
|
|
1264
|
+
} else {
|
|
1265
|
+
const { width, height } = device.getExternalImageSize(image);
|
|
1266
|
+
texture = device.createTexture({
|
|
1267
|
+
...baseOptions,
|
|
1268
|
+
width,
|
|
1269
|
+
height,
|
|
1270
|
+
data: image
|
|
1271
|
+
});
|
|
1272
|
+
}
|
|
898
1273
|
parsedMaterial.bindings[uniformName] = texture;
|
|
899
1274
|
if (define)
|
|
900
1275
|
parsedMaterial.defines[define] = true;
|
|
1276
|
+
if (enabledUniformName) {
|
|
1277
|
+
parsedMaterial.uniforms[enabledUniformName] = true;
|
|
1278
|
+
}
|
|
901
1279
|
parsedMaterial.generatedTextures.push(texture);
|
|
902
1280
|
}
|
|
1281
|
+
function resolveTextureInfo(gltfTexture, gltf) {
|
|
1282
|
+
if (gltfTexture.texture || gltfTexture.index === void 0 || !gltf?.textures) {
|
|
1283
|
+
return gltfTexture;
|
|
1284
|
+
}
|
|
1285
|
+
const resolvedTextureEntry = gltf.textures[gltfTexture.index];
|
|
1286
|
+
if (!resolvedTextureEntry) {
|
|
1287
|
+
return gltfTexture;
|
|
1288
|
+
}
|
|
1289
|
+
if ("texture" in resolvedTextureEntry && resolvedTextureEntry.texture) {
|
|
1290
|
+
return {
|
|
1291
|
+
...resolvedTextureEntry,
|
|
1292
|
+
...gltfTexture,
|
|
1293
|
+
texture: resolvedTextureEntry.texture
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1296
|
+
if (!("source" in resolvedTextureEntry)) {
|
|
1297
|
+
return gltfTexture;
|
|
1298
|
+
}
|
|
1299
|
+
return {
|
|
1300
|
+
...gltfTexture,
|
|
1301
|
+
texture: resolvedTextureEntry
|
|
1302
|
+
};
|
|
1303
|
+
}
|
|
1304
|
+
function createCompressedTextureFallback(device, baseOptions) {
|
|
1305
|
+
return device.createTexture({
|
|
1306
|
+
...baseOptions,
|
|
1307
|
+
format: "rgba8unorm",
|
|
1308
|
+
width: 1,
|
|
1309
|
+
height: 1,
|
|
1310
|
+
mipLevels: 1
|
|
1311
|
+
});
|
|
1312
|
+
}
|
|
1313
|
+
function resolveCompressedTextureFormat(level) {
|
|
1314
|
+
return level.textureFormat;
|
|
1315
|
+
}
|
|
1316
|
+
function getMaxCompressedMipLevels(baseWidth, baseHeight, format) {
|
|
1317
|
+
const { blockWidth = 1, blockHeight = 1 } = import_core.textureFormatDecoder.getInfo(format);
|
|
1318
|
+
let count = 1;
|
|
1319
|
+
for (let i = 1; ; i++) {
|
|
1320
|
+
const w = Math.max(1, baseWidth >> i);
|
|
1321
|
+
const h = Math.max(1, baseHeight >> i);
|
|
1322
|
+
if (w < blockWidth || h < blockHeight)
|
|
1323
|
+
break;
|
|
1324
|
+
count++;
|
|
1325
|
+
}
|
|
1326
|
+
return count;
|
|
1327
|
+
}
|
|
1328
|
+
function createCompressedTexture(device, image, baseOptions) {
|
|
1329
|
+
let levels;
|
|
1330
|
+
if (Array.isArray(image.data) && image.data[0]?.data) {
|
|
1331
|
+
levels = image.data;
|
|
1332
|
+
} else if ("mipmaps" in image && Array.isArray(image.mipmaps)) {
|
|
1333
|
+
levels = image.mipmaps;
|
|
1334
|
+
} else {
|
|
1335
|
+
levels = [];
|
|
1336
|
+
}
|
|
1337
|
+
if (levels.length === 0 || !levels[0]?.data) {
|
|
1338
|
+
import_core.log.warn(
|
|
1339
|
+
"createCompressedTexture: compressed image has no valid mip levels, creating fallback"
|
|
1340
|
+
)();
|
|
1341
|
+
return createCompressedTextureFallback(device, baseOptions);
|
|
1342
|
+
}
|
|
1343
|
+
const baseLevel = levels[0];
|
|
1344
|
+
const baseWidth = baseLevel.width ?? image.width ?? 0;
|
|
1345
|
+
const baseHeight = baseLevel.height ?? image.height ?? 0;
|
|
1346
|
+
if (baseWidth <= 0 || baseHeight <= 0) {
|
|
1347
|
+
import_core.log.warn("createCompressedTexture: base level has invalid dimensions, creating fallback")();
|
|
1348
|
+
return createCompressedTextureFallback(device, baseOptions);
|
|
1349
|
+
}
|
|
1350
|
+
const format = resolveCompressedTextureFormat(baseLevel);
|
|
1351
|
+
if (!format) {
|
|
1352
|
+
import_core.log.warn("createCompressedTexture: compressed image has no textureFormat, creating fallback")();
|
|
1353
|
+
return createCompressedTextureFallback(device, baseOptions);
|
|
1354
|
+
}
|
|
1355
|
+
const maxMipLevels = getMaxCompressedMipLevels(baseWidth, baseHeight, format);
|
|
1356
|
+
const levelLimit = Math.min(levels.length, maxMipLevels);
|
|
1357
|
+
let validLevelCount = 1;
|
|
1358
|
+
for (let i = 1; i < levelLimit; i++) {
|
|
1359
|
+
const level = levels[i];
|
|
1360
|
+
if (!level.data || level.width <= 0 || level.height <= 0) {
|
|
1361
|
+
import_core.log.warn(`createCompressedTexture: mip level ${i} has invalid data/dimensions, truncating`)();
|
|
1362
|
+
break;
|
|
1363
|
+
}
|
|
1364
|
+
const levelFormat = resolveCompressedTextureFormat(level);
|
|
1365
|
+
if (levelFormat && levelFormat !== format) {
|
|
1366
|
+
import_core.log.warn(
|
|
1367
|
+
`createCompressedTexture: mip level ${i} format '${levelFormat}' differs from base '${format}', truncating`
|
|
1368
|
+
)();
|
|
1369
|
+
break;
|
|
1370
|
+
}
|
|
1371
|
+
const expectedW = Math.max(1, baseWidth >> i);
|
|
1372
|
+
const expectedH = Math.max(1, baseHeight >> i);
|
|
1373
|
+
if (level.width !== expectedW || level.height !== expectedH) {
|
|
1374
|
+
import_core.log.warn(
|
|
1375
|
+
`createCompressedTexture: mip level ${i} dimensions ${level.width}x${level.height} don't match expected ${expectedW}x${expectedH}, truncating`
|
|
1376
|
+
)();
|
|
1377
|
+
break;
|
|
1378
|
+
}
|
|
1379
|
+
validLevelCount++;
|
|
1380
|
+
}
|
|
1381
|
+
const texture = device.createTexture({
|
|
1382
|
+
...baseOptions,
|
|
1383
|
+
format,
|
|
1384
|
+
usage: import_core.Texture.TEXTURE | import_core.Texture.COPY_DST,
|
|
1385
|
+
width: baseWidth,
|
|
1386
|
+
height: baseHeight,
|
|
1387
|
+
mipLevels: validLevelCount,
|
|
1388
|
+
data: baseLevel.data
|
|
1389
|
+
});
|
|
1390
|
+
for (let i = 1; i < validLevelCount; i++) {
|
|
1391
|
+
texture.writeData(levels[i].data, {
|
|
1392
|
+
width: levels[i].width,
|
|
1393
|
+
height: levels[i].height,
|
|
1394
|
+
mipLevel: i
|
|
1395
|
+
});
|
|
1396
|
+
}
|
|
1397
|
+
return texture;
|
|
1398
|
+
}
|
|
903
1399
|
|
|
904
1400
|
// ../../node_modules/@math.gl/core/dist/lib/common.js
|
|
905
1401
|
var RADIANS_TO_DEGREES = 1 / Math.PI * 180;
|
|
@@ -3473,33 +3969,42 @@ var __exports__ = (() => {
|
|
|
3473
3969
|
};
|
|
3474
3970
|
|
|
3475
3971
|
// src/parsers/parse-gltf-lights.ts
|
|
3972
|
+
var GLTF_COLOR_FACTOR = 255;
|
|
3476
3973
|
function parseGLTFLights(gltf) {
|
|
3477
|
-
const lightDefs =
|
|
3974
|
+
const lightDefs = (
|
|
3975
|
+
// `postProcessGLTF()` moves KHR_lights_punctual into `gltf.lights`.
|
|
3976
|
+
gltf.lights || gltf.extensions?.["KHR_lights_punctual"]?.["lights"]
|
|
3977
|
+
);
|
|
3478
3978
|
if (!lightDefs || !Array.isArray(lightDefs) || lightDefs.length === 0) {
|
|
3479
3979
|
return [];
|
|
3480
3980
|
}
|
|
3481
3981
|
const lights = [];
|
|
3982
|
+
const parentNodeById = createParentNodeMap(gltf.nodes || []);
|
|
3983
|
+
const worldMatrixByNodeId = /* @__PURE__ */ new Map();
|
|
3482
3984
|
for (const node of gltf.nodes || []) {
|
|
3483
|
-
const
|
|
3484
|
-
if (
|
|
3985
|
+
const lightIndex = node.light ?? node.extensions?.KHR_lights_punctual?.light;
|
|
3986
|
+
if (typeof lightIndex !== "number") {
|
|
3485
3987
|
continue;
|
|
3486
3988
|
}
|
|
3487
|
-
const gltfLight = lightDefs[
|
|
3989
|
+
const gltfLight = lightDefs[lightIndex];
|
|
3488
3990
|
if (!gltfLight) {
|
|
3489
3991
|
continue;
|
|
3490
3992
|
}
|
|
3491
|
-
const color =
|
|
3993
|
+
const color = normalizeGLTFLightColor(
|
|
3994
|
+
gltfLight.color || [1, 1, 1]
|
|
3995
|
+
);
|
|
3492
3996
|
const intensity = gltfLight.intensity ?? 1;
|
|
3493
3997
|
const range = gltfLight.range;
|
|
3998
|
+
const worldMatrix = getNodeWorldMatrix(node, parentNodeById, worldMatrixByNodeId);
|
|
3494
3999
|
switch (gltfLight.type) {
|
|
3495
4000
|
case "directional":
|
|
3496
|
-
lights.push(parseDirectionalLight(
|
|
4001
|
+
lights.push(parseDirectionalLight(worldMatrix, color, intensity));
|
|
3497
4002
|
break;
|
|
3498
4003
|
case "point":
|
|
3499
|
-
lights.push(parsePointLight(
|
|
4004
|
+
lights.push(parsePointLight(worldMatrix, color, intensity, range));
|
|
3500
4005
|
break;
|
|
3501
4006
|
case "spot":
|
|
3502
|
-
lights.push(
|
|
4007
|
+
lights.push(parseSpotLight(worldMatrix, color, intensity, range, gltfLight.spot));
|
|
3503
4008
|
break;
|
|
3504
4009
|
default:
|
|
3505
4010
|
break;
|
|
@@ -3507,8 +4012,11 @@ var __exports__ = (() => {
|
|
|
3507
4012
|
}
|
|
3508
4013
|
return lights;
|
|
3509
4014
|
}
|
|
3510
|
-
function
|
|
3511
|
-
|
|
4015
|
+
function normalizeGLTFLightColor(color) {
|
|
4016
|
+
return color.map((component) => component * GLTF_COLOR_FACTOR);
|
|
4017
|
+
}
|
|
4018
|
+
function parsePointLight(worldMatrix, color, intensity, range) {
|
|
4019
|
+
const position = getLightPosition(worldMatrix);
|
|
3512
4020
|
let attenuation = [1, 0, 0];
|
|
3513
4021
|
if (range !== void 0 && range > 0) {
|
|
3514
4022
|
attenuation = [1, 0, 1 / (range * range)];
|
|
@@ -3521,12 +4029,8 @@ var __exports__ = (() => {
|
|
|
3521
4029
|
attenuation
|
|
3522
4030
|
};
|
|
3523
4031
|
}
|
|
3524
|
-
function parseDirectionalLight(
|
|
3525
|
-
|
|
3526
|
-
if (node.rotation) {
|
|
3527
|
-
const orientation = new Matrix4().fromQuaternion(node.rotation);
|
|
3528
|
-
direction = orientation.transformDirection([0, 0, -1]);
|
|
3529
|
-
}
|
|
4032
|
+
function parseDirectionalLight(worldMatrix, color, intensity) {
|
|
4033
|
+
const direction = getLightDirection(worldMatrix);
|
|
3530
4034
|
return {
|
|
3531
4035
|
type: "directional",
|
|
3532
4036
|
direction,
|
|
@@ -3534,9 +4038,72 @@ var __exports__ = (() => {
|
|
|
3534
4038
|
intensity
|
|
3535
4039
|
};
|
|
3536
4040
|
}
|
|
4041
|
+
function parseSpotLight(worldMatrix, color, intensity, range, spot = {}) {
|
|
4042
|
+
const position = getLightPosition(worldMatrix);
|
|
4043
|
+
const direction = getLightDirection(worldMatrix);
|
|
4044
|
+
let attenuation = [1, 0, 0];
|
|
4045
|
+
if (range !== void 0 && range > 0) {
|
|
4046
|
+
attenuation = [1, 0, 1 / (range * range)];
|
|
4047
|
+
}
|
|
4048
|
+
return {
|
|
4049
|
+
type: "spot",
|
|
4050
|
+
position,
|
|
4051
|
+
direction,
|
|
4052
|
+
color,
|
|
4053
|
+
intensity,
|
|
4054
|
+
attenuation,
|
|
4055
|
+
innerConeAngle: spot.innerConeAngle ?? 0,
|
|
4056
|
+
outerConeAngle: spot.outerConeAngle ?? Math.PI / 4
|
|
4057
|
+
};
|
|
4058
|
+
}
|
|
4059
|
+
function createParentNodeMap(nodes) {
|
|
4060
|
+
const parentNodeById = /* @__PURE__ */ new Map();
|
|
4061
|
+
for (const node of nodes) {
|
|
4062
|
+
for (const childNode of node.children || []) {
|
|
4063
|
+
parentNodeById.set(childNode.id, node);
|
|
4064
|
+
}
|
|
4065
|
+
}
|
|
4066
|
+
return parentNodeById;
|
|
4067
|
+
}
|
|
4068
|
+
function getNodeWorldMatrix(node, parentNodeById, worldMatrixByNodeId) {
|
|
4069
|
+
const cachedWorldMatrix = worldMatrixByNodeId.get(node.id);
|
|
4070
|
+
if (cachedWorldMatrix) {
|
|
4071
|
+
return cachedWorldMatrix;
|
|
4072
|
+
}
|
|
4073
|
+
const localMatrix = getNodeLocalMatrix(node);
|
|
4074
|
+
const parentNode = parentNodeById.get(node.id);
|
|
4075
|
+
const worldMatrix = parentNode ? new Matrix4(
|
|
4076
|
+
getNodeWorldMatrix(parentNode, parentNodeById, worldMatrixByNodeId)
|
|
4077
|
+
).multiplyRight(localMatrix) : localMatrix;
|
|
4078
|
+
worldMatrixByNodeId.set(node.id, worldMatrix);
|
|
4079
|
+
return worldMatrix;
|
|
4080
|
+
}
|
|
4081
|
+
function getNodeLocalMatrix(node) {
|
|
4082
|
+
if (node.matrix) {
|
|
4083
|
+
return new Matrix4(node.matrix);
|
|
4084
|
+
}
|
|
4085
|
+
const matrix = new Matrix4();
|
|
4086
|
+
if (node.translation) {
|
|
4087
|
+
matrix.translate(node.translation);
|
|
4088
|
+
}
|
|
4089
|
+
if (node.rotation) {
|
|
4090
|
+
matrix.multiplyRight(new Matrix4().fromQuaternion(node.rotation));
|
|
4091
|
+
}
|
|
4092
|
+
if (node.scale) {
|
|
4093
|
+
matrix.scale(node.scale);
|
|
4094
|
+
}
|
|
4095
|
+
return matrix;
|
|
4096
|
+
}
|
|
4097
|
+
function getLightPosition(worldMatrix) {
|
|
4098
|
+
return worldMatrix.transformAsPoint([0, 0, 0]);
|
|
4099
|
+
}
|
|
4100
|
+
function getLightDirection(worldMatrix) {
|
|
4101
|
+
return worldMatrix.transformDirection([0, 0, -1]);
|
|
4102
|
+
}
|
|
3537
4103
|
|
|
3538
4104
|
// src/parsers/parse-gltf.ts
|
|
3539
|
-
var
|
|
4105
|
+
var import_engine4 = __toESM(require_engine(), 1);
|
|
4106
|
+
var import_shadertools2 = __toESM(require_shadertools(), 1);
|
|
3540
4107
|
|
|
3541
4108
|
// src/webgl-to-webgpu/convert-webgl-topology.ts
|
|
3542
4109
|
function convertGLDrawModeToTopology(drawMode) {
|
|
@@ -3558,55 +4125,94 @@ var __exports__ = (() => {
|
|
|
3558
4125
|
|
|
3559
4126
|
// src/gltf/create-gltf-model.ts
|
|
3560
4127
|
var import_core3 = __toESM(require_core(), 1);
|
|
3561
|
-
var import_shadertools = __toESM(require_shadertools(), 1);
|
|
3562
4128
|
var import_engine2 = __toESM(require_engine(), 1);
|
|
4129
|
+
var import_shadertools = __toESM(require_shadertools(), 1);
|
|
4130
|
+
var import_engine3 = __toESM(require_engine(), 1);
|
|
3563
4131
|
var SHADER = (
|
|
3564
4132
|
/* WGSL */
|
|
3565
4133
|
`
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
4134
|
+
struct VertexInputs {
|
|
4135
|
+
@location(0) positions: vec3f,
|
|
4136
|
+
#ifdef HAS_NORMALS
|
|
4137
|
+
@location(1) normals: vec3f,
|
|
4138
|
+
#endif
|
|
4139
|
+
#ifdef HAS_TANGENTS
|
|
4140
|
+
@location(2) TANGENT: vec4f,
|
|
4141
|
+
#endif
|
|
4142
|
+
#ifdef HAS_UV
|
|
4143
|
+
@location(3) texCoords: vec2f,
|
|
4144
|
+
#endif
|
|
4145
|
+
#ifdef HAS_SKIN
|
|
4146
|
+
@location(4) JOINTS_0: vec4u,
|
|
4147
|
+
@location(5) WEIGHTS_0: vec4f,
|
|
4148
|
+
#endif
|
|
4149
|
+
};
|
|
3575
4150
|
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
4151
|
+
struct FragmentInputs {
|
|
4152
|
+
@builtin(position) position: vec4f,
|
|
4153
|
+
@location(0) pbrPosition: vec3f,
|
|
4154
|
+
@location(1) pbrUV: vec2f,
|
|
4155
|
+
@location(2) pbrNormal: vec3f,
|
|
4156
|
+
#ifdef HAS_TANGENTS
|
|
4157
|
+
@location(3) pbrTangent: vec4f,
|
|
4158
|
+
#endif
|
|
4159
|
+
};
|
|
3580
4160
|
|
|
3581
4161
|
@vertex
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
4162
|
+
fn vertexMain(inputs: VertexInputs) -> FragmentInputs {
|
|
4163
|
+
var outputs: FragmentInputs;
|
|
4164
|
+
var position = vec4f(inputs.positions, 1.0);
|
|
4165
|
+
var normal = vec3f(0.0, 0.0, 1.0);
|
|
4166
|
+
var tangent = vec4f(1.0, 0.0, 0.0, 1.0);
|
|
4167
|
+
var uv = vec2f(0.0, 0.0);
|
|
3586
4168
|
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
4169
|
+
#ifdef HAS_NORMALS
|
|
4170
|
+
normal = inputs.normals;
|
|
4171
|
+
#endif
|
|
4172
|
+
#ifdef HAS_UV
|
|
4173
|
+
uv = inputs.texCoords;
|
|
4174
|
+
#endif
|
|
4175
|
+
#ifdef HAS_TANGENTS
|
|
4176
|
+
tangent = inputs.TANGENT;
|
|
4177
|
+
#endif
|
|
4178
|
+
#ifdef HAS_SKIN
|
|
4179
|
+
let skinMatrix = getSkinMatrix(inputs.WEIGHTS_0, inputs.JOINTS_0);
|
|
4180
|
+
position = skinMatrix * position;
|
|
4181
|
+
normal = normalize((skinMatrix * vec4f(normal, 0.0)).xyz);
|
|
4182
|
+
#ifdef HAS_TANGENTS
|
|
4183
|
+
tangent = vec4f(normalize((skinMatrix * vec4f(tangent.xyz, 0.0)).xyz), tangent.w);
|
|
4184
|
+
#endif
|
|
4185
|
+
#endif
|
|
3590
4186
|
|
|
3591
|
-
|
|
3592
|
-
_TANGENT = TANGENT;
|
|
3593
|
-
#endif
|
|
4187
|
+
let worldPosition = pbrProjection.modelMatrix * position;
|
|
3594
4188
|
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
4189
|
+
#ifdef HAS_NORMALS
|
|
4190
|
+
normal = normalize((pbrProjection.normalMatrix * vec4f(normal, 0.0)).xyz);
|
|
4191
|
+
#endif
|
|
4192
|
+
#ifdef HAS_TANGENTS
|
|
4193
|
+
let worldTangent = normalize((pbrProjection.modelMatrix * vec4f(tangent.xyz, 0.0)).xyz);
|
|
4194
|
+
outputs.pbrTangent = vec4f(worldTangent, tangent.w);
|
|
4195
|
+
#endif
|
|
3598
4196
|
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
4197
|
+
outputs.position = pbrProjection.modelViewProjectionMatrix * position;
|
|
4198
|
+
outputs.pbrPosition = worldPosition.xyz / worldPosition.w;
|
|
4199
|
+
outputs.pbrUV = uv;
|
|
4200
|
+
outputs.pbrNormal = normal;
|
|
4201
|
+
return outputs;
|
|
4202
|
+
}
|
|
3602
4203
|
|
|
3603
4204
|
@fragment
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
4205
|
+
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
4206
|
+
fragmentInputs.pbr_vPosition = inputs.pbrPosition;
|
|
4207
|
+
fragmentInputs.pbr_vUV = inputs.pbrUV;
|
|
4208
|
+
fragmentInputs.pbr_vNormal = inputs.pbrNormal;
|
|
4209
|
+
#ifdef HAS_TANGENTS
|
|
4210
|
+
let tangent = normalize(inputs.pbrTangent.xyz);
|
|
4211
|
+
let bitangent = normalize(cross(inputs.pbrNormal, tangent)) * inputs.pbrTangent.w;
|
|
4212
|
+
fragmentInputs.pbr_vTBN = mat3x3f(tangent, bitangent, inputs.pbrNormal);
|
|
4213
|
+
#endif
|
|
4214
|
+
return pbr_filterColor(vec4f(1.0));
|
|
4215
|
+
}
|
|
3610
4216
|
`
|
|
3611
4217
|
);
|
|
3612
4218
|
var vs = (
|
|
@@ -3630,6 +4236,11 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3630
4236
|
in vec2 texCoords;
|
|
3631
4237
|
#endif
|
|
3632
4238
|
|
|
4239
|
+
#ifdef HAS_SKIN
|
|
4240
|
+
in uvec4 JOINTS_0;
|
|
4241
|
+
in vec4 WEIGHTS_0;
|
|
4242
|
+
#endif
|
|
4243
|
+
|
|
3633
4244
|
void main(void) {
|
|
3634
4245
|
vec4 _NORMAL = vec4(0.);
|
|
3635
4246
|
vec4 _TANGENT = vec4(0.);
|
|
@@ -3647,8 +4258,17 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3647
4258
|
_TEXCOORD_0 = texCoords;
|
|
3648
4259
|
#endif
|
|
3649
4260
|
|
|
3650
|
-
|
|
3651
|
-
|
|
4261
|
+
vec4 pos = positions;
|
|
4262
|
+
|
|
4263
|
+
#ifdef HAS_SKIN
|
|
4264
|
+
mat4 skinMat = getSkinMatrix(WEIGHTS_0, JOINTS_0);
|
|
4265
|
+
pos = skinMat * pos;
|
|
4266
|
+
_NORMAL = skinMat * _NORMAL;
|
|
4267
|
+
_TANGENT = vec4((skinMat * vec4(_TANGENT.xyz, 0.)).xyz, _TANGENT.w);
|
|
4268
|
+
#endif
|
|
4269
|
+
|
|
4270
|
+
pbr_setPositionNormalTangentUV(pos, _NORMAL, _TANGENT, _TEXCOORD_0);
|
|
4271
|
+
gl_Position = pbrProjection.modelViewProjectionMatrix * pos;
|
|
3652
4272
|
}
|
|
3653
4273
|
`
|
|
3654
4274
|
);
|
|
@@ -3663,6 +4283,25 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3663
4283
|
}
|
|
3664
4284
|
`
|
|
3665
4285
|
);
|
|
4286
|
+
function createGLTFMaterial(device, options) {
|
|
4287
|
+
const materialFactory = options.materialFactory || new import_engine3.MaterialFactory(device, { modules: [import_shadertools.pbrMaterial] });
|
|
4288
|
+
const pbrMaterialProps = { ...options.parsedPPBRMaterial.uniforms };
|
|
4289
|
+
delete pbrMaterialProps.camera;
|
|
4290
|
+
const materialBindings = Object.fromEntries(
|
|
4291
|
+
Object.entries({
|
|
4292
|
+
...pbrMaterialProps,
|
|
4293
|
+
...options.parsedPPBRMaterial.bindings
|
|
4294
|
+
}).filter(
|
|
4295
|
+
([name, value]) => materialFactory.ownsBinding(name) && isMaterialBindingResource(value)
|
|
4296
|
+
)
|
|
4297
|
+
);
|
|
4298
|
+
const material = materialFactory.createMaterial({
|
|
4299
|
+
id: options.id,
|
|
4300
|
+
bindings: materialBindings
|
|
4301
|
+
});
|
|
4302
|
+
material.setProps({ pbrMaterial: pbrMaterialProps });
|
|
4303
|
+
return material;
|
|
4304
|
+
}
|
|
3666
4305
|
function createGLTFModel(device, options) {
|
|
3667
4306
|
const { id, geometry, parsedPPBRMaterial, vertexCount, modelOptions = {} } = options;
|
|
3668
4307
|
import_core3.log.info(4, "createGLTFModel defines: ", parsedPPBRMaterial.defines)();
|
|
@@ -3681,20 +4320,57 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3681
4320
|
geometry,
|
|
3682
4321
|
topology: geometry.topology,
|
|
3683
4322
|
vertexCount,
|
|
3684
|
-
modules: [import_shadertools.pbrMaterial],
|
|
4323
|
+
modules: [import_shadertools.pbrMaterial, import_shadertools.skin],
|
|
3685
4324
|
...modelOptions,
|
|
3686
4325
|
defines: { ...parsedPPBRMaterial.defines, ...modelOptions.defines },
|
|
3687
4326
|
parameters: { ...parameters, ...parsedPPBRMaterial.parameters, ...modelOptions.parameters }
|
|
3688
4327
|
};
|
|
3689
|
-
const
|
|
3690
|
-
|
|
4328
|
+
const material = options.material || createGLTFMaterial(device, {
|
|
4329
|
+
id: id ? `${id}-material` : void 0,
|
|
4330
|
+
parsedPPBRMaterial
|
|
4331
|
+
});
|
|
4332
|
+
modelProps.material = material;
|
|
4333
|
+
const model = new import_engine3.Model(device, modelProps);
|
|
4334
|
+
const sceneShaderInputValues = {
|
|
3691
4335
|
...parsedPPBRMaterial.uniforms,
|
|
3692
4336
|
...modelOptions.uniforms,
|
|
3693
4337
|
...parsedPPBRMaterial.bindings,
|
|
3694
4338
|
...modelOptions.bindings
|
|
3695
4339
|
};
|
|
3696
|
-
|
|
3697
|
-
|
|
4340
|
+
const sceneShaderInputProps = getSceneShaderInputProps(
|
|
4341
|
+
model.shaderInputs.getModules(),
|
|
4342
|
+
material,
|
|
4343
|
+
sceneShaderInputValues
|
|
4344
|
+
);
|
|
4345
|
+
model.shaderInputs.setProps(sceneShaderInputProps);
|
|
4346
|
+
return new import_engine3.ModelNode({ managedResources, model });
|
|
4347
|
+
}
|
|
4348
|
+
function isMaterialBindingResource(value) {
|
|
4349
|
+
return value instanceof import_core3.Buffer || value instanceof import_engine2.DynamicTexture || value instanceof import_core3.Sampler || value instanceof import_core3.Texture || value instanceof import_core3.TextureView;
|
|
4350
|
+
}
|
|
4351
|
+
function getSceneShaderInputProps(modules, material, shaderInputValues) {
|
|
4352
|
+
const propertyToModuleNameMap = /* @__PURE__ */ new Map();
|
|
4353
|
+
for (const module of modules) {
|
|
4354
|
+
for (const uniformName of Object.keys(module.uniformTypes || {})) {
|
|
4355
|
+
propertyToModuleNameMap.set(uniformName, module.name);
|
|
4356
|
+
}
|
|
4357
|
+
for (const binding of module.bindingLayout || []) {
|
|
4358
|
+
propertyToModuleNameMap.set(binding.name, module.name);
|
|
4359
|
+
}
|
|
4360
|
+
}
|
|
4361
|
+
const sceneShaderInputProps = {};
|
|
4362
|
+
for (const [propertyName, value] of Object.entries(shaderInputValues)) {
|
|
4363
|
+
if (value === void 0) {
|
|
4364
|
+
continue;
|
|
4365
|
+
}
|
|
4366
|
+
const moduleName = propertyToModuleNameMap.get(propertyName);
|
|
4367
|
+
if (!moduleName || material.ownsModule(moduleName)) {
|
|
4368
|
+
continue;
|
|
4369
|
+
}
|
|
4370
|
+
sceneShaderInputProps[moduleName] ||= {};
|
|
4371
|
+
sceneShaderInputProps[moduleName][propertyName] = value;
|
|
4372
|
+
}
|
|
4373
|
+
return sceneShaderInputProps;
|
|
3698
4374
|
}
|
|
3699
4375
|
|
|
3700
4376
|
// src/parsers/parse-gltf.ts
|
|
@@ -3705,82 +4381,128 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3705
4381
|
lights: true,
|
|
3706
4382
|
useTangents: false
|
|
3707
4383
|
};
|
|
3708
|
-
function parseGLTF(device, gltf,
|
|
3709
|
-
const
|
|
3710
|
-
const
|
|
3711
|
-
|
|
4384
|
+
function parseGLTF(device, gltf, options = {}) {
|
|
4385
|
+
const combinedOptions = { ...defaultOptions, ...options };
|
|
4386
|
+
const materialFactory = new import_engine4.MaterialFactory(device, { modules: [import_shadertools2.pbrMaterial] });
|
|
4387
|
+
const materials = (gltf.materials || []).map(
|
|
4388
|
+
(gltfMaterial, materialIndex) => createGLTFMaterial(device, {
|
|
4389
|
+
id: getGLTFMaterialId(gltfMaterial, materialIndex),
|
|
4390
|
+
parsedPPBRMaterial: parsePBRMaterial(
|
|
4391
|
+
device,
|
|
4392
|
+
gltfMaterial,
|
|
4393
|
+
{},
|
|
4394
|
+
{
|
|
4395
|
+
...combinedOptions,
|
|
4396
|
+
gltf,
|
|
4397
|
+
validateAttributes: false
|
|
4398
|
+
}
|
|
4399
|
+
),
|
|
4400
|
+
materialFactory
|
|
4401
|
+
})
|
|
3712
4402
|
);
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
const gltfSceneNodes = gltfScene.nodes || [];
|
|
3717
|
-
const nodes = gltfSceneNodes.map((node) => createNode(device, node, gltfNodes, options));
|
|
3718
|
-
const sceneNode = new import_engine3.GroupNode({
|
|
3719
|
-
id: gltfScene.name || gltfScene.id,
|
|
3720
|
-
children: nodes
|
|
4403
|
+
const gltfMaterialIdToMaterialMap = /* @__PURE__ */ new Map();
|
|
4404
|
+
(gltf.materials || []).forEach((gltfMaterial, materialIndex) => {
|
|
4405
|
+
gltfMaterialIdToMaterialMap.set(gltfMaterial.id, materials[materialIndex]);
|
|
3721
4406
|
});
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
4407
|
+
const gltfMeshIdToNodeMap = /* @__PURE__ */ new Map();
|
|
4408
|
+
gltf.meshes.forEach((gltfMesh, idx) => {
|
|
4409
|
+
const newMesh = createNodeForGLTFMesh(
|
|
4410
|
+
device,
|
|
4411
|
+
gltfMesh,
|
|
4412
|
+
gltf,
|
|
4413
|
+
gltfMaterialIdToMaterialMap,
|
|
4414
|
+
combinedOptions
|
|
4415
|
+
);
|
|
4416
|
+
gltfMeshIdToNodeMap.set(gltfMesh.id, newMesh);
|
|
4417
|
+
});
|
|
4418
|
+
const gltfNodeIndexToNodeMap = /* @__PURE__ */ new Map();
|
|
4419
|
+
const gltfNodeIdToNodeMap = /* @__PURE__ */ new Map();
|
|
4420
|
+
gltf.nodes.forEach((gltfNode, idx) => {
|
|
4421
|
+
const newNode = createNodeForGLTFNode(device, gltfNode, combinedOptions);
|
|
4422
|
+
gltfNodeIndexToNodeMap.set(idx, newNode);
|
|
4423
|
+
gltfNodeIdToNodeMap.set(gltfNode.id, newNode);
|
|
4424
|
+
});
|
|
4425
|
+
gltf.nodes.forEach((gltfNode, idx) => {
|
|
4426
|
+
gltfNodeIndexToNodeMap.get(idx).add(
|
|
4427
|
+
(gltfNode.children ?? []).map(({ id }) => {
|
|
4428
|
+
const child = gltfNodeIdToNodeMap.get(id);
|
|
4429
|
+
if (!child)
|
|
4430
|
+
throw new Error(`Cannot find child ${id} of node ${idx}`);
|
|
4431
|
+
return child;
|
|
4432
|
+
})
|
|
4433
|
+
);
|
|
3728
4434
|
if (gltfNode.mesh) {
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
id: gltfNode.name || gltfNode.id,
|
|
3733
|
-
children
|
|
3734
|
-
});
|
|
3735
|
-
if (gltfNode.matrix) {
|
|
3736
|
-
node.setMatrix(gltfNode.matrix);
|
|
3737
|
-
} else {
|
|
3738
|
-
node.matrix.identity();
|
|
3739
|
-
if (gltfNode.translation) {
|
|
3740
|
-
node.matrix.translate(gltfNode.translation);
|
|
3741
|
-
}
|
|
3742
|
-
if (gltfNode.rotation) {
|
|
3743
|
-
const rotationMatrix = new Matrix4().fromQuaternion(gltfNode.rotation);
|
|
3744
|
-
node.matrix.multiplyRight(rotationMatrix);
|
|
3745
|
-
}
|
|
3746
|
-
if (gltfNode.scale) {
|
|
3747
|
-
node.matrix.scale(gltfNode.scale);
|
|
4435
|
+
const mesh = gltfMeshIdToNodeMap.get(gltfNode.mesh.id);
|
|
4436
|
+
if (!mesh) {
|
|
4437
|
+
throw new Error(`Cannot find mesh child ${gltfNode.mesh.id} of node ${idx}`);
|
|
3748
4438
|
}
|
|
4439
|
+
gltfNodeIndexToNodeMap.get(idx).add(mesh);
|
|
3749
4440
|
}
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
if (!gltfMesh._mesh) {
|
|
3758
|
-
const gltfPrimitives = gltfMesh.primitives || [];
|
|
3759
|
-
const primitives = gltfPrimitives.map(
|
|
3760
|
-
(gltfPrimitive, i) => createPrimitive(device, gltfPrimitive, i, gltfMesh, options)
|
|
3761
|
-
);
|
|
3762
|
-
const mesh = new import_engine3.GroupNode({
|
|
3763
|
-
id: gltfMesh.name || gltfMesh.id,
|
|
3764
|
-
children: primitives
|
|
4441
|
+
});
|
|
4442
|
+
const scenes = gltf.scenes.map((gltfScene) => {
|
|
4443
|
+
const children = (gltfScene.nodes || []).map(({ id }) => {
|
|
4444
|
+
const child = gltfNodeIdToNodeMap.get(id);
|
|
4445
|
+
if (!child)
|
|
4446
|
+
throw new Error(`Cannot find child ${id} of scene ${gltfScene.name || gltfScene.id}`);
|
|
4447
|
+
return child;
|
|
3765
4448
|
});
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
4449
|
+
return new import_engine4.GroupNode({
|
|
4450
|
+
id: gltfScene.name || gltfScene.id,
|
|
4451
|
+
children
|
|
4452
|
+
});
|
|
4453
|
+
});
|
|
4454
|
+
return { scenes, materials, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap };
|
|
4455
|
+
}
|
|
4456
|
+
function createNodeForGLTFNode(device, gltfNode, options) {
|
|
4457
|
+
return new import_engine4.GroupNode({
|
|
4458
|
+
id: gltfNode.name || gltfNode.id,
|
|
4459
|
+
children: [],
|
|
4460
|
+
matrix: gltfNode.matrix,
|
|
4461
|
+
position: gltfNode.translation,
|
|
4462
|
+
rotation: gltfNode.rotation,
|
|
4463
|
+
scale: gltfNode.scale
|
|
4464
|
+
});
|
|
3769
4465
|
}
|
|
3770
|
-
function
|
|
3771
|
-
const
|
|
4466
|
+
function createNodeForGLTFMesh(device, gltfMesh, gltf, gltfMaterialIdToMaterialMap, options) {
|
|
4467
|
+
const gltfPrimitives = gltfMesh.primitives || [];
|
|
4468
|
+
const primitives = gltfPrimitives.map(
|
|
4469
|
+
(gltfPrimitive, i) => createNodeForGLTFPrimitive({
|
|
4470
|
+
device,
|
|
4471
|
+
gltfPrimitive,
|
|
4472
|
+
primitiveIndex: i,
|
|
4473
|
+
gltfMesh,
|
|
4474
|
+
gltf,
|
|
4475
|
+
gltfMaterialIdToMaterialMap,
|
|
4476
|
+
options
|
|
4477
|
+
})
|
|
4478
|
+
);
|
|
4479
|
+
const mesh = new import_engine4.GroupNode({
|
|
4480
|
+
id: gltfMesh.name || gltfMesh.id,
|
|
4481
|
+
children: primitives
|
|
4482
|
+
});
|
|
4483
|
+
return mesh;
|
|
4484
|
+
}
|
|
4485
|
+
function createNodeForGLTFPrimitive({
|
|
4486
|
+
device,
|
|
4487
|
+
gltfPrimitive,
|
|
4488
|
+
primitiveIndex,
|
|
4489
|
+
gltfMesh,
|
|
4490
|
+
gltf,
|
|
4491
|
+
gltfMaterialIdToMaterialMap,
|
|
4492
|
+
options
|
|
4493
|
+
}) {
|
|
4494
|
+
const id = gltfPrimitive.name || `${gltfMesh.name || gltfMesh.id}-primitive-${primitiveIndex}`;
|
|
3772
4495
|
const topology = convertGLDrawModeToTopology(gltfPrimitive.mode || 4);
|
|
3773
4496
|
const vertexCount = gltfPrimitive.indices ? gltfPrimitive.indices.count : getVertexCount(gltfPrimitive.attributes);
|
|
3774
4497
|
const geometry = createGeometry(id, gltfPrimitive, topology);
|
|
3775
|
-
const parsedPPBRMaterial = parsePBRMaterial(
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
options
|
|
3780
|
-
);
|
|
4498
|
+
const parsedPPBRMaterial = parsePBRMaterial(device, gltfPrimitive.material, geometry.attributes, {
|
|
4499
|
+
...options,
|
|
4500
|
+
gltf
|
|
4501
|
+
});
|
|
3781
4502
|
const modelNode = createGLTFModel(device, {
|
|
3782
4503
|
id,
|
|
3783
4504
|
geometry: createGeometry(id, gltfPrimitive, topology),
|
|
4505
|
+
material: gltfPrimitive.material ? gltfMaterialIdToMaterialMap.get(gltfPrimitive.material.id) || null : null,
|
|
3784
4506
|
parsedPPBRMaterial,
|
|
3785
4507
|
modelOptions: options.modelOptions,
|
|
3786
4508
|
vertexCount
|
|
@@ -3797,40 +4519,40 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3797
4519
|
const { components, size, value } = attribute;
|
|
3798
4520
|
attributes[attributeName] = { size: size ?? components, value };
|
|
3799
4521
|
}
|
|
3800
|
-
return new
|
|
4522
|
+
return new import_engine4.Geometry({
|
|
3801
4523
|
id,
|
|
3802
4524
|
topology,
|
|
3803
4525
|
indices: gltfPrimitive.indices.value,
|
|
3804
4526
|
attributes
|
|
3805
4527
|
});
|
|
3806
4528
|
}
|
|
4529
|
+
function getGLTFMaterialId(gltfMaterial, materialIndex) {
|
|
4530
|
+
return gltfMaterial.name || gltfMaterial.id || `material-${materialIndex}`;
|
|
4531
|
+
}
|
|
3807
4532
|
|
|
3808
4533
|
// src/gltf/gltf-animator.ts
|
|
3809
|
-
var
|
|
4534
|
+
var import_core6 = __toESM(require_core(), 1);
|
|
3810
4535
|
|
|
3811
4536
|
// src/gltf/animations/interpolate.ts
|
|
3812
|
-
var
|
|
3813
|
-
|
|
4537
|
+
var import_core4 = __toESM(require_core(), 1);
|
|
4538
|
+
function updateTargetPath(target, path, newValue) {
|
|
4539
|
+
switch (path) {
|
|
4540
|
+
case "translation":
|
|
4541
|
+
return target.setPosition(newValue).updateMatrix();
|
|
4542
|
+
case "rotation":
|
|
4543
|
+
return target.setRotation(newValue).updateMatrix();
|
|
4544
|
+
case "scale":
|
|
4545
|
+
return target.setScale(newValue).updateMatrix();
|
|
4546
|
+
default:
|
|
4547
|
+
import_core4.log.warn(`Bad animation path ${path}`)();
|
|
4548
|
+
return null;
|
|
4549
|
+
}
|
|
4550
|
+
}
|
|
3814
4551
|
function interpolate(time, { input, interpolation, output }, target, path) {
|
|
3815
4552
|
const maxTime = input[input.length - 1];
|
|
3816
4553
|
const animationTime = time % maxTime;
|
|
3817
4554
|
const nextIndex = input.findIndex((t) => t >= animationTime);
|
|
3818
4555
|
const previousIndex = Math.max(0, nextIndex - 1);
|
|
3819
|
-
if (!Array.isArray(target[path])) {
|
|
3820
|
-
switch (path) {
|
|
3821
|
-
case "translation":
|
|
3822
|
-
target[path] = [0, 0, 0];
|
|
3823
|
-
break;
|
|
3824
|
-
case "rotation":
|
|
3825
|
-
target[path] = [0, 0, 0, 1];
|
|
3826
|
-
break;
|
|
3827
|
-
case "scale":
|
|
3828
|
-
target[path] = [1, 1, 1];
|
|
3829
|
-
break;
|
|
3830
|
-
default:
|
|
3831
|
-
import_core5.log.warn(`Bad animation path ${path}`)();
|
|
3832
|
-
}
|
|
3833
|
-
}
|
|
3834
4556
|
const previousTime = input[previousIndex];
|
|
3835
4557
|
const nextTime = input[nextIndex];
|
|
3836
4558
|
switch (interpolation) {
|
|
@@ -3840,13 +4562,7 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3840
4562
|
case "LINEAR":
|
|
3841
4563
|
if (nextTime > previousTime) {
|
|
3842
4564
|
const ratio = (animationTime - previousTime) / (nextTime - previousTime);
|
|
3843
|
-
linearInterpolate(
|
|
3844
|
-
target,
|
|
3845
|
-
path,
|
|
3846
|
-
output[previousIndex],
|
|
3847
|
-
output[nextIndex],
|
|
3848
|
-
ratio
|
|
3849
|
-
);
|
|
4565
|
+
linearInterpolate(target, path, output[previousIndex], output[nextIndex], ratio);
|
|
3850
4566
|
}
|
|
3851
4567
|
break;
|
|
3852
4568
|
case "CUBICSPLINE":
|
|
@@ -3861,23 +4577,19 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3861
4577
|
}
|
|
3862
4578
|
break;
|
|
3863
4579
|
default:
|
|
3864
|
-
|
|
4580
|
+
import_core4.log.warn(`Interpolation ${interpolation} not supported`)();
|
|
3865
4581
|
break;
|
|
3866
4582
|
}
|
|
3867
4583
|
}
|
|
3868
4584
|
function linearInterpolate(target, path, start, stop, ratio) {
|
|
3869
|
-
if (!target[path]) {
|
|
3870
|
-
throw new Error();
|
|
3871
|
-
}
|
|
3872
4585
|
if (path === "rotation") {
|
|
3873
|
-
|
|
3874
|
-
for (let i = 0; i < scratchQuaternion.length; i++) {
|
|
3875
|
-
target[path][i] = scratchQuaternion[i];
|
|
3876
|
-
}
|
|
4586
|
+
updateTargetPath(target, path, new Quaternion().slerp({ start, target: stop, ratio }));
|
|
3877
4587
|
} else {
|
|
4588
|
+
const newVal = [];
|
|
3878
4589
|
for (let i = 0; i < start.length; i++) {
|
|
3879
|
-
|
|
4590
|
+
newVal[i] = ratio * stop[i] + (1 - ratio) * start[i];
|
|
3880
4591
|
}
|
|
4592
|
+
updateTargetPath(target, path, newVal);
|
|
3881
4593
|
}
|
|
3882
4594
|
}
|
|
3883
4595
|
function cubicsplineInterpolate(target, path, {
|
|
@@ -3888,83 +4600,83 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3888
4600
|
tDiff,
|
|
3889
4601
|
ratio: t
|
|
3890
4602
|
}) {
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
}
|
|
3894
|
-
for (let i = 0; i < target[path].length; i++) {
|
|
4603
|
+
const newVal = [];
|
|
4604
|
+
for (let i = 0; i < p0.length; i++) {
|
|
3895
4605
|
const m0 = outTangent0[i] * tDiff;
|
|
3896
4606
|
const m1 = inTangent1[i] * tDiff;
|
|
3897
|
-
|
|
4607
|
+
newVal[i] = (2 * Math.pow(t, 3) - 3 * Math.pow(t, 2) + 1) * p0[i] + (Math.pow(t, 3) - 2 * Math.pow(t, 2) + t) * m0 + (-2 * Math.pow(t, 3) + 3 * Math.pow(t, 2)) * p1[i] + (Math.pow(t, 3) - Math.pow(t, 2)) * m1;
|
|
3898
4608
|
}
|
|
4609
|
+
updateTargetPath(target, path, newVal);
|
|
3899
4610
|
}
|
|
3900
4611
|
function stepInterpolate(target, path, value) {
|
|
3901
|
-
|
|
3902
|
-
throw new Error();
|
|
3903
|
-
}
|
|
3904
|
-
for (let i = 0; i < value.length; i++) {
|
|
3905
|
-
target[path][i] = value[i];
|
|
3906
|
-
}
|
|
4612
|
+
updateTargetPath(target, path, value);
|
|
3907
4613
|
}
|
|
3908
4614
|
|
|
3909
4615
|
// src/gltf/gltf-animator.ts
|
|
3910
4616
|
var GLTFSingleAnimator = class {
|
|
4617
|
+
/** Animation definition being played. */
|
|
3911
4618
|
animation;
|
|
4619
|
+
/** Target scenegraph lookup table. */
|
|
4620
|
+
gltfNodeIdToNodeMap;
|
|
4621
|
+
/** Playback start time in seconds. */
|
|
3912
4622
|
startTime = 0;
|
|
4623
|
+
/** Whether playback is currently enabled. */
|
|
3913
4624
|
playing = true;
|
|
4625
|
+
/** Playback speed multiplier. */
|
|
3914
4626
|
speed = 1;
|
|
4627
|
+
/** Creates a single-animation controller. */
|
|
3915
4628
|
constructor(props) {
|
|
3916
4629
|
this.animation = props.animation;
|
|
4630
|
+
this.gltfNodeIdToNodeMap = props.gltfNodeIdToNodeMap;
|
|
3917
4631
|
this.animation.name ||= "unnamed";
|
|
3918
4632
|
Object.assign(this, props);
|
|
3919
4633
|
}
|
|
4634
|
+
/** Advances the animation to the supplied wall-clock time in milliseconds. */
|
|
3920
4635
|
setTime(timeMs) {
|
|
3921
4636
|
if (!this.playing) {
|
|
3922
4637
|
return;
|
|
3923
4638
|
}
|
|
3924
4639
|
const absTime = timeMs / 1e3;
|
|
3925
4640
|
const time = (absTime - this.startTime) * this.speed;
|
|
3926
|
-
this.animation.channels.forEach(({ sampler,
|
|
3927
|
-
|
|
3928
|
-
|
|
4641
|
+
this.animation.channels.forEach(({ sampler, targetNodeId, path }) => {
|
|
4642
|
+
const targetNode = this.gltfNodeIdToNodeMap.get(targetNodeId);
|
|
4643
|
+
if (!targetNode) {
|
|
4644
|
+
throw new Error(`Cannot find animation target node ${targetNodeId}`);
|
|
4645
|
+
}
|
|
4646
|
+
interpolate(time, sampler, targetNode, path);
|
|
3929
4647
|
});
|
|
3930
4648
|
}
|
|
3931
4649
|
};
|
|
3932
4650
|
var GLTFAnimator = class {
|
|
4651
|
+
/** Individual animation controllers. */
|
|
3933
4652
|
animations;
|
|
4653
|
+
/** Creates an animator for the supplied glTF scenegraph. */
|
|
3934
4654
|
constructor(props) {
|
|
3935
4655
|
this.animations = props.animations.map((animation, index) => {
|
|
3936
4656
|
const name = animation.name || `Animation-${index}`;
|
|
3937
4657
|
return new GLTFSingleAnimator({
|
|
4658
|
+
gltfNodeIdToNodeMap: props.gltfNodeIdToNodeMap,
|
|
3938
4659
|
animation: { name, channels: animation.channels }
|
|
3939
4660
|
});
|
|
3940
4661
|
});
|
|
3941
4662
|
}
|
|
3942
4663
|
/** @deprecated Use .setTime(). Will be removed (deck.gl is using this) */
|
|
3943
4664
|
animate(time) {
|
|
3944
|
-
|
|
4665
|
+
import_core6.log.warn("GLTFAnimator#animate is deprecated. Use GLTFAnimator#setTime instead")();
|
|
3945
4666
|
this.setTime(time);
|
|
3946
4667
|
}
|
|
4668
|
+
/** Advances every animation to the supplied wall-clock time in milliseconds. */
|
|
3947
4669
|
setTime(time) {
|
|
3948
4670
|
this.animations.forEach((animation) => animation.setTime(time));
|
|
3949
4671
|
}
|
|
4672
|
+
/** Returns the per-animation controllers managed by this animator. */
|
|
3950
4673
|
getAnimations() {
|
|
3951
4674
|
return this.animations;
|
|
3952
4675
|
}
|
|
3953
4676
|
};
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
if (gltfNode.translation) {
|
|
3958
|
-
node.matrix.translate(gltfNode.translation);
|
|
3959
|
-
}
|
|
3960
|
-
if (gltfNode.rotation) {
|
|
3961
|
-
const rotationMatrix = scratchMatrix.fromQuaternion(gltfNode.rotation);
|
|
3962
|
-
node.matrix.multiplyRight(rotationMatrix);
|
|
3963
|
-
}
|
|
3964
|
-
if (gltfNode.scale) {
|
|
3965
|
-
node.matrix.scale(gltfNode.scale);
|
|
3966
|
-
}
|
|
3967
|
-
}
|
|
4677
|
+
|
|
4678
|
+
// src/parsers/parse-gltf-animations.ts
|
|
4679
|
+
var import_core7 = __toESM(require_core(), 1);
|
|
3968
4680
|
|
|
3969
4681
|
// src/webgl-to-webgpu/convert-webgl-attribute.ts
|
|
3970
4682
|
var ATTRIBUTE_TYPE_TO_COMPONENTS = {
|
|
@@ -3996,65 +4708,331 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3996
4708
|
// src/parsers/parse-gltf-animations.ts
|
|
3997
4709
|
function parseGLTFAnimations(gltf) {
|
|
3998
4710
|
const gltfAnimations = gltf.animations || [];
|
|
3999
|
-
|
|
4711
|
+
const accessorCache1D = /* @__PURE__ */ new Map();
|
|
4712
|
+
const accessorCache2D = /* @__PURE__ */ new Map();
|
|
4713
|
+
return gltfAnimations.flatMap((animation, index) => {
|
|
4000
4714
|
const name = animation.name || `Animation-${index}`;
|
|
4001
|
-
const
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
}
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4715
|
+
const samplerCache = /* @__PURE__ */ new Map();
|
|
4716
|
+
const channels = animation.channels.flatMap(({ sampler, target }) => {
|
|
4717
|
+
const path = getSupportedAnimationPath(target.path);
|
|
4718
|
+
if (!path) {
|
|
4719
|
+
return [];
|
|
4720
|
+
}
|
|
4721
|
+
const targetNode = gltf.nodes[target.node ?? 0];
|
|
4722
|
+
if (!targetNode) {
|
|
4723
|
+
throw new Error(`Cannot find animation target ${target.node}`);
|
|
4724
|
+
}
|
|
4725
|
+
let parsedSampler = samplerCache.get(sampler);
|
|
4726
|
+
if (!parsedSampler) {
|
|
4727
|
+
const gltfSampler = animation.samplers[sampler];
|
|
4728
|
+
if (!gltfSampler) {
|
|
4729
|
+
throw new Error(`Cannot find animation sampler ${sampler}`);
|
|
4730
|
+
}
|
|
4731
|
+
const { input, interpolation = "LINEAR", output } = gltfSampler;
|
|
4732
|
+
parsedSampler = {
|
|
4733
|
+
input: accessorToJsArray1D(gltf.accessors[input], accessorCache1D),
|
|
4734
|
+
interpolation,
|
|
4735
|
+
output: accessorToJsArray2D(gltf.accessors[output], accessorCache2D)
|
|
4736
|
+
};
|
|
4737
|
+
samplerCache.set(sampler, parsedSampler);
|
|
4738
|
+
}
|
|
4739
|
+
return {
|
|
4740
|
+
sampler: parsedSampler,
|
|
4741
|
+
targetNodeId: targetNode.id,
|
|
4742
|
+
path
|
|
4743
|
+
};
|
|
4744
|
+
});
|
|
4745
|
+
return channels.length ? [{ name, channels }] : [];
|
|
4014
4746
|
});
|
|
4015
4747
|
}
|
|
4016
|
-
function
|
|
4017
|
-
if (
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
accessor._animation = Array.from(array);
|
|
4021
|
-
} else {
|
|
4022
|
-
const slicedArray = [];
|
|
4023
|
-
for (let i = 0; i < array.length; i += components) {
|
|
4024
|
-
slicedArray.push(Array.from(array.slice(i, i + components)));
|
|
4025
|
-
}
|
|
4026
|
-
accessor._animation = slicedArray;
|
|
4027
|
-
}
|
|
4748
|
+
function getSupportedAnimationPath(path) {
|
|
4749
|
+
if (path === "pointer") {
|
|
4750
|
+
import_core7.log.warn("KHR_animation_pointer channels are not supported and will be skipped")();
|
|
4751
|
+
return null;
|
|
4028
4752
|
}
|
|
4029
|
-
return
|
|
4753
|
+
return path;
|
|
4030
4754
|
}
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
if (ArrayBuffer.isView(object) || object instanceof ArrayBuffer || object instanceof ImageBitmap) {
|
|
4035
|
-
return object;
|
|
4755
|
+
function accessorToJsArray1D(accessor, accessorCache) {
|
|
4756
|
+
if (accessorCache.has(accessor)) {
|
|
4757
|
+
return accessorCache.get(accessor);
|
|
4036
4758
|
}
|
|
4037
|
-
|
|
4038
|
-
|
|
4759
|
+
const { typedArray: array, components } = accessorToTypedArray(accessor);
|
|
4760
|
+
assert3(components === 1, "accessorToJsArray1D must have exactly 1 component");
|
|
4761
|
+
const result = Array.from(array);
|
|
4762
|
+
accessorCache.set(accessor, result);
|
|
4763
|
+
return result;
|
|
4764
|
+
}
|
|
4765
|
+
function accessorToJsArray2D(accessor, accessorCache) {
|
|
4766
|
+
if (accessorCache.has(accessor)) {
|
|
4767
|
+
return accessorCache.get(accessor);
|
|
4768
|
+
}
|
|
4769
|
+
const { typedArray: array, components } = accessorToTypedArray(accessor);
|
|
4770
|
+
assert3(components >= 1, "accessorToJsArray2D must have at least 1 component");
|
|
4771
|
+
const result = [];
|
|
4772
|
+
for (let i = 0; i < array.length; i += components) {
|
|
4773
|
+
result.push(Array.from(array.slice(i, i + components)));
|
|
4774
|
+
}
|
|
4775
|
+
accessorCache.set(accessor, result);
|
|
4776
|
+
return result;
|
|
4777
|
+
}
|
|
4778
|
+
function assert3(condition, message) {
|
|
4779
|
+
if (!condition) {
|
|
4780
|
+
throw new Error(message);
|
|
4039
4781
|
}
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4782
|
+
}
|
|
4783
|
+
|
|
4784
|
+
// src/gltf/gltf-extension-support.ts
|
|
4785
|
+
var UNKNOWN_EXTENSION_SUPPORT = {
|
|
4786
|
+
supportLevel: "none",
|
|
4787
|
+
comment: "Not currently listed in the luma.gl glTF extension support registry."
|
|
4788
|
+
};
|
|
4789
|
+
var GLTF_EXTENSION_SUPPORT_REGISTRY = {
|
|
4790
|
+
KHR_draco_mesh_compression: {
|
|
4791
|
+
supportLevel: "built-in",
|
|
4792
|
+
comment: "Decoded by loaders.gl before luma.gl builds the scenegraph."
|
|
4793
|
+
},
|
|
4794
|
+
EXT_meshopt_compression: {
|
|
4795
|
+
supportLevel: "built-in",
|
|
4796
|
+
comment: "Meshopt-compressed primitives are decoded during load."
|
|
4797
|
+
},
|
|
4798
|
+
KHR_mesh_quantization: {
|
|
4799
|
+
supportLevel: "built-in",
|
|
4800
|
+
comment: "Quantized accessors are unpacked before geometry creation."
|
|
4801
|
+
},
|
|
4802
|
+
KHR_lights_punctual: {
|
|
4803
|
+
supportLevel: "built-in",
|
|
4804
|
+
comment: "Parsed into luma.gl Light objects."
|
|
4805
|
+
},
|
|
4806
|
+
KHR_materials_unlit: {
|
|
4807
|
+
supportLevel: "built-in",
|
|
4808
|
+
comment: "Unlit materials bypass the default lighting path."
|
|
4809
|
+
},
|
|
4810
|
+
KHR_materials_emissive_strength: {
|
|
4811
|
+
supportLevel: "built-in",
|
|
4812
|
+
comment: "Applied by the stock PBR shader."
|
|
4813
|
+
},
|
|
4814
|
+
KHR_texture_basisu: {
|
|
4815
|
+
supportLevel: "built-in",
|
|
4816
|
+
comment: "BasisU / KTX2 textures pass through when the device supports them."
|
|
4817
|
+
},
|
|
4818
|
+
KHR_texture_transform: {
|
|
4819
|
+
supportLevel: "built-in",
|
|
4820
|
+
comment: "UV transforms are applied during load."
|
|
4821
|
+
},
|
|
4822
|
+
EXT_texture_webp: {
|
|
4823
|
+
supportLevel: "loader-only",
|
|
4824
|
+
comment: "Texture source is resolved during load; final support depends on browser and device decode support."
|
|
4825
|
+
},
|
|
4826
|
+
EXT_texture_avif: {
|
|
4827
|
+
supportLevel: "loader-only",
|
|
4828
|
+
comment: "Texture source is resolved during load; final support depends on browser and device decode support."
|
|
4829
|
+
},
|
|
4830
|
+
KHR_materials_specular: {
|
|
4831
|
+
supportLevel: "built-in",
|
|
4832
|
+
comment: "The stock shader now applies specular factors and textures to the dielectric F0 term."
|
|
4833
|
+
},
|
|
4834
|
+
KHR_materials_ior: {
|
|
4835
|
+
supportLevel: "built-in",
|
|
4836
|
+
comment: "The stock shader now drives dielectric reflectance from the glTF IOR value."
|
|
4837
|
+
},
|
|
4838
|
+
KHR_materials_transmission: {
|
|
4839
|
+
supportLevel: "built-in",
|
|
4840
|
+
comment: "The stock shader now applies transmission to the base layer and exposes transparency through alpha, without a scene-color refraction buffer."
|
|
4841
|
+
},
|
|
4842
|
+
KHR_materials_volume: {
|
|
4843
|
+
supportLevel: "built-in",
|
|
4844
|
+
comment: "Thickness and attenuation now tint transmitted light in the stock shader."
|
|
4845
|
+
},
|
|
4846
|
+
KHR_materials_clearcoat: {
|
|
4847
|
+
supportLevel: "built-in",
|
|
4848
|
+
comment: "The stock shader now adds a secondary clearcoat specular lobe."
|
|
4849
|
+
},
|
|
4850
|
+
KHR_materials_sheen: {
|
|
4851
|
+
supportLevel: "built-in",
|
|
4852
|
+
comment: "The stock shader now adds a sheen lobe for cloth-like materials."
|
|
4853
|
+
},
|
|
4854
|
+
KHR_materials_iridescence: {
|
|
4855
|
+
supportLevel: "built-in",
|
|
4856
|
+
comment: "The stock shader now tints specular response with a view-dependent thin-film iridescence approximation."
|
|
4857
|
+
},
|
|
4858
|
+
KHR_materials_anisotropy: {
|
|
4859
|
+
supportLevel: "built-in",
|
|
4860
|
+
comment: "The stock shader now shapes highlights and IBL response with an anisotropy-direction approximation."
|
|
4861
|
+
},
|
|
4862
|
+
KHR_materials_pbrSpecularGlossiness: {
|
|
4863
|
+
supportLevel: "loader-only",
|
|
4864
|
+
comment: "Extension data can be loaded, but it is not translated into the default metallic-roughness material path."
|
|
4865
|
+
},
|
|
4866
|
+
KHR_materials_variants: {
|
|
4867
|
+
supportLevel: "loader-only",
|
|
4868
|
+
comment: "Variant metadata can be loaded, but applications must choose and apply variants."
|
|
4869
|
+
},
|
|
4870
|
+
EXT_mesh_gpu_instancing: {
|
|
4871
|
+
supportLevel: "none",
|
|
4872
|
+
comment: "GPU instancing data is not yet converted into luma.gl instanced draw setup."
|
|
4873
|
+
},
|
|
4874
|
+
KHR_node_visibility: {
|
|
4875
|
+
supportLevel: "none",
|
|
4876
|
+
comment: "Node-visibility animations and toggles are not mapped onto runtime scenegraph state."
|
|
4877
|
+
},
|
|
4878
|
+
KHR_animation_pointer: {
|
|
4879
|
+
supportLevel: "none",
|
|
4880
|
+
comment: "Animation pointers are not mapped onto runtime scenegraph updates."
|
|
4881
|
+
},
|
|
4882
|
+
KHR_materials_diffuse_transmission: {
|
|
4883
|
+
supportLevel: "none",
|
|
4884
|
+
comment: "Diffuse-transmission shading is not implemented in the stock PBR shader."
|
|
4885
|
+
},
|
|
4886
|
+
KHR_materials_dispersion: {
|
|
4887
|
+
supportLevel: "none",
|
|
4888
|
+
comment: "Chromatic dispersion is not implemented in the stock PBR shader."
|
|
4889
|
+
},
|
|
4890
|
+
KHR_materials_volume_scatter: {
|
|
4891
|
+
supportLevel: "none",
|
|
4892
|
+
comment: "Volume scattering is not implemented in the stock PBR shader."
|
|
4893
|
+
},
|
|
4894
|
+
KHR_xmp: {
|
|
4895
|
+
supportLevel: "none",
|
|
4896
|
+
comment: "Metadata payloads remain in the loaded glTF, but luma.gl does not interpret them."
|
|
4897
|
+
},
|
|
4898
|
+
KHR_xmp_json_ld: {
|
|
4899
|
+
supportLevel: "none",
|
|
4900
|
+
comment: "Metadata is preserved in the glTF, but luma.gl does not interpret it."
|
|
4901
|
+
},
|
|
4902
|
+
EXT_lights_image_based: {
|
|
4903
|
+
supportLevel: "none",
|
|
4904
|
+
comment: "Use loadPBREnvironment() or custom environment setup instead."
|
|
4905
|
+
},
|
|
4906
|
+
EXT_texture_video: {
|
|
4907
|
+
supportLevel: "none",
|
|
4908
|
+
comment: "Video textures are not created automatically by the stock pipeline."
|
|
4909
|
+
},
|
|
4910
|
+
MSFT_lod: {
|
|
4911
|
+
supportLevel: "none",
|
|
4912
|
+
comment: "Level-of-detail switching is not implemented in the stock scenegraph loader."
|
|
4913
|
+
}
|
|
4914
|
+
};
|
|
4915
|
+
function getGLTFExtensionSupport(gltf) {
|
|
4916
|
+
const extensionNames = Array.from(collectGLTFExtensionNames(gltf)).sort();
|
|
4917
|
+
const extensionSupportEntries = extensionNames.map(
|
|
4918
|
+
(extensionName) => {
|
|
4919
|
+
const extensionSupportDefinition = GLTF_EXTENSION_SUPPORT_REGISTRY[extensionName] || UNKNOWN_EXTENSION_SUPPORT;
|
|
4920
|
+
return [
|
|
4921
|
+
extensionName,
|
|
4922
|
+
{
|
|
4923
|
+
extensionName,
|
|
4924
|
+
supported: extensionSupportDefinition.supportLevel === "built-in",
|
|
4925
|
+
supportLevel: extensionSupportDefinition.supportLevel,
|
|
4926
|
+
comment: extensionSupportDefinition.comment
|
|
4927
|
+
}
|
|
4928
|
+
];
|
|
4044
4929
|
}
|
|
4045
|
-
|
|
4930
|
+
);
|
|
4931
|
+
return new Map(extensionSupportEntries);
|
|
4932
|
+
}
|
|
4933
|
+
function collectGLTFExtensionNames(gltf) {
|
|
4934
|
+
const gltfWithRemovedExtensions = gltf;
|
|
4935
|
+
const extensionNames = /* @__PURE__ */ new Set();
|
|
4936
|
+
addExtensionNames(extensionNames, gltf.extensionsUsed);
|
|
4937
|
+
addExtensionNames(extensionNames, gltf.extensionsRequired);
|
|
4938
|
+
addExtensionNames(extensionNames, gltfWithRemovedExtensions.extensionsRemoved);
|
|
4939
|
+
addExtensionNames(extensionNames, Object.keys(gltf.extensions || {}));
|
|
4940
|
+
if (gltfWithRemovedExtensions.lights?.length || gltf.nodes.some((node) => "light" in node)) {
|
|
4941
|
+
extensionNames.add("KHR_lights_punctual");
|
|
4942
|
+
}
|
|
4943
|
+
if (gltf.materials.some((material) => {
|
|
4944
|
+
const gltfMaterial = material;
|
|
4945
|
+
return gltfMaterial.unlit || gltfMaterial.extensions?.KHR_materials_unlit;
|
|
4946
|
+
})) {
|
|
4947
|
+
extensionNames.add("KHR_materials_unlit");
|
|
4948
|
+
}
|
|
4949
|
+
return extensionNames;
|
|
4950
|
+
}
|
|
4951
|
+
function addExtensionNames(extensionNames, newExtensionNames = []) {
|
|
4952
|
+
for (const extensionName of newExtensionNames) {
|
|
4953
|
+
extensionNames.add(extensionName);
|
|
4046
4954
|
}
|
|
4047
|
-
return object;
|
|
4048
4955
|
}
|
|
4049
4956
|
|
|
4050
4957
|
// src/gltf/create-scenegraph-from-gltf.ts
|
|
4051
4958
|
function createScenegraphsFromGLTF(device, gltf, options) {
|
|
4052
|
-
|
|
4053
|
-
const scenes = parseGLTF(device, gltf, options);
|
|
4959
|
+
const { scenes, materials, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap } = parseGLTF(device, gltf, options);
|
|
4054
4960
|
const animations = parseGLTFAnimations(gltf);
|
|
4055
|
-
const animator = new GLTFAnimator({ animations });
|
|
4961
|
+
const animator = new GLTFAnimator({ animations, gltfNodeIdToNodeMap });
|
|
4056
4962
|
const lights = parseGLTFLights(gltf);
|
|
4057
|
-
|
|
4963
|
+
const extensionSupport = getGLTFExtensionSupport(gltf);
|
|
4964
|
+
const sceneBounds = scenes.map((scene) => getScenegraphBounds(scene.getBounds()));
|
|
4965
|
+
const modelBounds = getCombinedScenegraphBounds(sceneBounds);
|
|
4966
|
+
return {
|
|
4967
|
+
scenes,
|
|
4968
|
+
materials,
|
|
4969
|
+
animator,
|
|
4970
|
+
lights,
|
|
4971
|
+
extensionSupport,
|
|
4972
|
+
sceneBounds,
|
|
4973
|
+
modelBounds,
|
|
4974
|
+
gltfMeshIdToNodeMap,
|
|
4975
|
+
gltfNodeIdToNodeMap,
|
|
4976
|
+
gltfNodeIndexToNodeMap,
|
|
4977
|
+
gltf
|
|
4978
|
+
};
|
|
4979
|
+
}
|
|
4980
|
+
function getScenegraphBounds(bounds) {
|
|
4981
|
+
if (!bounds) {
|
|
4982
|
+
return {
|
|
4983
|
+
bounds: null,
|
|
4984
|
+
center: [0, 0, 0],
|
|
4985
|
+
size: [0, 0, 0],
|
|
4986
|
+
radius: 0.5,
|
|
4987
|
+
recommendedOrbitDistance: 1
|
|
4988
|
+
};
|
|
4989
|
+
}
|
|
4990
|
+
const normalizedBounds = [
|
|
4991
|
+
[bounds[0][0], bounds[0][1], bounds[0][2]],
|
|
4992
|
+
[bounds[1][0], bounds[1][1], bounds[1][2]]
|
|
4993
|
+
];
|
|
4994
|
+
const size = [
|
|
4995
|
+
normalizedBounds[1][0] - normalizedBounds[0][0],
|
|
4996
|
+
normalizedBounds[1][1] - normalizedBounds[0][1],
|
|
4997
|
+
normalizedBounds[1][2] - normalizedBounds[0][2]
|
|
4998
|
+
];
|
|
4999
|
+
const center = [
|
|
5000
|
+
normalizedBounds[0][0] + size[0] * 0.5,
|
|
5001
|
+
normalizedBounds[0][1] + size[1] * 0.5,
|
|
5002
|
+
normalizedBounds[0][2] + size[2] * 0.5
|
|
5003
|
+
];
|
|
5004
|
+
const maxHalfExtent = Math.max(size[0], size[1], size[2]) * 0.5;
|
|
5005
|
+
const radius = Math.max(0.5 * Math.hypot(size[0], size[1], size[2]), 1e-3);
|
|
5006
|
+
return {
|
|
5007
|
+
bounds: normalizedBounds,
|
|
5008
|
+
center,
|
|
5009
|
+
size,
|
|
5010
|
+
radius,
|
|
5011
|
+
recommendedOrbitDistance: Math.max(
|
|
5012
|
+
Math.max(maxHalfExtent, 1e-3) / Math.tan(Math.PI / 6) * 1.15,
|
|
5013
|
+
radius * 1.1
|
|
5014
|
+
)
|
|
5015
|
+
};
|
|
5016
|
+
}
|
|
5017
|
+
function getCombinedScenegraphBounds(sceneBounds) {
|
|
5018
|
+
let combinedBounds = null;
|
|
5019
|
+
for (const sceneBoundInfo of sceneBounds) {
|
|
5020
|
+
if (!sceneBoundInfo.bounds) {
|
|
5021
|
+
continue;
|
|
5022
|
+
}
|
|
5023
|
+
if (!combinedBounds) {
|
|
5024
|
+
combinedBounds = [
|
|
5025
|
+
[...sceneBoundInfo.bounds[0]],
|
|
5026
|
+
[...sceneBoundInfo.bounds[1]]
|
|
5027
|
+
];
|
|
5028
|
+
continue;
|
|
5029
|
+
}
|
|
5030
|
+
for (let axis = 0; axis < 3; axis++) {
|
|
5031
|
+
combinedBounds[0][axis] = Math.min(combinedBounds[0][axis], sceneBoundInfo.bounds[0][axis]);
|
|
5032
|
+
combinedBounds[1][axis] = Math.max(combinedBounds[1][axis], sceneBoundInfo.bounds[1][axis]);
|
|
5033
|
+
}
|
|
5034
|
+
}
|
|
5035
|
+
return getScenegraphBounds(combinedBounds);
|
|
4058
5036
|
}
|
|
4059
5037
|
return __toCommonJS(bundle_exports);
|
|
4060
5038
|
})();
|