@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/index.cjs
CHANGED
|
@@ -93,8 +93,8 @@ function makeCube(device, { id, getTextureForFace, sampler }) {
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
// dist/parsers/parse-pbr-material.js
|
|
96
|
-
var import_constants2 = require("@luma.gl/constants");
|
|
97
96
|
var import_core = require("@luma.gl/core");
|
|
97
|
+
var import_constants2 = require("@luma.gl/constants");
|
|
98
98
|
|
|
99
99
|
// dist/webgl-to-webgpu/convert-webgl-sampler.js
|
|
100
100
|
var import_constants = require("@luma.gl/constants");
|
|
@@ -186,6 +186,8 @@ function parsePBRMaterial(device, material, attributes, options) {
|
|
|
186
186
|
parsedMaterial.defines["HAS_TANGENTS"] = true;
|
|
187
187
|
if (attributes["TEXCOORD_0"])
|
|
188
188
|
parsedMaterial.defines["HAS_UV"] = true;
|
|
189
|
+
if (attributes["JOINTS_0"] && attributes["WEIGHTS_0"])
|
|
190
|
+
parsedMaterial.defines["HAS_SKIN"] = true;
|
|
189
191
|
if (attributes["COLOR_0"])
|
|
190
192
|
parsedMaterial.defines["HAS_COLORS"] = true;
|
|
191
193
|
if (options == null ? void 0 : options.imageBasedLightingEnvironment)
|
|
@@ -256,12 +258,6 @@ function parsePbrMetallicRoughness(device, pbrMetallicRoughness, parsedMaterial)
|
|
|
256
258
|
function addTexture(device, gltfTexture, uniformName, define, parsedMaterial) {
|
|
257
259
|
var _a;
|
|
258
260
|
const image = gltfTexture.texture.source.image;
|
|
259
|
-
let textureOptions;
|
|
260
|
-
if (image.compressed) {
|
|
261
|
-
textureOptions = image;
|
|
262
|
-
} else {
|
|
263
|
-
textureOptions = { data: image };
|
|
264
|
-
}
|
|
265
261
|
const gltfSampler = {
|
|
266
262
|
wrapS: 10497,
|
|
267
263
|
// default REPEAT S (U) wrapping mode.
|
|
@@ -273,32 +269,136 @@ function addTexture(device, gltfTexture, uniformName, define, parsedMaterial) {
|
|
|
273
269
|
// default LINEAR filtering
|
|
274
270
|
...(_a = gltfTexture == null ? void 0 : gltfTexture.texture) == null ? void 0 : _a.sampler
|
|
275
271
|
};
|
|
276
|
-
const
|
|
272
|
+
const baseOptions = {
|
|
277
273
|
id: gltfTexture.uniformName || gltfTexture.id,
|
|
278
|
-
sampler: convertSampler(gltfSampler)
|
|
279
|
-
|
|
280
|
-
|
|
274
|
+
sampler: convertSampler(gltfSampler)
|
|
275
|
+
};
|
|
276
|
+
let texture;
|
|
277
|
+
if (image.compressed) {
|
|
278
|
+
texture = createCompressedTexture(device, image, baseOptions);
|
|
279
|
+
} else {
|
|
280
|
+
const { width, height } = device.getExternalImageSize(image);
|
|
281
|
+
texture = device.createTexture({
|
|
282
|
+
...baseOptions,
|
|
283
|
+
width,
|
|
284
|
+
height,
|
|
285
|
+
data: image
|
|
286
|
+
});
|
|
287
|
+
}
|
|
281
288
|
parsedMaterial.bindings[uniformName] = texture;
|
|
282
289
|
if (define)
|
|
283
290
|
parsedMaterial.defines[define] = true;
|
|
284
291
|
parsedMaterial.generatedTextures.push(texture);
|
|
285
292
|
}
|
|
293
|
+
function createCompressedTextureFallback(device, baseOptions) {
|
|
294
|
+
return device.createTexture({
|
|
295
|
+
...baseOptions,
|
|
296
|
+
format: "rgba8unorm",
|
|
297
|
+
width: 1,
|
|
298
|
+
height: 1,
|
|
299
|
+
mipLevels: 1
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
function resolveCompressedTextureFormat(level) {
|
|
303
|
+
return level.textureFormat;
|
|
304
|
+
}
|
|
305
|
+
function getMaxCompressedMipLevels(baseWidth, baseHeight, format) {
|
|
306
|
+
const { blockWidth = 1, blockHeight = 1 } = import_core.textureFormatDecoder.getInfo(format);
|
|
307
|
+
let count = 1;
|
|
308
|
+
for (let i = 1; ; i++) {
|
|
309
|
+
const w = Math.max(1, baseWidth >> i);
|
|
310
|
+
const h = Math.max(1, baseHeight >> i);
|
|
311
|
+
if (w < blockWidth || h < blockHeight)
|
|
312
|
+
break;
|
|
313
|
+
count++;
|
|
314
|
+
}
|
|
315
|
+
return count;
|
|
316
|
+
}
|
|
317
|
+
function createCompressedTexture(device, image, baseOptions) {
|
|
318
|
+
var _a, _b;
|
|
319
|
+
let levels;
|
|
320
|
+
if (Array.isArray(image.data) && ((_a = image.data[0]) == null ? void 0 : _a.data)) {
|
|
321
|
+
levels = image.data;
|
|
322
|
+
} else if ("mipmaps" in image && Array.isArray(image.mipmaps)) {
|
|
323
|
+
levels = image.mipmaps;
|
|
324
|
+
} else {
|
|
325
|
+
levels = [];
|
|
326
|
+
}
|
|
327
|
+
if (levels.length === 0 || !((_b = levels[0]) == null ? void 0 : _b.data)) {
|
|
328
|
+
import_core.log.warn("createCompressedTexture: compressed image has no valid mip levels, creating fallback")();
|
|
329
|
+
return createCompressedTextureFallback(device, baseOptions);
|
|
330
|
+
}
|
|
331
|
+
const baseLevel = levels[0];
|
|
332
|
+
const baseWidth = baseLevel.width ?? image.width ?? 0;
|
|
333
|
+
const baseHeight = baseLevel.height ?? image.height ?? 0;
|
|
334
|
+
if (baseWidth <= 0 || baseHeight <= 0) {
|
|
335
|
+
import_core.log.warn("createCompressedTexture: base level has invalid dimensions, creating fallback")();
|
|
336
|
+
return createCompressedTextureFallback(device, baseOptions);
|
|
337
|
+
}
|
|
338
|
+
const format = resolveCompressedTextureFormat(baseLevel);
|
|
339
|
+
if (!format) {
|
|
340
|
+
import_core.log.warn("createCompressedTexture: compressed image has no textureFormat, creating fallback")();
|
|
341
|
+
return createCompressedTextureFallback(device, baseOptions);
|
|
342
|
+
}
|
|
343
|
+
const maxMipLevels = getMaxCompressedMipLevels(baseWidth, baseHeight, format);
|
|
344
|
+
const levelLimit = Math.min(levels.length, maxMipLevels);
|
|
345
|
+
let validLevelCount = 1;
|
|
346
|
+
for (let i = 1; i < levelLimit; i++) {
|
|
347
|
+
const level = levels[i];
|
|
348
|
+
if (!level.data || level.width <= 0 || level.height <= 0) {
|
|
349
|
+
import_core.log.warn(`createCompressedTexture: mip level ${i} has invalid data/dimensions, truncating`)();
|
|
350
|
+
break;
|
|
351
|
+
}
|
|
352
|
+
const levelFormat = resolveCompressedTextureFormat(level);
|
|
353
|
+
if (levelFormat && levelFormat !== format) {
|
|
354
|
+
import_core.log.warn(`createCompressedTexture: mip level ${i} format '${levelFormat}' differs from base '${format}', truncating`)();
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
const expectedW = Math.max(1, baseWidth >> i);
|
|
358
|
+
const expectedH = Math.max(1, baseHeight >> i);
|
|
359
|
+
if (level.width !== expectedW || level.height !== expectedH) {
|
|
360
|
+
import_core.log.warn(`createCompressedTexture: mip level ${i} dimensions ${level.width}x${level.height} don't match expected ${expectedW}x${expectedH}, truncating`)();
|
|
361
|
+
break;
|
|
362
|
+
}
|
|
363
|
+
validLevelCount++;
|
|
364
|
+
}
|
|
365
|
+
const texture = device.createTexture({
|
|
366
|
+
...baseOptions,
|
|
367
|
+
format,
|
|
368
|
+
usage: import_core.Texture.TEXTURE | import_core.Texture.COPY_DST,
|
|
369
|
+
width: baseWidth,
|
|
370
|
+
height: baseHeight,
|
|
371
|
+
mipLevels: validLevelCount,
|
|
372
|
+
data: baseLevel.data
|
|
373
|
+
});
|
|
374
|
+
for (let i = 1; i < validLevelCount; i++) {
|
|
375
|
+
texture.writeData(levels[i].data, {
|
|
376
|
+
width: levels[i].width,
|
|
377
|
+
height: levels[i].height,
|
|
378
|
+
mipLevel: i
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
return texture;
|
|
382
|
+
}
|
|
286
383
|
|
|
287
384
|
// dist/parsers/parse-gltf-lights.js
|
|
288
385
|
var import_core2 = require("@math.gl/core");
|
|
289
386
|
function parseGLTFLights(gltf) {
|
|
290
|
-
var _a, _b, _c;
|
|
291
|
-
const lightDefs = (
|
|
387
|
+
var _a, _b, _c, _d;
|
|
388
|
+
const lightDefs = (
|
|
389
|
+
// `postProcessGLTF()` moves KHR_lights_punctual into `gltf.lights`.
|
|
390
|
+
gltf.lights || ((_b = (_a = gltf.extensions) == null ? void 0 : _a["KHR_lights_punctual"]) == null ? void 0 : _b["lights"])
|
|
391
|
+
);
|
|
292
392
|
if (!lightDefs || !Array.isArray(lightDefs) || lightDefs.length === 0) {
|
|
293
393
|
return [];
|
|
294
394
|
}
|
|
295
395
|
const lights = [];
|
|
296
396
|
for (const node of gltf.nodes || []) {
|
|
297
|
-
const
|
|
298
|
-
if (
|
|
397
|
+
const lightIndex = node.light ?? ((_d = (_c = node.extensions) == null ? void 0 : _c.KHR_lights_punctual) == null ? void 0 : _d.light);
|
|
398
|
+
if (typeof lightIndex !== "number") {
|
|
299
399
|
continue;
|
|
300
400
|
}
|
|
301
|
-
const gltfLight = lightDefs[
|
|
401
|
+
const gltfLight = lightDefs[lightIndex];
|
|
302
402
|
if (!gltfLight) {
|
|
303
403
|
continue;
|
|
304
404
|
}
|
|
@@ -322,7 +422,7 @@ function parseGLTFLights(gltf) {
|
|
|
322
422
|
return lights;
|
|
323
423
|
}
|
|
324
424
|
function parsePointLight(node, color, intensity, range) {
|
|
325
|
-
const position = node
|
|
425
|
+
const position = getNodePosition(node);
|
|
326
426
|
let attenuation = [1, 0, 0];
|
|
327
427
|
if (range !== void 0 && range > 0) {
|
|
328
428
|
attenuation = [1, 0, 1 / (range * range)];
|
|
@@ -336,11 +436,7 @@ function parsePointLight(node, color, intensity, range) {
|
|
|
336
436
|
};
|
|
337
437
|
}
|
|
338
438
|
function parseDirectionalLight(node, color, intensity) {
|
|
339
|
-
|
|
340
|
-
if (node.rotation) {
|
|
341
|
-
const orientation = new import_core2.Matrix4().fromQuaternion(node.rotation);
|
|
342
|
-
direction = orientation.transformDirection([0, 0, -1]);
|
|
343
|
-
}
|
|
439
|
+
const direction = getNodeDirection(node);
|
|
344
440
|
return {
|
|
345
441
|
type: "directional",
|
|
346
442
|
direction,
|
|
@@ -348,10 +444,27 @@ function parseDirectionalLight(node, color, intensity) {
|
|
|
348
444
|
intensity
|
|
349
445
|
};
|
|
350
446
|
}
|
|
447
|
+
function getNodePosition(node) {
|
|
448
|
+
if (node.matrix) {
|
|
449
|
+
return new import_core2.Matrix4(node.matrix).transformAsPoint([0, 0, 0]);
|
|
450
|
+
}
|
|
451
|
+
if (node.translation) {
|
|
452
|
+
return [...node.translation];
|
|
453
|
+
}
|
|
454
|
+
return [0, 0, 0];
|
|
455
|
+
}
|
|
456
|
+
function getNodeDirection(node) {
|
|
457
|
+
if (node.matrix) {
|
|
458
|
+
return new import_core2.Matrix4(node.matrix).transformDirection([0, 0, -1]);
|
|
459
|
+
}
|
|
460
|
+
if (node.rotation) {
|
|
461
|
+
return new import_core2.Matrix4().fromQuaternion(node.rotation).transformDirection([0, 0, -1]);
|
|
462
|
+
}
|
|
463
|
+
return [0, 0, -1];
|
|
464
|
+
}
|
|
351
465
|
|
|
352
466
|
// dist/parsers/parse-gltf.js
|
|
353
467
|
var import_engine3 = require("@luma.gl/engine");
|
|
354
|
-
var import_core4 = require("@math.gl/core");
|
|
355
468
|
|
|
356
469
|
// dist/webgl-to-webgpu/convert-webgl-topology.js
|
|
357
470
|
var GLEnum;
|
|
@@ -388,50 +501,88 @@ var import_engine2 = require("@luma.gl/engine");
|
|
|
388
501
|
var SHADER = (
|
|
389
502
|
/* WGSL */
|
|
390
503
|
`
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
504
|
+
struct VertexInputs {
|
|
505
|
+
@location(0) positions: vec3f,
|
|
506
|
+
#ifdef HAS_NORMALS
|
|
507
|
+
@location(1) normals: vec3f,
|
|
508
|
+
#endif
|
|
509
|
+
#ifdef HAS_TANGENTS
|
|
510
|
+
@location(2) TANGENT: vec4f,
|
|
511
|
+
#endif
|
|
512
|
+
#ifdef HAS_UV
|
|
513
|
+
@location(3) texCoords: vec2f,
|
|
514
|
+
#endif
|
|
515
|
+
#ifdef HAS_SKIN
|
|
516
|
+
@location(4) JOINTS_0: vec4u,
|
|
517
|
+
@location(5) WEIGHTS_0: vec4f,
|
|
518
|
+
#endif
|
|
519
|
+
};
|
|
400
520
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
521
|
+
struct FragmentInputs {
|
|
522
|
+
@builtin(position) position: vec4f,
|
|
523
|
+
@location(0) pbrPosition: vec3f,
|
|
524
|
+
@location(1) pbrUV: vec2f,
|
|
525
|
+
@location(2) pbrNormal: vec3f,
|
|
526
|
+
#ifdef HAS_TANGENTS
|
|
527
|
+
@location(3) pbrTangent: vec4f,
|
|
528
|
+
#endif
|
|
529
|
+
};
|
|
405
530
|
|
|
406
531
|
@vertex
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
532
|
+
fn vertexMain(inputs: VertexInputs) -> FragmentInputs {
|
|
533
|
+
var outputs: FragmentInputs;
|
|
534
|
+
var position = vec4f(inputs.positions, 1.0);
|
|
535
|
+
var normal = vec3f(0.0, 0.0, 1.0);
|
|
536
|
+
var tangent = vec4f(1.0, 0.0, 0.0, 1.0);
|
|
537
|
+
var uv = vec2f(0.0, 0.0);
|
|
411
538
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
539
|
+
#ifdef HAS_NORMALS
|
|
540
|
+
normal = inputs.normals;
|
|
541
|
+
#endif
|
|
542
|
+
#ifdef HAS_UV
|
|
543
|
+
uv = inputs.texCoords;
|
|
544
|
+
#endif
|
|
545
|
+
#ifdef HAS_TANGENTS
|
|
546
|
+
tangent = inputs.TANGENT;
|
|
547
|
+
#endif
|
|
548
|
+
#ifdef HAS_SKIN
|
|
549
|
+
let skinMatrix = getSkinMatrix(inputs.WEIGHTS_0, inputs.JOINTS_0);
|
|
550
|
+
position = skinMatrix * position;
|
|
551
|
+
normal = normalize((skinMatrix * vec4f(normal, 0.0)).xyz);
|
|
552
|
+
#ifdef HAS_TANGENTS
|
|
553
|
+
tangent = vec4f(normalize((skinMatrix * vec4f(tangent.xyz, 0.0)).xyz), tangent.w);
|
|
554
|
+
#endif
|
|
555
|
+
#endif
|
|
415
556
|
|
|
416
|
-
|
|
417
|
-
_TANGENT = TANGENT;
|
|
418
|
-
#endif
|
|
557
|
+
let worldPosition = pbrProjection.modelMatrix * position;
|
|
419
558
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
559
|
+
#ifdef HAS_NORMALS
|
|
560
|
+
normal = normalize((pbrProjection.normalMatrix * vec4f(normal, 0.0)).xyz);
|
|
561
|
+
#endif
|
|
562
|
+
#ifdef HAS_TANGENTS
|
|
563
|
+
let worldTangent = normalize((pbrProjection.modelMatrix * vec4f(tangent.xyz, 0.0)).xyz);
|
|
564
|
+
outputs.pbrTangent = vec4f(worldTangent, tangent.w);
|
|
565
|
+
#endif
|
|
423
566
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
567
|
+
outputs.position = pbrProjection.modelViewProjectionMatrix * position;
|
|
568
|
+
outputs.pbrPosition = worldPosition.xyz / worldPosition.w;
|
|
569
|
+
outputs.pbrUV = uv;
|
|
570
|
+
outputs.pbrNormal = normal;
|
|
571
|
+
return outputs;
|
|
572
|
+
}
|
|
427
573
|
|
|
428
574
|
@fragment
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
575
|
+
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
576
|
+
fragmentInputs.pbr_vPosition = inputs.pbrPosition;
|
|
577
|
+
fragmentInputs.pbr_vUV = inputs.pbrUV;
|
|
578
|
+
fragmentInputs.pbr_vNormal = inputs.pbrNormal;
|
|
579
|
+
#ifdef HAS_TANGENTS
|
|
580
|
+
let tangent = normalize(inputs.pbrTangent.xyz);
|
|
581
|
+
let bitangent = normalize(cross(inputs.pbrNormal, tangent)) * inputs.pbrTangent.w;
|
|
582
|
+
fragmentInputs.pbr_vTBN = mat3x3f(tangent, bitangent, inputs.pbrNormal);
|
|
583
|
+
#endif
|
|
584
|
+
return pbr_filterColor(vec4f(1.0));
|
|
585
|
+
}
|
|
435
586
|
`
|
|
436
587
|
);
|
|
437
588
|
var vs = (
|
|
@@ -455,6 +606,11 @@ var vs = (
|
|
|
455
606
|
in vec2 texCoords;
|
|
456
607
|
#endif
|
|
457
608
|
|
|
609
|
+
#ifdef HAS_SKIN
|
|
610
|
+
in uvec4 JOINTS_0;
|
|
611
|
+
in vec4 WEIGHTS_0;
|
|
612
|
+
#endif
|
|
613
|
+
|
|
458
614
|
void main(void) {
|
|
459
615
|
vec4 _NORMAL = vec4(0.);
|
|
460
616
|
vec4 _TANGENT = vec4(0.);
|
|
@@ -472,8 +628,17 @@ var vs = (
|
|
|
472
628
|
_TEXCOORD_0 = texCoords;
|
|
473
629
|
#endif
|
|
474
630
|
|
|
475
|
-
|
|
476
|
-
|
|
631
|
+
vec4 pos = positions;
|
|
632
|
+
|
|
633
|
+
#ifdef HAS_SKIN
|
|
634
|
+
mat4 skinMat = getSkinMatrix(WEIGHTS_0, JOINTS_0);
|
|
635
|
+
pos = skinMat * pos;
|
|
636
|
+
_NORMAL = skinMat * _NORMAL;
|
|
637
|
+
_TANGENT = vec4((skinMat * vec4(_TANGENT.xyz, 0.)).xyz, _TANGENT.w);
|
|
638
|
+
#endif
|
|
639
|
+
|
|
640
|
+
pbr_setPositionNormalTangentUV(pos, _NORMAL, _TANGENT, _TEXCOORD_0);
|
|
641
|
+
gl_Position = pbrProjection.modelViewProjectionMatrix * pos;
|
|
477
642
|
}
|
|
478
643
|
`
|
|
479
644
|
);
|
|
@@ -506,7 +671,7 @@ function createGLTFModel(device, options) {
|
|
|
506
671
|
geometry,
|
|
507
672
|
topology: geometry.topology,
|
|
508
673
|
vertexCount,
|
|
509
|
-
modules: [import_shadertools.pbrMaterial],
|
|
674
|
+
modules: [import_shadertools.pbrMaterial, import_shadertools.skin],
|
|
510
675
|
...modelOptions,
|
|
511
676
|
defines: { ...parsedPPBRMaterial.defines, ...modelOptions.defines },
|
|
512
677
|
parameters: { ...parameters, ...parsedPPBRMaterial.parameters, ...modelOptions.parameters }
|
|
@@ -530,65 +695,69 @@ var defaultOptions = {
|
|
|
530
695
|
lights: true,
|
|
531
696
|
useTangents: false
|
|
532
697
|
};
|
|
533
|
-
function parseGLTF(device, gltf,
|
|
534
|
-
const
|
|
535
|
-
const
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
const gltfSceneNodes = gltfScene.nodes || [];
|
|
540
|
-
const nodes = gltfSceneNodes.map((node) => createNode(device, node, gltfNodes, options));
|
|
541
|
-
const sceneNode = new import_engine3.GroupNode({
|
|
542
|
-
id: gltfScene.name || gltfScene.id,
|
|
543
|
-
children: nodes
|
|
698
|
+
function parseGLTF(device, gltf, options = {}) {
|
|
699
|
+
const combinedOptions = { ...defaultOptions, ...options };
|
|
700
|
+
const gltfMeshIdToNodeMap = /* @__PURE__ */ new Map();
|
|
701
|
+
gltf.meshes.forEach((gltfMesh, idx) => {
|
|
702
|
+
const newMesh = createNodeForGLTFMesh(device, gltfMesh, combinedOptions);
|
|
703
|
+
gltfMeshIdToNodeMap.set(gltfMesh.id, newMesh);
|
|
544
704
|
});
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
705
|
+
const gltfNodeIndexToNodeMap = /* @__PURE__ */ new Map();
|
|
706
|
+
const gltfNodeIdToNodeMap = /* @__PURE__ */ new Map();
|
|
707
|
+
gltf.nodes.forEach((gltfNode, idx) => {
|
|
708
|
+
const newNode = createNodeForGLTFNode(device, gltfNode, combinedOptions);
|
|
709
|
+
gltfNodeIndexToNodeMap.set(idx, newNode);
|
|
710
|
+
gltfNodeIdToNodeMap.set(gltfNode.id, newNode);
|
|
711
|
+
});
|
|
712
|
+
gltf.nodes.forEach((gltfNode, idx) => {
|
|
713
|
+
gltfNodeIndexToNodeMap.get(idx).add((gltfNode.children ?? []).map(({ id }) => {
|
|
714
|
+
const child = gltfNodeIdToNodeMap.get(id);
|
|
715
|
+
if (!child)
|
|
716
|
+
throw new Error(`Cannot find child ${id} of node ${idx}`);
|
|
717
|
+
return child;
|
|
718
|
+
}));
|
|
551
719
|
if (gltfNode.mesh) {
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
id: gltfNode.name || gltfNode.id,
|
|
556
|
-
children
|
|
557
|
-
});
|
|
558
|
-
if (gltfNode.matrix) {
|
|
559
|
-
node.setMatrix(gltfNode.matrix);
|
|
560
|
-
} else {
|
|
561
|
-
node.matrix.identity();
|
|
562
|
-
if (gltfNode.translation) {
|
|
563
|
-
node.matrix.translate(gltfNode.translation);
|
|
564
|
-
}
|
|
565
|
-
if (gltfNode.rotation) {
|
|
566
|
-
const rotationMatrix = new import_core4.Matrix4().fromQuaternion(gltfNode.rotation);
|
|
567
|
-
node.matrix.multiplyRight(rotationMatrix);
|
|
568
|
-
}
|
|
569
|
-
if (gltfNode.scale) {
|
|
570
|
-
node.matrix.scale(gltfNode.scale);
|
|
720
|
+
const mesh = gltfMeshIdToNodeMap.get(gltfNode.mesh.id);
|
|
721
|
+
if (!mesh) {
|
|
722
|
+
throw new Error(`Cannot find mesh child ${gltfNode.mesh.id} of node ${idx}`);
|
|
571
723
|
}
|
|
724
|
+
gltfNodeIndexToNodeMap.get(idx).add(mesh);
|
|
572
725
|
}
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
if (!gltfMesh._mesh) {
|
|
581
|
-
const gltfPrimitives = gltfMesh.primitives || [];
|
|
582
|
-
const primitives = gltfPrimitives.map((gltfPrimitive, i) => createPrimitive(device, gltfPrimitive, i, gltfMesh, options));
|
|
583
|
-
const mesh = new import_engine3.GroupNode({
|
|
584
|
-
id: gltfMesh.name || gltfMesh.id,
|
|
585
|
-
children: primitives
|
|
726
|
+
});
|
|
727
|
+
const scenes = gltf.scenes.map((gltfScene) => {
|
|
728
|
+
const children = (gltfScene.nodes || []).map(({ id }) => {
|
|
729
|
+
const child = gltfNodeIdToNodeMap.get(id);
|
|
730
|
+
if (!child)
|
|
731
|
+
throw new Error(`Cannot find child ${id} of scene ${gltfScene.name || gltfScene.id}`);
|
|
732
|
+
return child;
|
|
586
733
|
});
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
734
|
+
return new import_engine3.GroupNode({
|
|
735
|
+
id: gltfScene.name || gltfScene.id,
|
|
736
|
+
children
|
|
737
|
+
});
|
|
738
|
+
});
|
|
739
|
+
return { scenes, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap };
|
|
590
740
|
}
|
|
591
|
-
function
|
|
741
|
+
function createNodeForGLTFNode(device, gltfNode, options) {
|
|
742
|
+
return new import_engine3.GroupNode({
|
|
743
|
+
id: gltfNode.name || gltfNode.id,
|
|
744
|
+
children: [],
|
|
745
|
+
matrix: gltfNode.matrix,
|
|
746
|
+
position: gltfNode.translation,
|
|
747
|
+
rotation: gltfNode.rotation,
|
|
748
|
+
scale: gltfNode.scale
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
function createNodeForGLTFMesh(device, gltfMesh, options) {
|
|
752
|
+
const gltfPrimitives = gltfMesh.primitives || [];
|
|
753
|
+
const primitives = gltfPrimitives.map((gltfPrimitive, i) => createNodeForGLTFPrimitive(device, gltfPrimitive, i, gltfMesh, options));
|
|
754
|
+
const mesh = new import_engine3.GroupNode({
|
|
755
|
+
id: gltfMesh.name || gltfMesh.id,
|
|
756
|
+
children: primitives
|
|
757
|
+
});
|
|
758
|
+
return mesh;
|
|
759
|
+
}
|
|
760
|
+
function createNodeForGLTFPrimitive(device, gltfPrimitive, i, gltfMesh, options) {
|
|
592
761
|
const id = gltfPrimitive.name || `${gltfMesh.name || gltfMesh.id}-primitive-${i}`;
|
|
593
762
|
const topology = convertGLDrawModeToTopology(gltfPrimitive.mode || 4);
|
|
594
763
|
const vertexCount = gltfPrimitive.indices ? gltfPrimitive.indices.count : getVertexCount(gltfPrimitive.attributes);
|
|
@@ -622,33 +791,29 @@ function createGeometry(id, gltfPrimitive, topology) {
|
|
|
622
791
|
}
|
|
623
792
|
|
|
624
793
|
// dist/gltf/gltf-animator.js
|
|
625
|
-
var
|
|
626
|
-
var import_core8 = require("@math.gl/core");
|
|
794
|
+
var import_core6 = require("@luma.gl/core");
|
|
627
795
|
|
|
628
796
|
// dist/gltf/animations/interpolate.js
|
|
629
|
-
var
|
|
630
|
-
var
|
|
631
|
-
|
|
797
|
+
var import_core4 = require("@luma.gl/core");
|
|
798
|
+
var import_core5 = require("@math.gl/core");
|
|
799
|
+
function updateTargetPath(target, path, newValue) {
|
|
800
|
+
switch (path) {
|
|
801
|
+
case "translation":
|
|
802
|
+
return target.setPosition(newValue).updateMatrix();
|
|
803
|
+
case "rotation":
|
|
804
|
+
return target.setRotation(newValue).updateMatrix();
|
|
805
|
+
case "scale":
|
|
806
|
+
return target.setScale(newValue).updateMatrix();
|
|
807
|
+
default:
|
|
808
|
+
import_core4.log.warn(`Bad animation path ${path}`)();
|
|
809
|
+
return null;
|
|
810
|
+
}
|
|
811
|
+
}
|
|
632
812
|
function interpolate(time, { input, interpolation, output }, target, path) {
|
|
633
813
|
const maxTime = input[input.length - 1];
|
|
634
814
|
const animationTime = time % maxTime;
|
|
635
815
|
const nextIndex = input.findIndex((t) => t >= animationTime);
|
|
636
816
|
const previousIndex = Math.max(0, nextIndex - 1);
|
|
637
|
-
if (!Array.isArray(target[path])) {
|
|
638
|
-
switch (path) {
|
|
639
|
-
case "translation":
|
|
640
|
-
target[path] = [0, 0, 0];
|
|
641
|
-
break;
|
|
642
|
-
case "rotation":
|
|
643
|
-
target[path] = [0, 0, 0, 1];
|
|
644
|
-
break;
|
|
645
|
-
case "scale":
|
|
646
|
-
target[path] = [1, 1, 1];
|
|
647
|
-
break;
|
|
648
|
-
default:
|
|
649
|
-
import_core5.log.warn(`Bad animation path ${path}`)();
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
817
|
const previousTime = input[previousIndex];
|
|
653
818
|
const nextTime = input[nextIndex];
|
|
654
819
|
switch (interpolation) {
|
|
@@ -673,103 +838,96 @@ function interpolate(time, { input, interpolation, output }, target, path) {
|
|
|
673
838
|
}
|
|
674
839
|
break;
|
|
675
840
|
default:
|
|
676
|
-
|
|
841
|
+
import_core4.log.warn(`Interpolation ${interpolation} not supported`)();
|
|
677
842
|
break;
|
|
678
843
|
}
|
|
679
844
|
}
|
|
680
845
|
function linearInterpolate(target, path, start, stop, ratio) {
|
|
681
|
-
if (!target[path]) {
|
|
682
|
-
throw new Error();
|
|
683
|
-
}
|
|
684
846
|
if (path === "rotation") {
|
|
685
|
-
|
|
686
|
-
for (let i = 0; i < scratchQuaternion.length; i++) {
|
|
687
|
-
target[path][i] = scratchQuaternion[i];
|
|
688
|
-
}
|
|
847
|
+
updateTargetPath(target, path, new import_core5.Quaternion().slerp({ start, target: stop, ratio }));
|
|
689
848
|
} else {
|
|
849
|
+
const newVal = [];
|
|
690
850
|
for (let i = 0; i < start.length; i++) {
|
|
691
|
-
|
|
851
|
+
newVal[i] = ratio * stop[i] + (1 - ratio) * start[i];
|
|
692
852
|
}
|
|
853
|
+
updateTargetPath(target, path, newVal);
|
|
693
854
|
}
|
|
694
855
|
}
|
|
695
856
|
function cubicsplineInterpolate(target, path, { p0, outTangent0, inTangent1, p1, tDiff, ratio: t }) {
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
}
|
|
699
|
-
for (let i = 0; i < target[path].length; i++) {
|
|
857
|
+
const newVal = [];
|
|
858
|
+
for (let i = 0; i < p0.length; i++) {
|
|
700
859
|
const m0 = outTangent0[i] * tDiff;
|
|
701
860
|
const m1 = inTangent1[i] * tDiff;
|
|
702
|
-
|
|
861
|
+
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;
|
|
703
862
|
}
|
|
863
|
+
updateTargetPath(target, path, newVal);
|
|
704
864
|
}
|
|
705
865
|
function stepInterpolate(target, path, value) {
|
|
706
|
-
|
|
707
|
-
throw new Error();
|
|
708
|
-
}
|
|
709
|
-
for (let i = 0; i < value.length; i++) {
|
|
710
|
-
target[path][i] = value[i];
|
|
711
|
-
}
|
|
866
|
+
updateTargetPath(target, path, value);
|
|
712
867
|
}
|
|
713
868
|
|
|
714
869
|
// dist/gltf/gltf-animator.js
|
|
715
870
|
var GLTFSingleAnimator = class {
|
|
871
|
+
/** Animation definition being played. */
|
|
716
872
|
animation;
|
|
873
|
+
/** Target scenegraph lookup table. */
|
|
874
|
+
gltfNodeIdToNodeMap;
|
|
875
|
+
/** Playback start time in seconds. */
|
|
717
876
|
startTime = 0;
|
|
877
|
+
/** Whether playback is currently enabled. */
|
|
718
878
|
playing = true;
|
|
879
|
+
/** Playback speed multiplier. */
|
|
719
880
|
speed = 1;
|
|
881
|
+
/** Creates a single-animation controller. */
|
|
720
882
|
constructor(props) {
|
|
721
883
|
this.animation = props.animation;
|
|
884
|
+
this.gltfNodeIdToNodeMap = props.gltfNodeIdToNodeMap;
|
|
722
885
|
this.animation.name ||= "unnamed";
|
|
723
886
|
Object.assign(this, props);
|
|
724
887
|
}
|
|
888
|
+
/** Advances the animation to the supplied wall-clock time in milliseconds. */
|
|
725
889
|
setTime(timeMs) {
|
|
726
890
|
if (!this.playing) {
|
|
727
891
|
return;
|
|
728
892
|
}
|
|
729
893
|
const absTime = timeMs / 1e3;
|
|
730
894
|
const time = (absTime - this.startTime) * this.speed;
|
|
731
|
-
this.animation.channels.forEach(({ sampler,
|
|
732
|
-
|
|
733
|
-
|
|
895
|
+
this.animation.channels.forEach(({ sampler, targetNodeId, path }) => {
|
|
896
|
+
const targetNode = this.gltfNodeIdToNodeMap.get(targetNodeId);
|
|
897
|
+
if (!targetNode) {
|
|
898
|
+
throw new Error(`Cannot find animation target node ${targetNodeId}`);
|
|
899
|
+
}
|
|
900
|
+
interpolate(time, sampler, targetNode, path);
|
|
734
901
|
});
|
|
735
902
|
}
|
|
736
903
|
};
|
|
737
904
|
var GLTFAnimator = class {
|
|
905
|
+
/** Individual animation controllers. */
|
|
738
906
|
animations;
|
|
907
|
+
/** Creates an animator for the supplied glTF scenegraph. */
|
|
739
908
|
constructor(props) {
|
|
740
909
|
this.animations = props.animations.map((animation, index) => {
|
|
741
910
|
const name = animation.name || `Animation-${index}`;
|
|
742
911
|
return new GLTFSingleAnimator({
|
|
912
|
+
gltfNodeIdToNodeMap: props.gltfNodeIdToNodeMap,
|
|
743
913
|
animation: { name, channels: animation.channels }
|
|
744
914
|
});
|
|
745
915
|
});
|
|
746
916
|
}
|
|
747
917
|
/** @deprecated Use .setTime(). Will be removed (deck.gl is using this) */
|
|
748
918
|
animate(time) {
|
|
749
|
-
|
|
919
|
+
import_core6.log.warn("GLTFAnimator#animate is deprecated. Use GLTFAnimator#setTime instead")();
|
|
750
920
|
this.setTime(time);
|
|
751
921
|
}
|
|
922
|
+
/** Advances every animation to the supplied wall-clock time in milliseconds. */
|
|
752
923
|
setTime(time) {
|
|
753
924
|
this.animations.forEach((animation) => animation.setTime(time));
|
|
754
925
|
}
|
|
926
|
+
/** Returns the per-animation controllers managed by this animator. */
|
|
755
927
|
getAnimations() {
|
|
756
928
|
return this.animations;
|
|
757
929
|
}
|
|
758
930
|
};
|
|
759
|
-
var scratchMatrix = new import_core8.Matrix4();
|
|
760
|
-
function applyTranslationRotationScale(gltfNode, node) {
|
|
761
|
-
node.matrix.identity();
|
|
762
|
-
if (gltfNode.translation) {
|
|
763
|
-
node.matrix.translate(gltfNode.translation);
|
|
764
|
-
}
|
|
765
|
-
if (gltfNode.rotation) {
|
|
766
|
-
const rotationMatrix = scratchMatrix.fromQuaternion(gltfNode.rotation);
|
|
767
|
-
node.matrix.multiplyRight(rotationMatrix);
|
|
768
|
-
}
|
|
769
|
-
if (gltfNode.scale) {
|
|
770
|
-
node.matrix.scale(gltfNode.scale);
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
931
|
|
|
774
932
|
// dist/webgl-to-webgpu/convert-webgl-attribute.js
|
|
775
933
|
var ATTRIBUTE_TYPE_TO_COMPONENTS = {
|
|
@@ -802,62 +960,72 @@ function accessorToTypedArray(accessor) {
|
|
|
802
960
|
// dist/parsers/parse-gltf-animations.js
|
|
803
961
|
function parseGLTFAnimations(gltf) {
|
|
804
962
|
const gltfAnimations = gltf.animations || [];
|
|
963
|
+
const accessorCache1D = /* @__PURE__ */ new Map();
|
|
964
|
+
const accessorCache2D = /* @__PURE__ */ new Map();
|
|
805
965
|
return gltfAnimations.map((animation, index) => {
|
|
806
966
|
const name = animation.name || `Animation-${index}`;
|
|
807
967
|
const samplers = animation.samplers.map(({ input, interpolation = "LINEAR", output }) => ({
|
|
808
|
-
input:
|
|
968
|
+
input: accessorToJsArray1D(gltf.accessors[input], accessorCache1D),
|
|
809
969
|
interpolation,
|
|
810
|
-
output:
|
|
811
|
-
}));
|
|
812
|
-
const channels = animation.channels.map(({ sampler, target }) => ({
|
|
813
|
-
sampler: samplers[sampler],
|
|
814
|
-
target: gltf.nodes[target.node ?? 0],
|
|
815
|
-
path: target.path
|
|
970
|
+
output: accessorToJsArray2D(gltf.accessors[output], accessorCache2D)
|
|
816
971
|
}));
|
|
972
|
+
const channels = animation.channels.map(({ sampler, target }) => {
|
|
973
|
+
const targetNode = gltf.nodes[target.node ?? 0];
|
|
974
|
+
if (!targetNode) {
|
|
975
|
+
throw new Error(`Cannot find animation target ${target.node}`);
|
|
976
|
+
}
|
|
977
|
+
return {
|
|
978
|
+
sampler: samplers[sampler],
|
|
979
|
+
targetNodeId: targetNode.id,
|
|
980
|
+
path: target.path
|
|
981
|
+
};
|
|
982
|
+
});
|
|
817
983
|
return { name, channels };
|
|
818
984
|
});
|
|
819
985
|
}
|
|
820
|
-
function
|
|
821
|
-
if (
|
|
822
|
-
|
|
823
|
-
if (components === 1) {
|
|
824
|
-
accessor._animation = Array.from(array);
|
|
825
|
-
} else {
|
|
826
|
-
const slicedArray = [];
|
|
827
|
-
for (let i = 0; i < array.length; i += components) {
|
|
828
|
-
slicedArray.push(Array.from(array.slice(i, i + components)));
|
|
829
|
-
}
|
|
830
|
-
accessor._animation = slicedArray;
|
|
831
|
-
}
|
|
986
|
+
function accessorToJsArray1D(accessor, accessorCache) {
|
|
987
|
+
if (accessorCache.has(accessor)) {
|
|
988
|
+
return accessorCache.get(accessor);
|
|
832
989
|
}
|
|
833
|
-
|
|
990
|
+
const { typedArray: array, components } = accessorToTypedArray(accessor);
|
|
991
|
+
assert(components === 1, "accessorToJsArray1D must have exactly 1 component");
|
|
992
|
+
const result = Array.from(array);
|
|
993
|
+
accessorCache.set(accessor, result);
|
|
994
|
+
return result;
|
|
834
995
|
}
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
if (ArrayBuffer.isView(object) || object instanceof ArrayBuffer || object instanceof ImageBitmap) {
|
|
839
|
-
return object;
|
|
996
|
+
function accessorToJsArray2D(accessor, accessorCache) {
|
|
997
|
+
if (accessorCache.has(accessor)) {
|
|
998
|
+
return accessorCache.get(accessor);
|
|
840
999
|
}
|
|
841
|
-
|
|
842
|
-
|
|
1000
|
+
const { typedArray: array, components } = accessorToTypedArray(accessor);
|
|
1001
|
+
assert(components > 1, "accessorToJsArray2D must have more than 1 component");
|
|
1002
|
+
const result = [];
|
|
1003
|
+
for (let i = 0; i < array.length; i += components) {
|
|
1004
|
+
result.push(Array.from(array.slice(i, i + components)));
|
|
843
1005
|
}
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
1006
|
+
accessorCache.set(accessor, result);
|
|
1007
|
+
return result;
|
|
1008
|
+
}
|
|
1009
|
+
function assert(condition, message) {
|
|
1010
|
+
if (!condition) {
|
|
1011
|
+
throw new Error(message);
|
|
850
1012
|
}
|
|
851
|
-
return object;
|
|
852
1013
|
}
|
|
853
1014
|
|
|
854
1015
|
// dist/gltf/create-scenegraph-from-gltf.js
|
|
855
1016
|
function createScenegraphsFromGLTF(device, gltf, options) {
|
|
856
|
-
|
|
857
|
-
const scenes = parseGLTF(device, gltf, options);
|
|
1017
|
+
const { scenes, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap } = parseGLTF(device, gltf, options);
|
|
858
1018
|
const animations = parseGLTFAnimations(gltf);
|
|
859
|
-
const animator = new GLTFAnimator({ animations });
|
|
1019
|
+
const animator = new GLTFAnimator({ animations, gltfNodeIdToNodeMap });
|
|
860
1020
|
const lights = parseGLTFLights(gltf);
|
|
861
|
-
return {
|
|
1021
|
+
return {
|
|
1022
|
+
scenes,
|
|
1023
|
+
animator,
|
|
1024
|
+
lights,
|
|
1025
|
+
gltfMeshIdToNodeMap,
|
|
1026
|
+
gltfNodeIdToNodeMap,
|
|
1027
|
+
gltfNodeIndexToNodeMap,
|
|
1028
|
+
gltf
|
|
1029
|
+
};
|
|
862
1030
|
}
|
|
863
1031
|
//# sourceMappingURL=index.cjs.map
|