@babylonjs/lite 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/CHANGELOG.md +735 -0
  2. package/README.md +26 -1
  3. package/THIRD_PARTY_NOTICES.txt +139 -0
  4. package/dist/index.js +292 -277
  5. package/dist/index.js.map +1 -1
  6. package/index.d.ts +277 -11
  7. package/lib/_chunks/vendor/{manifold-Sh8xE2da.js → manifold-DtI3BJoR.js} +2 -2
  8. package/lib/_chunks/vendor/{manifold-Sh8xE2da.js.map → manifold-DtI3BJoR.js.map} +1 -1
  9. package/lib/animation/animation-group-task.js +1 -1
  10. package/lib/animation/animation-group-task.js.map +1 -1
  11. package/lib/animation/animation-group.js +20 -15
  12. package/lib/animation/animation-group.js.map +1 -1
  13. package/lib/animation/animation-tick.js +10 -0
  14. package/lib/animation/animation-tick.js.map +1 -0
  15. package/lib/animation/property-animation.js +2 -1
  16. package/lib/animation/property-animation.js.map +1 -1
  17. package/lib/animation/weighted-gltf-mixer.js +1 -1
  18. package/lib/animation/weighted-gltf-mixer.js.map +1 -1
  19. package/lib/animation/weighted-pointer-mixer.js +1 -1
  20. package/lib/animation/weighted-pointer-mixer.js.map +1 -1
  21. package/lib/engine/device-lost-recovery.js +1 -0
  22. package/lib/engine/device-lost-recovery.js.map +1 -1
  23. package/lib/engine/engine.js +1 -1
  24. package/lib/engine/null-engine.js +29 -0
  25. package/lib/engine/null-engine.js.map +1 -0
  26. package/lib/frame-graph/depth-pyramid.js +158 -0
  27. package/lib/frame-graph/depth-pyramid.js.map +1 -0
  28. package/lib/frame-graph/frame-graph-actions.js +10 -1
  29. package/lib/frame-graph/frame-graph-actions.js.map +1 -1
  30. package/lib/frame-graph/render-task.js +7 -0
  31. package/lib/frame-graph/render-task.js.map +1 -1
  32. package/lib/frame-graph/transmission-depth-grab.js +88 -0
  33. package/lib/frame-graph/transmission-depth-grab.js.map +1 -0
  34. package/lib/frame-graph/transmission.js +30 -1
  35. package/lib/frame-graph/transmission.js.map +1 -1
  36. package/lib/gizmo/bounding-box-gizmo.js +1 -1
  37. package/lib/index.js +8 -6
  38. package/lib/index.js.map +1 -1
  39. package/lib/loader-gltf/gltf-feature-gpu-instancing.js +1 -1
  40. package/lib/loader-gltf/gltf-interleave.js +1 -1
  41. package/lib/loader-gltf/load-gltf.js +1 -1
  42. package/lib/material/shader/shader-pipeline.js +1 -1
  43. package/lib/material/shader/shader-pipeline.js.map +1 -1
  44. package/lib/material/shader/shader-renderable.js +23 -8
  45. package/lib/material/shader/shader-renderable.js.map +1 -1
  46. package/lib/math/aabb.js +1 -1
  47. package/lib/math/compute-aabb.js +63 -1
  48. package/lib/math/compute-aabb.js.map +1 -1
  49. package/lib/math/index.js +1 -1
  50. package/lib/mesh/csg2.js +3 -2
  51. package/lib/mesh/csg2.js.map +1 -1
  52. package/lib/mesh/mesh-factories.js +1 -1
  53. package/lib/mesh/thin-instance-gpu-culling.js +4 -2
  54. package/lib/mesh/thin-instance-gpu-culling.js.map +1 -1
  55. package/lib/mesh/thin-instance.js +8 -1
  56. package/lib/mesh/thin-instance.js.map +1 -1
  57. package/lib/navigation/index.js +1 -1
  58. package/lib/navigation/navigation.js +9 -1
  59. package/lib/navigation/navigation.js.map +1 -1
  60. package/lib/physics/character-controller.js +2 -2
  61. package/lib/physics/character-controller.js.map +1 -1
  62. package/lib/physics/havok-floating-origin.js +2 -2
  63. package/lib/physics/havok-floating-origin.js.map +1 -1
  64. package/lib/physics/havok.js +40 -13
  65. package/lib/physics/havok.js.map +1 -1
  66. package/lib/picking/gpu-picker.js +16 -2
  67. package/lib/picking/gpu-picker.js.map +1 -1
  68. package/lib/scene/scene-core.js +9 -3
  69. package/lib/scene/scene-core.js.map +1 -1
  70. package/lib/scene/scene-remove.js +8 -0
  71. package/lib/scene/scene-remove.js.map +1 -1
  72. package/lib/texture/pixels-texture.js +31 -1
  73. package/lib/texture/pixels-texture.js.map +1 -1
  74. package/lib/vat/vat-baker.js +41 -2
  75. package/lib/vat/vat-baker.js.map +1 -1
  76. package/package.json +15 -3
  77. package/lib/_chunks/__vite-browser-external-BFTKbDcV.js +0 -68
  78. package/lib/_chunks/__vite-browser-external-BFTKbDcV.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { tickAnimation } from './animation-group.js';
1
+ import { tickAnimation } from './animation-tick.js';
2
2
  import { createAnimationTask, addAnimationTask, removeAnimationTask } from './animation-manager.js';
3
3
 
4
4
  const ANIMATION_GROUP_TASK_CATEGORY = "animation-group";
