@luma.gl/gltf 9.2.6 → 9.3.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +1362 -313
- package/dist/dist.min.js +98 -46
- package/dist/gltf/animations/animations.d.ts +16 -4
- package/dist/gltf/animations/animations.d.ts.map +1 -1
- package/dist/gltf/animations/interpolate.d.ts +4 -3
- package/dist/gltf/animations/interpolate.d.ts.map +1 -1
- package/dist/gltf/animations/interpolate.js +27 -36
- package/dist/gltf/animations/interpolate.js.map +1 -1
- package/dist/gltf/create-gltf-model.d.ts +15 -1
- package/dist/gltf/create-gltf-model.d.ts.map +1 -1
- package/dist/gltf/create-gltf-model.js +154 -48
- package/dist/gltf/create-gltf-model.js.map +1 -1
- package/dist/gltf/create-scenegraph-from-gltf.d.ts +39 -2
- package/dist/gltf/create-scenegraph-from-gltf.d.ts.map +1 -1
- package/dist/gltf/create-scenegraph-from-gltf.js +76 -6
- package/dist/gltf/create-scenegraph-from-gltf.js.map +1 -1
- package/dist/gltf/gltf-animator.d.ts +26 -0
- package/dist/gltf/gltf-animator.d.ts.map +1 -1
- package/dist/gltf/gltf-animator.js +22 -19
- package/dist/gltf/gltf-animator.js.map +1 -1
- package/dist/gltf/gltf-extension-support.d.ts +10 -0
- package/dist/gltf/gltf-extension-support.d.ts.map +1 -0
- package/dist/gltf/gltf-extension-support.js +173 -0
- package/dist/gltf/gltf-extension-support.js.map +1 -0
- package/dist/index.cjs +1302 -276
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/parsers/parse-gltf-animations.d.ts +1 -0
- package/dist/parsers/parse-gltf-animations.d.ts.map +1 -1
- package/dist/parsers/parse-gltf-animations.js +73 -28
- package/dist/parsers/parse-gltf-animations.js.map +1 -1
- package/dist/parsers/parse-gltf-lights.d.ts +5 -0
- package/dist/parsers/parse-gltf-lights.d.ts.map +1 -0
- package/dist/parsers/parse-gltf-lights.js +163 -0
- package/dist/parsers/parse-gltf-lights.js.map +1 -0
- package/dist/parsers/parse-gltf.d.ts +19 -2
- package/dist/parsers/parse-gltf.d.ts.map +1 -1
- package/dist/parsers/parse-gltf.js +101 -61
- package/dist/parsers/parse-gltf.js.map +1 -1
- package/dist/parsers/parse-pbr-material.d.ts +115 -2
- package/dist/parsers/parse-pbr-material.d.ts.map +1 -1
- package/dist/parsers/parse-pbr-material.js +570 -54
- package/dist/parsers/parse-pbr-material.js.map +1 -1
- package/dist/pbr/pbr-environment.d.ts +10 -4
- package/dist/pbr/pbr-environment.d.ts.map +1 -1
- package/dist/pbr/pbr-environment.js +18 -15
- package/dist/pbr/pbr-environment.js.map +1 -1
- package/dist/pbr/pbr-material.d.ts +13 -3
- package/dist/pbr/pbr-material.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-attribute.d.ts +12 -1
- package/dist/webgl-to-webgpu/convert-webgl-attribute.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-attribute.js +3 -0
- package/dist/webgl-to-webgpu/convert-webgl-attribute.js.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-sampler.d.ts +11 -5
- package/dist/webgl-to-webgpu/convert-webgl-sampler.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-sampler.js +16 -12
- package/dist/webgl-to-webgpu/convert-webgl-sampler.js.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-topology.d.ts +2 -9
- package/dist/webgl-to-webgpu/convert-webgl-topology.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-topology.js +2 -14
- package/dist/webgl-to-webgpu/convert-webgl-topology.js.map +1 -1
- package/dist/webgl-to-webgpu/gltf-webgl-constants.d.ts +27 -0
- package/dist/webgl-to-webgpu/gltf-webgl-constants.d.ts.map +1 -0
- package/dist/webgl-to-webgpu/gltf-webgl-constants.js +34 -0
- package/dist/webgl-to-webgpu/gltf-webgl-constants.js.map +1 -0
- package/package.json +8 -9
- package/src/gltf/animations/animations.ts +17 -5
- package/src/gltf/animations/interpolate.ts +49 -68
- package/src/gltf/create-gltf-model.ts +214 -48
- package/src/gltf/create-scenegraph-from-gltf.ts +134 -11
- package/src/gltf/gltf-animator.ts +34 -25
- package/src/gltf/gltf-extension-support.ts +214 -0
- package/src/index.ts +11 -2
- package/src/parsers/parse-gltf-animations.ts +94 -33
- package/src/parsers/parse-gltf-lights.ts +218 -0
- package/src/parsers/parse-gltf.ts +170 -90
- package/src/parsers/parse-pbr-material.ts +870 -80
- package/src/pbr/pbr-environment.ts +44 -21
- package/src/pbr/pbr-material.ts +18 -3
- package/src/webgl-to-webgpu/convert-webgl-attribute.ts +12 -1
- package/src/webgl-to-webgpu/convert-webgl-sampler.ts +38 -29
- package/src/webgl-to-webgpu/convert-webgl-topology.ts +2 -14
- package/src/webgl-to-webgpu/gltf-webgl-constants.ts +35 -0
- package/dist/utils/deep-copy.d.ts +0 -3
- package/dist/utils/deep-copy.d.ts.map +0 -1
- package/dist/utils/deep-copy.js +0 -21
- package/dist/utils/deep-copy.js.map +0 -1
- package/src/utils/deep-copy.ts +0 -22
package/dist/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,7 +64,9 @@ var __exports__ = (() => {
|
|
|
71
64
|
__export(bundle_exports, {
|
|
72
65
|
GLTFAnimator: () => GLTFAnimator,
|
|
73
66
|
createScenegraphsFromGLTF: () => createScenegraphsFromGLTF,
|
|
67
|
+
getGLTFExtensionSupport: () => getGLTFExtensionSupport,
|
|
74
68
|
loadPBREnvironment: () => loadPBREnvironment,
|
|
69
|
+
parseGLTFLights: () => parseGLTFLights,
|
|
75
70
|
parsePBRMaterial: () => parsePBRMaterial
|
|
76
71
|
});
|
|
77
72
|
__reExport(bundle_exports, __toESM(require_core(), 1));
|
|
@@ -121,7 +116,7 @@ var __exports__ = (() => {
|
|
|
121
116
|
}
|
|
122
117
|
|
|
123
118
|
// ../../node_modules/@loaders.gl/images/dist/lib/utils/version.js
|
|
124
|
-
var VERSION = true ? "4.
|
|
119
|
+
var VERSION = true ? "4.4.0-alpha.18" : "latest";
|
|
125
120
|
|
|
126
121
|
// ../../node_modules/@loaders.gl/images/dist/lib/category-api/image-type.js
|
|
127
122
|
var parseImageNode = globalThis.loaders?.parseImageNode;
|
|
@@ -262,7 +257,6 @@ var __exports__ = (() => {
|
|
|
262
257
|
}
|
|
263
258
|
|
|
264
259
|
// ../../node_modules/@loaders.gl/images/dist/lib/parsers/parse-to-image-bitmap.js
|
|
265
|
-
var EMPTY_OBJECT = {};
|
|
266
260
|
var imagebitmapOptionsSupported = true;
|
|
267
261
|
async function parseToImageBitmap(arrayBuffer, options, url) {
|
|
268
262
|
let blob;
|
|
@@ -290,8 +284,13 @@ var __exports__ = (() => {
|
|
|
290
284
|
return await createImageBitmap(blob);
|
|
291
285
|
}
|
|
292
286
|
function isEmptyObject(object) {
|
|
293
|
-
|
|
294
|
-
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
|
+
}
|
|
295
294
|
}
|
|
296
295
|
return true;
|
|
297
296
|
}
|
|
@@ -615,7 +614,8 @@ var __exports__ = (() => {
|
|
|
615
614
|
|
|
616
615
|
// src/pbr/pbr-environment.ts
|
|
617
616
|
function loadPBREnvironment(device, props) {
|
|
618
|
-
const
|
|
617
|
+
const specularMipLevels = props.specularMipLevels ?? 1;
|
|
618
|
+
const brdfLutTexture = new import_engine.DynamicTexture(device, {
|
|
619
619
|
id: "brdfLUT",
|
|
620
620
|
sampler: {
|
|
621
621
|
addressModeU: "clamp-to-edge",
|
|
@@ -628,7 +628,9 @@ var __exports__ = (() => {
|
|
|
628
628
|
});
|
|
629
629
|
const diffuseEnvSampler = makeCube(device, {
|
|
630
630
|
id: "DiffuseEnvSampler",
|
|
631
|
-
getTextureForFace: (
|
|
631
|
+
getTextureForFace: (face) => loadImageTexture(
|
|
632
|
+
props.getTexUrl("diffuse", FACES.indexOf(face), 0)
|
|
633
|
+
),
|
|
632
634
|
sampler: {
|
|
633
635
|
addressModeU: "clamp-to-edge",
|
|
634
636
|
addressModeV: "clamp-to-edge",
|
|
@@ -638,12 +640,13 @@ var __exports__ = (() => {
|
|
|
638
640
|
});
|
|
639
641
|
const specularEnvSampler = makeCube(device, {
|
|
640
642
|
id: "SpecularEnvSampler",
|
|
641
|
-
getTextureForFace: (
|
|
643
|
+
getTextureForFace: (face) => {
|
|
642
644
|
const imageArray = [];
|
|
643
|
-
|
|
644
|
-
|
|
645
|
+
const direction = FACES.indexOf(face);
|
|
646
|
+
for (let lod = 0; lod < specularMipLevels; lod++) {
|
|
647
|
+
imageArray.push(loadImageTexture(props.getTexUrl("specular", direction, lod)));
|
|
645
648
|
}
|
|
646
|
-
return imageArray;
|
|
649
|
+
return Promise.all(imageArray);
|
|
647
650
|
},
|
|
648
651
|
sampler: {
|
|
649
652
|
addressModeU: "clamp-to-edge",
|
|
@@ -659,32 +662,34 @@ var __exports__ = (() => {
|
|
|
659
662
|
specularEnvSampler
|
|
660
663
|
};
|
|
661
664
|
}
|
|
662
|
-
var FACES = [
|
|
665
|
+
var FACES = ["+X", "-X", "+Y", "-Y", "+Z", "-Z"];
|
|
663
666
|
function makeCube(device, {
|
|
664
667
|
id,
|
|
665
668
|
getTextureForFace,
|
|
666
669
|
sampler
|
|
667
670
|
}) {
|
|
668
|
-
const data =
|
|
669
|
-
|
|
670
|
-
|
|
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;
|
|
671
679
|
});
|
|
672
|
-
return new import_engine.
|
|
680
|
+
return new import_engine.DynamicTexture(device, {
|
|
673
681
|
id,
|
|
674
682
|
dimension: "cube",
|
|
675
683
|
mipmaps: false,
|
|
676
684
|
sampler,
|
|
677
|
-
// @ts-expect-error
|
|
678
685
|
data
|
|
679
686
|
});
|
|
680
687
|
}
|
|
681
688
|
|
|
682
689
|
// src/parsers/parse-pbr-material.ts
|
|
683
|
-
var import_constants2 = __toESM(require_constants(), 1);
|
|
684
690
|
var import_core = __toESM(require_core(), 1);
|
|
685
691
|
|
|
686
692
|
// src/webgl-to-webgpu/convert-webgl-sampler.ts
|
|
687
|
-
var import_constants = __toESM(require_constants(), 1);
|
|
688
693
|
function convertSampler(gltfSampler) {
|
|
689
694
|
return {
|
|
690
695
|
addressModeU: convertSamplerWrapMode(gltfSampler.wrapS),
|
|
@@ -695,11 +700,11 @@ var __exports__ = (() => {
|
|
|
695
700
|
}
|
|
696
701
|
function convertSamplerWrapMode(mode) {
|
|
697
702
|
switch (mode) {
|
|
698
|
-
case
|
|
703
|
+
case 33071 /* CLAMP_TO_EDGE */:
|
|
699
704
|
return "clamp-to-edge";
|
|
700
|
-
case
|
|
705
|
+
case 10497 /* REPEAT */:
|
|
701
706
|
return "repeat";
|
|
702
|
-
case
|
|
707
|
+
case 33648 /* MIRRORED_REPEAT */:
|
|
703
708
|
return "mirror-repeat";
|
|
704
709
|
default:
|
|
705
710
|
return void 0;
|
|
@@ -707,9 +712,9 @@ var __exports__ = (() => {
|
|
|
707
712
|
}
|
|
708
713
|
function convertSamplerMagFilter(mode) {
|
|
709
714
|
switch (mode) {
|
|
710
|
-
case
|
|
715
|
+
case 9728 /* NEAREST */:
|
|
711
716
|
return "nearest";
|
|
712
|
-
case
|
|
717
|
+
case 9729 /* LINEAR */:
|
|
713
718
|
return "linear";
|
|
714
719
|
default:
|
|
715
720
|
return void 0;
|
|
@@ -717,17 +722,17 @@ var __exports__ = (() => {
|
|
|
717
722
|
}
|
|
718
723
|
function convertSamplerMinFilter(mode) {
|
|
719
724
|
switch (mode) {
|
|
720
|
-
case
|
|
725
|
+
case 9728 /* NEAREST */:
|
|
721
726
|
return { minFilter: "nearest" };
|
|
722
|
-
case
|
|
727
|
+
case 9729 /* LINEAR */:
|
|
723
728
|
return { minFilter: "linear" };
|
|
724
|
-
case
|
|
729
|
+
case 9984 /* NEAREST_MIPMAP_NEAREST */:
|
|
725
730
|
return { minFilter: "nearest", mipmapFilter: "nearest" };
|
|
726
|
-
case
|
|
731
|
+
case 9985 /* LINEAR_MIPMAP_NEAREST */:
|
|
727
732
|
return { minFilter: "linear", mipmapFilter: "nearest" };
|
|
728
|
-
case
|
|
733
|
+
case 9986 /* NEAREST_MIPMAP_LINEAR */:
|
|
729
734
|
return { minFilter: "nearest", mipmapFilter: "linear" };
|
|
730
|
-
case
|
|
735
|
+
case 9987 /* LINEAR_MIPMAP_LINEAR */:
|
|
731
736
|
return { minFilter: "linear", mipmapFilter: "linear" };
|
|
732
737
|
default:
|
|
733
738
|
return {};
|
|
@@ -759,7 +764,8 @@ var __exports__ = (() => {
|
|
|
759
764
|
if (imageBasedLightingEnvironment) {
|
|
760
765
|
parsedMaterial.bindings.pbr_diffuseEnvSampler = imageBasedLightingEnvironment.diffuseEnvSampler.texture;
|
|
761
766
|
parsedMaterial.bindings.pbr_specularEnvSampler = imageBasedLightingEnvironment.specularEnvSampler.texture;
|
|
762
|
-
parsedMaterial.bindings.
|
|
767
|
+
parsedMaterial.bindings.pbr_brdfLUT = imageBasedLightingEnvironment.brdfLutTexture.texture;
|
|
768
|
+
parsedMaterial.uniforms.IBLenabled = true;
|
|
763
769
|
parsedMaterial.uniforms.scaleIBLAmbient = [1, 1];
|
|
764
770
|
}
|
|
765
771
|
if (options?.pbrDebug) {
|
|
@@ -773,86 +779,190 @@ var __exports__ = (() => {
|
|
|
773
779
|
parsedMaterial.defines["HAS_TANGENTS"] = true;
|
|
774
780
|
if (attributes["TEXCOORD_0"])
|
|
775
781
|
parsedMaterial.defines["HAS_UV"] = true;
|
|
782
|
+
if (attributes["JOINTS_0"] && attributes["WEIGHTS_0"])
|
|
783
|
+
parsedMaterial.defines["HAS_SKIN"] = true;
|
|
784
|
+
if (attributes["COLOR_0"])
|
|
785
|
+
parsedMaterial.defines["HAS_COLORS"] = true;
|
|
776
786
|
if (options?.imageBasedLightingEnvironment)
|
|
777
787
|
parsedMaterial.defines["USE_IBL"] = true;
|
|
778
788
|
if (options?.lights)
|
|
779
789
|
parsedMaterial.defines["USE_LIGHTS"] = true;
|
|
780
790
|
if (material) {
|
|
781
|
-
|
|
791
|
+
if (options.validateAttributes !== false) {
|
|
792
|
+
warnOnMissingExpectedAttributes(material, attributes);
|
|
793
|
+
}
|
|
794
|
+
parseMaterial(device, material, parsedMaterial, options.gltf);
|
|
782
795
|
}
|
|
783
796
|
return parsedMaterial;
|
|
784
797
|
}
|
|
785
|
-
function
|
|
786
|
-
|
|
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
|
+
);
|
|
787
864
|
if (material.pbrMetallicRoughness) {
|
|
788
|
-
parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial);
|
|
865
|
+
parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial, gltf);
|
|
789
866
|
}
|
|
790
867
|
if (material.normalTexture) {
|
|
791
|
-
addTexture(
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
);
|
|
868
|
+
addTexture(device, material.normalTexture, "pbr_normalSampler", parsedMaterial, {
|
|
869
|
+
featureOptions: {
|
|
870
|
+
define: "HAS_NORMALMAP",
|
|
871
|
+
enabledUniformName: "normalMapEnabled"
|
|
872
|
+
},
|
|
873
|
+
gltf
|
|
874
|
+
});
|
|
798
875
|
const { scale: scale4 = 1 } = material.normalTexture;
|
|
799
876
|
parsedMaterial.uniforms.normalScale = scale4;
|
|
800
877
|
}
|
|
801
878
|
if (material.occlusionTexture) {
|
|
802
|
-
addTexture(
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
);
|
|
879
|
+
addTexture(device, material.occlusionTexture, "pbr_occlusionSampler", parsedMaterial, {
|
|
880
|
+
featureOptions: {
|
|
881
|
+
define: "HAS_OCCLUSIONMAP",
|
|
882
|
+
enabledUniformName: "occlusionMapEnabled"
|
|
883
|
+
},
|
|
884
|
+
gltf
|
|
885
|
+
});
|
|
809
886
|
const { strength = 1 } = material.occlusionTexture;
|
|
810
887
|
parsedMaterial.uniforms.occlusionStrength = strength;
|
|
811
888
|
}
|
|
889
|
+
parsedMaterial.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];
|
|
812
890
|
if (material.emissiveTexture) {
|
|
813
|
-
addTexture(
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
);
|
|
820
|
-
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
|
+
});
|
|
821
898
|
}
|
|
822
|
-
|
|
823
|
-
|
|
899
|
+
parseMaterialExtensions(device, material.extensions, parsedMaterial, gltf);
|
|
900
|
+
switch (material.alphaMode || "OPAQUE") {
|
|
901
|
+
case "OPAQUE":
|
|
902
|
+
break;
|
|
903
|
+
case "MASK": {
|
|
824
904
|
const { alphaCutoff = 0.5 } = material;
|
|
825
905
|
parsedMaterial.defines["ALPHA_CUTOFF"] = true;
|
|
906
|
+
parsedMaterial.uniforms.alphaCutoffEnabled = true;
|
|
826
907
|
parsedMaterial.uniforms.alphaCutoff = alphaCutoff;
|
|
827
908
|
break;
|
|
909
|
+
}
|
|
828
910
|
case "BLEND":
|
|
829
911
|
import_core.log.warn("glTF BLEND alphaMode might not work well because it requires mesh sorting")();
|
|
830
|
-
parsedMaterial
|
|
831
|
-
parsedMaterial.parameters.blendColorOperation = "add";
|
|
832
|
-
parsedMaterial.parameters.blendColorSrcFactor = "src-alpha";
|
|
833
|
-
parsedMaterial.parameters.blendColorDstFactor = "one-minus-src-alpha";
|
|
834
|
-
parsedMaterial.parameters.blendAlphaOperation = "add";
|
|
835
|
-
parsedMaterial.parameters.blendAlphaSrcFactor = "one";
|
|
836
|
-
parsedMaterial.parameters.blendAlphaDstFactor = "one-minus-src-alpha";
|
|
837
|
-
parsedMaterial.glParameters["blend"] = true;
|
|
838
|
-
parsedMaterial.glParameters["blendEquation"] = import_constants2.GL.FUNC_ADD;
|
|
839
|
-
parsedMaterial.glParameters["blendFunc"] = [
|
|
840
|
-
import_constants2.GL.SRC_ALPHA,
|
|
841
|
-
import_constants2.GL.ONE_MINUS_SRC_ALPHA,
|
|
842
|
-
import_constants2.GL.ONE,
|
|
843
|
-
import_constants2.GL.ONE_MINUS_SRC_ALPHA
|
|
844
|
-
];
|
|
912
|
+
applyAlphaBlendParameters(parsedMaterial);
|
|
845
913
|
break;
|
|
846
914
|
}
|
|
847
915
|
}
|
|
848
|
-
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) {
|
|
849
953
|
if (pbrMetallicRoughness.baseColorTexture) {
|
|
850
954
|
addTexture(
|
|
851
955
|
device,
|
|
852
956
|
pbrMetallicRoughness.baseColorTexture,
|
|
853
957
|
"pbr_baseColorSampler",
|
|
854
|
-
|
|
855
|
-
|
|
958
|
+
parsedMaterial,
|
|
959
|
+
{
|
|
960
|
+
featureOptions: {
|
|
961
|
+
define: "HAS_BASECOLORMAP",
|
|
962
|
+
enabledUniformName: "baseColorMapEnabled"
|
|
963
|
+
},
|
|
964
|
+
gltf
|
|
965
|
+
}
|
|
856
966
|
);
|
|
857
967
|
}
|
|
858
968
|
parsedMaterial.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];
|
|
@@ -861,41 +971,431 @@ var __exports__ = (() => {
|
|
|
861
971
|
device,
|
|
862
972
|
pbrMetallicRoughness.metallicRoughnessTexture,
|
|
863
973
|
"pbr_metallicRoughnessSampler",
|
|
864
|
-
|
|
865
|
-
|
|
974
|
+
parsedMaterial,
|
|
975
|
+
{
|
|
976
|
+
featureOptions: {
|
|
977
|
+
define: "HAS_METALROUGHNESSMAP",
|
|
978
|
+
enabledUniformName: "metallicRoughnessMapEnabled"
|
|
979
|
+
},
|
|
980
|
+
gltf
|
|
981
|
+
}
|
|
866
982
|
);
|
|
867
983
|
}
|
|
868
984
|
const { metallicFactor = 1, roughnessFactor = 1 } = pbrMetallicRoughness;
|
|
869
985
|
parsedMaterial.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];
|
|
870
986
|
}
|
|
871
|
-
function
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
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;
|
|
878
1245
|
}
|
|
879
1246
|
const gltfSampler = {
|
|
880
1247
|
wrapS: 10497,
|
|
881
1248
|
// default REPEAT S (U) wrapping mode.
|
|
882
1249
|
wrapT: 10497,
|
|
883
1250
|
// default REPEAT T (V) wrapping mode.
|
|
884
|
-
|
|
1251
|
+
minFilter: 9729,
|
|
1252
|
+
// default LINEAR filtering
|
|
1253
|
+
magFilter: 9729,
|
|
1254
|
+
// default LINEAR filtering
|
|
1255
|
+
...resolvedTextureInfo?.texture?.sampler
|
|
885
1256
|
};
|
|
886
|
-
const
|
|
887
|
-
id:
|
|
888
|
-
sampler: convertSampler(gltfSampler)
|
|
889
|
-
|
|
890
|
-
|
|
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
|
+
}
|
|
891
1273
|
parsedMaterial.bindings[uniformName] = texture;
|
|
892
1274
|
if (define)
|
|
893
1275
|
parsedMaterial.defines[define] = true;
|
|
1276
|
+
if (enabledUniformName) {
|
|
1277
|
+
parsedMaterial.uniforms[enabledUniformName] = true;
|
|
1278
|
+
}
|
|
894
1279
|
parsedMaterial.generatedTextures.push(texture);
|
|
895
1280
|
}
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
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
|
+
}
|
|
899
1399
|
|
|
900
1400
|
// ../../node_modules/@math.gl/core/dist/lib/common.js
|
|
901
1401
|
var RADIANS_TO_DEGREES = 1 / Math.PI * 180;
|
|
@@ -3468,6 +3968,143 @@ var __exports__ = (() => {
|
|
|
3468
3968
|
}
|
|
3469
3969
|
};
|
|
3470
3970
|
|
|
3971
|
+
// src/parsers/parse-gltf-lights.ts
|
|
3972
|
+
var GLTF_COLOR_FACTOR = 255;
|
|
3973
|
+
function parseGLTFLights(gltf) {
|
|
3974
|
+
const lightDefs = (
|
|
3975
|
+
// `postProcessGLTF()` moves KHR_lights_punctual into `gltf.lights`.
|
|
3976
|
+
gltf.lights || gltf.extensions?.["KHR_lights_punctual"]?.["lights"]
|
|
3977
|
+
);
|
|
3978
|
+
if (!lightDefs || !Array.isArray(lightDefs) || lightDefs.length === 0) {
|
|
3979
|
+
return [];
|
|
3980
|
+
}
|
|
3981
|
+
const lights = [];
|
|
3982
|
+
const parentNodeById = createParentNodeMap(gltf.nodes || []);
|
|
3983
|
+
const worldMatrixByNodeId = /* @__PURE__ */ new Map();
|
|
3984
|
+
for (const node of gltf.nodes || []) {
|
|
3985
|
+
const lightIndex = node.light ?? node.extensions?.KHR_lights_punctual?.light;
|
|
3986
|
+
if (typeof lightIndex !== "number") {
|
|
3987
|
+
continue;
|
|
3988
|
+
}
|
|
3989
|
+
const gltfLight = lightDefs[lightIndex];
|
|
3990
|
+
if (!gltfLight) {
|
|
3991
|
+
continue;
|
|
3992
|
+
}
|
|
3993
|
+
const color = normalizeGLTFLightColor(
|
|
3994
|
+
gltfLight.color || [1, 1, 1]
|
|
3995
|
+
);
|
|
3996
|
+
const intensity = gltfLight.intensity ?? 1;
|
|
3997
|
+
const range = gltfLight.range;
|
|
3998
|
+
const worldMatrix = getNodeWorldMatrix(node, parentNodeById, worldMatrixByNodeId);
|
|
3999
|
+
switch (gltfLight.type) {
|
|
4000
|
+
case "directional":
|
|
4001
|
+
lights.push(parseDirectionalLight(worldMatrix, color, intensity));
|
|
4002
|
+
break;
|
|
4003
|
+
case "point":
|
|
4004
|
+
lights.push(parsePointLight(worldMatrix, color, intensity, range));
|
|
4005
|
+
break;
|
|
4006
|
+
case "spot":
|
|
4007
|
+
lights.push(parseSpotLight(worldMatrix, color, intensity, range, gltfLight.spot));
|
|
4008
|
+
break;
|
|
4009
|
+
default:
|
|
4010
|
+
break;
|
|
4011
|
+
}
|
|
4012
|
+
}
|
|
4013
|
+
return lights;
|
|
4014
|
+
}
|
|
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);
|
|
4020
|
+
let attenuation = [1, 0, 0];
|
|
4021
|
+
if (range !== void 0 && range > 0) {
|
|
4022
|
+
attenuation = [1, 0, 1 / (range * range)];
|
|
4023
|
+
}
|
|
4024
|
+
return {
|
|
4025
|
+
type: "point",
|
|
4026
|
+
position,
|
|
4027
|
+
color,
|
|
4028
|
+
intensity,
|
|
4029
|
+
attenuation
|
|
4030
|
+
};
|
|
4031
|
+
}
|
|
4032
|
+
function parseDirectionalLight(worldMatrix, color, intensity) {
|
|
4033
|
+
const direction = getLightDirection(worldMatrix);
|
|
4034
|
+
return {
|
|
4035
|
+
type: "directional",
|
|
4036
|
+
direction,
|
|
4037
|
+
color,
|
|
4038
|
+
intensity
|
|
4039
|
+
};
|
|
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
|
+
}
|
|
4103
|
+
|
|
4104
|
+
// src/parsers/parse-gltf.ts
|
|
4105
|
+
var import_engine4 = __toESM(require_engine(), 1);
|
|
4106
|
+
var import_shadertools2 = __toESM(require_shadertools(), 1);
|
|
4107
|
+
|
|
3471
4108
|
// src/webgl-to-webgpu/convert-webgl-topology.ts
|
|
3472
4109
|
function convertGLDrawModeToTopology(drawMode) {
|
|
3473
4110
|
switch (drawMode) {
|
|
@@ -3487,56 +4124,95 @@ var __exports__ = (() => {
|
|
|
3487
4124
|
}
|
|
3488
4125
|
|
|
3489
4126
|
// src/gltf/create-gltf-model.ts
|
|
3490
|
-
var
|
|
3491
|
-
var import_shadertools = __toESM(require_shadertools(), 1);
|
|
4127
|
+
var import_core3 = __toESM(require_core(), 1);
|
|
3492
4128
|
var import_engine2 = __toESM(require_engine(), 1);
|
|
4129
|
+
var import_shadertools = __toESM(require_shadertools(), 1);
|
|
4130
|
+
var import_engine3 = __toESM(require_engine(), 1);
|
|
3493
4131
|
var SHADER = (
|
|
3494
4132
|
/* WGSL */
|
|
3495
4133
|
`
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
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
|
+
};
|
|
3505
4150
|
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
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
|
+
};
|
|
3510
4160
|
|
|
3511
4161
|
@vertex
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
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);
|
|
3516
4168
|
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
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
|
|
3520
4186
|
|
|
3521
|
-
|
|
3522
|
-
_TANGENT = TANGENT;
|
|
3523
|
-
#endif
|
|
4187
|
+
let worldPosition = pbrProjection.modelMatrix * position;
|
|
3524
4188
|
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
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
|
|
3528
4196
|
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
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
|
+
}
|
|
3532
4203
|
|
|
3533
4204
|
@fragment
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
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
|
+
}
|
|
3540
4216
|
`
|
|
3541
4217
|
);
|
|
3542
4218
|
var vs = (
|
|
@@ -3560,6 +4236,11 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3560
4236
|
in vec2 texCoords;
|
|
3561
4237
|
#endif
|
|
3562
4238
|
|
|
4239
|
+
#ifdef HAS_SKIN
|
|
4240
|
+
in uvec4 JOINTS_0;
|
|
4241
|
+
in vec4 WEIGHTS_0;
|
|
4242
|
+
#endif
|
|
4243
|
+
|
|
3563
4244
|
void main(void) {
|
|
3564
4245
|
vec4 _NORMAL = vec4(0.);
|
|
3565
4246
|
vec4 _TANGENT = vec4(0.);
|
|
@@ -3577,8 +4258,17 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3577
4258
|
_TEXCOORD_0 = texCoords;
|
|
3578
4259
|
#endif
|
|
3579
4260
|
|
|
3580
|
-
|
|
3581
|
-
|
|
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;
|
|
3582
4272
|
}
|
|
3583
4273
|
`
|
|
3584
4274
|
);
|
|
@@ -3593,9 +4283,28 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3593
4283
|
}
|
|
3594
4284
|
`
|
|
3595
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
|
+
}
|
|
3596
4305
|
function createGLTFModel(device, options) {
|
|
3597
4306
|
const { id, geometry, parsedPPBRMaterial, vertexCount, modelOptions = {} } = options;
|
|
3598
|
-
|
|
4307
|
+
import_core3.log.info(4, "createGLTFModel defines: ", parsedPPBRMaterial.defines)();
|
|
3599
4308
|
const managedResources = [];
|
|
3600
4309
|
const parameters = {
|
|
3601
4310
|
depthWriteEnabled: true,
|
|
@@ -3611,20 +4320,57 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3611
4320
|
geometry,
|
|
3612
4321
|
topology: geometry.topology,
|
|
3613
4322
|
vertexCount,
|
|
3614
|
-
modules: [import_shadertools.pbrMaterial],
|
|
4323
|
+
modules: [import_shadertools.pbrMaterial, import_shadertools.skin],
|
|
3615
4324
|
...modelOptions,
|
|
3616
4325
|
defines: { ...parsedPPBRMaterial.defines, ...modelOptions.defines },
|
|
3617
4326
|
parameters: { ...parameters, ...parsedPPBRMaterial.parameters, ...modelOptions.parameters }
|
|
3618
4327
|
};
|
|
3619
|
-
const
|
|
3620
|
-
|
|
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 = {
|
|
3621
4335
|
...parsedPPBRMaterial.uniforms,
|
|
3622
4336
|
...modelOptions.uniforms,
|
|
3623
4337
|
...parsedPPBRMaterial.bindings,
|
|
3624
4338
|
...modelOptions.bindings
|
|
3625
4339
|
};
|
|
3626
|
-
|
|
3627
|
-
|
|
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;
|
|
3628
4374
|
}
|
|
3629
4375
|
|
|
3630
4376
|
// src/parsers/parse-gltf.ts
|
|
@@ -3635,82 +4381,128 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3635
4381
|
lights: true,
|
|
3636
4382
|
useTangents: false
|
|
3637
4383
|
};
|
|
3638
|
-
function parseGLTF(device, gltf,
|
|
3639
|
-
const
|
|
3640
|
-
const
|
|
3641
|
-
|
|
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
|
+
})
|
|
3642
4402
|
);
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
const gltfSceneNodes = gltfScene.nodes || [];
|
|
3647
|
-
const nodes = gltfSceneNodes.map((node) => createNode(device, node, gltfNodes, options));
|
|
3648
|
-
const sceneNode = new import_engine3.GroupNode({
|
|
3649
|
-
id: gltfScene.name || gltfScene.id,
|
|
3650
|
-
children: nodes
|
|
4403
|
+
const gltfMaterialIdToMaterialMap = /* @__PURE__ */ new Map();
|
|
4404
|
+
(gltf.materials || []).forEach((gltfMaterial, materialIndex) => {
|
|
4405
|
+
gltfMaterialIdToMaterialMap.set(gltfMaterial.id, materials[materialIndex]);
|
|
3651
4406
|
});
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
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
|
+
);
|
|
3658
4434
|
if (gltfNode.mesh) {
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
id: gltfNode.name || gltfNode.id,
|
|
3663
|
-
children
|
|
3664
|
-
});
|
|
3665
|
-
if (gltfNode.matrix) {
|
|
3666
|
-
node.setMatrix(gltfNode.matrix);
|
|
3667
|
-
} else {
|
|
3668
|
-
node.matrix.identity();
|
|
3669
|
-
if (gltfNode.translation) {
|
|
3670
|
-
node.matrix.translate(gltfNode.translation);
|
|
3671
|
-
}
|
|
3672
|
-
if (gltfNode.rotation) {
|
|
3673
|
-
const rotationMatrix = new Matrix4().fromQuaternion(gltfNode.rotation);
|
|
3674
|
-
node.matrix.multiplyRight(rotationMatrix);
|
|
3675
|
-
}
|
|
3676
|
-
if (gltfNode.scale) {
|
|
3677
|
-
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}`);
|
|
3678
4438
|
}
|
|
4439
|
+
gltfNodeIndexToNodeMap.get(idx).add(mesh);
|
|
3679
4440
|
}
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
if (!gltfMesh._mesh) {
|
|
3688
|
-
const gltfPrimitives = gltfMesh.primitives || [];
|
|
3689
|
-
const primitives = gltfPrimitives.map(
|
|
3690
|
-
(gltfPrimitive, i) => createPrimitive(device, gltfPrimitive, i, gltfMesh, options)
|
|
3691
|
-
);
|
|
3692
|
-
const mesh = new import_engine3.GroupNode({
|
|
3693
|
-
id: gltfMesh.name || gltfMesh.id,
|
|
3694
|
-
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;
|
|
3695
4448
|
});
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
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
|
+
});
|
|
3699
4465
|
}
|
|
3700
|
-
function
|
|
3701
|
-
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}`;
|
|
3702
4495
|
const topology = convertGLDrawModeToTopology(gltfPrimitive.mode || 4);
|
|
3703
4496
|
const vertexCount = gltfPrimitive.indices ? gltfPrimitive.indices.count : getVertexCount(gltfPrimitive.attributes);
|
|
3704
4497
|
const geometry = createGeometry(id, gltfPrimitive, topology);
|
|
3705
|
-
const parsedPPBRMaterial = parsePBRMaterial(
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
options
|
|
3710
|
-
);
|
|
4498
|
+
const parsedPPBRMaterial = parsePBRMaterial(device, gltfPrimitive.material, geometry.attributes, {
|
|
4499
|
+
...options,
|
|
4500
|
+
gltf
|
|
4501
|
+
});
|
|
3711
4502
|
const modelNode = createGLTFModel(device, {
|
|
3712
4503
|
id,
|
|
3713
4504
|
geometry: createGeometry(id, gltfPrimitive, topology),
|
|
4505
|
+
material: gltfPrimitive.material ? gltfMaterialIdToMaterialMap.get(gltfPrimitive.material.id) || null : null,
|
|
3714
4506
|
parsedPPBRMaterial,
|
|
3715
4507
|
modelOptions: options.modelOptions,
|
|
3716
4508
|
vertexCount
|
|
@@ -3727,40 +4519,40 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3727
4519
|
const { components, size, value } = attribute;
|
|
3728
4520
|
attributes[attributeName] = { size: size ?? components, value };
|
|
3729
4521
|
}
|
|
3730
|
-
return new
|
|
4522
|
+
return new import_engine4.Geometry({
|
|
3731
4523
|
id,
|
|
3732
4524
|
topology,
|
|
3733
4525
|
indices: gltfPrimitive.indices.value,
|
|
3734
4526
|
attributes
|
|
3735
4527
|
});
|
|
3736
4528
|
}
|
|
4529
|
+
function getGLTFMaterialId(gltfMaterial, materialIndex) {
|
|
4530
|
+
return gltfMaterial.name || gltfMaterial.id || `material-${materialIndex}`;
|
|
4531
|
+
}
|
|
3737
4532
|
|
|
3738
4533
|
// src/gltf/gltf-animator.ts
|
|
3739
4534
|
var import_core6 = __toESM(require_core(), 1);
|
|
3740
4535
|
|
|
3741
4536
|
// src/gltf/animations/interpolate.ts
|
|
3742
4537
|
var import_core4 = __toESM(require_core(), 1);
|
|
3743
|
-
|
|
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
|
+
}
|
|
3744
4551
|
function interpolate(time, { input, interpolation, output }, target, path) {
|
|
3745
4552
|
const maxTime = input[input.length - 1];
|
|
3746
4553
|
const animationTime = time % maxTime;
|
|
3747
4554
|
const nextIndex = input.findIndex((t) => t >= animationTime);
|
|
3748
4555
|
const previousIndex = Math.max(0, nextIndex - 1);
|
|
3749
|
-
if (!Array.isArray(target[path])) {
|
|
3750
|
-
switch (path) {
|
|
3751
|
-
case "translation":
|
|
3752
|
-
target[path] = [0, 0, 0];
|
|
3753
|
-
break;
|
|
3754
|
-
case "rotation":
|
|
3755
|
-
target[path] = [0, 0, 0, 1];
|
|
3756
|
-
break;
|
|
3757
|
-
case "scale":
|
|
3758
|
-
target[path] = [1, 1, 1];
|
|
3759
|
-
break;
|
|
3760
|
-
default:
|
|
3761
|
-
import_core4.log.warn(`Bad animation path ${path}`)();
|
|
3762
|
-
}
|
|
3763
|
-
}
|
|
3764
4556
|
const previousTime = input[previousIndex];
|
|
3765
4557
|
const nextTime = input[nextIndex];
|
|
3766
4558
|
switch (interpolation) {
|
|
@@ -3770,13 +4562,7 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3770
4562
|
case "LINEAR":
|
|
3771
4563
|
if (nextTime > previousTime) {
|
|
3772
4564
|
const ratio = (animationTime - previousTime) / (nextTime - previousTime);
|
|
3773
|
-
linearInterpolate(
|
|
3774
|
-
target,
|
|
3775
|
-
path,
|
|
3776
|
-
output[previousIndex],
|
|
3777
|
-
output[nextIndex],
|
|
3778
|
-
ratio
|
|
3779
|
-
);
|
|
4565
|
+
linearInterpolate(target, path, output[previousIndex], output[nextIndex], ratio);
|
|
3780
4566
|
}
|
|
3781
4567
|
break;
|
|
3782
4568
|
case "CUBICSPLINE":
|
|
@@ -3796,18 +4582,14 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3796
4582
|
}
|
|
3797
4583
|
}
|
|
3798
4584
|
function linearInterpolate(target, path, start, stop, ratio) {
|
|
3799
|
-
if (!target[path]) {
|
|
3800
|
-
throw new Error();
|
|
3801
|
-
}
|
|
3802
4585
|
if (path === "rotation") {
|
|
3803
|
-
|
|
3804
|
-
for (let i = 0; i < scratchQuaternion.length; i++) {
|
|
3805
|
-
target[path][i] = scratchQuaternion[i];
|
|
3806
|
-
}
|
|
4586
|
+
updateTargetPath(target, path, new Quaternion().slerp({ start, target: stop, ratio }));
|
|
3807
4587
|
} else {
|
|
4588
|
+
const newVal = [];
|
|
3808
4589
|
for (let i = 0; i < start.length; i++) {
|
|
3809
|
-
|
|
4590
|
+
newVal[i] = ratio * stop[i] + (1 - ratio) * start[i];
|
|
3810
4591
|
}
|
|
4592
|
+
updateTargetPath(target, path, newVal);
|
|
3811
4593
|
}
|
|
3812
4594
|
}
|
|
3813
4595
|
function cubicsplineInterpolate(target, path, {
|
|
@@ -3818,53 +4600,62 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3818
4600
|
tDiff,
|
|
3819
4601
|
ratio: t
|
|
3820
4602
|
}) {
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
}
|
|
3824
|
-
for (let i = 0; i < target[path].length; i++) {
|
|
4603
|
+
const newVal = [];
|
|
4604
|
+
for (let i = 0; i < p0.length; i++) {
|
|
3825
4605
|
const m0 = outTangent0[i] * tDiff;
|
|
3826
4606
|
const m1 = inTangent1[i] * tDiff;
|
|
3827
|
-
|
|
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;
|
|
3828
4608
|
}
|
|
4609
|
+
updateTargetPath(target, path, newVal);
|
|
3829
4610
|
}
|
|
3830
4611
|
function stepInterpolate(target, path, value) {
|
|
3831
|
-
|
|
3832
|
-
throw new Error();
|
|
3833
|
-
}
|
|
3834
|
-
for (let i = 0; i < value.length; i++) {
|
|
3835
|
-
target[path][i] = value[i];
|
|
3836
|
-
}
|
|
4612
|
+
updateTargetPath(target, path, value);
|
|
3837
4613
|
}
|
|
3838
4614
|
|
|
3839
4615
|
// src/gltf/gltf-animator.ts
|
|
3840
4616
|
var GLTFSingleAnimator = class {
|
|
4617
|
+
/** Animation definition being played. */
|
|
3841
4618
|
animation;
|
|
4619
|
+
/** Target scenegraph lookup table. */
|
|
4620
|
+
gltfNodeIdToNodeMap;
|
|
4621
|
+
/** Playback start time in seconds. */
|
|
3842
4622
|
startTime = 0;
|
|
4623
|
+
/** Whether playback is currently enabled. */
|
|
3843
4624
|
playing = true;
|
|
4625
|
+
/** Playback speed multiplier. */
|
|
3844
4626
|
speed = 1;
|
|
4627
|
+
/** Creates a single-animation controller. */
|
|
3845
4628
|
constructor(props) {
|
|
3846
4629
|
this.animation = props.animation;
|
|
4630
|
+
this.gltfNodeIdToNodeMap = props.gltfNodeIdToNodeMap;
|
|
3847
4631
|
this.animation.name ||= "unnamed";
|
|
3848
4632
|
Object.assign(this, props);
|
|
3849
4633
|
}
|
|
4634
|
+
/** Advances the animation to the supplied wall-clock time in milliseconds. */
|
|
3850
4635
|
setTime(timeMs) {
|
|
3851
4636
|
if (!this.playing) {
|
|
3852
4637
|
return;
|
|
3853
4638
|
}
|
|
3854
4639
|
const absTime = timeMs / 1e3;
|
|
3855
4640
|
const time = (absTime - this.startTime) * this.speed;
|
|
3856
|
-
this.animation.channels.forEach(({ sampler,
|
|
3857
|
-
|
|
3858
|
-
|
|
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);
|
|
3859
4647
|
});
|
|
3860
4648
|
}
|
|
3861
4649
|
};
|
|
3862
4650
|
var GLTFAnimator = class {
|
|
4651
|
+
/** Individual animation controllers. */
|
|
3863
4652
|
animations;
|
|
4653
|
+
/** Creates an animator for the supplied glTF scenegraph. */
|
|
3864
4654
|
constructor(props) {
|
|
3865
4655
|
this.animations = props.animations.map((animation, index) => {
|
|
3866
4656
|
const name = animation.name || `Animation-${index}`;
|
|
3867
4657
|
return new GLTFSingleAnimator({
|
|
4658
|
+
gltfNodeIdToNodeMap: props.gltfNodeIdToNodeMap,
|
|
3868
4659
|
animation: { name, channels: animation.channels }
|
|
3869
4660
|
});
|
|
3870
4661
|
});
|
|
@@ -3874,27 +4665,18 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3874
4665
|
import_core6.log.warn("GLTFAnimator#animate is deprecated. Use GLTFAnimator#setTime instead")();
|
|
3875
4666
|
this.setTime(time);
|
|
3876
4667
|
}
|
|
4668
|
+
/** Advances every animation to the supplied wall-clock time in milliseconds. */
|
|
3877
4669
|
setTime(time) {
|
|
3878
4670
|
this.animations.forEach((animation) => animation.setTime(time));
|
|
3879
4671
|
}
|
|
4672
|
+
/** Returns the per-animation controllers managed by this animator. */
|
|
3880
4673
|
getAnimations() {
|
|
3881
4674
|
return this.animations;
|
|
3882
4675
|
}
|
|
3883
4676
|
};
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
if (gltfNode.translation) {
|
|
3888
|
-
node.matrix.translate(gltfNode.translation);
|
|
3889
|
-
}
|
|
3890
|
-
if (gltfNode.rotation) {
|
|
3891
|
-
const rotationMatrix = scratchMatrix.fromQuaternion(gltfNode.rotation);
|
|
3892
|
-
node.matrix.multiplyRight(rotationMatrix);
|
|
3893
|
-
}
|
|
3894
|
-
if (gltfNode.scale) {
|
|
3895
|
-
node.matrix.scale(gltfNode.scale);
|
|
3896
|
-
}
|
|
3897
|
-
}
|
|
4677
|
+
|
|
4678
|
+
// src/parsers/parse-gltf-animations.ts
|
|
4679
|
+
var import_core7 = __toESM(require_core(), 1);
|
|
3898
4680
|
|
|
3899
4681
|
// src/webgl-to-webgpu/convert-webgl-attribute.ts
|
|
3900
4682
|
var ATTRIBUTE_TYPE_TO_COMPONENTS = {
|
|
@@ -3926,64 +4708,331 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3926
4708
|
// src/parsers/parse-gltf-animations.ts
|
|
3927
4709
|
function parseGLTFAnimations(gltf) {
|
|
3928
4710
|
const gltfAnimations = gltf.animations || [];
|
|
3929
|
-
|
|
4711
|
+
const accessorCache1D = /* @__PURE__ */ new Map();
|
|
4712
|
+
const accessorCache2D = /* @__PURE__ */ new Map();
|
|
4713
|
+
return gltfAnimations.flatMap((animation, index) => {
|
|
3930
4714
|
const name = animation.name || `Animation-${index}`;
|
|
3931
|
-
const
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
}
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
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 }] : [];
|
|
3944
4746
|
});
|
|
3945
4747
|
}
|
|
3946
|
-
function
|
|
3947
|
-
if (
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
accessor._animation = Array.from(array);
|
|
3951
|
-
} else {
|
|
3952
|
-
const slicedArray = [];
|
|
3953
|
-
for (let i = 0; i < array.length; i += components) {
|
|
3954
|
-
slicedArray.push(Array.from(array.slice(i, i + components)));
|
|
3955
|
-
}
|
|
3956
|
-
accessor._animation = slicedArray;
|
|
3957
|
-
}
|
|
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;
|
|
3958
4752
|
}
|
|
3959
|
-
return
|
|
4753
|
+
return path;
|
|
3960
4754
|
}
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
if (ArrayBuffer.isView(object) || object instanceof ArrayBuffer || object instanceof ImageBitmap) {
|
|
3965
|
-
return object;
|
|
4755
|
+
function accessorToJsArray1D(accessor, accessorCache) {
|
|
4756
|
+
if (accessorCache.has(accessor)) {
|
|
4757
|
+
return accessorCache.get(accessor);
|
|
3966
4758
|
}
|
|
3967
|
-
|
|
3968
|
-
|
|
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);
|
|
4781
|
+
}
|
|
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."
|
|
3969
4913
|
}
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
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
|
+
];
|
|
3974
4929
|
}
|
|
3975
|
-
|
|
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);
|
|
3976
4954
|
}
|
|
3977
|
-
return object;
|
|
3978
4955
|
}
|
|
3979
4956
|
|
|
3980
4957
|
// src/gltf/create-scenegraph-from-gltf.ts
|
|
3981
4958
|
function createScenegraphsFromGLTF(device, gltf, options) {
|
|
3982
|
-
|
|
3983
|
-
const scenes = parseGLTF(device, gltf, options);
|
|
4959
|
+
const { scenes, materials, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap } = parseGLTF(device, gltf, options);
|
|
3984
4960
|
const animations = parseGLTFAnimations(gltf);
|
|
3985
|
-
const animator = new GLTFAnimator({ animations });
|
|
3986
|
-
|
|
4961
|
+
const animator = new GLTFAnimator({ animations, gltfNodeIdToNodeMap });
|
|
4962
|
+
const lights = parseGLTFLights(gltf);
|
|
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);
|
|
3987
5036
|
}
|
|
3988
5037
|
return __toCommonJS(bundle_exports);
|
|
3989
5038
|
})();
|