@luma.gl/gltf 9.3.0-alpha.4 → 9.3.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +397 -220
- 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 +6 -0
- package/dist/gltf/create-gltf-model.d.ts.map +1 -1
- package/dist/gltf/create-gltf-model.js +96 -44
- package/dist/gltf/create-gltf-model.js.map +1 -1
- package/dist/gltf/create-scenegraph-from-gltf.d.ts +15 -1
- package/dist/gltf/create-scenegraph-from-gltf.d.ts.map +1 -1
- package/dist/gltf/create-scenegraph-from-gltf.js +12 -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/index.cjs +378 -210
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- 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 +46 -23
- 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 +40 -12
- package/dist/parsers/parse-gltf-lights.js.map +1 -1
- package/dist/parsers/parse-gltf.d.ts +16 -1
- package/dist/parsers/parse-gltf.d.ts.map +1 -1
- package/dist/parsers/parse-gltf.js +65 -57
- package/dist/parsers/parse-gltf.js.map +1 -1
- package/dist/parsers/parse-pbr-material.d.ts +46 -1
- package/dist/parsers/parse-pbr-material.d.ts.map +1 -1
- package/dist/parsers/parse-pbr-material.js +137 -13
- 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 +1 -0
- package/dist/pbr/pbr-environment.js.map +1 -1
- package/dist/pbr/pbr-material.d.ts +5 -0
- 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 +6 -0
- package/dist/webgl-to-webgpu/convert-webgl-sampler.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-sampler.js +4 -0
- package/dist/webgl-to-webgpu/convert-webgl-sampler.js.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-topology.d.ts +2 -0
- package/dist/webgl-to-webgpu/convert-webgl-topology.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-topology.js +2 -0
- package/dist/webgl-to-webgpu/convert-webgl-topology.js.map +1 -1
- package/package.json +5 -5
- package/src/gltf/animations/animations.ts +17 -5
- package/src/gltf/animations/interpolate.ts +49 -68
- package/src/gltf/create-gltf-model.ts +101 -43
- package/src/gltf/create-scenegraph-from-gltf.ts +39 -11
- package/src/gltf/gltf-animator.ts +34 -25
- package/src/index.ts +1 -2
- package/src/parsers/parse-gltf-animations.ts +63 -26
- package/src/parsers/parse-gltf-lights.ts +51 -13
- package/src/parsers/parse-gltf.ts +90 -77
- package/src/parsers/parse-pbr-material.ts +204 -14
- package/src/pbr/pbr-environment.ts +10 -0
- package/src/pbr/pbr-material.ts +5 -0
- package/src/webgl-to-webgpu/convert-webgl-attribute.ts +12 -1
- package/src/webgl-to-webgpu/convert-webgl-sampler.ts +9 -0
- package/src/webgl-to-webgpu/convert-webgl-topology.ts +2 -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
|
@@ -122,7 +122,7 @@ var __exports__ = (() => {
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
// ../../node_modules/@loaders.gl/images/dist/lib/utils/version.js
|
|
125
|
-
var VERSION = true ? "4.
|
|
125
|
+
var VERSION = true ? "4.4.0-alpha.18" : "latest";
|
|
126
126
|
|
|
127
127
|
// ../../node_modules/@loaders.gl/images/dist/lib/category-api/image-type.js
|
|
128
128
|
var parseImageNode = globalThis.loaders?.parseImageNode;
|
|
@@ -263,7 +263,6 @@ var __exports__ = (() => {
|
|
|
263
263
|
}
|
|
264
264
|
|
|
265
265
|
// ../../node_modules/@loaders.gl/images/dist/lib/parsers/parse-to-image-bitmap.js
|
|
266
|
-
var EMPTY_OBJECT = {};
|
|
267
266
|
var imagebitmapOptionsSupported = true;
|
|
268
267
|
async function parseToImageBitmap(arrayBuffer, options, url) {
|
|
269
268
|
let blob;
|
|
@@ -291,8 +290,13 @@ var __exports__ = (() => {
|
|
|
291
290
|
return await createImageBitmap(blob);
|
|
292
291
|
}
|
|
293
292
|
function isEmptyObject(object) {
|
|
294
|
-
|
|
295
|
-
return
|
|
293
|
+
if (!object) {
|
|
294
|
+
return true;
|
|
295
|
+
}
|
|
296
|
+
for (const key in object) {
|
|
297
|
+
if (Object.prototype.hasOwnProperty.call(object, key)) {
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
296
300
|
}
|
|
297
301
|
return true;
|
|
298
302
|
}
|
|
@@ -681,8 +685,8 @@ var __exports__ = (() => {
|
|
|
681
685
|
}
|
|
682
686
|
|
|
683
687
|
// src/parsers/parse-pbr-material.ts
|
|
684
|
-
var import_constants2 = __toESM(require_constants(), 1);
|
|
685
688
|
var import_core = __toESM(require_core(), 1);
|
|
689
|
+
var import_constants2 = __toESM(require_constants(), 1);
|
|
686
690
|
|
|
687
691
|
// src/webgl-to-webgpu/convert-webgl-sampler.ts
|
|
688
692
|
var import_constants = __toESM(require_constants(), 1);
|
|
@@ -774,6 +778,8 @@ var __exports__ = (() => {
|
|
|
774
778
|
parsedMaterial.defines["HAS_TANGENTS"] = true;
|
|
775
779
|
if (attributes["TEXCOORD_0"])
|
|
776
780
|
parsedMaterial.defines["HAS_UV"] = true;
|
|
781
|
+
if (attributes["JOINTS_0"] && attributes["WEIGHTS_0"])
|
|
782
|
+
parsedMaterial.defines["HAS_SKIN"] = true;
|
|
777
783
|
if (attributes["COLOR_0"])
|
|
778
784
|
parsedMaterial.defines["HAS_COLORS"] = true;
|
|
779
785
|
if (options?.imageBasedLightingEnvironment)
|
|
@@ -873,12 +879,6 @@ var __exports__ = (() => {
|
|
|
873
879
|
}
|
|
874
880
|
function addTexture(device, gltfTexture, uniformName, define, parsedMaterial) {
|
|
875
881
|
const image = gltfTexture.texture.source.image;
|
|
876
|
-
let textureOptions;
|
|
877
|
-
if (image.compressed) {
|
|
878
|
-
textureOptions = image;
|
|
879
|
-
} else {
|
|
880
|
-
textureOptions = { data: image };
|
|
881
|
-
}
|
|
882
882
|
const gltfSampler = {
|
|
883
883
|
wrapS: 10497,
|
|
884
884
|
// default REPEAT S (U) wrapping mode.
|
|
@@ -890,16 +890,122 @@ var __exports__ = (() => {
|
|
|
890
890
|
// default LINEAR filtering
|
|
891
891
|
...gltfTexture?.texture?.sampler
|
|
892
892
|
};
|
|
893
|
-
const
|
|
893
|
+
const baseOptions = {
|
|
894
894
|
id: gltfTexture.uniformName || gltfTexture.id,
|
|
895
|
-
sampler: convertSampler(gltfSampler)
|
|
896
|
-
|
|
897
|
-
|
|
895
|
+
sampler: convertSampler(gltfSampler)
|
|
896
|
+
};
|
|
897
|
+
let texture;
|
|
898
|
+
if (image.compressed) {
|
|
899
|
+
texture = createCompressedTexture(device, image, baseOptions);
|
|
900
|
+
} else {
|
|
901
|
+
const { width, height } = device.getExternalImageSize(image);
|
|
902
|
+
texture = device.createTexture({
|
|
903
|
+
...baseOptions,
|
|
904
|
+
width,
|
|
905
|
+
height,
|
|
906
|
+
data: image
|
|
907
|
+
});
|
|
908
|
+
}
|
|
898
909
|
parsedMaterial.bindings[uniformName] = texture;
|
|
899
910
|
if (define)
|
|
900
911
|
parsedMaterial.defines[define] = true;
|
|
901
912
|
parsedMaterial.generatedTextures.push(texture);
|
|
902
913
|
}
|
|
914
|
+
function createCompressedTextureFallback(device, baseOptions) {
|
|
915
|
+
return device.createTexture({
|
|
916
|
+
...baseOptions,
|
|
917
|
+
format: "rgba8unorm",
|
|
918
|
+
width: 1,
|
|
919
|
+
height: 1,
|
|
920
|
+
mipLevels: 1
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
function resolveCompressedTextureFormat(level) {
|
|
924
|
+
return level.textureFormat;
|
|
925
|
+
}
|
|
926
|
+
function getMaxCompressedMipLevels(baseWidth, baseHeight, format) {
|
|
927
|
+
const { blockWidth = 1, blockHeight = 1 } = import_core.textureFormatDecoder.getInfo(format);
|
|
928
|
+
let count = 1;
|
|
929
|
+
for (let i = 1; ; i++) {
|
|
930
|
+
const w = Math.max(1, baseWidth >> i);
|
|
931
|
+
const h = Math.max(1, baseHeight >> i);
|
|
932
|
+
if (w < blockWidth || h < blockHeight)
|
|
933
|
+
break;
|
|
934
|
+
count++;
|
|
935
|
+
}
|
|
936
|
+
return count;
|
|
937
|
+
}
|
|
938
|
+
function createCompressedTexture(device, image, baseOptions) {
|
|
939
|
+
let levels;
|
|
940
|
+
if (Array.isArray(image.data) && image.data[0]?.data) {
|
|
941
|
+
levels = image.data;
|
|
942
|
+
} else if ("mipmaps" in image && Array.isArray(image.mipmaps)) {
|
|
943
|
+
levels = image.mipmaps;
|
|
944
|
+
} else {
|
|
945
|
+
levels = [];
|
|
946
|
+
}
|
|
947
|
+
if (levels.length === 0 || !levels[0]?.data) {
|
|
948
|
+
import_core.log.warn(
|
|
949
|
+
"createCompressedTexture: compressed image has no valid mip levels, creating fallback"
|
|
950
|
+
)();
|
|
951
|
+
return createCompressedTextureFallback(device, baseOptions);
|
|
952
|
+
}
|
|
953
|
+
const baseLevel = levels[0];
|
|
954
|
+
const baseWidth = baseLevel.width ?? image.width ?? 0;
|
|
955
|
+
const baseHeight = baseLevel.height ?? image.height ?? 0;
|
|
956
|
+
if (baseWidth <= 0 || baseHeight <= 0) {
|
|
957
|
+
import_core.log.warn("createCompressedTexture: base level has invalid dimensions, creating fallback")();
|
|
958
|
+
return createCompressedTextureFallback(device, baseOptions);
|
|
959
|
+
}
|
|
960
|
+
const format = resolveCompressedTextureFormat(baseLevel);
|
|
961
|
+
if (!format) {
|
|
962
|
+
import_core.log.warn("createCompressedTexture: compressed image has no textureFormat, creating fallback")();
|
|
963
|
+
return createCompressedTextureFallback(device, baseOptions);
|
|
964
|
+
}
|
|
965
|
+
const maxMipLevels = getMaxCompressedMipLevels(baseWidth, baseHeight, format);
|
|
966
|
+
const levelLimit = Math.min(levels.length, maxMipLevels);
|
|
967
|
+
let validLevelCount = 1;
|
|
968
|
+
for (let i = 1; i < levelLimit; i++) {
|
|
969
|
+
const level = levels[i];
|
|
970
|
+
if (!level.data || level.width <= 0 || level.height <= 0) {
|
|
971
|
+
import_core.log.warn(`createCompressedTexture: mip level ${i} has invalid data/dimensions, truncating`)();
|
|
972
|
+
break;
|
|
973
|
+
}
|
|
974
|
+
const levelFormat = resolveCompressedTextureFormat(level);
|
|
975
|
+
if (levelFormat && levelFormat !== format) {
|
|
976
|
+
import_core.log.warn(
|
|
977
|
+
`createCompressedTexture: mip level ${i} format '${levelFormat}' differs from base '${format}', truncating`
|
|
978
|
+
)();
|
|
979
|
+
break;
|
|
980
|
+
}
|
|
981
|
+
const expectedW = Math.max(1, baseWidth >> i);
|
|
982
|
+
const expectedH = Math.max(1, baseHeight >> i);
|
|
983
|
+
if (level.width !== expectedW || level.height !== expectedH) {
|
|
984
|
+
import_core.log.warn(
|
|
985
|
+
`createCompressedTexture: mip level ${i} dimensions ${level.width}x${level.height} don't match expected ${expectedW}x${expectedH}, truncating`
|
|
986
|
+
)();
|
|
987
|
+
break;
|
|
988
|
+
}
|
|
989
|
+
validLevelCount++;
|
|
990
|
+
}
|
|
991
|
+
const texture = device.createTexture({
|
|
992
|
+
...baseOptions,
|
|
993
|
+
format,
|
|
994
|
+
usage: import_core.Texture.TEXTURE | import_core.Texture.COPY_DST,
|
|
995
|
+
width: baseWidth,
|
|
996
|
+
height: baseHeight,
|
|
997
|
+
mipLevels: validLevelCount,
|
|
998
|
+
data: baseLevel.data
|
|
999
|
+
});
|
|
1000
|
+
for (let i = 1; i < validLevelCount; i++) {
|
|
1001
|
+
texture.writeData(levels[i].data, {
|
|
1002
|
+
width: levels[i].width,
|
|
1003
|
+
height: levels[i].height,
|
|
1004
|
+
mipLevel: i
|
|
1005
|
+
});
|
|
1006
|
+
}
|
|
1007
|
+
return texture;
|
|
1008
|
+
}
|
|
903
1009
|
|
|
904
1010
|
// ../../node_modules/@math.gl/core/dist/lib/common.js
|
|
905
1011
|
var RADIANS_TO_DEGREES = 1 / Math.PI * 180;
|
|
@@ -3474,17 +3580,20 @@ var __exports__ = (() => {
|
|
|
3474
3580
|
|
|
3475
3581
|
// src/parsers/parse-gltf-lights.ts
|
|
3476
3582
|
function parseGLTFLights(gltf) {
|
|
3477
|
-
const lightDefs =
|
|
3583
|
+
const lightDefs = (
|
|
3584
|
+
// `postProcessGLTF()` moves KHR_lights_punctual into `gltf.lights`.
|
|
3585
|
+
gltf.lights || gltf.extensions?.["KHR_lights_punctual"]?.["lights"]
|
|
3586
|
+
);
|
|
3478
3587
|
if (!lightDefs || !Array.isArray(lightDefs) || lightDefs.length === 0) {
|
|
3479
3588
|
return [];
|
|
3480
3589
|
}
|
|
3481
3590
|
const lights = [];
|
|
3482
3591
|
for (const node of gltf.nodes || []) {
|
|
3483
|
-
const
|
|
3484
|
-
if (
|
|
3592
|
+
const lightIndex = node.light ?? node.extensions?.KHR_lights_punctual?.light;
|
|
3593
|
+
if (typeof lightIndex !== "number") {
|
|
3485
3594
|
continue;
|
|
3486
3595
|
}
|
|
3487
|
-
const gltfLight = lightDefs[
|
|
3596
|
+
const gltfLight = lightDefs[lightIndex];
|
|
3488
3597
|
if (!gltfLight) {
|
|
3489
3598
|
continue;
|
|
3490
3599
|
}
|
|
@@ -3508,7 +3617,7 @@ var __exports__ = (() => {
|
|
|
3508
3617
|
return lights;
|
|
3509
3618
|
}
|
|
3510
3619
|
function parsePointLight(node, color, intensity, range) {
|
|
3511
|
-
const position = node
|
|
3620
|
+
const position = getNodePosition(node);
|
|
3512
3621
|
let attenuation = [1, 0, 0];
|
|
3513
3622
|
if (range !== void 0 && range > 0) {
|
|
3514
3623
|
attenuation = [1, 0, 1 / (range * range)];
|
|
@@ -3522,11 +3631,7 @@ var __exports__ = (() => {
|
|
|
3522
3631
|
};
|
|
3523
3632
|
}
|
|
3524
3633
|
function parseDirectionalLight(node, color, intensity) {
|
|
3525
|
-
|
|
3526
|
-
if (node.rotation) {
|
|
3527
|
-
const orientation = new Matrix4().fromQuaternion(node.rotation);
|
|
3528
|
-
direction = orientation.transformDirection([0, 0, -1]);
|
|
3529
|
-
}
|
|
3634
|
+
const direction = getNodeDirection(node);
|
|
3530
3635
|
return {
|
|
3531
3636
|
type: "directional",
|
|
3532
3637
|
direction,
|
|
@@ -3534,6 +3639,24 @@ var __exports__ = (() => {
|
|
|
3534
3639
|
intensity
|
|
3535
3640
|
};
|
|
3536
3641
|
}
|
|
3642
|
+
function getNodePosition(node) {
|
|
3643
|
+
if (node.matrix) {
|
|
3644
|
+
return new Matrix4(node.matrix).transformAsPoint([0, 0, 0]);
|
|
3645
|
+
}
|
|
3646
|
+
if (node.translation) {
|
|
3647
|
+
return [...node.translation];
|
|
3648
|
+
}
|
|
3649
|
+
return [0, 0, 0];
|
|
3650
|
+
}
|
|
3651
|
+
function getNodeDirection(node) {
|
|
3652
|
+
if (node.matrix) {
|
|
3653
|
+
return new Matrix4(node.matrix).transformDirection([0, 0, -1]);
|
|
3654
|
+
}
|
|
3655
|
+
if (node.rotation) {
|
|
3656
|
+
return new Matrix4().fromQuaternion(node.rotation).transformDirection([0, 0, -1]);
|
|
3657
|
+
}
|
|
3658
|
+
return [0, 0, -1];
|
|
3659
|
+
}
|
|
3537
3660
|
|
|
3538
3661
|
// src/parsers/parse-gltf.ts
|
|
3539
3662
|
var import_engine3 = __toESM(require_engine(), 1);
|
|
@@ -3563,50 +3686,88 @@ var __exports__ = (() => {
|
|
|
3563
3686
|
var SHADER = (
|
|
3564
3687
|
/* WGSL */
|
|
3565
3688
|
`
|
|
3566
|
-
|
|
3689
|
+
struct VertexInputs {
|
|
3690
|
+
@location(0) positions: vec3f,
|
|
3691
|
+
#ifdef HAS_NORMALS
|
|
3692
|
+
@location(1) normals: vec3f,
|
|
3693
|
+
#endif
|
|
3694
|
+
#ifdef HAS_TANGENTS
|
|
3695
|
+
@location(2) TANGENT: vec4f,
|
|
3696
|
+
#endif
|
|
3697
|
+
#ifdef HAS_UV
|
|
3698
|
+
@location(3) texCoords: vec2f,
|
|
3699
|
+
#endif
|
|
3700
|
+
#ifdef HAS_SKIN
|
|
3701
|
+
@location(4) JOINTS_0: vec4u,
|
|
3702
|
+
@location(5) WEIGHTS_0: vec4f,
|
|
3703
|
+
#endif
|
|
3704
|
+
};
|
|
3567
3705
|
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
// in vec2 TEXCOORD_0;
|
|
3578
|
-
in vec2 texCoords;
|
|
3579
|
-
#endif
|
|
3706
|
+
struct FragmentInputs {
|
|
3707
|
+
@builtin(position) position: vec4f,
|
|
3708
|
+
@location(0) pbrPosition: vec3f,
|
|
3709
|
+
@location(1) pbrUV: vec2f,
|
|
3710
|
+
@location(2) pbrNormal: vec3f,
|
|
3711
|
+
#ifdef HAS_TANGENTS
|
|
3712
|
+
@location(3) pbrTangent: vec4f,
|
|
3713
|
+
#endif
|
|
3714
|
+
};
|
|
3580
3715
|
|
|
3581
3716
|
@vertex
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3717
|
+
fn vertexMain(inputs: VertexInputs) -> FragmentInputs {
|
|
3718
|
+
var outputs: FragmentInputs;
|
|
3719
|
+
var position = vec4f(inputs.positions, 1.0);
|
|
3720
|
+
var normal = vec3f(0.0, 0.0, 1.0);
|
|
3721
|
+
var tangent = vec4f(1.0, 0.0, 0.0, 1.0);
|
|
3722
|
+
var uv = vec2f(0.0, 0.0);
|
|
3586
3723
|
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3724
|
+
#ifdef HAS_NORMALS
|
|
3725
|
+
normal = inputs.normals;
|
|
3726
|
+
#endif
|
|
3727
|
+
#ifdef HAS_UV
|
|
3728
|
+
uv = inputs.texCoords;
|
|
3729
|
+
#endif
|
|
3730
|
+
#ifdef HAS_TANGENTS
|
|
3731
|
+
tangent = inputs.TANGENT;
|
|
3732
|
+
#endif
|
|
3733
|
+
#ifdef HAS_SKIN
|
|
3734
|
+
let skinMatrix = getSkinMatrix(inputs.WEIGHTS_0, inputs.JOINTS_0);
|
|
3735
|
+
position = skinMatrix * position;
|
|
3736
|
+
normal = normalize((skinMatrix * vec4f(normal, 0.0)).xyz);
|
|
3737
|
+
#ifdef HAS_TANGENTS
|
|
3738
|
+
tangent = vec4f(normalize((skinMatrix * vec4f(tangent.xyz, 0.0)).xyz), tangent.w);
|
|
3739
|
+
#endif
|
|
3740
|
+
#endif
|
|
3590
3741
|
|
|
3591
|
-
|
|
3592
|
-
_TANGENT = TANGENT;
|
|
3593
|
-
#endif
|
|
3742
|
+
let worldPosition = pbrProjection.modelMatrix * position;
|
|
3594
3743
|
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3744
|
+
#ifdef HAS_NORMALS
|
|
3745
|
+
normal = normalize((pbrProjection.normalMatrix * vec4f(normal, 0.0)).xyz);
|
|
3746
|
+
#endif
|
|
3747
|
+
#ifdef HAS_TANGENTS
|
|
3748
|
+
let worldTangent = normalize((pbrProjection.modelMatrix * vec4f(tangent.xyz, 0.0)).xyz);
|
|
3749
|
+
outputs.pbrTangent = vec4f(worldTangent, tangent.w);
|
|
3750
|
+
#endif
|
|
3598
3751
|
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3752
|
+
outputs.position = pbrProjection.modelViewProjectionMatrix * position;
|
|
3753
|
+
outputs.pbrPosition = worldPosition.xyz / worldPosition.w;
|
|
3754
|
+
outputs.pbrUV = uv;
|
|
3755
|
+
outputs.pbrNormal = normal;
|
|
3756
|
+
return outputs;
|
|
3757
|
+
}
|
|
3602
3758
|
|
|
3603
3759
|
@fragment
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3760
|
+
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
3761
|
+
fragmentInputs.pbr_vPosition = inputs.pbrPosition;
|
|
3762
|
+
fragmentInputs.pbr_vUV = inputs.pbrUV;
|
|
3763
|
+
fragmentInputs.pbr_vNormal = inputs.pbrNormal;
|
|
3764
|
+
#ifdef HAS_TANGENTS
|
|
3765
|
+
let tangent = normalize(inputs.pbrTangent.xyz);
|
|
3766
|
+
let bitangent = normalize(cross(inputs.pbrNormal, tangent)) * inputs.pbrTangent.w;
|
|
3767
|
+
fragmentInputs.pbr_vTBN = mat3x3f(tangent, bitangent, inputs.pbrNormal);
|
|
3768
|
+
#endif
|
|
3769
|
+
return pbr_filterColor(vec4f(1.0));
|
|
3770
|
+
}
|
|
3610
3771
|
`
|
|
3611
3772
|
);
|
|
3612
3773
|
var vs = (
|
|
@@ -3630,6 +3791,11 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3630
3791
|
in vec2 texCoords;
|
|
3631
3792
|
#endif
|
|
3632
3793
|
|
|
3794
|
+
#ifdef HAS_SKIN
|
|
3795
|
+
in uvec4 JOINTS_0;
|
|
3796
|
+
in vec4 WEIGHTS_0;
|
|
3797
|
+
#endif
|
|
3798
|
+
|
|
3633
3799
|
void main(void) {
|
|
3634
3800
|
vec4 _NORMAL = vec4(0.);
|
|
3635
3801
|
vec4 _TANGENT = vec4(0.);
|
|
@@ -3647,8 +3813,17 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3647
3813
|
_TEXCOORD_0 = texCoords;
|
|
3648
3814
|
#endif
|
|
3649
3815
|
|
|
3650
|
-
|
|
3651
|
-
|
|
3816
|
+
vec4 pos = positions;
|
|
3817
|
+
|
|
3818
|
+
#ifdef HAS_SKIN
|
|
3819
|
+
mat4 skinMat = getSkinMatrix(WEIGHTS_0, JOINTS_0);
|
|
3820
|
+
pos = skinMat * pos;
|
|
3821
|
+
_NORMAL = skinMat * _NORMAL;
|
|
3822
|
+
_TANGENT = vec4((skinMat * vec4(_TANGENT.xyz, 0.)).xyz, _TANGENT.w);
|
|
3823
|
+
#endif
|
|
3824
|
+
|
|
3825
|
+
pbr_setPositionNormalTangentUV(pos, _NORMAL, _TANGENT, _TEXCOORD_0);
|
|
3826
|
+
gl_Position = pbrProjection.modelViewProjectionMatrix * pos;
|
|
3652
3827
|
}
|
|
3653
3828
|
`
|
|
3654
3829
|
);
|
|
@@ -3681,7 +3856,7 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3681
3856
|
geometry,
|
|
3682
3857
|
topology: geometry.topology,
|
|
3683
3858
|
vertexCount,
|
|
3684
|
-
modules: [import_shadertools.pbrMaterial],
|
|
3859
|
+
modules: [import_shadertools.pbrMaterial, import_shadertools.skin],
|
|
3685
3860
|
...modelOptions,
|
|
3686
3861
|
defines: { ...parsedPPBRMaterial.defines, ...modelOptions.defines },
|
|
3687
3862
|
parameters: { ...parameters, ...parsedPPBRMaterial.parameters, ...modelOptions.parameters }
|
|
@@ -3705,69 +3880,73 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3705
3880
|
lights: true,
|
|
3706
3881
|
useTangents: false
|
|
3707
3882
|
};
|
|
3708
|
-
function parseGLTF(device, gltf,
|
|
3709
|
-
const
|
|
3710
|
-
const
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
}
|
|
3715
|
-
function createScene(device, gltfScene, gltfNodes, options) {
|
|
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
|
|
3883
|
+
function parseGLTF(device, gltf, options = {}) {
|
|
3884
|
+
const combinedOptions = { ...defaultOptions, ...options };
|
|
3885
|
+
const gltfMeshIdToNodeMap = /* @__PURE__ */ new Map();
|
|
3886
|
+
gltf.meshes.forEach((gltfMesh, idx) => {
|
|
3887
|
+
const newMesh = createNodeForGLTFMesh(device, gltfMesh, combinedOptions);
|
|
3888
|
+
gltfMeshIdToNodeMap.set(gltfMesh.id, newMesh);
|
|
3721
3889
|
});
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3890
|
+
const gltfNodeIndexToNodeMap = /* @__PURE__ */ new Map();
|
|
3891
|
+
const gltfNodeIdToNodeMap = /* @__PURE__ */ new Map();
|
|
3892
|
+
gltf.nodes.forEach((gltfNode, idx) => {
|
|
3893
|
+
const newNode = createNodeForGLTFNode(device, gltfNode, combinedOptions);
|
|
3894
|
+
gltfNodeIndexToNodeMap.set(idx, newNode);
|
|
3895
|
+
gltfNodeIdToNodeMap.set(gltfNode.id, newNode);
|
|
3896
|
+
});
|
|
3897
|
+
gltf.nodes.forEach((gltfNode, idx) => {
|
|
3898
|
+
gltfNodeIndexToNodeMap.get(idx).add(
|
|
3899
|
+
(gltfNode.children ?? []).map(({ id }) => {
|
|
3900
|
+
const child = gltfNodeIdToNodeMap.get(id);
|
|
3901
|
+
if (!child)
|
|
3902
|
+
throw new Error(`Cannot find child ${id} of node ${idx}`);
|
|
3903
|
+
return child;
|
|
3904
|
+
})
|
|
3905
|
+
);
|
|
3728
3906
|
if (gltfNode.mesh) {
|
|
3729
|
-
|
|
3907
|
+
const mesh = gltfMeshIdToNodeMap.get(gltfNode.mesh.id);
|
|
3908
|
+
if (!mesh) {
|
|
3909
|
+
throw new Error(`Cannot find mesh child ${gltfNode.mesh.id} of node ${idx}`);
|
|
3910
|
+
}
|
|
3911
|
+
gltfNodeIndexToNodeMap.get(idx).add(mesh);
|
|
3730
3912
|
}
|
|
3731
|
-
|
|
3732
|
-
|
|
3913
|
+
});
|
|
3914
|
+
const scenes = gltf.scenes.map((gltfScene) => {
|
|
3915
|
+
const children = (gltfScene.nodes || []).map(({ id }) => {
|
|
3916
|
+
const child = gltfNodeIdToNodeMap.get(id);
|
|
3917
|
+
if (!child)
|
|
3918
|
+
throw new Error(`Cannot find child ${id} of scene ${gltfScene.name || gltfScene.id}`);
|
|
3919
|
+
return child;
|
|
3920
|
+
});
|
|
3921
|
+
return new import_engine3.GroupNode({
|
|
3922
|
+
id: gltfScene.name || gltfScene.id,
|
|
3733
3923
|
children
|
|
3734
3924
|
});
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
node.matrix.scale(gltfNode.scale);
|
|
3748
|
-
}
|
|
3749
|
-
}
|
|
3750
|
-
gltfNode._node = node;
|
|
3751
|
-
}
|
|
3752
|
-
const topLevelNode = gltfNodes.find((node) => node.id === gltfNode.id);
|
|
3753
|
-
topLevelNode._node = gltfNode._node;
|
|
3754
|
-
return gltfNode._node;
|
|
3925
|
+
});
|
|
3926
|
+
return { scenes, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap };
|
|
3927
|
+
}
|
|
3928
|
+
function createNodeForGLTFNode(device, gltfNode, options) {
|
|
3929
|
+
return new import_engine3.GroupNode({
|
|
3930
|
+
id: gltfNode.name || gltfNode.id,
|
|
3931
|
+
children: [],
|
|
3932
|
+
matrix: gltfNode.matrix,
|
|
3933
|
+
position: gltfNode.translation,
|
|
3934
|
+
rotation: gltfNode.rotation,
|
|
3935
|
+
scale: gltfNode.scale
|
|
3936
|
+
});
|
|
3755
3937
|
}
|
|
3756
|
-
function
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
gltfMesh._mesh = mesh;
|
|
3767
|
-
}
|
|
3768
|
-
return gltfMesh._mesh;
|
|
3938
|
+
function createNodeForGLTFMesh(device, gltfMesh, options) {
|
|
3939
|
+
const gltfPrimitives = gltfMesh.primitives || [];
|
|
3940
|
+
const primitives = gltfPrimitives.map(
|
|
3941
|
+
(gltfPrimitive, i) => createNodeForGLTFPrimitive(device, gltfPrimitive, i, gltfMesh, options)
|
|
3942
|
+
);
|
|
3943
|
+
const mesh = new import_engine3.GroupNode({
|
|
3944
|
+
id: gltfMesh.name || gltfMesh.id,
|
|
3945
|
+
children: primitives
|
|
3946
|
+
});
|
|
3947
|
+
return mesh;
|
|
3769
3948
|
}
|
|
3770
|
-
function
|
|
3949
|
+
function createNodeForGLTFPrimitive(device, gltfPrimitive, i, gltfMesh, options) {
|
|
3771
3950
|
const id = gltfPrimitive.name || `${gltfMesh.name || gltfMesh.id}-primitive-${i}`;
|
|
3772
3951
|
const topology = convertGLDrawModeToTopology(gltfPrimitive.mode || 4);
|
|
3773
3952
|
const vertexCount = gltfPrimitive.indices ? gltfPrimitive.indices.count : getVertexCount(gltfPrimitive.attributes);
|
|
@@ -3806,31 +3985,28 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3806
3985
|
}
|
|
3807
3986
|
|
|
3808
3987
|
// src/gltf/gltf-animator.ts
|
|
3809
|
-
var
|
|
3988
|
+
var import_core6 = __toESM(require_core(), 1);
|
|
3810
3989
|
|
|
3811
3990
|
// src/gltf/animations/interpolate.ts
|
|
3812
|
-
var
|
|
3813
|
-
|
|
3991
|
+
var import_core4 = __toESM(require_core(), 1);
|
|
3992
|
+
function updateTargetPath(target, path, newValue) {
|
|
3993
|
+
switch (path) {
|
|
3994
|
+
case "translation":
|
|
3995
|
+
return target.setPosition(newValue).updateMatrix();
|
|
3996
|
+
case "rotation":
|
|
3997
|
+
return target.setRotation(newValue).updateMatrix();
|
|
3998
|
+
case "scale":
|
|
3999
|
+
return target.setScale(newValue).updateMatrix();
|
|
4000
|
+
default:
|
|
4001
|
+
import_core4.log.warn(`Bad animation path ${path}`)();
|
|
4002
|
+
return null;
|
|
4003
|
+
}
|
|
4004
|
+
}
|
|
3814
4005
|
function interpolate(time, { input, interpolation, output }, target, path) {
|
|
3815
4006
|
const maxTime = input[input.length - 1];
|
|
3816
4007
|
const animationTime = time % maxTime;
|
|
3817
4008
|
const nextIndex = input.findIndex((t) => t >= animationTime);
|
|
3818
4009
|
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
4010
|
const previousTime = input[previousIndex];
|
|
3835
4011
|
const nextTime = input[nextIndex];
|
|
3836
4012
|
switch (interpolation) {
|
|
@@ -3840,13 +4016,7 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3840
4016
|
case "LINEAR":
|
|
3841
4017
|
if (nextTime > previousTime) {
|
|
3842
4018
|
const ratio = (animationTime - previousTime) / (nextTime - previousTime);
|
|
3843
|
-
linearInterpolate(
|
|
3844
|
-
target,
|
|
3845
|
-
path,
|
|
3846
|
-
output[previousIndex],
|
|
3847
|
-
output[nextIndex],
|
|
3848
|
-
ratio
|
|
3849
|
-
);
|
|
4019
|
+
linearInterpolate(target, path, output[previousIndex], output[nextIndex], ratio);
|
|
3850
4020
|
}
|
|
3851
4021
|
break;
|
|
3852
4022
|
case "CUBICSPLINE":
|
|
@@ -3861,23 +4031,19 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3861
4031
|
}
|
|
3862
4032
|
break;
|
|
3863
4033
|
default:
|
|
3864
|
-
|
|
4034
|
+
import_core4.log.warn(`Interpolation ${interpolation} not supported`)();
|
|
3865
4035
|
break;
|
|
3866
4036
|
}
|
|
3867
4037
|
}
|
|
3868
4038
|
function linearInterpolate(target, path, start, stop, ratio) {
|
|
3869
|
-
if (!target[path]) {
|
|
3870
|
-
throw new Error();
|
|
3871
|
-
}
|
|
3872
4039
|
if (path === "rotation") {
|
|
3873
|
-
|
|
3874
|
-
for (let i = 0; i < scratchQuaternion.length; i++) {
|
|
3875
|
-
target[path][i] = scratchQuaternion[i];
|
|
3876
|
-
}
|
|
4040
|
+
updateTargetPath(target, path, new Quaternion().slerp({ start, target: stop, ratio }));
|
|
3877
4041
|
} else {
|
|
4042
|
+
const newVal = [];
|
|
3878
4043
|
for (let i = 0; i < start.length; i++) {
|
|
3879
|
-
|
|
4044
|
+
newVal[i] = ratio * stop[i] + (1 - ratio) * start[i];
|
|
3880
4045
|
}
|
|
4046
|
+
updateTargetPath(target, path, newVal);
|
|
3881
4047
|
}
|
|
3882
4048
|
}
|
|
3883
4049
|
function cubicsplineInterpolate(target, path, {
|
|
@@ -3888,83 +4054,80 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3888
4054
|
tDiff,
|
|
3889
4055
|
ratio: t
|
|
3890
4056
|
}) {
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
}
|
|
3894
|
-
for (let i = 0; i < target[path].length; i++) {
|
|
4057
|
+
const newVal = [];
|
|
4058
|
+
for (let i = 0; i < p0.length; i++) {
|
|
3895
4059
|
const m0 = outTangent0[i] * tDiff;
|
|
3896
4060
|
const m1 = inTangent1[i] * tDiff;
|
|
3897
|
-
|
|
4061
|
+
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
4062
|
}
|
|
4063
|
+
updateTargetPath(target, path, newVal);
|
|
3899
4064
|
}
|
|
3900
4065
|
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
|
-
}
|
|
4066
|
+
updateTargetPath(target, path, value);
|
|
3907
4067
|
}
|
|
3908
4068
|
|
|
3909
4069
|
// src/gltf/gltf-animator.ts
|
|
3910
4070
|
var GLTFSingleAnimator = class {
|
|
4071
|
+
/** Animation definition being played. */
|
|
3911
4072
|
animation;
|
|
4073
|
+
/** Target scenegraph lookup table. */
|
|
4074
|
+
gltfNodeIdToNodeMap;
|
|
4075
|
+
/** Playback start time in seconds. */
|
|
3912
4076
|
startTime = 0;
|
|
4077
|
+
/** Whether playback is currently enabled. */
|
|
3913
4078
|
playing = true;
|
|
4079
|
+
/** Playback speed multiplier. */
|
|
3914
4080
|
speed = 1;
|
|
4081
|
+
/** Creates a single-animation controller. */
|
|
3915
4082
|
constructor(props) {
|
|
3916
4083
|
this.animation = props.animation;
|
|
4084
|
+
this.gltfNodeIdToNodeMap = props.gltfNodeIdToNodeMap;
|
|
3917
4085
|
this.animation.name ||= "unnamed";
|
|
3918
4086
|
Object.assign(this, props);
|
|
3919
4087
|
}
|
|
4088
|
+
/** Advances the animation to the supplied wall-clock time in milliseconds. */
|
|
3920
4089
|
setTime(timeMs) {
|
|
3921
4090
|
if (!this.playing) {
|
|
3922
4091
|
return;
|
|
3923
4092
|
}
|
|
3924
4093
|
const absTime = timeMs / 1e3;
|
|
3925
4094
|
const time = (absTime - this.startTime) * this.speed;
|
|
3926
|
-
this.animation.channels.forEach(({ sampler,
|
|
3927
|
-
|
|
3928
|
-
|
|
4095
|
+
this.animation.channels.forEach(({ sampler, targetNodeId, path }) => {
|
|
4096
|
+
const targetNode = this.gltfNodeIdToNodeMap.get(targetNodeId);
|
|
4097
|
+
if (!targetNode) {
|
|
4098
|
+
throw new Error(`Cannot find animation target node ${targetNodeId}`);
|
|
4099
|
+
}
|
|
4100
|
+
interpolate(time, sampler, targetNode, path);
|
|
3929
4101
|
});
|
|
3930
4102
|
}
|
|
3931
4103
|
};
|
|
3932
4104
|
var GLTFAnimator = class {
|
|
4105
|
+
/** Individual animation controllers. */
|
|
3933
4106
|
animations;
|
|
4107
|
+
/** Creates an animator for the supplied glTF scenegraph. */
|
|
3934
4108
|
constructor(props) {
|
|
3935
4109
|
this.animations = props.animations.map((animation, index) => {
|
|
3936
4110
|
const name = animation.name || `Animation-${index}`;
|
|
3937
4111
|
return new GLTFSingleAnimator({
|
|
4112
|
+
gltfNodeIdToNodeMap: props.gltfNodeIdToNodeMap,
|
|
3938
4113
|
animation: { name, channels: animation.channels }
|
|
3939
4114
|
});
|
|
3940
4115
|
});
|
|
3941
4116
|
}
|
|
3942
4117
|
/** @deprecated Use .setTime(). Will be removed (deck.gl is using this) */
|
|
3943
4118
|
animate(time) {
|
|
3944
|
-
|
|
4119
|
+
import_core6.log.warn("GLTFAnimator#animate is deprecated. Use GLTFAnimator#setTime instead")();
|
|
3945
4120
|
this.setTime(time);
|
|
3946
4121
|
}
|
|
4122
|
+
/** Advances every animation to the supplied wall-clock time in milliseconds. */
|
|
3947
4123
|
setTime(time) {
|
|
3948
4124
|
this.animations.forEach((animation) => animation.setTime(time));
|
|
3949
4125
|
}
|
|
4126
|
+
/** Returns the per-animation controllers managed by this animator. */
|
|
3950
4127
|
getAnimations() {
|
|
3951
4128
|
return this.animations;
|
|
3952
4129
|
}
|
|
3953
4130
|
};
|
|
3954
|
-
var scratchMatrix = new Matrix4();
|
|
3955
|
-
function applyTranslationRotationScale(gltfNode, node) {
|
|
3956
|
-
node.matrix.identity();
|
|
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
|
-
}
|
|
3968
4131
|
|
|
3969
4132
|
// src/webgl-to-webgpu/convert-webgl-attribute.ts
|
|
3970
4133
|
var ATTRIBUTE_TYPE_TO_COMPONENTS = {
|
|
@@ -3996,65 +4159,79 @@ layout(0) positions: vec4; // in vec4 POSITION;
|
|
|
3996
4159
|
// src/parsers/parse-gltf-animations.ts
|
|
3997
4160
|
function parseGLTFAnimations(gltf) {
|
|
3998
4161
|
const gltfAnimations = gltf.animations || [];
|
|
4162
|
+
const accessorCache1D = /* @__PURE__ */ new Map();
|
|
4163
|
+
const accessorCache2D = /* @__PURE__ */ new Map();
|
|
3999
4164
|
return gltfAnimations.map((animation, index) => {
|
|
4000
4165
|
const name = animation.name || `Animation-${index}`;
|
|
4001
4166
|
const samplers = animation.samplers.map(
|
|
4002
4167
|
({ input, interpolation = "LINEAR", output }) => ({
|
|
4003
|
-
input:
|
|
4168
|
+
input: accessorToJsArray1D(gltf.accessors[input], accessorCache1D),
|
|
4004
4169
|
interpolation,
|
|
4005
|
-
output:
|
|
4170
|
+
output: accessorToJsArray2D(gltf.accessors[output], accessorCache2D)
|
|
4006
4171
|
})
|
|
4007
4172
|
);
|
|
4008
|
-
const channels = animation.channels.map(({ sampler, target }) =>
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4173
|
+
const channels = animation.channels.map(({ sampler, target }) => {
|
|
4174
|
+
const targetNode = gltf.nodes[target.node ?? 0];
|
|
4175
|
+
if (!targetNode) {
|
|
4176
|
+
throw new Error(`Cannot find animation target ${target.node}`);
|
|
4177
|
+
}
|
|
4178
|
+
return {
|
|
4179
|
+
sampler: samplers[sampler],
|
|
4180
|
+
targetNodeId: targetNode.id,
|
|
4181
|
+
path: target.path
|
|
4182
|
+
};
|
|
4183
|
+
});
|
|
4013
4184
|
return { name, channels };
|
|
4014
4185
|
});
|
|
4015
4186
|
}
|
|
4016
|
-
function
|
|
4017
|
-
if (
|
|
4018
|
-
|
|
4019
|
-
if (components === 1) {
|
|
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
|
-
}
|
|
4187
|
+
function accessorToJsArray1D(accessor, accessorCache) {
|
|
4188
|
+
if (accessorCache.has(accessor)) {
|
|
4189
|
+
return accessorCache.get(accessor);
|
|
4028
4190
|
}
|
|
4029
|
-
|
|
4191
|
+
const { typedArray: array, components } = accessorToTypedArray(accessor);
|
|
4192
|
+
assert3(components === 1, "accessorToJsArray1D must have exactly 1 component");
|
|
4193
|
+
const result = Array.from(array);
|
|
4194
|
+
accessorCache.set(accessor, result);
|
|
4195
|
+
return result;
|
|
4030
4196
|
}
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
if (ArrayBuffer.isView(object) || object instanceof ArrayBuffer || object instanceof ImageBitmap) {
|
|
4035
|
-
return object;
|
|
4197
|
+
function accessorToJsArray2D(accessor, accessorCache) {
|
|
4198
|
+
if (accessorCache.has(accessor)) {
|
|
4199
|
+
return accessorCache.get(accessor);
|
|
4036
4200
|
}
|
|
4037
|
-
|
|
4038
|
-
|
|
4201
|
+
const { typedArray: array, components } = accessorToTypedArray(accessor);
|
|
4202
|
+
assert3(components > 1, "accessorToJsArray2D must have more than 1 component");
|
|
4203
|
+
const result = [];
|
|
4204
|
+
for (let i = 0; i < array.length; i += components) {
|
|
4205
|
+
result.push(Array.from(array.slice(i, i + components)));
|
|
4039
4206
|
}
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4207
|
+
accessorCache.set(accessor, result);
|
|
4208
|
+
return result;
|
|
4209
|
+
}
|
|
4210
|
+
function assert3(condition, message) {
|
|
4211
|
+
if (!condition) {
|
|
4212
|
+
throw new Error(message);
|
|
4046
4213
|
}
|
|
4047
|
-
return object;
|
|
4048
4214
|
}
|
|
4049
4215
|
|
|
4050
4216
|
// src/gltf/create-scenegraph-from-gltf.ts
|
|
4051
4217
|
function createScenegraphsFromGLTF(device, gltf, options) {
|
|
4052
|
-
|
|
4053
|
-
|
|
4218
|
+
const { scenes, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap } = parseGLTF(
|
|
4219
|
+
device,
|
|
4220
|
+
gltf,
|
|
4221
|
+
options
|
|
4222
|
+
);
|
|
4054
4223
|
const animations = parseGLTFAnimations(gltf);
|
|
4055
|
-
const animator = new GLTFAnimator({ animations });
|
|
4224
|
+
const animator = new GLTFAnimator({ animations, gltfNodeIdToNodeMap });
|
|
4056
4225
|
const lights = parseGLTFLights(gltf);
|
|
4057
|
-
return {
|
|
4226
|
+
return {
|
|
4227
|
+
scenes,
|
|
4228
|
+
animator,
|
|
4229
|
+
lights,
|
|
4230
|
+
gltfMeshIdToNodeMap,
|
|
4231
|
+
gltfNodeIdToNodeMap,
|
|
4232
|
+
gltfNodeIndexToNodeMap,
|
|
4233
|
+
gltf
|
|
4234
|
+
};
|
|
4058
4235
|
}
|
|
4059
4236
|
return __toCommonJS(bundle_exports);
|
|
4060
4237
|
})();
|