@@ -1 +1 @@
1
- {"version":3,"file":"animation-group-task.js","sources":["../../../src/animation/animation-group-task.ts"],"sourcesContent":["import { tickAnimation } from \"./animation-group.js\";\nimport type { AnimationGroup } from \"./animation-group.js\";\nimport { addAnimationTask, createAnimationTask, removeAnimationTask } from \"./animation-manager.js\";\nimport type { AnimationManager, AnimationTask } from \"./animation-manager.js\";\n\nexport const ANIMATION_GROUP_TASK_CATEGORY = \"animation-group\";\n\ninterface AnimationGroupTaskManager extends AnimationManager {\n _animationGroups?: AnimationGroup[];\n}\n\ninterface AnimationGroupTaskGroup extends AnimationGroup {\n _animationManager?: AnimationManager;\n _animationTask?: AnimationTask;\n}\n\nfunction getMutableAnimationGroups(manager: AnimationManager): AnimationGroup[] {\n const managerInternal = manager as AnimationGroupTaskManager;\n let groups = managerInternal._animationGroups;\n if (!groups) {\n groups = [];\n managerInternal._animationGroups = groups;\n }\n return groups;\n}\n\n/** Returns the animation groups currently attached to `manager`, or an empty array if none. */\nexport function getAnimationGroups(manager: AnimationManager): readonly AnimationGroup[] {\n return (manager as AnimationGroupTaskManager)._animationGroups ?? [];\n}\n\nexport function getAnimationGroupOwner(group: AnimationGroup): AnimationManager | undefined {\n return (group as AnimationGroupTaskGroup)._animationManager;\n}\n\n/** Attaches `group` to `manager` so it is ticked each update, creating its backing animation task on first use.\n * @param manager - Animation manager that will own and drive the group.\n * @param group - Animation group to attach.\n * @throws If the group is already attached to a different manager. */\nexport function addAnimationGroup(manager: AnimationManager, group: AnimationGroup): void {\n const groupInternal = group as AnimationGroupTaskGroup;\n const owner = groupInternal._animationManager;\n if (owner && owner !== manager) {\n throw new Error(`AnimationGroup \"${group.name}\" is already attached to another AnimationManager`);\n }\n if (owner === manager) {\n return;\n }\n const task =\n groupInternal._animationTask ??\n createAnimationTask(\n (taskManager, deltaMs) => {\n tickAnimation(group, deltaMs, taskManager.engine);\n },\n {\n category: ANIMATION_GROUP_TASK_CATEGORY,\n dispose: (ownerManager) => {\n const groups = (ownerManager as AnimationGroupTaskManager)._animationGroups;\n const index = groups?.indexOf(group) ?? -1;\n if (groups && index !== -1) {\n groups.splice(index, 1);\n }\n if (groupInternal._animationManager === ownerManager) {\n groupInternal._animationManager = undefined;\n }\n },\n }\n );\n getMutableAnimationGroups(manager).push(group);\n groupInternal._animationManager = manager;\n groupInternal._animationTask = task;\n addAnimationTask(manager, task);\n}\n\n/** Attaches each group in `groups` to `manager` via {@link addAnimationGroup}. */\nexport function addAnimationGroups(manager: AnimationManager, groups: readonly AnimationGroup[]): void {\n for (const group of groups) {\n addAnimationGroup(manager, group);\n }\n}\n\n/** Detaches `group` from `manager`, removing its animation task so it is no longer ticked. */\nexport function removeAnimationGroup(manager: AnimationManager, group: AnimationGroup): void {\n const groupInternal = group as AnimationGroupTaskGroup;\n const task = groupInternal._animationTask;\n if (task && groupInternal._animationManager === manager) {\n removeAnimationTask(manager, task);\n return;\n }\n const groups = (manager as AnimationGroupTaskManager)._animationGroups;\n const index = groups?.indexOf(group) ?? -1;\n if (groups && index !== -1) {\n groups.splice(index, 1);\n }\n if (groupInternal._animationManager === manager) {\n groupInternal._animationManager = undefined;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"animation-group-task.js","sources":["../../../src/animation/animation-group-task.ts"],"sourcesContent":["import { tickAnimation } from \"./animation-tick.js\";\nimport type { AnimationGroup } from \"./animation-group.js\";\nimport { addAnimationTask, createAnimationTask, removeAnimationTask } from \"./animation-manager.js\";\nimport type { AnimationManager, AnimationTask } from \"./animation-manager.js\";\n\nexport const ANIMATION_GROUP_TASK_CATEGORY = \"animation-group\";\n\ninterface AnimationGroupTaskManager extends AnimationManager {\n _animationGroups?: AnimationGroup[];\n}\n\ninterface AnimationGroupTaskGroup extends AnimationGroup {\n _animationManager?: AnimationManager;\n _animationTask?: AnimationTask;\n}\n\nfunction getMutableAnimationGroups(manager: AnimationManager): AnimationGroup[] {\n const managerInternal = manager as AnimationGroupTaskManager;\n let groups = managerInternal._animationGroups;\n if (!groups) {\n groups = [];\n managerInternal._animationGroups = groups;\n }\n return groups;\n}\n\n/** Returns the animation groups currently attached to `manager`, or an empty array if none. */\nexport function getAnimationGroups(manager: AnimationManager): readonly AnimationGroup[] {\n return (manager as AnimationGroupTaskManager)._animationGroups ?? [];\n}\n\nexport function getAnimationGroupOwner(group: AnimationGroup): AnimationManager | undefined {\n return (group as AnimationGroupTaskGroup)._animationManager;\n}\n\n/** Attaches `group` to `manager` so it is ticked each update, creating its backing animation task on first use.\n * @param manager - Animation manager that will own and drive the group.\n * @param group - Animation group to attach.\n * @throws If the group is already attached to a different manager. */\nexport function addAnimationGroup(manager: AnimationManager, group: AnimationGroup): void {\n const groupInternal = group as AnimationGroupTaskGroup;\n const owner = groupInternal._animationManager;\n if (owner && owner !== manager) {\n throw new Error(`AnimationGroup \"${group.name}\" is already attached to another AnimationManager`);\n }\n if (owner === manager) {\n return;\n }\n const task =\n groupInternal._animationTask ??\n createAnimationTask(\n (taskManager, deltaMs) => {\n tickAnimation(group, deltaMs, taskManager.engine);\n },\n {\n category: ANIMATION_GROUP_TASK_CATEGORY,\n dispose: (ownerManager) => {\n const groups = (ownerManager as AnimationGroupTaskManager)._animationGroups;\n const index = groups?.indexOf(group) ?? -1;\n if (groups && index !== -1) {\n groups.splice(index, 1);\n }\n if (groupInternal._animationManager === ownerManager) {\n groupInternal._animationManager = undefined;\n }\n },\n }\n );\n getMutableAnimationGroups(manager).push(group);\n groupInternal._animationManager = manager;\n groupInternal._animationTask = task;\n addAnimationTask(manager, task);\n}\n\n/** Attaches each group in `groups` to `manager` via {@link addAnimationGroup}. */\nexport function addAnimationGroups(manager: AnimationManager, groups: readonly AnimationGroup[]): void {\n for (const group of groups) {\n addAnimationGroup(manager, group);\n }\n}\n\n/** Detaches `group` from `manager`, removing its animation task so it is no longer ticked. */\nexport function removeAnimationGroup(manager: AnimationManager, group: AnimationGroup): void {\n const groupInternal = group as AnimationGroupTaskGroup;\n const task = groupInternal._animationTask;\n if (task && groupInternal._animationManager === manager) {\n removeAnimationTask(manager, task);\n return;\n }\n const groups = (manager as AnimationGroupTaskManager)._animationGroups;\n const index = groups?.indexOf(group) ?? -1;\n if (groups && index !== -1) {\n groups.splice(index, 1);\n }\n if (groupInternal._animationManager === manager) {\n groupInternal._animationManager = undefined;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { PATH_POINTER, PATH_TRANSLATION, PATH_ROTATION, PATH_SCALE } from './types.js';
2
2
  import { createAnimationController } from '../skeleton/skeleton-updater.js';
3
+ import { _setTickAnimationImpl } from './animation-tick.js';
3
4
 
4
5
  const DEFAULT_FRAME_RATE = 60;
5
6
  function playAnimation(group) {
@@ -14,6 +15,23 @@ function stopAnimation(group) {
14
15
  group.currentTime = 0;
15
16
  group._stopped = true;
16
17
  }
18
+ function syncControllerFromGroup(group, ctrl) {
19
+ ctrl.time = group.currentTime;
20
+ ctrl.playing = group.isPlaying;
21
+ ctrl.speedRatio = group.speedRatio;
22
+ ctrl.loop = group.loopAnimation;
23
+ ctrl._setMask?.(group.mask ?? null);
24
+ }
25
+ function tickAnimationImpl(group, deltaMs, engine) {
26
+ if (!group._stopped && group._ctrl) {
27
+ syncControllerFromGroup(group, group._ctrl);
28
+ group._ctrl.tick(deltaMs, engine);
29
+ group.currentTime = group._ctrl.time;
30
+ }
31
+ }
32
+ function _installTickAnimation() {
33
+ _setTickAnimationImpl(tickAnimationImpl);
34
+ }
17
35
  function goToFrame(group, frame, engine) {
18
36
  const ctrl = group._ctrl;
19
37
  group.currentTime = frame / (group.frameRate || DEFAULT_FRAME_RATE);
@@ -26,20 +44,6 @@ function goToFrame(group, frame, engine) {
26
44
  }
27
45
  }
28
46
  }
29
- function tickAnimation(group, deltaMs, engine) {
30
- if (!group._stopped && group._ctrl) {
31
- syncControllerFromGroup(group, group._ctrl);
32
- group._ctrl.tick(deltaMs, engine);
33
- group.currentTime = group._ctrl.time;
34
- }
35
- }
36
- function syncControllerFromGroup(group, ctrl) {
37
- ctrl.time = group.currentTime;
38
- ctrl.playing = group.isPlaying;
39
- ctrl.speedRatio = group.speedRatio;
40
- ctrl.loop = group.loopAnimation;
41
- ctrl._setMask?.(group.mask ?? null);
42
- }
43
47
  function createAnimationGroups(animData) {
44
48
  const { clips, nodes, skeletons, morphBindings, nodeTargets, excludedNodeIndices, nodeNames, boneOverrides } = animData;
45
49
  const hasPointer = clips.some((c) => c.channels.some((ch) => ch.path === PATH_POINTER));
@@ -51,6 +55,7 @@ function createAnimationGroups(animData) {
51
55
  if (clips.length === 0 || skeletons.length === 0 && morphBindings.length === 0 && !hasPointer && !hasNodeWriteback) {
52
56
  return [];
53
57
  }
58
+ _installTickAnimation();
54
59
  return clips.map((clip, clipIndex) => {
55
60
  const ctrl = createAnimationController(clip, nodes, skeletons, morphBindings, nodeTargets, excludedNodeIndices, boneOverrides, nodeNames);
56
61
  const started = clipIndex === 0;
@@ -83,5 +88,5 @@ function pathName(path) {
83
88
  return path === PATH_TRANSLATION ? "translation" : path === PATH_ROTATION ? "rotation" : path === PATH_SCALE ? "scale" : path === PATH_POINTER ? "pointer" : "weights";
84
89
  }
85
90
 
86
- export { createAnimationGroups, goToFrame, pauseAnimation, playAnimation, stopAnimation, tickAnimation };
91
+ export { _installTickAnimation, createAnimationGroups, goToFrame, pauseAnimation, playAnimation, stopAnimation };
87
92
  //# sourceMappingURL=animation-group.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"animation-group.js","sources":["../../../src/animation/animation-group.ts"],"sourcesContent":["// AnimationGroup — user-facing handle for a single animation clip.\n// Stored on scene.animationGroups[]. Pure state interface.\n\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { AnimationClip, AnimationSampler, GltfAnimationData, NodeRest, SkeletonBinding } from \"./types.js\";\nimport type { AnimationGroupMask } from \"./animation-group-mask.js\";\nimport type { LiteMetadata } from \"../metadata.js\";\nimport { PATH_POINTER, PATH_TRANSLATION, PATH_ROTATION, PATH_SCALE } from \"./types.js\";\nimport { createAnimationController } from \"../skeleton/skeleton-updater.js\";\nimport type { AnimationController } from \"../skeleton/skeleton-updater.js\";\n\nconst DEFAULT_FRAME_RATE = 60;\n\nexport interface AnimationPropertyRuntimeTrack {\n readonly sampler: AnimationSampler;\n readonly stride: number;\n readonly quaternion: boolean;\n readonly writer: (output: Float32Array, offset: number) => void;\n readonly mixTarget: object;\n readonly mixProperty: string;\n}\nexport type AnimationPropertyMixer = readonly [readonly AnimationPropertyRuntimeTrack[], number, number, number];\nexport type AnimationGltfMixer = readonly [AnimationClip, readonly NodeRest[], readonly SkeletonBinding[]];\nexport interface AnimationAdditiveMixer {\n readonly referenceTime: number;\n}\n\n/** Lightweight public description of one target affected by an animation group. */\nexport interface TargetedAnimation {\n /** Runtime target object when one is directly addressable. */\n readonly target?: object;\n /** glTF node or bone name when available. */\n readonly targetName?: string;\n /** glTF node index for node channels. Undefined for manual property tracks. */\n readonly nodeIndex?: number;\n /** Animated path, e.g. `translation`, `rotation`, `scale`, `weights`, or a manual property path. */\n readonly path: string;\n}\n\n/** User-facing animation group — one per animation clip. Pure state. */\nexport interface AnimationGroup {\n /** Name of this animation. */\n readonly name: string;\n /** Duration in seconds. */\n readonly duration: number;\n /** Frame rate used by goToFrame(). */\n readonly frameRate?: number;\n /** True if currently playing. */\n isPlaying: boolean;\n /** Current playback time in seconds. */\n currentTime: number;\n /** Lightweight list of targets affected by this group. */\n readonly targetedAnimations: readonly TargetedAnimation[];\n /** User metadata bag. */\n metadata?: LiteMetadata;\n /** Playback speed multiplier (default 1). */\n speedRatio: number;\n /** Whether animation loops (default true). */\n loopAnimation: boolean;\n /** Weighted contribution used by AnimationManager mixing (default 1). */\n weight: number;\n /** Optional include/exclude target-name mask. When set, only targets the mask retains\n * animate; masked-out targets stay at their bind/rest pose. Matched by glTF node /\n * bone name. See {@link createAnimationGroupMask}. To update an active mask, change\n * its `mode`/`disabled`, replace its `names` array, or reassign `group.mask`;\n * in-place same-length edits of `names` are not picked up. */\n mask?: AnimationGroupMask;\n /** @internal Debug: internal animation controller. */\n readonly _ctrl?: AnimationController;\n /** @internal Manual property animation metadata used by the optional weighted mixer. */\n _propertyMixer?: AnimationPropertyMixer;\n /** @internal glTF skeleton metadata used by the optional weighted mixer. */\n _gltfMixer?: AnimationGltfMixer;\n /** @internal Additive animation metadata used by the optional blending mixer. */\n _additive?: AnimationAdditiveMixer;\n /** @internal Whether stop() was called (suppresses tickAnimation). */\n _stopped: boolean;\n}\n\n/** Start playing an animation group. */\nexport function playAnimation(group: AnimationGroup): void {\n group.isPlaying = true;\n group._stopped = false;\n}\n\n/** Pause playback of an animation group. */\nexport function pauseAnimation(group: AnimationGroup): void {\n group.isPlaying = false;\n}\n\n/** Stop playback and reset to frame 0. */\nexport function stopAnimation(group: AnimationGroup): void {\n group.isPlaying = false;\n group.currentTime = 0;\n group._stopped = true;\n}\n\n/** Seek to a specific frame, apply the pose, and pause. */\nexport function goToFrame(group: AnimationGroup, frame: number, engine?: EngineContext): void {\n const ctrl = group._ctrl;\n group.currentTime = frame / (group.frameRate || DEFAULT_FRAME_RATE);\n group.isPlaying = false;\n if (ctrl) {\n syncControllerFromGroup(group, ctrl);\n if (engine || !group._stopped || !group._gltfMixer) {\n ctrl.tick(0, engine);\n group.currentTime = ctrl.time;\n }\n }\n}\n\n/** @internal Advance animation by deltaMs. Called by the engine each frame. */\nexport function tickAnimation(group: AnimationGroup, deltaMs: number, engine?: EngineContext): void {\n if (!group._stopped && group._ctrl) {\n syncControllerFromGroup(group, group._ctrl);\n group._ctrl.tick(deltaMs, engine);\n group.currentTime = group._ctrl.time;\n }\n}\n\nfunction syncControllerFromGroup(group: AnimationGroup, ctrl: AnimationController): void {\n ctrl.time = group.currentTime;\n ctrl.playing = group.isPlaying;\n ctrl.speedRatio = group.speedRatio;\n ctrl.loop = group.loopAnimation;\n ctrl._setMask?.(group.mask ?? null);\n}\n\n/** Create AnimationGroup(s) from parsed glTF animation data.\n * Returns one group per animation clip. */\nexport function createAnimationGroups(animData: GltfAnimationData): AnimationGroup[] {\n const { clips, nodes, skeletons, morphBindings, nodeTargets, excludedNodeIndices, nodeNames, boneOverrides } = animData;\n const hasPointer = clips.some((c) => c.channels.some((ch) => ch.path === PATH_POINTER));\n const hasNodeWriteback = clips.some((c) =>\n c.channels.some(\n (ch) =>\n (ch.path === PATH_TRANSLATION || ch.path === PATH_ROTATION || ch.path === PATH_SCALE) &&\n ch.nodeIdx >= 0 &&\n !excludedNodeIndices.has(ch.nodeIdx) &&\n !!nodeTargets[ch.nodeIdx]\n )\n );\n if (clips.length === 0 || (skeletons.length === 0 && morphBindings.length === 0 && !hasPointer && !hasNodeWriteback)) {\n return [];\n }\n\n return clips.map((clip, clipIndex) => {\n const ctrl: AnimationController = createAnimationController(clip, nodes, skeletons, morphBindings, nodeTargets, excludedNodeIndices, boneOverrides, nodeNames);\n const started = clipIndex === 0;\n const group: AnimationGroup = {\n name: clip.name || `animation_${clipIndex}`,\n duration: clip.duration,\n frameRate: clip.frameRate || DEFAULT_FRAME_RATE,\n isPlaying: started,\n currentTime: 0,\n targetedAnimations: clip.channels.map((ch) => {\n const nodeIndex = ch.nodeIdx >= 0 ? ch.nodeIdx : undefined;\n return {\n target: nodeIndex !== undefined ? nodeTargets[nodeIndex] : undefined,\n targetName: nodeIndex !== undefined ? nodeNames[nodeIndex] : undefined,\n nodeIndex,\n path: pathName(ch.path),\n };\n }),\n speedRatio: 1,\n loopAnimation: true,\n weight: 1,\n _ctrl: ctrl,\n _stopped: !started,\n };\n group._gltfMixer = [clip, nodes, skeletons];\n return group;\n });\n}\n\nfunction pathName(path: number): string {\n return path === PATH_TRANSLATION ? \"translation\" : path === PATH_ROTATION ? \"rotation\" : path === PATH_SCALE ? \"scale\" : path === PATH_POINTER ? \"pointer\" : \"weights\";\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"animation-group.js","sources":["../../../src/animation/animation-group.ts"],"sourcesContent":["// AnimationGroup — user-facing handle for a single animation clip.\n// Stored on scene.animationGroups[]. Pure state interface.\n\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { AnimationClip, AnimationSampler, GltfAnimationData, NodeRest, SkeletonBinding } from \"./types.js\";\nimport type { AnimationGroupMask } from \"./animation-group-mask.js\";\nimport type { LiteMetadata } from \"../metadata.js\";\nimport { PATH_POINTER, PATH_TRANSLATION, PATH_ROTATION, PATH_SCALE } from \"./types.js\";\nimport { createAnimationController } from \"../skeleton/skeleton-updater.js\";\nimport type { AnimationController } from \"../skeleton/skeleton-updater.js\";\nimport { _setTickAnimationImpl } from \"./animation-tick.js\";\n\nconst DEFAULT_FRAME_RATE = 60;\n\nexport interface AnimationPropertyRuntimeTrack {\n readonly sampler: AnimationSampler;\n readonly stride: number;\n readonly quaternion: boolean;\n readonly writer: (output: Float32Array, offset: number) => void;\n readonly mixTarget: object;\n readonly mixProperty: string;\n}\nexport type AnimationPropertyMixer = readonly [readonly AnimationPropertyRuntimeTrack[], number, number, number];\nexport type AnimationGltfMixer = readonly [AnimationClip, readonly NodeRest[], readonly SkeletonBinding[]];\nexport interface AnimationAdditiveMixer {\n readonly referenceTime: number;\n}\n\n/** Lightweight public description of one target affected by an animation group. */\nexport interface TargetedAnimation {\n /** Runtime target object when one is directly addressable. */\n readonly target?: object;\n /** glTF node or bone name when available. */\n readonly targetName?: string;\n /** glTF node index for node channels. Undefined for manual property tracks. */\n readonly nodeIndex?: number;\n /** Animated path, e.g. `translation`, `rotation`, `scale`, `weights`, or a manual property path. */\n readonly path: string;\n}\n\n/** User-facing animation group — one per animation clip. Pure state. */\nexport interface AnimationGroup {\n /** Name of this animation. */\n readonly name: string;\n /** Duration in seconds. */\n readonly duration: number;\n /** Frame rate used by goToFrame(). */\n readonly frameRate?: number;\n /** True if currently playing. */\n isPlaying: boolean;\n /** Current playback time in seconds. */\n currentTime: number;\n /** Lightweight list of targets affected by this group. */\n readonly targetedAnimations: readonly TargetedAnimation[];\n /** User metadata bag. */\n metadata?: LiteMetadata;\n /** Playback speed multiplier (default 1). */\n speedRatio: number;\n /** Whether animation loops (default true). */\n loopAnimation: boolean;\n /** Weighted contribution used by AnimationManager mixing (default 1). */\n weight: number;\n /** Optional include/exclude target-name mask. When set, only targets the mask retains\n * animate; masked-out targets stay at their bind/rest pose. Matched by glTF node /\n * bone name. See {@link createAnimationGroupMask}. To update an active mask, change\n * its `mode`/`disabled`, replace its `names` array, or reassign `group.mask`;\n * in-place same-length edits of `names` are not picked up. */\n mask?: AnimationGroupMask;\n /** @internal Debug: internal animation controller. */\n readonly _ctrl?: AnimationController;\n /** @internal Manual property animation metadata used by the optional weighted mixer. */\n _propertyMixer?: AnimationPropertyMixer;\n /** @internal glTF skeleton metadata used by the optional weighted mixer. */\n _gltfMixer?: AnimationGltfMixer;\n /** @internal Additive animation metadata used by the optional blending mixer. */\n _additive?: AnimationAdditiveMixer;\n /** @internal Whether stop() was called (suppresses tickAnimation). */\n _stopped: boolean;\n}\n\n/** Start playing an animation group. */\nexport function playAnimation(group: AnimationGroup): void {\n group.isPlaying = true;\n group._stopped = false;\n}\n\n/** Pause playback of an animation group. */\nexport function pauseAnimation(group: AnimationGroup): void {\n group.isPlaying = false;\n}\n\n/** Stop playback and reset to frame 0. */\nexport function stopAnimation(group: AnimationGroup): void {\n group.isPlaying = false;\n group.currentTime = 0;\n group._stopped = true;\n}\n\n/** Push the group's public playback state into its controller. */\nfunction syncControllerFromGroup(group: AnimationGroup, ctrl: AnimationController): void {\n ctrl.time = group.currentTime;\n ctrl.playing = group.isPlaying;\n ctrl.speedRatio = group.speedRatio;\n ctrl.loop = group.loopAnimation;\n ctrl._setMask?.(group.mask ?? null);\n}\n\n/** The real per-frame stepper. Lives in this dynamically-loaded module; the always-loaded\n * animation-tick forwarder calls it once registered. */\nfunction tickAnimationImpl(group: AnimationGroup, deltaMs: number, engine?: EngineContext): void {\n if (!group._stopped && group._ctrl) {\n syncControllerFromGroup(group, group._ctrl);\n group._ctrl.tick(deltaMs, engine);\n group.currentTime = group._ctrl.time;\n }\n}\n\n/** @internal Wire the always-loaded tickAnimation forwarder to its real implementation.\n * Called by the group factories so a scene cannot hold groups before the impl is registered. */\nexport function _installTickAnimation(): void {\n _setTickAnimationImpl(tickAnimationImpl);\n}\n\n/** Seek to a specific frame, apply the pose, and pause. */\nexport function goToFrame(group: AnimationGroup, frame: number, engine?: EngineContext): void {\n const ctrl = group._ctrl;\n group.currentTime = frame / (group.frameRate || DEFAULT_FRAME_RATE);\n group.isPlaying = false;\n if (ctrl) {\n syncControllerFromGroup(group, ctrl);\n if (engine || !group._stopped || !group._gltfMixer) {\n ctrl.tick(0, engine);\n group.currentTime = ctrl.time;\n }\n }\n}\n\n/** Create AnimationGroup(s) from parsed glTF animation data.\n * Returns one group per animation clip. */\nexport function createAnimationGroups(animData: GltfAnimationData): AnimationGroup[] {\n const { clips, nodes, skeletons, morphBindings, nodeTargets, excludedNodeIndices, nodeNames, boneOverrides } = animData;\n const hasPointer = clips.some((c) => c.channels.some((ch) => ch.path === PATH_POINTER));\n const hasNodeWriteback = clips.some((c) =>\n c.channels.some(\n (ch) =>\n (ch.path === PATH_TRANSLATION || ch.path === PATH_ROTATION || ch.path === PATH_SCALE) &&\n ch.nodeIdx >= 0 &&\n !excludedNodeIndices.has(ch.nodeIdx) &&\n !!nodeTargets[ch.nodeIdx]\n )\n );\n if (clips.length === 0 || (skeletons.length === 0 && morphBindings.length === 0 && !hasPointer && !hasNodeWriteback)) {\n return [];\n }\n\n _installTickAnimation();\n\n return clips.map((clip, clipIndex) => {\n const ctrl: AnimationController = createAnimationController(clip, nodes, skeletons, morphBindings, nodeTargets, excludedNodeIndices, boneOverrides, nodeNames);\n const started = clipIndex === 0;\n const group: AnimationGroup = {\n name: clip.name || `animation_${clipIndex}`,\n duration: clip.duration,\n frameRate: clip.frameRate || DEFAULT_FRAME_RATE,\n isPlaying: started,\n currentTime: 0,\n targetedAnimations: clip.channels.map((ch) => {\n const nodeIndex = ch.nodeIdx >= 0 ? ch.nodeIdx : undefined;\n return {\n target: nodeIndex !== undefined ? nodeTargets[nodeIndex] : undefined,\n targetName: nodeIndex !== undefined ? nodeNames[nodeIndex] : undefined,\n nodeIndex,\n path: pathName(ch.path),\n };\n }),\n speedRatio: 1,\n loopAnimation: true,\n weight: 1,\n _ctrl: ctrl,\n _stopped: !started,\n };\n group._gltfMixer = [clip, nodes, skeletons];\n return group;\n });\n}\n\nfunction pathName(path: number): string {\n return path === PATH_TRANSLATION ? \"translation\" : path === PATH_ROTATION ? \"rotation\" : path === PATH_SCALE ? \"scale\" : path === PATH_POINTER ? \"pointer\" : \"weights\";\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ let _tickAnimationImpl = null;
2
+ function _setTickAnimationImpl(impl) {
3
+ _tickAnimationImpl = impl;
4
+ }
5
+ function tickAnimation(group, deltaMs, engine) {
6
+ _tickAnimationImpl?.(group, deltaMs, engine);
7
+ }
8
+
9
+ export { _setTickAnimationImpl, tickAnimation };
10
+ //# sourceMappingURL=animation-tick.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animation-tick.js","sources":["../../../src/animation/animation-tick.ts"],"sourcesContent":["// Tiny always-loaded forwarder for the per-frame animation tick. The real implementation\n// (state sync + controller advance + writeback) lives in the dynamically-loaded animation\n// module and registers itself here when the first animation group is created. This keeps the\n// always-loaded scene render loop free of the animation logic (and of animation-group.ts),\n// while staying fully synchronous: a scene cannot hold animation groups unless the animation\n// module already loaded and registered the implementation, which happens before the first\n// rendered frame can call tickAnimation.\n\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { AnimationGroup } from \"./animation-group.js\";\n\ntype TickAnimationFn = (group: AnimationGroup, deltaMs: number, engine?: EngineContext) => void;\n\nlet _tickAnimationImpl: TickAnimationFn | null = null;\n\n/** @internal Register the real tick implementation. Called by the animation group factories. */\nexport function _setTickAnimationImpl(impl: TickAnimationFn): void {\n _tickAnimationImpl = impl;\n}\n\n/** @internal Advance animation by deltaMs. Forwards to the implementation registered when the\n * first animation group was created; a no-op before any group exists. */\nexport function tickAnimation(group: AnimationGroup, deltaMs: number, engine?: EngineContext): void {\n _tickAnimationImpl?.(group, deltaMs, engine);\n}\n"],"names":[],"mappings":"AAaA,IAAI,kBAAA,GAA6C,IAAA;AAG1C,SAAS,sBAAsB,IAAA,EAA6B;AAC/D,EAAA,kBAAA,GAAqB,IAAA;AACzB;AAIO,SAAS,aAAA,CAAc,KAAA,EAAuB,OAAA,EAAiB,MAAA,EAA8B;AAChG,EAAA,kBAAA,GAAqB,KAAA,EAAO,SAAS,MAAM,CAAA;AAC/C;;;;"}
@@ -1,5 +1,5 @@
1
1
  import { F32 } from '../engine/typed-arrays.js';
2
- import { playAnimation } from './animation-group.js';
2
+ import { playAnimation, _installTickAnimation } from './animation-group.js';
3
3
  import { addAnimationGroup } from './animation-group-task.js';
4
4
  import { INTERP_STEP, INTERP_LINEAR } from './types.js';
5
5
  import { evaluateSampler } from './evaluate.js';
@@ -83,6 +83,7 @@ function createPointerAnimationGroup(name, duration, frameRate, tracks, fromTime
83
83
  }
84
84
  }
85
85
  };
86
+ _installTickAnimation();
86
87
  return {
87
88
  name,
88
89
  duration,
@@ -1 +1 @@
1
- {"version":3,"file":"property-animation.js","sources":["../../../src/animation/property-animation.ts"],"sourcesContent":["import { F32 } from \"../engine/typed-arrays.js\";\nimport { playAnimation } from \"./animation-group.js\";\nimport type { AnimationGroup, AnimationPropertyRuntimeTrack } from \"./animation-group.js\";\nimport { addAnimationGroup } from \"./animation-group-task.js\";\nimport type { AnimationManager } from \"./animation-manager.js\";\nimport { INTERP_LINEAR, INTERP_STEP } from \"./types.js\";\nimport type { AnimationSampler } from \"./types.js\";\nimport { evaluateSampler } from \"./evaluate.js\";\nimport type { AnimationController } from \"../skeleton/skeleton-updater.js\";\n\nconst DEFAULT_FRAME_RATE = 60;\n\n/** A keyframe value: a single scalar or a fixed-length tuple of components (e.g. a vector or quaternion). */\nexport type AnimationKeyframeValue = number | readonly number[];\n\n/** A single keyframe on a property animation track. Supply exactly one of `time` (seconds) or `frame`. */\nexport interface AnimationKeyframe {\n readonly time?: number;\n readonly frame?: number;\n readonly value: AnimationKeyframeValue;\n}\n\n/** Interpolation mode between keyframes: smooth `\"linear\"` or hold-previous `\"step\"`. */\nexport type PropertyAnimationInterpolation = \"linear\" | \"step\";\n\n/** Options describing one animated property track passed to {@link createPropertyAnimationClip}. */\nexport interface PropertyAnimationTrackOptions {\n readonly path: string;\n readonly keys: readonly AnimationKeyframe[];\n readonly frameRate?: number;\n readonly interpolation?: PropertyAnimationInterpolation;\n readonly quaternion?: boolean;\n}\n\n/** Options for {@link createPropertyAnimationClip}. */\nexport interface PropertyAnimationClipOptions {\n readonly frameRate?: number;\n}\n\n/** A compiled animation track: a sampler plus the metadata needed to evaluate and write its property. */\nexport interface PropertyAnimationTrack {\n readonly path: string;\n readonly sampler: AnimationSampler;\n readonly stride: number;\n readonly quaternion: boolean;\n}\n\n/** A reusable, target-independent set of compiled property tracks with a total duration. */\nexport interface PropertyAnimationClip {\n readonly name: string;\n readonly tracks: readonly PropertyAnimationTrack[];\n readonly duration: number;\n readonly frameRate: number;\n}\n\n/** Options for {@link createPropertyAnimationGroup}, controlling looping, speed, and play range. */\nexport interface CreatePropertyAnimationGroupOptions {\n readonly loop?: boolean;\n readonly speedRatio?: number;\n readonly fromFrame?: number;\n readonly toFrame?: number;\n readonly fromTime?: number;\n readonly toTime?: number;\n}\n\ntype PropertyWriter = (output: Float32Array, offset: number) => void;\n\ninterface ResolvedPropertyBinding {\n readonly mixTarget: object;\n readonly mixProperty: string;\n readonly writer: PropertyWriter;\n}\n\ninterface PathSettable {\n set: (...values: number[]) => void;\n}\n\n/** Compiles a set of track definitions into a reusable {@link PropertyAnimationClip}.\n * @param name - Clip name.\n * @param tracks - One or more track definitions; their keyframes are sorted and baked into samplers.\n * @param options - Optional default frame rate.\n * @returns The compiled clip, with its duration set to the longest track.\n * @throws If no tracks are provided. */\nexport function createPropertyAnimationClip(name: string, tracks: readonly PropertyAnimationTrackOptions[], options?: PropertyAnimationClipOptions): PropertyAnimationClip {\n if (tracks.length === 0) {\n throw new Error(\"createPropertyAnimationClip requires at least one track\");\n }\n const frameRate = options?.frameRate ?? tracks[0]?.frameRate ?? DEFAULT_FRAME_RATE;\n let duration = 0;\n const builtTracks = tracks.map((track) => {\n const trackFrameRate = track.frameRate ?? frameRate;\n const sampler = createSampler(track, trackFrameRate);\n const trackDuration = sampler.input[sampler.input.length - 1] ?? 0;\n if (trackDuration > duration) {\n duration = trackDuration;\n }\n return {\n path: track.path,\n sampler,\n stride: getTrackStride(track),\n quaternion: track.quaternion === true || track.path === \"rotationQuaternion\" || track.path.endsWith(\".rotationQuaternion\"),\n };\n });\n return { name, tracks: builtTracks, duration, frameRate };\n}\n\n/** Binds `clip` to `target`'s properties, creates a playing animation group, and attaches it to `manager`.\n * @param manager - Animation manager that drives the resulting group.\n * @param target - Object whose properties (resolved by each track's dotted path) are animated.\n * @param clip - Compiled clip to play.\n * @param options - Optional looping, speed, and play-range overrides.\n * @returns The started animation group.\n * @throws If the resolved play range does not have `toTime` greater than `fromTime`. */\nexport function createPropertyAnimationGroup(\n manager: AnimationManager,\n target: object,\n clip: PropertyAnimationClip,\n options?: CreatePropertyAnimationGroupOptions\n): AnimationGroup {\n const runtimeTracks: AnimationPropertyRuntimeTrack[] = [];\n for (let i = 0; i < clip.tracks.length; i++) {\n const track = clip.tracks[i]!;\n const binding = resolvePropertyBinding(target, track.path, track.stride);\n runtimeTracks.push({\n sampler: track.sampler,\n stride: track.stride,\n quaternion: track.quaternion,\n writer: binding.writer,\n mixTarget: binding.mixTarget,\n mixProperty: binding.mixProperty,\n });\n }\n\n const fromTime = options?.fromTime ?? (options?.fromFrame !== undefined ? options.fromFrame / clip.frameRate : 0);\n const toTime = options?.toTime ?? (options?.toFrame !== undefined ? options.toFrame / clip.frameRate : clip.duration);\n if (!(toTime > fromTime)) {\n throw new Error(\"Animation play range must have toTime greater than fromTime\");\n }\n\n const group = createPointerAnimationGroup(clip.name, clip.duration, clip.frameRate, runtimeTracks, fromTime, toTime, options);\n group.loopAnimation = options?.loop ?? true;\n group.speedRatio = options?.speedRatio ?? 1;\n group._propertyMixer = [runtimeTracks, fromTime, toTime, clip.duration];\n playAnimation(group);\n addAnimationGroup(manager, group);\n return group;\n}\n\nfunction createPointerAnimationGroup(\n name: string,\n duration: number,\n frameRate: number,\n tracks: readonly AnimationPropertyRuntimeTrack[],\n fromTime: number,\n toTime: number,\n options?: CreatePropertyAnimationGroupOptions\n): AnimationGroup {\n const ctrl: AnimationController = {\n time: fromTime,\n playing: false,\n speedRatio: options?.speedRatio ?? 1,\n loop: options?.loop ?? true,\n tick(deltaMs: number): void {\n if (ctrl.playing) {\n ctrl.time += (deltaMs / 1000) * ctrl.speedRatio;\n }\n const duration = Math.max(0, toTime - fromTime);\n if (duration <= 0) {\n return;\n }\n if (ctrl.loop && ctrl.playing) {\n ctrl.time = fromTime + ((ctrl.time - fromTime) % duration);\n if (ctrl.time < fromTime) {\n ctrl.time += duration;\n }\n } else {\n ctrl.time = Math.min(Math.max(ctrl.time, fromTime), toTime);\n }\n for (let trackIndex = 0; trackIndex < tracks.length; trackIndex++) {\n const track = tracks[trackIndex]!;\n evaluateSampler(track.sampler, ctrl.time, track.stride, track.quaternion, _pointerScratch, 0);\n track.writer(_pointerScratch, 0);\n }\n },\n };\n return {\n name,\n duration,\n frameRate: frameRate || DEFAULT_FRAME_RATE,\n isPlaying: false,\n currentTime: fromTime,\n targetedAnimations: tracks.map((track) => ({ target: track.mixTarget, path: track.mixProperty })),\n speedRatio: options?.speedRatio ?? 1,\n loopAnimation: options?.loop ?? true,\n weight: 1,\n _ctrl: ctrl,\n _stopped: false,\n };\n}\n\nconst _pointerScratch = new F32(16);\n\nfunction createSampler(track: PropertyAnimationTrackOptions, frameRate: number): AnimationSampler {\n if (track.keys.length === 0) {\n throw new Error(`Animation track \"${track.path}\" requires at least one key`);\n }\n if (!(frameRate > 0)) {\n throw new Error(`Animation track \"${track.path}\" requires a positive frameRate`);\n }\n\n const stride = getTrackStride(track);\n const sorted = [...track.keys].sort((a, b) => getKeyTime(a, frameRate, track.path) - getKeyTime(b, frameRate, track.path));\n const input = new F32(sorted.length);\n const output = new F32(sorted.length * stride);\n let lastTime = -Infinity;\n for (let i = 0; i < sorted.length; i++) {\n const key = sorted[i]!;\n const time = getKeyTime(key, frameRate, track.path);\n if (time < lastTime) {\n throw new Error(`Animation track \"${track.path}\" key times must be monotonically increasing`);\n }\n input[i] = time;\n lastTime = time;\n writeKeyValue(track.path, key.value, stride, output, i * stride);\n }\n return {\n input,\n output,\n interpolation: track.interpolation === \"step\" ? INTERP_STEP : INTERP_LINEAR,\n };\n}\n\nfunction getTrackStride(track: PropertyAnimationTrackOptions): number {\n const value = track.keys[0]?.value;\n if (value === undefined) {\n throw new Error(`Animation track \"${track.path}\" requires at least one key`);\n }\n return typeof value === \"number\" ? 1 : value.length;\n}\n\nfunction getKeyTime(key: AnimationKeyframe, frameRate: number, path: string): number {\n const hasTime = key.time !== undefined;\n const hasFrame = key.frame !== undefined;\n if (hasTime === hasFrame) {\n throw new Error(`Animation key for \"${path}\" must provide exactly one of time or frame`);\n }\n const time = hasTime ? key.time! : key.frame! / frameRate;\n if (!(time >= 0)) {\n throw new Error(`Animation key for \"${path}\" must have a non-negative time`);\n }\n return time;\n}\n\nfunction writeKeyValue(path: string, value: AnimationKeyframeValue, stride: number, output: Float32Array, offset: number): void {\n if (typeof value === \"number\") {\n if (stride !== 1) {\n throw new Error(`Animation key for \"${path}\" expected ${stride} values`);\n }\n output[offset] = value;\n return;\n }\n if (value.length !== stride) {\n throw new Error(`Animation key for \"${path}\" expected ${stride} values`);\n }\n for (let i = 0; i < stride; i++) {\n output[offset + i] = value[i]!;\n }\n}\n\nfunction resolvePropertyBinding(target: object, path: string, stride: number): ResolvedPropertyBinding {\n const parts = path.split(\".\");\n if (parts.length === 0 || parts.some((p) => p.length === 0)) {\n throw new Error(`Invalid animation property path \"${path}\"`);\n }\n\n let owner: unknown = target;\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i]!;\n const record = asRecord(owner, path);\n if (!(part in record)) {\n throw new Error(`Animation property path \"${path}\" could not resolve \"${part}\"`);\n }\n owner = record[part];\n }\n\n const property = parts[parts.length - 1]!;\n const record = asRecord(owner, path);\n if (!(property in record)) {\n throw new Error(`Animation property path \"${path}\" could not resolve \"${property}\"`);\n }\n\n return { mixTarget: record, mixProperty: property, writer: createPropertyWriter(record, property, stride, path) };\n}\n\nfunction asRecord(value: unknown, path: string): Record<string, unknown> {\n if ((typeof value !== \"object\" && typeof value !== \"function\") || value === null) {\n throw new Error(`Animation property path \"${path}\" reached a non-object value`);\n }\n return value as Record<string, unknown>;\n}\n\nfunction isSettable(value: unknown): value is PathSettable {\n return (typeof value === \"object\" || typeof value === \"function\") && value !== null && typeof (value as { set?: unknown }).set === \"function\";\n}\n\nfunction createPropertyWriter(target: Record<string, unknown>, property: string, stride: number, path: string): PropertyWriter {\n if (stride === 1) {\n return (output, offset) => {\n target[property] = output[offset]!;\n };\n }\n if (stride > 4) {\n throw new Error(`Animation property path \"${path}\" has unsupported vector size ${stride}`);\n }\n\n const targetValue = target[property];\n if (isSettable(targetValue)) {\n switch (stride) {\n case 2:\n return (output, offset) => targetValue.set(output[offset]!, output[offset + 1]!);\n case 3:\n return (output, offset) => targetValue.set(output[offset]!, output[offset + 1]!, output[offset + 2]!);\n case 4:\n return (output, offset) => targetValue.set(output[offset]!, output[offset + 1]!, output[offset + 2]!, output[offset + 3]!);\n }\n }\n\n const valueRecord = asRecord(targetValue, path);\n const components = \"xyzw\";\n for (let i = 0; i < stride; i++) {\n if (!(components[i]! in valueRecord)) {\n throw new Error(`Animation property path \"${path}\" could not resolve component \"${components[i]!}\"`);\n }\n }\n return (output, offset) => {\n for (let i = 0; i < stride; i++) {\n valueRecord[components[i]!] = output[offset + i]!;\n }\n };\n}\n"],"names":["duration","record"],"mappings":";;;;;;AAUA,MAAM,kBAAA,GAAqB,EAAA;AAyEpB,SAAS,2BAAA,CAA4B,IAAA,EAAc,MAAA,EAAkD,OAAA,EAA+D;AACvK,EAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACrB,IAAA,MAAM,IAAI,MAAM,yDAAyD,CAAA;AAAA,EAC7E;AACA,EAAA,MAAM,YAAY,OAAA,EAAS,SAAA,IAAa,MAAA,CAAO,CAAC,GAAG,SAAA,IAAa,kBAAA;AAChE,EAAA,IAAI,QAAA,GAAW,CAAA;AACf,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,KAAU;AACtC,IAAA,MAAM,cAAA,GAAiB,MAAM,SAAA,IAAa,SAAA;AAC1C,IAAA,MAAM,OAAA,GAAU,aAAA,CAAc,KAAA,EAAO,cAAc,CAAA;AACnD,IAAA,MAAM,gBAAgB,OAAA,CAAQ,KAAA,CAAM,QAAQ,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA,IAAK,CAAA;AACjE,IAAA,IAAI,gBAAgB,QAAA,EAAU;AAC1B,MAAA,QAAA,GAAW,aAAA;AAAA,IACf;AACA,IAAA,OAAO;AAAA,MACH,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,OAAA;AAAA,MACA,MAAA,EAAQ,eAAe,KAAK,CAAA;AAAA,MAC5B,UAAA,EAAY,KAAA,CAAM,UAAA,KAAe,IAAA,IAAQ,KAAA,CAAM,SAAS,oBAAA,IAAwB,KAAA,CAAM,IAAA,CAAK,QAAA,CAAS,qBAAqB;AAAA,KAC7H;AAAA,EACJ,CAAC,CAAA;AACD,EAAA,OAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAA,EAAa,UAAU,SAAA,EAAU;AAC5D;AASO,SAAS,4BAAA,CACZ,OAAA,EACA,MAAA,EACA,IAAA,EACA,OAAA,EACc;AACd,EAAA,MAAM,gBAAiD,EAAC;AACxD,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AACzC,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA;AAC3B,IAAA,MAAM,UAAU,sBAAA,CAAuB,MAAA,EAAQ,KAAA,CAAM,IAAA,EAAM,MAAM,MAAM,CAAA;AACvE,IAAA,aAAA,CAAc,IAAA,CAAK;AAAA,MACf,SAAS,KAAA,CAAM,OAAA;AAAA,MACf,QAAQ,KAAA,CAAM,MAAA;AAAA,MACd,YAAY,KAAA,CAAM,UAAA;AAAA,MAClB,QAAQ,OAAA,CAAQ,MAAA;AAAA,MAChB,WAAW,OAAA,CAAQ,SAAA;AAAA,MACnB,aAAa,OAAA,CAAQ;AAAA,KACxB,CAAA;AAAA,EACL;AAEA,EAAA,MAAM,QAAA,GAAW,SAAS,QAAA,KAAa,OAAA,EAAS,cAAc,MAAA,GAAY,OAAA,CAAQ,SAAA,GAAY,IAAA,CAAK,SAAA,GAAY,CAAA,CAAA;AAC/G,EAAA,MAAM,MAAA,GAAS,OAAA,EAAS,MAAA,KAAW,OAAA,EAAS,OAAA,KAAY,SAAY,OAAA,CAAQ,OAAA,GAAU,IAAA,CAAK,SAAA,GAAY,IAAA,CAAK,QAAA,CAAA;AAC5G,EAAA,IAAI,EAAE,SAAS,QAAA,CAAA,EAAW;AACtB,IAAA,MAAM,IAAI,MAAM,6DAA6D,CAAA;AAAA,EACjF;AAEA,EAAA,MAAM,KAAA,GAAQ,2BAAA,CAA4B,IAAA,CAAK,IAAA,EAAM,IAAA,CAAK,QAAA,EAAU,IAAA,CAAK,SAAA,EAAW,aAAA,EAAe,QAAA,EAAU,MAAA,EAAQ,OAAO,CAAA;AAC5H,EAAA,KAAA,CAAM,aAAA,GAAgB,SAAS,IAAA,IAAQ,IAAA;AACvC,EAAA,KAAA,CAAM,UAAA,GAAa,SAAS,UAAA,IAAc,CAAA;AAC1C,EAAA,KAAA,CAAM,iBAAiB,CAAC,aAAA,EAAe,QAAA,EAAU,MAAA,EAAQ,KAAK,QAAQ,CAAA;AACtE,EAAA,aAAA,CAAc,KAAK,CAAA;AACnB,EAAA,iBAAA,CAAkB,SAAS,KAAK,CAAA;AAChC,EAAA,OAAO,KAAA;AACX;AAEA,SAAS,4BACL,IAAA,EACA,QAAA,EACA,WACA,MAAA,EACA,QAAA,EACA,QACA,OAAA,EACc;AACd,EAAA,MAAM,IAAA,GAA4B;AAAA,IAC9B,IAAA,EAAM,QAAA;AAAA,IACN,OAAA,EAAS,KAAA;AAAA,IACT,UAAA,EAAY,SAAS,UAAA,IAAc,CAAA;AAAA,IACnC,IAAA,EAAM,SAAS,IAAA,IAAQ,IAAA;AAAA,IACvB,KAAK,OAAA,EAAuB;AACxB,MAAA,IAAI,KAAK,OAAA,EAAS;AACd,QAAA,IAAA,CAAK,IAAA,IAAS,OAAA,GAAU,GAAA,GAAQ,IAAA,CAAK,UAAA;AAAA,MACzC;AACA,MAAA,MAAMA,SAAAA,GAAW,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,SAAS,QAAQ,CAAA;AAC9C,MAAA,IAAIA,aAAY,CAAA,EAAG;AACf,QAAA;AAAA,MACJ;AACA,MAAA,IAAI,IAAA,CAAK,IAAA,IAAQ,IAAA,CAAK,OAAA,EAAS;AAC3B,QAAA,IAAA,CAAK,IAAA,GAAO,QAAA,GAAA,CAAa,IAAA,CAAK,IAAA,GAAO,QAAA,IAAYA,SAAAA;AACjD,QAAA,IAAI,IAAA,CAAK,OAAO,QAAA,EAAU;AACtB,UAAA,IAAA,CAAK,IAAA,IAAQA,SAAAA;AAAA,QACjB;AAAA,MACJ,CAAA,MAAO;AACH,QAAA,IAAA,CAAK,IAAA,GAAO,KAAK,GAAA,CAAI,IAAA,CAAK,IAAI,IAAA,CAAK,IAAA,EAAM,QAAQ,CAAA,EAAG,MAAM,CAAA;AAAA,MAC9D;AACA,MAAA,KAAA,IAAS,UAAA,GAAa,CAAA,EAAG,UAAA,GAAa,MAAA,CAAO,QAAQ,UAAA,EAAA,EAAc;AAC/D,QAAA,MAAM,KAAA,GAAQ,OAAO,UAAU,CAAA;AAC/B,QAAA,eAAA,CAAgB,KAAA,CAAM,SAAS,IAAA,CAAK,IAAA,EAAM,MAAM,MAAA,EAAQ,KAAA,CAAM,UAAA,EAAY,eAAA,EAAiB,CAAC,CAAA;AAC5F,QAAA,KAAA,CAAM,MAAA,CAAO,iBAAiB,CAAC,CAAA;AAAA,MACnC;AAAA,IACJ;AAAA,GACJ;AACA,EAAA,OAAO;AAAA,IACH,IAAA;AAAA,IACA,QAAA;AAAA,IACA,WAAW,SAAA,IAAa,kBAAA;AAAA,IACxB,SAAA,EAAW,KAAA;AAAA,IACX,WAAA,EAAa,QAAA;AAAA,IACb,kBAAA,EAAoB,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,MAAW,EAAE,MAAA,EAAQ,KAAA,CAAM,SAAA,EAAW,IAAA,EAAM,KAAA,CAAM,WAAA,EAAY,CAAE,CAAA;AAAA,IAChG,UAAA,EAAY,SAAS,UAAA,IAAc,CAAA;AAAA,IACnC,aAAA,EAAe,SAAS,IAAA,IAAQ,IAAA;AAAA,IAChC,MAAA,EAAQ,CAAA;AAAA,IACR,KAAA,EAAO,IAAA;AAAA,IACP,QAAA,EAAU;AAAA,GACd;AACJ;AAEA,MAAM,eAAA,GAAkB,IAAI,GAAA,CAAI,EAAE,CAAA;AAElC,SAAS,aAAA,CAAc,OAAsC,SAAA,EAAqC;AAC9F,EAAA,IAAI,KAAA,CAAM,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG;AACzB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iBAAA,EAAoB,KAAA,CAAM,IAAI,CAAA,2BAAA,CAA6B,CAAA;AAAA,EAC/E;AACA,EAAA,IAAI,EAAE,YAAY,CAAA,CAAA,EAAI;AAClB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iBAAA,EAAoB,KAAA,CAAM,IAAI,CAAA,+BAAA,CAAiC,CAAA;AAAA,EACnF;AAEA,EAAA,MAAM,MAAA,GAAS,eAAe,KAAK,CAAA;AACnC,EAAA,MAAM,MAAA,GAAS,CAAC,GAAG,KAAA,CAAM,IAAI,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,WAAW,CAAA,EAAG,SAAA,EAAW,MAAM,IAAI,CAAA,GAAI,WAAW,CAAA,EAAG,SAAA,EAAW,KAAA,CAAM,IAAI,CAAC,CAAA;AACzH,EAAA,MAAM,KAAA,GAAQ,IAAI,GAAA,CAAI,MAAA,CAAO,MAAM,CAAA;AACnC,EAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,MAAA,CAAO,SAAS,MAAM,CAAA;AAC7C,EAAA,IAAI,QAAA,GAAW,CAAA,QAAA;AACf,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AACpC,IAAA,MAAM,GAAA,GAAM,OAAO,CAAC,CAAA;AACpB,IAAA,MAAM,IAAA,GAAO,UAAA,CAAW,GAAA,EAAK,SAAA,EAAW,MAAM,IAAI,CAAA;AAClD,IAAA,IAAI,OAAO,QAAA,EAAU;AACjB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iBAAA,EAAoB,KAAA,CAAM,IAAI,CAAA,4CAAA,CAA8C,CAAA;AAAA,IAChG;AACA,IAAA,KAAA,CAAM,CAAC,CAAA,GAAI,IAAA;AACX,IAAA,QAAA,GAAW,IAAA;AACX,IAAA,aAAA,CAAc,MAAM,IAAA,EAAM,GAAA,CAAI,OAAO,MAAA,EAAQ,MAAA,EAAQ,IAAI,MAAM,CAAA;AAAA,EACnE;AACA,EAAA,OAAO;AAAA,IACH,KAAA;AAAA,IACA,MAAA;AAAA,IACA,aAAA,EAAe,KAAA,CAAM,aAAA,KAAkB,MAAA,GAAS,WAAA,GAAc;AAAA,GAClE;AACJ;AAEA,SAAS,eAAe,KAAA,EAA8C;AAClE,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,EAAG,KAAA;AAC7B,EAAA,IAAI,UAAU,MAAA,EAAW;AACrB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iBAAA,EAAoB,KAAA,CAAM,IAAI,CAAA,2BAAA,CAA6B,CAAA;AAAA,EAC/E;AACA,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,GAAW,CAAA,GAAI,KAAA,CAAM,MAAA;AACjD;AAEA,SAAS,UAAA,CAAW,GAAA,EAAwB,SAAA,EAAmB,IAAA,EAAsB;AACjF,EAAA,MAAM,OAAA,GAAU,IAAI,IAAA,KAAS,MAAA;AAC7B,EAAA,MAAM,QAAA,GAAW,IAAI,KAAA,KAAU,MAAA;AAC/B,EAAA,IAAI,YAAY,QAAA,EAAU;AACtB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,IAAI,CAAA,2CAAA,CAA6C,CAAA;AAAA,EAC3F;AACA,EAAA,MAAM,IAAA,GAAO,OAAA,GAAU,GAAA,CAAI,IAAA,GAAQ,IAAI,KAAA,GAAS,SAAA;AAChD,EAAA,IAAI,EAAE,QAAQ,CAAA,CAAA,EAAI;AACd,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,IAAI,CAAA,+BAAA,CAAiC,CAAA;AAAA,EAC/E;AACA,EAAA,OAAO,IAAA;AACX;AAEA,SAAS,aAAA,CAAc,IAAA,EAAc,KAAA,EAA+B,MAAA,EAAgB,QAAsB,MAAA,EAAsB;AAC5H,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC3B,IAAA,IAAI,WAAW,CAAA,EAAG;AACd,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,IAAI,CAAA,WAAA,EAAc,MAAM,CAAA,OAAA,CAAS,CAAA;AAAA,IAC3E;AACA,IAAA,MAAA,CAAO,MAAM,CAAA,GAAI,KAAA;AACjB,IAAA;AAAA,EACJ;AACA,EAAA,IAAI,KAAA,CAAM,WAAW,MAAA,EAAQ;AACzB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,IAAI,CAAA,WAAA,EAAc,MAAM,CAAA,OAAA,CAAS,CAAA;AAAA,EAC3E;AACA,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAA,EAAK;AAC7B,IAAA,MAAA,CAAO,MAAA,GAAS,CAAC,CAAA,GAAI,KAAA,CAAM,CAAC,CAAA;AAAA,EAChC;AACJ;AAEA,SAAS,sBAAA,CAAuB,MAAA,EAAgB,IAAA,EAAc,MAAA,EAAyC;AACnG,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC5B,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,IAAK,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,CAAC,CAAA,EAAG;AACzD,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iCAAA,EAAoC,IAAI,CAAA,CAAA,CAAG,CAAA;AAAA,EAC/D;AAEA,EAAA,IAAI,KAAA,GAAiB,MAAA;AACrB,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,MAAA,GAAS,GAAG,CAAA,EAAA,EAAK;AACvC,IAAA,MAAM,IAAA,GAAO,MAAM,CAAC,CAAA;AACpB,IAAA,MAAMC,OAAAA,GAAS,QAAA,CAAS,KAAA,EAAO,IAAI,CAAA;AACnC,IAAA,IAAI,EAAE,QAAQA,OAAAA,CAAAA,EAAS;AACnB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,yBAAA,EAA4B,IAAI,CAAA,qBAAA,EAAwB,IAAI,CAAA,CAAA,CAAG,CAAA;AAAA,IACnF;AACA,IAAA,KAAA,GAAQA,QAAO,IAAI,CAAA;AAAA,EACvB;AAEA,EAAA,MAAM,QAAA,GAAW,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA;AACvC,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,KAAA,EAAO,IAAI,CAAA;AACnC,EAAA,IAAI,EAAE,YAAY,MAAA,CAAA,EAAS;AACvB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,yBAAA,EAA4B,IAAI,CAAA,qBAAA,EAAwB,QAAQ,CAAA,CAAA,CAAG,CAAA;AAAA,EACvF;AAEA,EAAA,OAAO,EAAE,SAAA,EAAW,MAAA,EAAQ,WAAA,EAAa,QAAA,EAAU,MAAA,EAAQ,oBAAA,CAAqB,MAAA,EAAQ,QAAA,EAAU,MAAA,EAAQ,IAAI,CAAA,EAAE;AACpH;AAEA,SAAS,QAAA,CAAS,OAAgB,IAAA,EAAuC;AACrE,EAAA,IAAK,OAAO,KAAA,KAAU,QAAA,IAAY,OAAO,KAAA,KAAU,UAAA,IAAe,UAAU,IAAA,EAAM;AAC9E,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,yBAAA,EAA4B,IAAI,CAAA,4BAAA,CAA8B,CAAA;AAAA,EAClF;AACA,EAAA,OAAO,KAAA;AACX;AAEA,SAAS,WAAW,KAAA,EAAuC;AACvD,EAAA,OAAA,CAAQ,OAAO,KAAA,KAAU,QAAA,IAAY,OAAO,KAAA,KAAU,eAAe,KAAA,KAAU,IAAA,IAAQ,OAAQ,KAAA,CAA4B,GAAA,KAAQ,UAAA;AACvI;AAEA,SAAS,oBAAA,CAAqB,MAAA,EAAiC,QAAA,EAAkB,MAAA,EAAgB,IAAA,EAA8B;AAC3H,EAAA,IAAI,WAAW,CAAA,EAAG;AACd,IAAA,OAAO,CAAC,QAAQ,MAAA,KAAW;AACvB,MAAA,MAAA,CAAO,QAAQ,CAAA,GAAI,MAAA,CAAO,MAAM,CAAA;AAAA,IACpC,CAAA;AAAA,EACJ;AACA,EAAA,IAAI,SAAS,CAAA,EAAG;AACZ,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,yBAAA,EAA4B,IAAI,CAAA,8BAAA,EAAiC,MAAM,CAAA,CAAE,CAAA;AAAA,EAC7F;AAEA,EAAA,MAAM,WAAA,GAAc,OAAO,QAAQ,CAAA;AACnC,EAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AACzB,IAAA,QAAQ,MAAA;AAAQ,MACZ,KAAK,CAAA;AACD,QAAA,OAAO,CAAC,MAAA,EAAQ,MAAA,KAAW,WAAA,CAAY,GAAA,CAAI,MAAA,CAAO,MAAM,CAAA,EAAI,MAAA,CAAO,MAAA,GAAS,CAAC,CAAE,CAAA;AAAA,MACnF,KAAK,CAAA;AACD,QAAA,OAAO,CAAC,MAAA,EAAQ,MAAA,KAAW,WAAA,CAAY,IAAI,MAAA,CAAO,MAAM,CAAA,EAAI,MAAA,CAAO,SAAS,CAAC,CAAA,EAAI,MAAA,CAAO,MAAA,GAAS,CAAC,CAAE,CAAA;AAAA,MACxG,KAAK,CAAA;AACD,QAAA,OAAO,CAAC,MAAA,EAAQ,MAAA,KAAW,YAAY,GAAA,CAAI,MAAA,CAAO,MAAM,CAAA,EAAI,MAAA,CAAO,SAAS,CAAC,CAAA,EAAI,OAAO,MAAA,GAAS,CAAC,GAAI,MAAA,CAAO,MAAA,GAAS,CAAC,CAAE,CAAA;AAAA;AACjI,EACJ;AAEA,EAAA,MAAM,WAAA,GAAc,QAAA,CAAS,WAAA,EAAa,IAAI,CAAA;AAC9C,EAAA,MAAM,UAAA,GAAa,MAAA;AACnB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAA,EAAK;AAC7B,IAAA,IAAI,EAAE,UAAA,CAAW,CAAC,CAAA,IAAM,WAAA,CAAA,EAAc;AAClC,MAAA,MAAM,IAAI,MAAM,CAAA,yBAAA,EAA4B,IAAI,kCAAkC,UAAA,CAAW,CAAC,CAAE,CAAA,CAAA,CAAG,CAAA;AAAA,IACvG;AAAA,EACJ;AACA,EAAA,OAAO,CAAC,QAAQ,MAAA,KAAW;AACvB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAA,EAAK;AAC7B,MAAA,WAAA,CAAY,WAAW,CAAC,CAAE,CAAA,GAAI,MAAA,CAAO,SAAS,CAAC,CAAA;AAAA,IACnD;AAAA,EACJ,CAAA;AACJ;;;;"}
1
+ {"version":3,"file":"property-animation.js","sources":["../../../src/animation/property-animation.ts"],"sourcesContent":["import { F32 } from \"../engine/typed-arrays.js\";\nimport { playAnimation, _installTickAnimation } from \"./animation-group.js\";\nimport type { AnimationGroup, AnimationPropertyRuntimeTrack } from \"./animation-group.js\";\nimport { addAnimationGroup } from \"./animation-group-task.js\";\nimport type { AnimationManager } from \"./animation-manager.js\";\nimport { INTERP_LINEAR, INTERP_STEP } from \"./types.js\";\nimport type { AnimationSampler } from \"./types.js\";\nimport { evaluateSampler } from \"./evaluate.js\";\nimport type { AnimationController } from \"../skeleton/skeleton-updater.js\";\n\nconst DEFAULT_FRAME_RATE = 60;\n\n/** A keyframe value: a single scalar or a fixed-length tuple of components (e.g. a vector or quaternion). */\nexport type AnimationKeyframeValue = number | readonly number[];\n\n/** A single keyframe on a property animation track. Supply exactly one of `time` (seconds) or `frame`. */\nexport interface AnimationKeyframe {\n readonly time?: number;\n readonly frame?: number;\n readonly value: AnimationKeyframeValue;\n}\n\n/** Interpolation mode between keyframes: smooth `\"linear\"` or hold-previous `\"step\"`. */\nexport type PropertyAnimationInterpolation = \"linear\" | \"step\";\n\n/** Options describing one animated property track passed to {@link createPropertyAnimationClip}. */\nexport interface PropertyAnimationTrackOptions {\n readonly path: string;\n readonly keys: readonly AnimationKeyframe[];\n readonly frameRate?: number;\n readonly interpolation?: PropertyAnimationInterpolation;\n readonly quaternion?: boolean;\n}\n\n/** Options for {@link createPropertyAnimationClip}. */\nexport interface PropertyAnimationClipOptions {\n readonly frameRate?: number;\n}\n\n/** A compiled animation track: a sampler plus the metadata needed to evaluate and write its property. */\nexport interface PropertyAnimationTrack {\n readonly path: string;\n readonly sampler: AnimationSampler;\n readonly stride: number;\n readonly quaternion: boolean;\n}\n\n/** A reusable, target-independent set of compiled property tracks with a total duration. */\nexport interface PropertyAnimationClip {\n readonly name: string;\n readonly tracks: readonly PropertyAnimationTrack[];\n readonly duration: number;\n readonly frameRate: number;\n}\n\n/** Options for {@link createPropertyAnimationGroup}, controlling looping, speed, and play range. */\nexport interface CreatePropertyAnimationGroupOptions {\n readonly loop?: boolean;\n readonly speedRatio?: number;\n readonly fromFrame?: number;\n readonly toFrame?: number;\n readonly fromTime?: number;\n readonly toTime?: number;\n}\n\ntype PropertyWriter = (output: Float32Array, offset: number) => void;\n\ninterface ResolvedPropertyBinding {\n readonly mixTarget: object;\n readonly mixProperty: string;\n readonly writer: PropertyWriter;\n}\n\ninterface PathSettable {\n set: (...values: number[]) => void;\n}\n\n/** Compiles a set of track definitions into a reusable {@link PropertyAnimationClip}.\n * @param name - Clip name.\n * @param tracks - One or more track definitions; their keyframes are sorted and baked into samplers.\n * @param options - Optional default frame rate.\n * @returns The compiled clip, with its duration set to the longest track.\n * @throws If no tracks are provided. */\nexport function createPropertyAnimationClip(name: string, tracks: readonly PropertyAnimationTrackOptions[], options?: PropertyAnimationClipOptions): PropertyAnimationClip {\n if (tracks.length === 0) {\n throw new Error(\"createPropertyAnimationClip requires at least one track\");\n }\n const frameRate = options?.frameRate ?? tracks[0]?.frameRate ?? DEFAULT_FRAME_RATE;\n let duration = 0;\n const builtTracks = tracks.map((track) => {\n const trackFrameRate = track.frameRate ?? frameRate;\n const sampler = createSampler(track, trackFrameRate);\n const trackDuration = sampler.input[sampler.input.length - 1] ?? 0;\n if (trackDuration > duration) {\n duration = trackDuration;\n }\n return {\n path: track.path,\n sampler,\n stride: getTrackStride(track),\n quaternion: track.quaternion === true || track.path === \"rotationQuaternion\" || track.path.endsWith(\".rotationQuaternion\"),\n };\n });\n return { name, tracks: builtTracks, duration, frameRate };\n}\n\n/** Binds `clip` to `target`'s properties, creates a playing animation group, and attaches it to `manager`.\n * @param manager - Animation manager that drives the resulting group.\n * @param target - Object whose properties (resolved by each track's dotted path) are animated.\n * @param clip - Compiled clip to play.\n * @param options - Optional looping, speed, and play-range overrides.\n * @returns The started animation group.\n * @throws If the resolved play range does not have `toTime` greater than `fromTime`. */\nexport function createPropertyAnimationGroup(\n manager: AnimationManager,\n target: object,\n clip: PropertyAnimationClip,\n options?: CreatePropertyAnimationGroupOptions\n): AnimationGroup {\n const runtimeTracks: AnimationPropertyRuntimeTrack[] = [];\n for (let i = 0; i < clip.tracks.length; i++) {\n const track = clip.tracks[i]!;\n const binding = resolvePropertyBinding(target, track.path, track.stride);\n runtimeTracks.push({\n sampler: track.sampler,\n stride: track.stride,\n quaternion: track.quaternion,\n writer: binding.writer,\n mixTarget: binding.mixTarget,\n mixProperty: binding.mixProperty,\n });\n }\n\n const fromTime = options?.fromTime ?? (options?.fromFrame !== undefined ? options.fromFrame / clip.frameRate : 0);\n const toTime = options?.toTime ?? (options?.toFrame !== undefined ? options.toFrame / clip.frameRate : clip.duration);\n if (!(toTime > fromTime)) {\n throw new Error(\"Animation play range must have toTime greater than fromTime\");\n }\n\n const group = createPointerAnimationGroup(clip.name, clip.duration, clip.frameRate, runtimeTracks, fromTime, toTime, options);\n group.loopAnimation = options?.loop ?? true;\n group.speedRatio = options?.speedRatio ?? 1;\n group._propertyMixer = [runtimeTracks, fromTime, toTime, clip.duration];\n playAnimation(group);\n addAnimationGroup(manager, group);\n return group;\n}\n\nfunction createPointerAnimationGroup(\n name: string,\n duration: number,\n frameRate: number,\n tracks: readonly AnimationPropertyRuntimeTrack[],\n fromTime: number,\n toTime: number,\n options?: CreatePropertyAnimationGroupOptions\n): AnimationGroup {\n const ctrl: AnimationController = {\n time: fromTime,\n playing: false,\n speedRatio: options?.speedRatio ?? 1,\n loop: options?.loop ?? true,\n tick(deltaMs: number): void {\n if (ctrl.playing) {\n ctrl.time += (deltaMs / 1000) * ctrl.speedRatio;\n }\n const duration = Math.max(0, toTime - fromTime);\n if (duration <= 0) {\n return;\n }\n if (ctrl.loop && ctrl.playing) {\n ctrl.time = fromTime + ((ctrl.time - fromTime) % duration);\n if (ctrl.time < fromTime) {\n ctrl.time += duration;\n }\n } else {\n ctrl.time = Math.min(Math.max(ctrl.time, fromTime), toTime);\n }\n for (let trackIndex = 0; trackIndex < tracks.length; trackIndex++) {\n const track = tracks[trackIndex]!;\n evaluateSampler(track.sampler, ctrl.time, track.stride, track.quaternion, _pointerScratch, 0);\n track.writer(_pointerScratch, 0);\n }\n },\n };\n _installTickAnimation();\n return {\n name,\n duration,\n frameRate: frameRate || DEFAULT_FRAME_RATE,\n isPlaying: false,\n currentTime: fromTime,\n targetedAnimations: tracks.map((track) => ({ target: track.mixTarget, path: track.mixProperty })),\n speedRatio: options?.speedRatio ?? 1,\n loopAnimation: options?.loop ?? true,\n weight: 1,\n _ctrl: ctrl,\n _stopped: false,\n };\n}\n\nconst _pointerScratch = new F32(16);\n\nfunction createSampler(track: PropertyAnimationTrackOptions, frameRate: number): AnimationSampler {\n if (track.keys.length === 0) {\n throw new Error(`Animation track \"${track.path}\" requires at least one key`);\n }\n if (!(frameRate > 0)) {\n throw new Error(`Animation track \"${track.path}\" requires a positive frameRate`);\n }\n\n const stride = getTrackStride(track);\n const sorted = [...track.keys].sort((a, b) => getKeyTime(a, frameRate, track.path) - getKeyTime(b, frameRate, track.path));\n const input = new F32(sorted.length);\n const output = new F32(sorted.length * stride);\n let lastTime = -Infinity;\n for (let i = 0; i < sorted.length; i++) {\n const key = sorted[i]!;\n const time = getKeyTime(key, frameRate, track.path);\n if (time < lastTime) {\n throw new Error(`Animation track \"${track.path}\" key times must be monotonically increasing`);\n }\n input[i] = time;\n lastTime = time;\n writeKeyValue(track.path, key.value, stride, output, i * stride);\n }\n return {\n input,\n output,\n interpolation: track.interpolation === \"step\" ? INTERP_STEP : INTERP_LINEAR,\n };\n}\n\nfunction getTrackStride(track: PropertyAnimationTrackOptions): number {\n const value = track.keys[0]?.value;\n if (value === undefined) {\n throw new Error(`Animation track \"${track.path}\" requires at least one key`);\n }\n return typeof value === \"number\" ? 1 : value.length;\n}\n\nfunction getKeyTime(key: AnimationKeyframe, frameRate: number, path: string): number {\n const hasTime = key.time !== undefined;\n const hasFrame = key.frame !== undefined;\n if (hasTime === hasFrame) {\n throw new Error(`Animation key for \"${path}\" must provide exactly one of time or frame`);\n }\n const time = hasTime ? key.time! : key.frame! / frameRate;\n if (!(time >= 0)) {\n throw new Error(`Animation key for \"${path}\" must have a non-negative time`);\n }\n return time;\n}\n\nfunction writeKeyValue(path: string, value: AnimationKeyframeValue, stride: number, output: Float32Array, offset: number): void {\n if (typeof value === \"number\") {\n if (stride !== 1) {\n throw new Error(`Animation key for \"${path}\" expected ${stride} values`);\n }\n output[offset] = value;\n return;\n }\n if (value.length !== stride) {\n throw new Error(`Animation key for \"${path}\" expected ${stride} values`);\n }\n for (let i = 0; i < stride; i++) {\n output[offset + i] = value[i]!;\n }\n}\n\nfunction resolvePropertyBinding(target: object, path: string, stride: number): ResolvedPropertyBinding {\n const parts = path.split(\".\");\n if (parts.length === 0 || parts.some((p) => p.length === 0)) {\n throw new Error(`Invalid animation property path \"${path}\"`);\n }\n\n let owner: unknown = target;\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i]!;\n const record = asRecord(owner, path);\n if (!(part in record)) {\n throw new Error(`Animation property path \"${path}\" could not resolve \"${part}\"`);\n }\n owner = record[part];\n }\n\n const property = parts[parts.length - 1]!;\n const record = asRecord(owner, path);\n if (!(property in record)) {\n throw new Error(`Animation property path \"${path}\" could not resolve \"${property}\"`);\n }\n\n return { mixTarget: record, mixProperty: property, writer: createPropertyWriter(record, property, stride, path) };\n}\n\nfunction asRecord(value: unknown, path: string): Record<string, unknown> {\n if ((typeof value !== \"object\" && typeof value !== \"function\") || value === null) {\n throw new Error(`Animation property path \"${path}\" reached a non-object value`);\n }\n return value as Record<string, unknown>;\n}\n\nfunction isSettable(value: unknown): value is PathSettable {\n return (typeof value === \"object\" || typeof value === \"function\") && value !== null && typeof (value as { set?: unknown }).set === \"function\";\n}\n\nfunction createPropertyWriter(target: Record<string, unknown>, property: string, stride: number, path: string): PropertyWriter {\n if (stride === 1) {\n return (output, offset) => {\n target[property] = output[offset]!;\n };\n }\n if (stride > 4) {\n throw new Error(`Animation property path \"${path}\" has unsupported vector size ${stride}`);\n }\n\n const targetValue = target[property];\n if (isSettable(targetValue)) {\n switch (stride) {\n case 2:\n return (output, offset) => targetValue.set(output[offset]!, output[offset + 1]!);\n case 3:\n return (output, offset) => targetValue.set(output[offset]!, output[offset + 1]!, output[offset + 2]!);\n case 4:\n return (output, offset) => targetValue.set(output[offset]!, output[offset + 1]!, output[offset + 2]!, output[offset + 3]!);\n }\n }\n\n const valueRecord = asRecord(targetValue, path);\n const components = \"xyzw\";\n for (let i = 0; i < stride; i++) {\n if (!(components[i]! in valueRecord)) {\n throw new Error(`Animation property path \"${path}\" could not resolve component \"${components[i]!}\"`);\n }\n }\n return (output, offset) => {\n for (let i = 0; i < stride; i++) {\n valueRecord[components[i]!] = output[offset + i]!;\n }\n };\n}\n"],"names":["duration","record"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { F32, I32, U8 } from '../engine/typed-arrays.js';
2
- import { tickAnimation } from './animation-group.js';
2
+ import { tickAnimation } from './animation-tick.js';
3
3
  import { ANIMATION_GROUP_TASK_CATEGORY, getAnimationGroupOwner, getAnimationGroups } from './animation-group-task.js';
4
4
  import { setAnimationTaskCategoryHandler } from './animation-manager.js';
5
5
  import { PATH_ROTATION, PATH_SCALE, PATH_TRANSLATION } from './types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"weighted-gltf-mixer.js","sources":["../../../src/animation/weighted-gltf-mixer.ts"],"sourcesContent":["import { F32, I32, U8 } from \"../engine/typed-arrays.js\";\nimport { tickAnimation } from \"./animation-group.js\";\nimport type { AnimationGltfMixer, AnimationGroup } from \"./animation-group.js\";\nimport { ANIMATION_GROUP_TASK_CATEGORY, getAnimationGroupOwner, getAnimationGroups } from \"./animation-group-task.js\";\nimport { setAnimationTaskCategoryHandler } from \"./animation-manager.js\";\nimport type { AnimationManager } from \"./animation-manager.js\";\nimport type { NodeRest, SkeletonBinding } from \"./types.js\";\nimport { PATH_ROTATION, PATH_SCALE, PATH_TRANSLATION } from \"./types.js\";\nimport { evaluateSampler } from \"./evaluate.js\";\nimport { mat4ComposeInto } from \"../math/mat4-compose-into.js\";\nimport { mat4MultiplyInto } from \"../math/mat4-multiply-into.js\";\nimport type { Mat4Storage } from \"../math/types.js\";\n\nconst GLTF_CLIP = 0;\nconst GLTF_NODES = 1;\nconst GLTF_SKELETONS = 2;\nconst TRS_STRIDE = 12;\nconst T_OFF = 0;\nconst R_OFF = 3;\nconst S_OFF = 7;\n\n// RH->LH root transform (same as skeleton-updater.ts)\n// prettier-ignore\nconst RH_TO_LH = new F32([-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);\n\nconst _boneTmp = new F32(16);\n\ninterface WeightedGltfTarget {\n readonly nodes: readonly NodeRest[];\n readonly skeletons: readonly SkeletonBinding[];\n readonly trs: Float32Array;\n readonly localMat: Float32Array;\n readonly worldMat: Float32Array;\n readonly topoOrder: Int32Array;\n readonly tWeight: Float32Array;\n readonly rWeight: Float32Array;\n readonly sWeight: Float32Array;\n active: boolean;\n}\n\ninterface WeightedGltfScratch {\n readonly keys: Set<object>;\n readonly targets: Map<object, WeightedGltfTarget>;\n readonly sample: Float32Array;\n readonly reference: Float32Array;\n readonly delta: Float32Array;\n}\n\nlet scratchByManager: WeakMap<AnimationManager, WeightedGltfScratch> | undefined;\n\n/** Options for {@link setAnimationAdditive}, selecting the reference pose subtracted from an additive animation. */\nexport interface AnimationAdditiveOptions {\n readonly referenceFrame?: number;\n readonly referenceTime?: number;\n}\n\n/** Enable advanced animation blending for a manager. Kept opt-in so manual-only weights do not pay for skeletal mixing code. */\nexport function enableAnimationBlending(manager: AnimationManager): void {\n setAnimationTaskCategoryHandler(manager, ANIMATION_GROUP_TASK_CATEGORY, updateWeightedGltfAnimations);\n}\n\n/** Mark an animation group as additive. Reference defaults to frame 0, matching Babylon.js MakeAnimationAdditive. */\nexport function setAnimationAdditive(group: AnimationGroup, options?: AnimationAdditiveOptions): void {\n if (options?.referenceFrame !== undefined && options.referenceTime !== undefined) {\n throw new Error(\"Additive animation reference must use either referenceFrame or referenceTime, not both\");\n }\n const referenceTime = options?.referenceTime ?? (options?.referenceFrame ?? 0) / (group.frameRate || 60);\n if (!Number.isFinite(referenceTime) || referenceTime < 0) {\n throw new Error(`Additive animation reference time must be a finite non-negative number, got ${referenceTime}`);\n }\n group._additive = { referenceTime };\n const owner = getAnimationGroupOwner(group);\n if (owner) {\n enableAnimationBlending(owner);\n }\n}\n\nfunction getScratch(manager: AnimationManager): WeightedGltfScratch {\n scratchByManager ??= new WeakMap();\n let scratch = scratchByManager.get(manager);\n if (!scratch) {\n scratch = {\n keys: new Set<object>(),\n targets: new Map<object, WeightedGltfTarget>(),\n sample: new F32(16),\n reference: new F32(16),\n delta: new F32(16),\n };\n scratchByManager.set(manager, scratch);\n }\n return scratch;\n}\n\nfunction updateWeightedGltfAnimations(manager: AnimationManager, deltaMs: number): boolean {\n const scratch = getScratch(manager);\n const keys = scratch.keys;\n keys.clear();\n\n const groups = getAnimationGroups(manager);\n for (let groupIndex = 0; groupIndex < groups.length; groupIndex++) {\n const group = groups[groupIndex]!;\n const mixer = group._gltfMixer;\n if (group._stopped || !mixer || (group.weight === 1 && !group._additive)) {\n continue;\n }\n keys.add(mixer[GLTF_NODES]);\n }\n\n if (keys.size === 0) {\n return false;\n }\n\n scratch.targets.forEach(resetWeightedGltfTarget);\n\n for (let groupIndex = 0; groupIndex < groups.length; groupIndex++) {\n const group = groups[groupIndex]!;\n if (group._stopped) {\n continue;\n }\n\n const mixer = group._gltfMixer;\n if (mixer && keys.has(mixer[GLTF_NODES])) {\n if (group._additive) {\n getTarget(scratch, mixer).active = true;\n advanceGroupTime(group, mixer, deltaMs);\n } else {\n accumulateGroup(manager, scratch, group, mixer, deltaMs);\n }\n continue;\n }\n\n tickAnimation(group, deltaMs, manager.engine);\n }\n\n for (let groupIndex = 0; groupIndex < groups.length; groupIndex++) {\n const group = groups[groupIndex]!;\n const mixer = group._gltfMixer;\n if (!group._stopped && group._additive && mixer && keys.has(mixer[GLTF_NODES])) {\n accumulateAdditiveGroup(scratch, group, mixer);\n }\n }\n\n scratch.targets.forEach((target, key) => {\n if (target.active && keys.has(key)) {\n uploadTarget(manager, target);\n }\n });\n\n return true;\n}\n\nfunction resetWeightedGltfTarget(target: WeightedGltfTarget): void {\n target.active = false;\n target.tWeight.fill(0);\n target.rWeight.fill(0);\n target.sWeight.fill(0);\n resetTarget(target);\n}\n\nfunction getTarget(scratch: WeightedGltfScratch, mixer: AnimationGltfMixer): WeightedGltfTarget {\n const nodes = mixer[GLTF_NODES];\n let target = scratch.targets.get(nodes);\n if (!target) {\n const numNodes = nodes.length;\n target = {\n nodes,\n skeletons: mixer[GLTF_SKELETONS],\n trs: new F32(numNodes * TRS_STRIDE),\n localMat: new F32(numNodes * 16),\n worldMat: new F32(numNodes * 16),\n topoOrder: computeTopoOrder(nodes),\n tWeight: new F32(numNodes),\n rWeight: new F32(numNodes),\n sWeight: new F32(numNodes),\n active: false,\n };\n scratch.targets.set(nodes, target);\n }\n return target;\n}\n\nfunction resetTarget(target: WeightedGltfTarget): void {\n const { nodes, trs } = target;\n for (let i = 0; i < nodes.length; i++) {\n const n = nodes[i]!;\n const off = i * TRS_STRIDE;\n trs[off + T_OFF] = n.tx;\n trs[off + T_OFF + 1] = n.ty;\n trs[off + T_OFF + 2] = n.tz;\n trs[off + R_OFF] = n.rx;\n trs[off + R_OFF + 1] = n.ry;\n trs[off + R_OFF + 2] = n.rz;\n trs[off + R_OFF + 3] = n.rw;\n trs[off + S_OFF] = n.sx;\n trs[off + S_OFF + 1] = n.sy;\n trs[off + S_OFF + 2] = n.sz;\n }\n}\n\nfunction accumulateAdditiveGroup(scratch: WeightedGltfScratch, group: AnimationGroup, mixer: AnimationGltfMixer): void {\n const additive = group._additive;\n const weight = group.weight;\n if (!additive || weight === 0) {\n return;\n }\n\n const target = getTarget(scratch, mixer);\n const clip = mixer[GLTF_CLIP];\n const t = group.currentTime;\n for (let channelIndex = 0; channelIndex < clip.channels.length; channelIndex++) {\n const ch = clip.channels[channelIndex]!;\n const sampler = clip.samplers[ch.samplerIdx]!;\n const nodeIdx = ch.nodeIdx;\n const base = nodeIdx * TRS_STRIDE;\n switch (ch.path) {\n case PATH_TRANSLATION:\n evaluateSampler(sampler, t, 3, false, scratch.sample, 0);\n evaluateSampler(sampler, additive.referenceTime, 3, false, scratch.reference, 0);\n target.trs[base + T_OFF] = target.trs[base + T_OFF]! + (scratch.sample[0]! - scratch.reference[0]!) * weight;\n target.trs[base + T_OFF + 1] = target.trs[base + T_OFF + 1]! + (scratch.sample[1]! - scratch.reference[1]!) * weight;\n target.trs[base + T_OFF + 2] = target.trs[base + T_OFF + 2]! + (scratch.sample[2]! - scratch.reference[2]!) * weight;\n break;\n case PATH_SCALE:\n evaluateSampler(sampler, t, 3, false, scratch.sample, 0);\n evaluateSampler(sampler, additive.referenceTime, 3, false, scratch.reference, 0);\n target.trs[base + S_OFF] = target.trs[base + S_OFF]! + (scratch.sample[0]! - scratch.reference[0]!) * weight;\n target.trs[base + S_OFF + 1] = target.trs[base + S_OFF + 1]! + (scratch.sample[1]! - scratch.reference[1]!) * weight;\n target.trs[base + S_OFF + 2] = target.trs[base + S_OFF + 2]! + (scratch.sample[2]! - scratch.reference[2]!) * weight;\n break;\n case PATH_ROTATION:\n evaluateSampler(sampler, t, 4, true, scratch.sample, 0);\n evaluateSampler(sampler, additive.referenceTime, 4, true, scratch.reference, 0);\n quatRefInverseTimesSample(scratch.delta, scratch.reference, scratch.sample);\n applyAdditiveQuaternion(target.trs, base + R_OFF, scratch.delta, weight);\n break;\n }\n }\n}\n\nfunction accumulateGroup(manager: AnimationManager, scratch: WeightedGltfScratch, group: AnimationGroup, mixer: AnimationGltfMixer, deltaMs: number): void {\n if (!manager.engine) {\n throw new Error(\"Weighted glTF animation requires an AnimationManager engine\");\n }\n\n const target = getTarget(scratch, mixer);\n const t = advanceGroupTime(group, mixer, deltaMs);\n const weight = group.weight;\n target.active = true;\n if (weight === 0) {\n return;\n }\n\n const clip = mixer[GLTF_CLIP];\n for (let channelIndex = 0; channelIndex < clip.channels.length; channelIndex++) {\n const ch = clip.channels[channelIndex]!;\n const sampler = clip.samplers[ch.samplerIdx]!;\n const nodeIdx = ch.nodeIdx;\n const base = nodeIdx * TRS_STRIDE;\n switch (ch.path) {\n case PATH_TRANSLATION:\n evaluateSampler(sampler, t, 3, false, scratch.sample, 0);\n if (target.tWeight[nodeIdx] === 0) {\n target.trs[base + T_OFF] = 0;\n target.trs[base + T_OFF + 1] = 0;\n target.trs[base + T_OFF + 2] = 0;\n }\n target.trs[base + T_OFF] = target.trs[base + T_OFF]! + scratch.sample[0]! * weight;\n target.trs[base + T_OFF + 1] = target.trs[base + T_OFF + 1]! + scratch.sample[1]! * weight;\n target.trs[base + T_OFF + 2] = target.trs[base + T_OFF + 2]! + scratch.sample[2]! * weight;\n target.tWeight[nodeIdx] = target.tWeight[nodeIdx]! + weight;\n break;\n case PATH_SCALE:\n evaluateSampler(sampler, t, 3, false, scratch.sample, 0);\n if (target.sWeight[nodeIdx] === 0) {\n target.trs[base + S_OFF] = 0;\n target.trs[base + S_OFF + 1] = 0;\n target.trs[base + S_OFF + 2] = 0;\n }\n target.trs[base + S_OFF] = target.trs[base + S_OFF]! + scratch.sample[0]! * weight;\n target.trs[base + S_OFF + 1] = target.trs[base + S_OFF + 1]! + scratch.sample[1]! * weight;\n target.trs[base + S_OFF + 2] = target.trs[base + S_OFF + 2]! + scratch.sample[2]! * weight;\n target.sWeight[nodeIdx] = target.sWeight[nodeIdx]! + weight;\n break;\n case PATH_ROTATION: {\n evaluateSampler(sampler, t, 4, true, scratch.sample, 0);\n if (target.rWeight[nodeIdx] === 0) {\n target.trs[base + R_OFF] = scratch.sample[0]!;\n target.trs[base + R_OFF + 1] = scratch.sample[1]!;\n target.trs[base + R_OFF + 2] = scratch.sample[2]!;\n target.trs[base + R_OFF + 3] = scratch.sample[3]!;\n target.rWeight[nodeIdx] = weight;\n break;\n }\n const accumulatedWeight = target.rWeight[nodeIdx]!;\n quatSlerpInto(\n target.trs,\n base + R_OFF,\n target.trs[base + R_OFF]!,\n target.trs[base + R_OFF + 1]!,\n target.trs[base + R_OFF + 2]!,\n target.trs[base + R_OFF + 3]!,\n scratch.sample[0]!,\n scratch.sample[1]!,\n scratch.sample[2]!,\n scratch.sample[3]!,\n weight / (accumulatedWeight + weight)\n );\n target.rWeight[nodeIdx] = accumulatedWeight + weight;\n break;\n }\n }\n }\n}\n\nfunction advanceGroupTime(group: AnimationGroup, mixer: AnimationGltfMixer, deltaMs: number): number {\n const clip = mixer[GLTF_CLIP];\n const isPlaying = group.isPlaying;\n if (isPlaying) {\n group.currentTime += (deltaMs / 1000) * group.speedRatio;\n }\n\n if (clip.duration <= 0) {\n return 0;\n }\n\n if (group.loopAnimation && isPlaying) {\n group.currentTime %= clip.duration;\n if (group.currentTime < 0) {\n group.currentTime += clip.duration;\n }\n } else {\n group.currentTime = Math.min(Math.max(group.currentTime, 0), clip.duration);\n }\n return group.currentTime;\n}\n\nfunction uploadTarget(manager: AnimationManager, target: WeightedGltfTarget): void {\n if (!manager.engine) {\n throw new Error(\"Weighted glTF animation requires an AnimationManager engine\");\n }\n const device = manager.engine._device;\n const { nodes, trs, localMat, worldMat } = target;\n\n for (let i = 0; i < nodes.length; i++) {\n const rotationWeight = target.rWeight[i]!;\n if (rotationWeight > 0 && rotationWeight < 1) {\n const off = i * TRS_STRIDE + R_OFF;\n const node = nodes[i]!;\n quatSlerpInto(trs, off, node.rx, node.ry, node.rz, node.rw, trs[off]!, trs[off + 1]!, trs[off + 2]!, trs[off + 3]!, rotationWeight);\n } else if (rotationWeight > 0) {\n normalizeQuaternionAt(trs, i * TRS_STRIDE + R_OFF);\n }\n }\n\n for (let idx = 0; idx < nodes.length; idx++) {\n const nodeIdx = target.topoOrder[idx]!;\n const node = nodes[nodeIdx]!;\n const off = nodeIdx * TRS_STRIDE;\n if (node._matrix) {\n localMat.set(node._matrix, nodeIdx * 16);\n } else {\n mat4ComposeInto(\n localMat,\n nodeIdx * 16,\n trs[off + T_OFF]!,\n trs[off + T_OFF + 1]!,\n trs[off + T_OFF + 2]!,\n trs[off + R_OFF]!,\n trs[off + R_OFF + 1]!,\n trs[off + R_OFF + 2]!,\n trs[off + R_OFF + 3]!,\n trs[off + S_OFF]!,\n trs[off + S_OFF + 1]!,\n trs[off + S_OFF + 2]!\n );\n }\n\n const parentIdx = node.parentIdx;\n if (parentIdx >= 0) {\n mat4MultiplyInto(worldMat, nodeIdx * 16, worldMat, parentIdx * 16, localMat, nodeIdx * 16);\n } else {\n mat4MultiplyInto(worldMat, nodeIdx * 16, RH_TO_LH, 0, localMat, nodeIdx * 16);\n }\n }\n\n for (let skeletonIndex = 0; skeletonIndex < target.skeletons.length; skeletonIndex++) {\n const skel = target.skeletons[skeletonIndex]!;\n const boneData = skel.boneMatrices;\n for (let bi = 0; bi < skel.boneCount; bi++) {\n const jointIdx = skel.jointNodes[bi]!;\n const ibmOff = bi * 16;\n mat4MultiplyInto(_boneTmp, 0, skel.invMeshWorld as unknown as Mat4Storage, 0, worldMat, jointIdx * 16);\n mat4MultiplyInto(boneData, bi * 16, _boneTmp, 0, skel.inverseBindMatrices, ibmOff);\n }\n\n const texWidth = skel.boneCount * 4;\n device.queue.writeTexture({ texture: skel.boneTexture }, boneData.buffer, { bytesPerRow: texWidth * 16 }, { width: texWidth, height: 1 });\n }\n}\n\nfunction computeTopoOrder(nodes: readonly { readonly parentIdx: number }[]): Int32Array {\n const order = new I32(nodes.length);\n const visited = new U8(nodes.length);\n let cursor = 0;\n\n function visit(idx: number): void {\n if (visited[idx]!) {\n return;\n }\n visited[idx] = 1;\n const p = nodes[idx]!.parentIdx;\n if (p >= 0) {\n visit(p);\n }\n order[cursor++] = idx;\n }\n\n for (let i = 0; i < nodes.length; i++) {\n visit(i);\n }\n return order;\n}\n\nfunction normalizeQuaternionAt(values: Float32Array, offset: number): void {\n const x = values[offset]!;\n const y = values[offset + 1]!;\n const z = values[offset + 2]!;\n const w = values[offset + 3]!;\n const lenSq = x * x + y * y + z * z + w * w;\n if (lenSq > 0) {\n const inv = 1 / Math.sqrt(lenSq);\n values[offset] = x * inv;\n values[offset + 1] = y * inv;\n values[offset + 2] = z * inv;\n values[offset + 3] = w * inv;\n }\n}\n\nfunction quatRefInverseTimesSample(out: Float32Array, ref: Float32Array, sample: Float32Array): void {\n const ax = -ref[0]!;\n const ay = -ref[1]!;\n const az = -ref[2]!;\n const aw = ref[3]!;\n const bx = sample[0]!;\n const by = sample[1]!;\n const bz = sample[2]!;\n const bw = sample[3]!;\n out[0] = aw * bx + ax * bw + ay * bz - az * by;\n out[1] = aw * by - ax * bz + ay * bw + az * bx;\n out[2] = aw * bz + ax * by - ay * bx + az * bw;\n out[3] = aw * bw - ax * bx - ay * by - az * bz;\n normalizeQuaternionAt(out, 0);\n}\n\nfunction applyAdditiveQuaternion(base: Float32Array, offset: number, delta: Float32Array, weight: number): void {\n const bx = base[offset]!;\n const by = base[offset + 1]!;\n const bz = base[offset + 2]!;\n const bw = base[offset + 3]!;\n const dx = delta[0]!;\n const dy = delta[1]!;\n const dz = delta[2]!;\n const dw = delta[3]!;\n quatSlerpInto(\n base,\n offset,\n bx,\n by,\n bz,\n bw,\n bw * dx + bx * dw + by * dz - bz * dy,\n bw * dy - bx * dz + by * dw + bz * dx,\n bw * dz + bx * dy - by * dx + bz * dw,\n bw * dw - bx * dx - by * dy - bz * dz,\n weight\n );\n}\n\nfunction quatSlerpInto(out: Float32Array, offset: number, ax: number, ay: number, az: number, aw: number, bx: number, by: number, bz: number, bw: number, t: number): void {\n let dot = ax * bx + ay * by + az * bz + aw * bw;\n if (dot < 0) {\n bx = -bx;\n by = -by;\n bz = -bz;\n bw = -bw;\n dot = -dot;\n }\n if (dot > 0.9995) {\n out[offset] = ax + t * (bx - ax);\n out[offset + 1] = ay + t * (by - ay);\n out[offset + 2] = az + t * (bz - az);\n out[offset + 3] = aw + t * (bw - aw);\n normalizeQuaternionAt(out, offset);\n return;\n }\n const theta = Math.acos(dot);\n const sinTheta = Math.sin(theta);\n const wa = Math.sin((1 - t) * theta) / sinTheta;\n const wb = Math.sin(t * theta) / sinTheta;\n out[offset] = wa * ax + wb * bx;\n out[offset + 1] = wa * ay + wb * by;\n out[offset + 2] = wa * az + wb * bz;\n out[offset + 3] = wa * aw + wb * bw;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"weighted-gltf-mixer.js","sources":["../../../src/animation/weighted-gltf-mixer.ts"],"sourcesContent":["import { F32, I32, U8 } from \"../engine/typed-arrays.js\";\nimport { tickAnimation } from \"./animation-tick.js\";\nimport type { AnimationGltfMixer, AnimationGroup } from \"./animation-group.js\";\nimport { ANIMATION_GROUP_TASK_CATEGORY, getAnimationGroupOwner, getAnimationGroups } from \"./animation-group-task.js\";\nimport { setAnimationTaskCategoryHandler } from \"./animation-manager.js\";\nimport type { AnimationManager } from \"./animation-manager.js\";\nimport type { NodeRest, SkeletonBinding } from \"./types.js\";\nimport { PATH_ROTATION, PATH_SCALE, PATH_TRANSLATION } from \"./types.js\";\nimport { evaluateSampler } from \"./evaluate.js\";\nimport { mat4ComposeInto } from \"../math/mat4-compose-into.js\";\nimport { mat4MultiplyInto } from \"../math/mat4-multiply-into.js\";\nimport type { Mat4Storage } from \"../math/types.js\";\n\nconst GLTF_CLIP = 0;\nconst GLTF_NODES = 1;\nconst GLTF_SKELETONS = 2;\nconst TRS_STRIDE = 12;\nconst T_OFF = 0;\nconst R_OFF = 3;\nconst S_OFF = 7;\n\n// RH->LH root transform (same as skeleton-updater.ts)\n// prettier-ignore\nconst RH_TO_LH = new F32([-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);\n\nconst _boneTmp = new F32(16);\n\ninterface WeightedGltfTarget {\n readonly nodes: readonly NodeRest[];\n readonly skeletons: readonly SkeletonBinding[];\n readonly trs: Float32Array;\n readonly localMat: Float32Array;\n readonly worldMat: Float32Array;\n readonly topoOrder: Int32Array;\n readonly tWeight: Float32Array;\n readonly rWeight: Float32Array;\n readonly sWeight: Float32Array;\n active: boolean;\n}\n\ninterface WeightedGltfScratch {\n readonly keys: Set<object>;\n readonly targets: Map<object, WeightedGltfTarget>;\n readonly sample: Float32Array;\n readonly reference: Float32Array;\n readonly delta: Float32Array;\n}\n\nlet scratchByManager: WeakMap<AnimationManager, WeightedGltfScratch> | undefined;\n\n/** Options for {@link setAnimationAdditive}, selecting the reference pose subtracted from an additive animation. */\nexport interface AnimationAdditiveOptions {\n readonly referenceFrame?: number;\n readonly referenceTime?: number;\n}\n\n/** Enable advanced animation blending for a manager. Kept opt-in so manual-only weights do not pay for skeletal mixing code. */\nexport function enableAnimationBlending(manager: AnimationManager): void {\n setAnimationTaskCategoryHandler(manager, ANIMATION_GROUP_TASK_CATEGORY, updateWeightedGltfAnimations);\n}\n\n/** Mark an animation group as additive. Reference defaults to frame 0, matching Babylon.js MakeAnimationAdditive. */\nexport function setAnimationAdditive(group: AnimationGroup, options?: AnimationAdditiveOptions): void {\n if (options?.referenceFrame !== undefined && options.referenceTime !== undefined) {\n throw new Error(\"Additive animation reference must use either referenceFrame or referenceTime, not both\");\n }\n const referenceTime = options?.referenceTime ?? (options?.referenceFrame ?? 0) / (group.frameRate || 60);\n if (!Number.isFinite(referenceTime) || referenceTime < 0) {\n throw new Error(`Additive animation reference time must be a finite non-negative number, got ${referenceTime}`);\n }\n group._additive = { referenceTime };\n const owner = getAnimationGroupOwner(group);\n if (owner) {\n enableAnimationBlending(owner);\n }\n}\n\nfunction getScratch(manager: AnimationManager): WeightedGltfScratch {\n scratchByManager ??= new WeakMap();\n let scratch = scratchByManager.get(manager);\n if (!scratch) {\n scratch = {\n keys: new Set<object>(),\n targets: new Map<object, WeightedGltfTarget>(),\n sample: new F32(16),\n reference: new F32(16),\n delta: new F32(16),\n };\n scratchByManager.set(manager, scratch);\n }\n return scratch;\n}\n\nfunction updateWeightedGltfAnimations(manager: AnimationManager, deltaMs: number): boolean {\n const scratch = getScratch(manager);\n const keys = scratch.keys;\n keys.clear();\n\n const groups = getAnimationGroups(manager);\n for (let groupIndex = 0; groupIndex < groups.length; groupIndex++) {\n const group = groups[groupIndex]!;\n const mixer = group._gltfMixer;\n if (group._stopped || !mixer || (group.weight === 1 && !group._additive)) {\n continue;\n }\n keys.add(mixer[GLTF_NODES]);\n }\n\n if (keys.size === 0) {\n return false;\n }\n\n scratch.targets.forEach(resetWeightedGltfTarget);\n\n for (let groupIndex = 0; groupIndex < groups.length; groupIndex++) {\n const group = groups[groupIndex]!;\n if (group._stopped) {\n continue;\n }\n\n const mixer = group._gltfMixer;\n if (mixer && keys.has(mixer[GLTF_NODES])) {\n if (group._additive) {\n getTarget(scratch, mixer).active = true;\n advanceGroupTime(group, mixer, deltaMs);\n } else {\n accumulateGroup(manager, scratch, group, mixer, deltaMs);\n }\n continue;\n }\n\n tickAnimation(group, deltaMs, manager.engine);\n }\n\n for (let groupIndex = 0; groupIndex < groups.length; groupIndex++) {\n const group = groups[groupIndex]!;\n const mixer = group._gltfMixer;\n if (!group._stopped && group._additive && mixer && keys.has(mixer[GLTF_NODES])) {\n accumulateAdditiveGroup(scratch, group, mixer);\n }\n }\n\n scratch.targets.forEach((target, key) => {\n if (target.active && keys.has(key)) {\n uploadTarget(manager, target);\n }\n });\n\n return true;\n}\n\nfunction resetWeightedGltfTarget(target: WeightedGltfTarget): void {\n target.active = false;\n target.tWeight.fill(0);\n target.rWeight.fill(0);\n target.sWeight.fill(0);\n resetTarget(target);\n}\n\nfunction getTarget(scratch: WeightedGltfScratch, mixer: AnimationGltfMixer): WeightedGltfTarget {\n const nodes = mixer[GLTF_NODES];\n let target = scratch.targets.get(nodes);\n if (!target) {\n const numNodes = nodes.length;\n target = {\n nodes,\n skeletons: mixer[GLTF_SKELETONS],\n trs: new F32(numNodes * TRS_STRIDE),\n localMat: new F32(numNodes * 16),\n worldMat: new F32(numNodes * 16),\n topoOrder: computeTopoOrder(nodes),\n tWeight: new F32(numNodes),\n rWeight: new F32(numNodes),\n sWeight: new F32(numNodes),\n active: false,\n };\n scratch.targets.set(nodes, target);\n }\n return target;\n}\n\nfunction resetTarget(target: WeightedGltfTarget): void {\n const { nodes, trs } = target;\n for (let i = 0; i < nodes.length; i++) {\n const n = nodes[i]!;\n const off = i * TRS_STRIDE;\n trs[off + T_OFF] = n.tx;\n trs[off + T_OFF + 1] = n.ty;\n trs[off + T_OFF + 2] = n.tz;\n trs[off + R_OFF] = n.rx;\n trs[off + R_OFF + 1] = n.ry;\n trs[off + R_OFF + 2] = n.rz;\n trs[off + R_OFF + 3] = n.rw;\n trs[off + S_OFF] = n.sx;\n trs[off + S_OFF + 1] = n.sy;\n trs[off + S_OFF + 2] = n.sz;\n }\n}\n\nfunction accumulateAdditiveGroup(scratch: WeightedGltfScratch, group: AnimationGroup, mixer: AnimationGltfMixer): void {\n const additive = group._additive;\n const weight = group.weight;\n if (!additive || weight === 0) {\n return;\n }\n\n const target = getTarget(scratch, mixer);\n const clip = mixer[GLTF_CLIP];\n const t = group.currentTime;\n for (let channelIndex = 0; channelIndex < clip.channels.length; channelIndex++) {\n const ch = clip.channels[channelIndex]!;\n const sampler = clip.samplers[ch.samplerIdx]!;\n const nodeIdx = ch.nodeIdx;\n const base = nodeIdx * TRS_STRIDE;\n switch (ch.path) {\n case PATH_TRANSLATION:\n evaluateSampler(sampler, t, 3, false, scratch.sample, 0);\n evaluateSampler(sampler, additive.referenceTime, 3, false, scratch.reference, 0);\n target.trs[base + T_OFF] = target.trs[base + T_OFF]! + (scratch.sample[0]! - scratch.reference[0]!) * weight;\n target.trs[base + T_OFF + 1] = target.trs[base + T_OFF + 1]! + (scratch.sample[1]! - scratch.reference[1]!) * weight;\n target.trs[base + T_OFF + 2] = target.trs[base + T_OFF + 2]! + (scratch.sample[2]! - scratch.reference[2]!) * weight;\n break;\n case PATH_SCALE:\n evaluateSampler(sampler, t, 3, false, scratch.sample, 0);\n evaluateSampler(sampler, additive.referenceTime, 3, false, scratch.reference, 0);\n target.trs[base + S_OFF] = target.trs[base + S_OFF]! + (scratch.sample[0]! - scratch.reference[0]!) * weight;\n target.trs[base + S_OFF + 1] = target.trs[base + S_OFF + 1]! + (scratch.sample[1]! - scratch.reference[1]!) * weight;\n target.trs[base + S_OFF + 2] = target.trs[base + S_OFF + 2]! + (scratch.sample[2]! - scratch.reference[2]!) * weight;\n break;\n case PATH_ROTATION:\n evaluateSampler(sampler, t, 4, true, scratch.sample, 0);\n evaluateSampler(sampler, additive.referenceTime, 4, true, scratch.reference, 0);\n quatRefInverseTimesSample(scratch.delta, scratch.reference, scratch.sample);\n applyAdditiveQuaternion(target.trs, base + R_OFF, scratch.delta, weight);\n break;\n }\n }\n}\n\nfunction accumulateGroup(manager: AnimationManager, scratch: WeightedGltfScratch, group: AnimationGroup, mixer: AnimationGltfMixer, deltaMs: number): void {\n if (!manager.engine) {\n throw new Error(\"Weighted glTF animation requires an AnimationManager engine\");\n }\n\n const target = getTarget(scratch, mixer);\n const t = advanceGroupTime(group, mixer, deltaMs);\n const weight = group.weight;\n target.active = true;\n if (weight === 0) {\n return;\n }\n\n const clip = mixer[GLTF_CLIP];\n for (let channelIndex = 0; channelIndex < clip.channels.length; channelIndex++) {\n const ch = clip.channels[channelIndex]!;\n const sampler = clip.samplers[ch.samplerIdx]!;\n const nodeIdx = ch.nodeIdx;\n const base = nodeIdx * TRS_STRIDE;\n switch (ch.path) {\n case PATH_TRANSLATION:\n evaluateSampler(sampler, t, 3, false, scratch.sample, 0);\n if (target.tWeight[nodeIdx] === 0) {\n target.trs[base + T_OFF] = 0;\n target.trs[base + T_OFF + 1] = 0;\n target.trs[base + T_OFF + 2] = 0;\n }\n target.trs[base + T_OFF] = target.trs[base + T_OFF]! + scratch.sample[0]! * weight;\n target.trs[base + T_OFF + 1] = target.trs[base + T_OFF + 1]! + scratch.sample[1]! * weight;\n target.trs[base + T_OFF + 2] = target.trs[base + T_OFF + 2]! + scratch.sample[2]! * weight;\n target.tWeight[nodeIdx] = target.tWeight[nodeIdx]! + weight;\n break;\n case PATH_SCALE:\n evaluateSampler(sampler, t, 3, false, scratch.sample, 0);\n if (target.sWeight[nodeIdx] === 0) {\n target.trs[base + S_OFF] = 0;\n target.trs[base + S_OFF + 1] = 0;\n target.trs[base + S_OFF + 2] = 0;\n }\n target.trs[base + S_OFF] = target.trs[base + S_OFF]! + scratch.sample[0]! * weight;\n target.trs[base + S_OFF + 1] = target.trs[base + S_OFF + 1]! + scratch.sample[1]! * weight;\n target.trs[base + S_OFF + 2] = target.trs[base + S_OFF + 2]! + scratch.sample[2]! * weight;\n target.sWeight[nodeIdx] = target.sWeight[nodeIdx]! + weight;\n break;\n case PATH_ROTATION: {\n evaluateSampler(sampler, t, 4, true, scratch.sample, 0);\n if (target.rWeight[nodeIdx] === 0) {\n target.trs[base + R_OFF] = scratch.sample[0]!;\n target.trs[base + R_OFF + 1] = scratch.sample[1]!;\n target.trs[base + R_OFF + 2] = scratch.sample[2]!;\n target.trs[base + R_OFF + 3] = scratch.sample[3]!;\n target.rWeight[nodeIdx] = weight;\n break;\n }\n const accumulatedWeight = target.rWeight[nodeIdx]!;\n quatSlerpInto(\n target.trs,\n base + R_OFF,\n target.trs[base + R_OFF]!,\n target.trs[base + R_OFF + 1]!,\n target.trs[base + R_OFF + 2]!,\n target.trs[base + R_OFF + 3]!,\n scratch.sample[0]!,\n scratch.sample[1]!,\n scratch.sample[2]!,\n scratch.sample[3]!,\n weight / (accumulatedWeight + weight)\n );\n target.rWeight[nodeIdx] = accumulatedWeight + weight;\n break;\n }\n }\n }\n}\n\nfunction advanceGroupTime(group: AnimationGroup, mixer: AnimationGltfMixer, deltaMs: number): number {\n const clip = mixer[GLTF_CLIP];\n const isPlaying = group.isPlaying;\n if (isPlaying) {\n group.currentTime += (deltaMs / 1000) * group.speedRatio;\n }\n\n if (clip.duration <= 0) {\n return 0;\n }\n\n if (group.loopAnimation && isPlaying) {\n group.currentTime %= clip.duration;\n if (group.currentTime < 0) {\n group.currentTime += clip.duration;\n }\n } else {\n group.currentTime = Math.min(Math.max(group.currentTime, 0), clip.duration);\n }\n return group.currentTime;\n}\n\nfunction uploadTarget(manager: AnimationManager, target: WeightedGltfTarget): void {\n if (!manager.engine) {\n throw new Error(\"Weighted glTF animation requires an AnimationManager engine\");\n }\n const device = manager.engine._device;\n const { nodes, trs, localMat, worldMat } = target;\n\n for (let i = 0; i < nodes.length; i++) {\n const rotationWeight = target.rWeight[i]!;\n if (rotationWeight > 0 && rotationWeight < 1) {\n const off = i * TRS_STRIDE + R_OFF;\n const node = nodes[i]!;\n quatSlerpInto(trs, off, node.rx, node.ry, node.rz, node.rw, trs[off]!, trs[off + 1]!, trs[off + 2]!, trs[off + 3]!, rotationWeight);\n } else if (rotationWeight > 0) {\n normalizeQuaternionAt(trs, i * TRS_STRIDE + R_OFF);\n }\n }\n\n for (let idx = 0; idx < nodes.length; idx++) {\n const nodeIdx = target.topoOrder[idx]!;\n const node = nodes[nodeIdx]!;\n const off = nodeIdx * TRS_STRIDE;\n if (node._matrix) {\n localMat.set(node._matrix, nodeIdx * 16);\n } else {\n mat4ComposeInto(\n localMat,\n nodeIdx * 16,\n trs[off + T_OFF]!,\n trs[off + T_OFF + 1]!,\n trs[off + T_OFF + 2]!,\n trs[off + R_OFF]!,\n trs[off + R_OFF + 1]!,\n trs[off + R_OFF + 2]!,\n trs[off + R_OFF + 3]!,\n trs[off + S_OFF]!,\n trs[off + S_OFF + 1]!,\n trs[off + S_OFF + 2]!\n );\n }\n\n const parentIdx = node.parentIdx;\n if (parentIdx >= 0) {\n mat4MultiplyInto(worldMat, nodeIdx * 16, worldMat, parentIdx * 16, localMat, nodeIdx * 16);\n } else {\n mat4MultiplyInto(worldMat, nodeIdx * 16, RH_TO_LH, 0, localMat, nodeIdx * 16);\n }\n }\n\n for (let skeletonIndex = 0; skeletonIndex < target.skeletons.length; skeletonIndex++) {\n const skel = target.skeletons[skeletonIndex]!;\n const boneData = skel.boneMatrices;\n for (let bi = 0; bi < skel.boneCount; bi++) {\n const jointIdx = skel.jointNodes[bi]!;\n const ibmOff = bi * 16;\n mat4MultiplyInto(_boneTmp, 0, skel.invMeshWorld as unknown as Mat4Storage, 0, worldMat, jointIdx * 16);\n mat4MultiplyInto(boneData, bi * 16, _boneTmp, 0, skel.inverseBindMatrices, ibmOff);\n }\n\n const texWidth = skel.boneCount * 4;\n device.queue.writeTexture({ texture: skel.boneTexture }, boneData.buffer, { bytesPerRow: texWidth * 16 }, { width: texWidth, height: 1 });\n }\n}\n\nfunction computeTopoOrder(nodes: readonly { readonly parentIdx: number }[]): Int32Array {\n const order = new I32(nodes.length);\n const visited = new U8(nodes.length);\n let cursor = 0;\n\n function visit(idx: number): void {\n if (visited[idx]!) {\n return;\n }\n visited[idx] = 1;\n const p = nodes[idx]!.parentIdx;\n if (p >= 0) {\n visit(p);\n }\n order[cursor++] = idx;\n }\n\n for (let i = 0; i < nodes.length; i++) {\n visit(i);\n }\n return order;\n}\n\nfunction normalizeQuaternionAt(values: Float32Array, offset: number): void {\n const x = values[offset]!;\n const y = values[offset + 1]!;\n const z = values[offset + 2]!;\n const w = values[offset + 3]!;\n const lenSq = x * x + y * y + z * z + w * w;\n if (lenSq > 0) {\n const inv = 1 / Math.sqrt(lenSq);\n values[offset] = x * inv;\n values[offset + 1] = y * inv;\n values[offset + 2] = z * inv;\n values[offset + 3] = w * inv;\n }\n}\n\nfunction quatRefInverseTimesSample(out: Float32Array, ref: Float32Array, sample: Float32Array): void {\n const ax = -ref[0]!;\n const ay = -ref[1]!;\n const az = -ref[2]!;\n const aw = ref[3]!;\n const bx = sample[0]!;\n const by = sample[1]!;\n const bz = sample[2]!;\n const bw = sample[3]!;\n out[0] = aw * bx + ax * bw + ay * bz - az * by;\n out[1] = aw * by - ax * bz + ay * bw + az * bx;\n out[2] = aw * bz + ax * by - ay * bx + az * bw;\n out[3] = aw * bw - ax * bx - ay * by - az * bz;\n normalizeQuaternionAt(out, 0);\n}\n\nfunction applyAdditiveQuaternion(base: Float32Array, offset: number, delta: Float32Array, weight: number): void {\n const bx = base[offset]!;\n const by = base[offset + 1]!;\n const bz = base[offset + 2]!;\n const bw = base[offset + 3]!;\n const dx = delta[0]!;\n const dy = delta[1]!;\n const dz = delta[2]!;\n const dw = delta[3]!;\n quatSlerpInto(\n base,\n offset,\n bx,\n by,\n bz,\n bw,\n bw * dx + bx * dw + by * dz - bz * dy,\n bw * dy - bx * dz + by * dw + bz * dx,\n bw * dz + bx * dy - by * dx + bz * dw,\n bw * dw - bx * dx - by * dy - bz * dz,\n weight\n );\n}\n\nfunction quatSlerpInto(out: Float32Array, offset: number, ax: number, ay: number, az: number, aw: number, bx: number, by: number, bz: number, bw: number, t: number): void {\n let dot = ax * bx + ay * by + az * bz + aw * bw;\n if (dot < 0) {\n bx = -bx;\n by = -by;\n bz = -bz;\n bw = -bw;\n dot = -dot;\n }\n if (dot > 0.9995) {\n out[offset] = ax + t * (bx - ax);\n out[offset + 1] = ay + t * (by - ay);\n out[offset + 2] = az + t * (bz - az);\n out[offset + 3] = aw + t * (bw - aw);\n normalizeQuaternionAt(out, offset);\n return;\n }\n const theta = Math.acos(dot);\n const sinTheta = Math.sin(theta);\n const wa = Math.sin((1 - t) * theta) / sinTheta;\n const wb = Math.sin(t * theta) / sinTheta;\n out[offset] = wa * ax + wb * bx;\n out[offset + 1] = wa * ay + wb * by;\n out[offset + 2] = wa * az + wb * bz;\n out[offset + 3] = wa * aw + wb * bw;\n}\n"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { F32 } from '../engine/typed-arrays.js';
2
- import { tickAnimation } from './animation-group.js';
2
+ import { tickAnimation } from './animation-tick.js';
3
3
  import { ANIMATION_GROUP_TASK_CATEGORY, getAnimationGroups } from './animation-group-task.js';
4
4
  import { setAnimationTaskCategoryHandler } from './animation-manager.js';
5
5
  import { evaluateSampler } from './evaluate.js';