@haiyue/extensions 0.1.0 → 0.2.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.
- package/README.md +25 -0
- package/dist/animation/Animation2DComponent.d.ts +18 -0
- package/dist/animation/Animation2DExtensionRegistry.d.ts +7 -0
- package/dist/animation/Animation2DRenderSystem.d.ts +6 -0
- package/dist/animation/Animation2DRuntime.d.ts +6 -2
- package/dist/animation/AnimationTextRasterizer.d.ts +4 -0
- package/dist/animation/AnimationVisual2D.d.ts +58 -2
- package/dist/animation/interaction/InteractionRuntime.d.ts +83 -0
- package/dist/animation/interaction/runtime-types.d.ts +257 -0
- package/dist/animation.d.ts +3 -1
- package/dist/animation.js +551 -59
- package/dist/animation3d.js +1 -1
- package/dist/canvas-text.js +1 -1
- package/dist/chunks/2d-ui-animation-2d.generated-FpziAeGJ.js +4 -0
- package/dist/chunks/2d-ui-indexed-sprite.generated-DmKR0CC3.js +4 -0
- package/dist/chunks/Animation2DStateMachine-BHcA6Cu3.js +18212 -0
- package/dist/chunks/{AnimationStateMachineController-BIcAh-sT.js → AnimationStateMachineController-4sKaqh9E.js} +2 -2
- package/dist/chunks/AnimationVisual2D-8y3qp0_U.js +230 -0
- package/dist/chunks/{RenderSystem2DBase-DDT61dAu.js → RenderSystem2DBase-CF2s00vg.js} +2 -2
- package/dist/controls/VirtualJoystickControls.d.ts +46 -0
- package/dist/controls/contracts.d.ts +91 -0
- package/dist/controls.d.ts +2 -0
- package/dist/controls.js +358 -0
- package/dist/deformable-animation/runtime/DeformableMesh2DRuntimeExtension.d.ts +11 -0
- package/dist/deformable-animation/runtime/DeformableMesh2DSampler.d.ts +11 -0
- package/dist/deformable-animation.d.ts +5 -0
- package/dist/deformable-animation.js +316 -0
- package/dist/experimental-indexed-sprite.d.ts +5 -0
- package/dist/experimental-indexed-sprite.js +482 -0
- package/dist/gltf-worker-runtime.js +9 -9
- package/dist/hya-state-machine.js +3 -2
- package/dist/index.js +1 -1
- package/dist/indexed-sprite/AtlasLayout.d.ts +2 -0
- package/dist/indexed-sprite/IndexedSpriteRenderer.d.ts +23 -0
- package/dist/indexed-sprite/contracts.d.ts +89 -0
- package/dist/internal/2d-ui-shader-artifact.js +232 -23
- package/dist/ray-tracing/acceleration/bvh.d.ts +37 -0
- package/dist/ray-tracing/acceleration/index.d.ts +6 -0
- package/dist/ray-tracing/acceleration/pack.d.ts +152 -0
- package/dist/ray-tracing/acceleration/query.d.ts +4 -0
- package/dist/ray-tracing/acceleration/runtime.d.ts +30 -0
- package/dist/ray-tracing/acceleration/tlas.d.ts +4 -0
- package/dist/ray-tracing/acceleration/types.d.ts +165 -0
- package/dist/ray-tracing/denoise/index.d.ts +3 -0
- package/dist/ray-tracing/denoise/layout.d.ts +9 -0
- package/dist/ray-tracing/denoise/runtime.d.ts +23 -0
- package/dist/ray-tracing/denoise/types.d.ts +28 -0
- package/dist/ray-tracing/hybrid/contract.d.ts +2 -0
- package/dist/ray-tracing/hybrid/index.d.ts +5 -0
- package/dist/ray-tracing/hybrid/layout.d.ts +17 -0
- package/dist/ray-tracing/hybrid/plan.d.ts +2 -0
- package/dist/ray-tracing/hybrid/runtime.d.ts +31 -0
- package/dist/ray-tracing/hybrid/shaders/hybrid-artifact.generated.d.ts +625 -0
- package/dist/ray-tracing/hybrid/types.d.ts +144 -0
- package/dist/ray-tracing/lifecycle/device-recovery.d.ts +31 -0
- package/dist/ray-tracing/lifecycle/index.d.ts +2 -0
- package/dist/ray-tracing/lifecycle/types.d.ts +37 -0
- package/dist/ray-tracing/material/index.d.ts +2 -0
- package/dist/ray-tracing/material/pack.d.ts +5 -0
- package/dist/ray-tracing/material/types.d.ts +63 -0
- package/dist/ray-tracing/reference/index.d.ts +122 -0
- package/dist/ray-tracing/renderer/index.d.ts +7 -0
- package/dist/ray-tracing/renderer/layout.d.ts +20 -0
- package/dist/ray-tracing/renderer/plan.d.ts +2 -0
- package/dist/ray-tracing/renderer/reference.d.ts +17 -0
- package/dist/ray-tracing/renderer/runtime.d.ts +39 -0
- package/dist/ray-tracing/renderer/scene.d.ts +4 -0
- package/dist/ray-tracing/renderer/types.d.ts +115 -0
- package/dist/ray-tracing/sampling/index.d.ts +8 -0
- package/dist/ray-tracing/sampling/layout.d.ts +12 -0
- package/dist/ray-tracing/sampling/plan.d.ts +5 -0
- package/dist/ray-tracing/sampling/revision.d.ts +15 -0
- package/dist/ray-tracing/sampling/runtime.d.ts +44 -0
- package/dist/ray-tracing/sampling/sequence.d.ts +2 -0
- package/dist/ray-tracing/sampling/types.d.ts +96 -0
- package/dist/ray-tracing/scene/index.d.ts +41 -0
- package/dist/ray-tracing/traversal/index.d.ts +4 -0
- package/dist/ray-tracing/traversal/layout.d.ts +16 -0
- package/dist/ray-tracing/traversal/plan.d.ts +2 -0
- package/dist/ray-tracing/traversal/runtime.d.ts +25 -0
- package/dist/ray-tracing/traversal/types.d.ts +79 -0
- package/dist/ray-tracing/worker/client.d.ts +25 -0
- package/dist/ray-tracing/worker/index.d.ts +5 -0
- package/dist/ray-tracing/worker/runtime.d.ts +11 -0
- package/dist/ray-tracing/worker/serialization.d.ts +16 -0
- package/dist/ray-tracing/worker/source.d.ts +1 -0
- package/dist/ray-tracing/worker/types.d.ts +91 -0
- package/dist/ray-tracing.d.ts +17 -0
- package/dist/ray-tracing.js +7666 -0
- package/dist/spine.js +1 -1
- package/dist/tilemap.js +1 -1
- package/package.json +26 -23
- package/dist/animation/Animation2DStateMachineVisualRuntime.d.ts +0 -27
- package/dist/animation/Particle2DDescriptorAdapter.d.ts +0 -5
- package/dist/animation3d/Animation3DResource.d.ts +0 -28
- package/dist/animation3d/hya/HyaAnimation3DStateMachineRuntime.d.ts +0 -65
- package/dist/animation3d/hya/index.d.ts +0 -4
- package/dist/animation3d/runtime/integration/Animation3DStateMachineMixerAdapter.d.ts +0 -81
- package/dist/animation3d/runtime/integration/Animation3DStateMachineMixerIntegration.d.ts +0 -39
- package/dist/animation3d/runtime/integration/index.d.ts +0 -2
- package/dist/animation3d/runtime/mixer/Action.d.ts +0 -150
- package/dist/animation3d/runtime/mixer/Animation3DMixerRuntimeStore.d.ts +0 -6
- package/dist/animation3d/runtime/mixer/Mixer.d.ts +0 -59
- package/dist/animation3d/runtime/mixer/PoseBuffer.d.ts +0 -1
- package/dist/animation3d/runtime/mixer/TrackSampler.d.ts +0 -24
- package/dist/animation3d/runtime/mixer/index.d.ts +0 -4
- package/dist/animation3d/runtime/state-machine/Animation3DBlendTreeWeights.d.ts +0 -1
- package/dist/animation3d/runtime/state-machine/Animation3DStateMachineCompiler.d.ts +0 -1
- package/dist/animation3d/runtime/state-machine/Animation3DStateMachineController.d.ts +0 -1
- package/dist/animation3d/runtime/state-machine/Animation3DStateMachineMixerPort.d.ts +0 -1
- package/dist/animation3d/runtime/state-machine/index.d.ts +0 -6
- package/dist/benchmark.d.ts +0 -30
- package/dist/chunks/2d-ui-animation-2d.generated-D4aHzFU2.js +0 -4
- package/dist/chunks/Animation2DStateMachine-9IonguNa.js +0 -3245
- package/dist/gltf/GltfAccessorReader.d.ts +0 -7
- package/dist/gltf/GltfDracoDecoder.d.ts +0 -4
- package/dist/gltf/GltfLoaderErrors.d.ts +0 -4
- package/dist/gltf/GltfMaterialDescriptor.d.ts +0 -23
- package/dist/gltf/GltfMaterialLoader.d.ts +0 -6
- package/dist/gltf-worker-runtime.d.ts +0 -7
- package/dist/plugins/pluginUtils.d.ts +0 -20
- package/dist/plugins.d.ts +0 -6
- package/dist/shaders/generated/2d-ui-artifact.generated.d.ts +0 -658
- package/dist/spine/Spine2DGpuRenderer.d.ts +0 -65
- package/dist/spine/Spine2DRuntime.d.ts +0 -103
- package/dist/spine/SpineAnimationBoneTimelines.d.ts +0 -8
- package/dist/spine/SpineFloatBuilder.d.ts +0 -15
- package/dist/spine/SpinePathConstraintSolver.d.ts +0 -32
- package/dist/spine/SpineSkeletonRuntime.d.ts +0 -185
- package/dist/spine/SpineSlotAnimation.d.ts +0 -17
- package/dist/spine/SpineTimelineRuntime.d.ts +0 -25
- package/dist/spine/SpineVertexBuilder.d.ts +0 -61
- package/dist/tilemap/Tilemap2DRenderer.d.ts +0 -24
- package/dist/utils/arrayAccess.d.ts +0 -4
- package/dist/utils/camera2d.d.ts +0 -12
- package/src/animation/Animation2DComponent.ts +0 -135
- package/src/animation/Animation2DExtensionRegistry.ts +0 -52
- package/src/animation/Animation2DRenderSystem.ts +0 -1026
- package/src/animation/Animation2DRuntime.ts +0 -1326
- package/src/animation/Animation2DStateMachine.ts +0 -39
- package/src/animation/Animation2DStateMachineComponent.ts +0 -228
- package/src/animation/Animation2DStateMachineRuntime.ts +0 -141
- package/src/animation/Animation2DStateMachineSystem.ts +0 -60
- package/src/animation/Animation2DStateMachineVisualRuntime.ts +0 -282
- package/src/animation/Animation2DSystem.ts +0 -72
- package/src/animation/AnimationAssetLoader.ts +0 -84
- package/src/animation/AnimationAudioClip.ts +0 -140
- package/src/animation/AnimationPathTessellator.ts +0 -691
- package/src/animation/AnimationTextRasterizer.ts +0 -340
- package/src/animation/AnimationVisual2D.ts +0 -153
- package/src/animation/HyaAnimation2DClipAdapter.ts +0 -845
- package/src/animation/Particle2DDescriptorAdapter.ts +0 -35
- package/src/animation/runtime/mixer/Action.ts +0 -876
- package/src/animation/runtime/mixer/Mixer.ts +0 -505
- package/src/animation/runtime/mixer/PoseBuffer.ts +0 -105
- package/src/animation/runtime/mixer/Sampler.ts +0 -252
- package/src/animation/runtime/mixer/Types.ts +0 -138
- package/src/animation/runtime/mixer/index.ts +0 -31
- package/src/animation-state-machine/AnimationStateMachine.ts +0 -146
- package/src/animation-state-machine/AnimationStateMachineChannels.ts +0 -116
- package/src/animation-state-machine/runtime/Animation2DStateMachineMixerAdapter.ts +0 -197
- package/src/animation-state-machine/runtime/AnimationStateMachineBlendTreeWeights.ts +0 -503
- package/src/animation-state-machine/runtime/AnimationStateMachineCompiler.ts +0 -763
- package/src/animation-state-machine/runtime/AnimationStateMachineController.ts +0 -987
- package/src/animation-state-machine/runtime/AnimationStateMachineMixerPort.ts +0 -54
- package/src/animation-state-machine/runtime/index.ts +0 -47
- package/src/animation.ts +0 -33
- package/src/animation3d/Animation3DAction.ts +0 -73
- package/src/animation3d/Animation3DBinding.ts +0 -116
- package/src/animation3d/Animation3DClip.ts +0 -22
- package/src/animation3d/Animation3DError.ts +0 -34
- package/src/animation3d/Animation3DMixer.ts +0 -82
- package/src/animation3d/Animation3DPose.ts +0 -100
- package/src/animation3d/Animation3DPoseBuffer.ts +0 -85
- package/src/animation3d/Animation3DResource.ts +0 -49
- package/src/animation3d/Animation3DStateMachine.ts +0 -126
- package/src/animation3d/Animation3DStateMachineRuntime.ts +0 -191
- package/src/animation3d/Animation3DTrack.ts +0 -29
- package/src/animation3d/hya/HyaAnimation3DRuntime.ts +0 -756
- package/src/animation3d/hya/HyaAnimation3DStateMachineRuntime.ts +0 -618
- package/src/animation3d/hya/HyaAnimation3DTypes.ts +0 -168
- package/src/animation3d/hya/index.ts +0 -10
- package/src/animation3d/index.ts +0 -76
- package/src/animation3d/runtime/integration/Animation3DStateMachineMixerAdapter.ts +0 -325
- package/src/animation3d/runtime/integration/Animation3DStateMachineMixerIntegration.ts +0 -158
- package/src/animation3d/runtime/integration/index.ts +0 -9
- package/src/animation3d/runtime/mixer/Action.ts +0 -833
- package/src/animation3d/runtime/mixer/Animation3DMixerRuntimeStore.ts +0 -26
- package/src/animation3d/runtime/mixer/Mixer.ts +0 -562
- package/src/animation3d/runtime/mixer/PoseBuffer.ts +0 -1
- package/src/animation3d/runtime/mixer/TrackSampler.ts +0 -399
- package/src/animation3d/runtime/mixer/index.ts +0 -8
- package/src/animation3d/runtime/state-machine/Animation3DBlendTreeWeights.ts +0 -4
- package/src/animation3d/runtime/state-machine/Animation3DStateMachineCompiler.ts +0 -1
- package/src/animation3d/runtime/state-machine/Animation3DStateMachineController.ts +0 -1
- package/src/animation3d/runtime/state-machine/Animation3DStateMachineMixerPort.ts +0 -1
- package/src/animation3d/runtime/state-machine/index.ts +0 -45
- package/src/animation3d.ts +0 -5
- package/src/benchmark.ts +0 -168
- package/src/canvas-text/CanvasText2DRenderSystem.ts +0 -292
- package/src/canvas-text/CanvasTextComponent.ts +0 -47
- package/src/canvas-text.ts +0 -4
- package/src/experimental-gltf-worker.ts +0 -18
- package/src/experimental-spine-worker.ts +0 -9
- package/src/gltf/GltfAccessorReader.ts +0 -271
- package/src/gltf/GltfAnimation3DAdapter.ts +0 -680
- package/src/gltf/GltfAnimationRuntime.ts +0 -392
- package/src/gltf/GltfAssetWorkerClient.ts +0 -136
- package/src/gltf/GltfCompatibilityReport.ts +0 -214
- package/src/gltf/GltfConservativeBounds.ts +0 -219
- package/src/gltf/GltfDracoDecoder.ts +0 -251
- package/src/gltf/GltfExtensionAdapter.ts +0 -340
- package/src/gltf/GltfLoaderContract.ts +0 -333
- package/src/gltf/GltfLoaderErrors.ts +0 -59
- package/src/gltf/GltfMaterialDescriptor.ts +0 -134
- package/src/gltf/GltfMaterialEncoder.ts +0 -173
- package/src/gltf/GltfMaterialLoader.ts +0 -293
- package/src/gltf/GltfModelComponent.ts +0 -115
- package/src/gltf/GltfModelSystem.ts +0 -208
- package/src/gltf/GltfPlugin.ts +0 -84
- package/src/gltf/GltfSchema.ts +0 -229
- package/src/gltf/GltfUvSemanticPlanner.ts +0 -166
- package/src/gltf/gltfLoader.ts +0 -910
- package/src/gltf-animation3d.ts +0 -10
- package/src/gltf-worker-runtime.ts +0 -10
- package/src/gltf.ts +0 -56
- package/src/grid/Grid2DComponent.ts +0 -69
- package/src/grid.ts +0 -2
- package/src/hya-state-machine.ts +0 -19
- package/src/index.ts +0 -2
- package/src/plugins/pluginUtils.ts +0 -50
- package/src/plugins.ts +0 -6
- package/src/shaders/generated/2d-ui-animation-2d.generated.wgsl +0 -242
- package/src/shaders/generated/2d-ui-artifact.generated.ts +0 -867
- package/src/shaders/generated/2d-ui-canvas-text-2d.generated.wgsl +0 -38
- package/src/shaders/generated/2d-ui-spine2d.generated.wgsl +0 -41
- package/src/shaders/generated/2d-ui-tilemap2d.generated.wgsl +0 -36
- package/src/spine/Spine2DComponent.ts +0 -168
- package/src/spine/Spine2DGpuRenderer.ts +0 -449
- package/src/spine/Spine2DRenderSystem.ts +0 -199
- package/src/spine/Spine2DRuntime.ts +0 -1529
- package/src/spine/SpineAnimationBoneTimelines.ts +0 -30
- package/src/spine/SpineAssetParser.ts +0 -20
- package/src/spine/SpineAssetWorkerClient.ts +0 -112
- package/src/spine/SpineAssetWorkerContract.ts +0 -4
- package/src/spine/SpineAtlasParser.ts +0 -127
- package/src/spine/SpineFloatBuilder.ts +0 -66
- package/src/spine/SpinePathConstraintSolver.ts +0 -582
- package/src/spine/SpinePlugin.ts +0 -76
- package/src/spine/SpineSkeletonRuntime.ts +0 -521
- package/src/spine/SpineSlotAnimation.ts +0 -195
- package/src/spine/SpineTimelineRuntime.ts +0 -453
- package/src/spine/SpineVertexBuilder.ts +0 -686
- package/src/spine.ts +0 -7
- package/src/tilemap/Tilemap2DComponent.ts +0 -232
- package/src/tilemap/Tilemap2DRenderSystem.ts +0 -58
- package/src/tilemap/Tilemap2DRenderer.ts +0 -289
- package/src/tilemap/TilemapPlugin.ts +0 -75
- package/src/tilemap.ts +0 -6
- package/src/tween/Tween2DComponent.ts +0 -83
- package/src/tween/Tween2DSystem.ts +0 -78
- package/src/tween.ts +0 -4
- package/src/types/earcut.d.ts +0 -7
- package/src/types/wgsl.d.ts +0 -4
- package/src/utils/RenderSystem2DBase.ts +0 -164
- package/src/utils/arrayAccess.ts +0 -17
- package/src/utils/camera2d.ts +0 -68
- package/src/utils/render2dGpu.ts +0 -132
- package/test/fixtures/gltf/animation-characterization.gltf +0 -344
|
@@ -1,876 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
Animation2DActionOptions,
|
|
3
|
-
Animation2DActionStatus,
|
|
4
|
-
Animation2DBinding,
|
|
5
|
-
Animation2DBindingMask,
|
|
6
|
-
Animation2DBlendMode,
|
|
7
|
-
Animation2DClip,
|
|
8
|
-
Animation2DEffectCue,
|
|
9
|
-
Animation2DEffectEvent,
|
|
10
|
-
Animation2DEffectLifecycle,
|
|
11
|
-
Animation2DLoopMode,
|
|
12
|
-
Animation2DMutablePose,
|
|
13
|
-
Animation2DTrack,
|
|
14
|
-
} from './Types.js';
|
|
15
|
-
import { Animation2DSampler, isNumericBinding } from './Sampler.js';
|
|
16
|
-
|
|
17
|
-
export interface Animation2DActionOwner {
|
|
18
|
-
readonly time: number;
|
|
19
|
-
assertActive(): void;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface Animation2DActionTrackRuntime {
|
|
23
|
-
readonly track: Animation2DTrack;
|
|
24
|
-
readonly sampler: Animation2DSampler;
|
|
25
|
-
readonly reference: Float32Array;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
interface RuntimeEffect {
|
|
29
|
-
readonly cue: Animation2DEffectCue;
|
|
30
|
-
readonly start: number;
|
|
31
|
-
readonly end: number;
|
|
32
|
-
readonly fullSpan: boolean;
|
|
33
|
-
readonly loopBehavior: 'continue' | 'restart';
|
|
34
|
-
readonly enterEvent: Animation2DEffectEvent;
|
|
35
|
-
readonly exitEvent: Animation2DEffectEvent;
|
|
36
|
-
readonly restartEvent: Animation2DEffectEvent;
|
|
37
|
-
readonly loopEvent: Animation2DEffectEvent;
|
|
38
|
-
readonly seekEvent: Animation2DEffectEvent;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
interface EffectOutput {
|
|
42
|
-
emit(effect: Animation2DEffectEvent): void;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/** @internal Reusable exact state used by controller-owned transactions. */
|
|
46
|
-
export interface Animation2DActionSynchronizedState {
|
|
47
|
-
status: Animation2DActionStatus;
|
|
48
|
-
paused: boolean;
|
|
49
|
-
time: number;
|
|
50
|
-
rawTime: number;
|
|
51
|
-
timeScale: number;
|
|
52
|
-
weight: number;
|
|
53
|
-
loop: Animation2DLoopMode;
|
|
54
|
-
repetitions: number;
|
|
55
|
-
clampWhenFinished: boolean;
|
|
56
|
-
blendMode: Animation2DBlendMode;
|
|
57
|
-
mask: Animation2DBindingMask | null;
|
|
58
|
-
layer: number;
|
|
59
|
-
effectsStarted: boolean;
|
|
60
|
-
fadeActive: boolean;
|
|
61
|
-
fadeStart: number;
|
|
62
|
-
fadeEnd: number;
|
|
63
|
-
fadeFrom: number;
|
|
64
|
-
fadeTo: number;
|
|
65
|
-
fadeValue: number;
|
|
66
|
-
readonly effectActive: Uint8Array;
|
|
67
|
-
readonly pendingEffects: Animation2DEffectEvent[];
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Mutable mixer-owned playback state. Effect lifecycle records and sampler
|
|
72
|
-
* outputs are allocated at construction and reused on every frame.
|
|
73
|
-
*/
|
|
74
|
-
export class Animation2DActionRuntime {
|
|
75
|
-
readonly id: string;
|
|
76
|
-
readonly clip: Animation2DClip;
|
|
77
|
-
readonly order: number;
|
|
78
|
-
readonly runtimeTracks: readonly Animation2DActionTrackRuntime[];
|
|
79
|
-
readonly runtimeEffects: readonly RuntimeEffect[];
|
|
80
|
-
|
|
81
|
-
private readonly _owner: Animation2DActionOwner;
|
|
82
|
-
private readonly _effectActive: Uint8Array;
|
|
83
|
-
private readonly _pendingEffects: Animation2DEffectEvent[] = [];
|
|
84
|
-
private readonly _pendingEffectOutput: EffectOutput = {
|
|
85
|
-
emit: effect => { this._pendingEffects.push(effect); },
|
|
86
|
-
};
|
|
87
|
-
private _valid = true;
|
|
88
|
-
private _status: Animation2DActionStatus = 'idle';
|
|
89
|
-
private _paused = false;
|
|
90
|
-
private _time = 0;
|
|
91
|
-
private _rawTime = 0;
|
|
92
|
-
private _timeScale: number;
|
|
93
|
-
private _weight: number;
|
|
94
|
-
private _loop: Animation2DLoopMode;
|
|
95
|
-
private _repetitions: number;
|
|
96
|
-
private _clampWhenFinished: boolean;
|
|
97
|
-
private _blendMode: Animation2DBlendMode;
|
|
98
|
-
private _mask: Animation2DBindingMask | null;
|
|
99
|
-
private _layer: number;
|
|
100
|
-
private _effectsStarted = false;
|
|
101
|
-
|
|
102
|
-
private _fadeActive = false;
|
|
103
|
-
private _fadeStart = 0;
|
|
104
|
-
private _fadeEnd = 0;
|
|
105
|
-
private _fadeFrom = 1;
|
|
106
|
-
private _fadeTo = 1;
|
|
107
|
-
private _fadeValue = 1;
|
|
108
|
-
|
|
109
|
-
constructor(
|
|
110
|
-
owner: Animation2DActionOwner,
|
|
111
|
-
clip: Animation2DClip,
|
|
112
|
-
id: string,
|
|
113
|
-
order: number,
|
|
114
|
-
options: Animation2DActionOptions = {},
|
|
115
|
-
) {
|
|
116
|
-
validateClip(clip);
|
|
117
|
-
this._owner = owner;
|
|
118
|
-
this.clip = clip;
|
|
119
|
-
this.id = id;
|
|
120
|
-
this.order = order;
|
|
121
|
-
this._loop = options.loop ?? 'once';
|
|
122
|
-
this._repetitions = validateRepetitions(
|
|
123
|
-
options.repetitions ?? (this._loop === 'once' ? 1 : Infinity),
|
|
124
|
-
);
|
|
125
|
-
this._clampWhenFinished = options.clampWhenFinished ?? false;
|
|
126
|
-
this._timeScale = finiteNumber(options.timeScale ?? 1, 'Animation2DAction.timeScale');
|
|
127
|
-
this._weight = nonNegativeNumber(options.weight ?? 1, 'Animation2DAction.weight');
|
|
128
|
-
this._fadeValue = this._weight;
|
|
129
|
-
this._layer = integerNumber(options.layer ?? 0, 'Animation2DAction.layer');
|
|
130
|
-
this._blendMode = options.blendMode ?? 'override';
|
|
131
|
-
this._mask = options.mask ?? null;
|
|
132
|
-
|
|
133
|
-
const tracks: Animation2DActionTrackRuntime[] = [];
|
|
134
|
-
for (let index = 0; index < clip.tracks.length; index++) {
|
|
135
|
-
const track = clip.tracks[index]!;
|
|
136
|
-
const sampler = new Animation2DSampler(track);
|
|
137
|
-
const reference = isNumericBinding(track.binding)
|
|
138
|
-
? new Float32Array(track.binding.valueSize!)
|
|
139
|
-
: new Float32Array(0);
|
|
140
|
-
if (reference.length > 0) sampler.sample(0, reference);
|
|
141
|
-
tracks.push({ track, sampler, reference });
|
|
142
|
-
}
|
|
143
|
-
this.runtimeTracks = tracks;
|
|
144
|
-
|
|
145
|
-
const effects: RuntimeEffect[] = [];
|
|
146
|
-
const sourceEffects = clip.effects ?? [];
|
|
147
|
-
for (let index = 0; index < sourceEffects.length; index++) {
|
|
148
|
-
const cue = sourceEffects[index]!;
|
|
149
|
-
const start = cue.start;
|
|
150
|
-
const end = cue.end ?? clip.duration;
|
|
151
|
-
validateEffect(cue, start, end, clip.duration);
|
|
152
|
-
effects.push({
|
|
153
|
-
cue,
|
|
154
|
-
start,
|
|
155
|
-
end,
|
|
156
|
-
fullSpan: start === 0 && end === clip.duration,
|
|
157
|
-
loopBehavior: cue.loopBehavior ?? (cue.kind === 'particle' ? 'restart' : 'continue'),
|
|
158
|
-
enterEvent: effectEvent(id, clip.id, cue, 'enter'),
|
|
159
|
-
exitEvent: effectEvent(id, clip.id, cue, 'exit'),
|
|
160
|
-
restartEvent: effectEvent(id, clip.id, cue, 'restart'),
|
|
161
|
-
loopEvent: effectEvent(id, clip.id, cue, 'loop'),
|
|
162
|
-
seekEvent: effectEvent(id, clip.id, cue, 'seek'),
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
this.runtimeEffects = effects;
|
|
166
|
-
this._effectActive = new Uint8Array(effects.length);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
get duration(): number { return this.clip.duration; }
|
|
170
|
-
get status(): Animation2DActionStatus { return this._status; }
|
|
171
|
-
get paused(): boolean { return this._paused; }
|
|
172
|
-
set paused(value: boolean) {
|
|
173
|
-
this._assertValid();
|
|
174
|
-
this._paused = Boolean(value);
|
|
175
|
-
if (this._paused && this._status === 'running') this._status = 'paused';
|
|
176
|
-
else if (!this._paused && this._status === 'paused') this._status = 'running';
|
|
177
|
-
}
|
|
178
|
-
get time(): number { return this._time; }
|
|
179
|
-
set time(value: number) { this.seek(value); }
|
|
180
|
-
get timeScale(): number { return this._timeScale; }
|
|
181
|
-
set timeScale(value: number) {
|
|
182
|
-
this._assertValid();
|
|
183
|
-
this._timeScale = finiteNumber(value, 'Animation2DAction.timeScale');
|
|
184
|
-
}
|
|
185
|
-
get weight(): number { return this._weight; }
|
|
186
|
-
set weight(value: number) {
|
|
187
|
-
this._assertValid();
|
|
188
|
-
this._weight = nonNegativeNumber(value, 'Animation2DAction.weight');
|
|
189
|
-
this._fadeActive = false;
|
|
190
|
-
this._fadeValue = this._weight;
|
|
191
|
-
}
|
|
192
|
-
get layer(): number { return this._layer; }
|
|
193
|
-
set layer(value: number) {
|
|
194
|
-
this._assertValid();
|
|
195
|
-
this._layer = integerNumber(value, 'Animation2DAction.layer');
|
|
196
|
-
}
|
|
197
|
-
get loop(): Animation2DLoopMode { return this._loop; }
|
|
198
|
-
set loop(value: Animation2DLoopMode) {
|
|
199
|
-
this._assertValid();
|
|
200
|
-
if (value !== 'once' && value !== 'repeat' && value !== 'ping-pong') {
|
|
201
|
-
throw new RangeError(`Unsupported Animation2D loop mode "${String(value)}".`);
|
|
202
|
-
}
|
|
203
|
-
this._loop = value;
|
|
204
|
-
this._setSampleTime(0);
|
|
205
|
-
}
|
|
206
|
-
get repetitions(): number { return this._repetitions; }
|
|
207
|
-
set repetitions(value: number) {
|
|
208
|
-
this._assertValid();
|
|
209
|
-
this._repetitions = validateRepetitions(value);
|
|
210
|
-
}
|
|
211
|
-
get clampWhenFinished(): boolean { return this._clampWhenFinished; }
|
|
212
|
-
set clampWhenFinished(value: boolean) {
|
|
213
|
-
this._assertValid();
|
|
214
|
-
this._clampWhenFinished = Boolean(value);
|
|
215
|
-
}
|
|
216
|
-
get blendMode(): Animation2DBlendMode { return this._blendMode; }
|
|
217
|
-
set blendMode(value: Animation2DBlendMode) {
|
|
218
|
-
this._assertValid();
|
|
219
|
-
if (value !== 'override' && value !== 'additive') {
|
|
220
|
-
throw new RangeError(`Unsupported Animation2D blend mode "${String(value)}".`);
|
|
221
|
-
}
|
|
222
|
-
this._blendMode = value;
|
|
223
|
-
}
|
|
224
|
-
get mask(): Animation2DBindingMask | null { return this._mask; }
|
|
225
|
-
set mask(value: Animation2DBindingMask | null) {
|
|
226
|
-
this._assertValid();
|
|
227
|
-
this._mask = value;
|
|
228
|
-
}
|
|
229
|
-
get effectiveWeight(): number {
|
|
230
|
-
if (!this._valid || this._paused || (this._status !== 'running'
|
|
231
|
-
&& !(this._status === 'finished' && this._clampWhenFinished))) return 0;
|
|
232
|
-
return this._fadeFactor(this._owner.time);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
play(): this {
|
|
236
|
-
this._assertValid();
|
|
237
|
-
if (this._status === 'finished' && !this._clampWhenFinished) {
|
|
238
|
-
this._rawTime = this._timeScale < 0 ? this.clip.duration : 0;
|
|
239
|
-
this._setSampleTime(0);
|
|
240
|
-
this._effectsStarted = false;
|
|
241
|
-
}
|
|
242
|
-
this._paused = false;
|
|
243
|
-
this._status = 'running';
|
|
244
|
-
return this;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
pause(): this {
|
|
248
|
-
this.paused = true;
|
|
249
|
-
return this;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
stop(): this {
|
|
253
|
-
this._assertValid();
|
|
254
|
-
this._queueActiveExits();
|
|
255
|
-
this._paused = false;
|
|
256
|
-
this._status = 'stopped';
|
|
257
|
-
this._effectsStarted = false;
|
|
258
|
-
return this;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
reset(): this {
|
|
262
|
-
this._assertValid();
|
|
263
|
-
this._queueActiveExits();
|
|
264
|
-
this._paused = false;
|
|
265
|
-
this._status = 'idle';
|
|
266
|
-
this._rawTime = 0;
|
|
267
|
-
this._time = 0;
|
|
268
|
-
this._effectsStarted = false;
|
|
269
|
-
this._fadeActive = false;
|
|
270
|
-
this._fadeValue = this._weight;
|
|
271
|
-
this._resetSamplerCursors();
|
|
272
|
-
return this;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
seek(timeSeconds: number): this {
|
|
276
|
-
this._assertValid();
|
|
277
|
-
const next = Math.min(
|
|
278
|
-
this.clip.duration,
|
|
279
|
-
Math.max(0, finiteNumber(timeSeconds, 'Animation2DAction.time')),
|
|
280
|
-
);
|
|
281
|
-
for (let index = 0; index < this.runtimeEffects.length; index++) {
|
|
282
|
-
const wasActive = this._effectActive[index] !== 0;
|
|
283
|
-
const active = effectActiveAt(this.runtimeEffects[index]!, next, this.clip.duration);
|
|
284
|
-
const effect = this.runtimeEffects[index]!;
|
|
285
|
-
if (wasActive && !active) this._pendingEffects.push(effect.exitEvent);
|
|
286
|
-
this._pendingEffects.push(effect.seekEvent);
|
|
287
|
-
if (!wasActive && active) this._pendingEffects.push(effect.enterEvent);
|
|
288
|
-
this._effectActive[index] = active ? 1 : 0;
|
|
289
|
-
}
|
|
290
|
-
this._rawTime = next;
|
|
291
|
-
this._time = next;
|
|
292
|
-
this._effectsStarted = true;
|
|
293
|
-
this._resetSamplerCursors();
|
|
294
|
-
return this;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* Advances a controller-owned absolute playhead without classifying the
|
|
299
|
-
* move as a seek. Crossed side-effect boundaries are queued exactly once.
|
|
300
|
-
*/
|
|
301
|
-
synchronizeTime(timeSeconds: number): this {
|
|
302
|
-
this._assertValid();
|
|
303
|
-
const after = this._clampSynchronizedTime(timeSeconds);
|
|
304
|
-
const terminalDirection = this._terminalDirection(after);
|
|
305
|
-
if (!this._effectsStarted) {
|
|
306
|
-
this._emitInitialEffects(this._pendingEffectOutput);
|
|
307
|
-
this._effectsStarted = true;
|
|
308
|
-
}
|
|
309
|
-
this._emitEffectCrossings(
|
|
310
|
-
this._rawTime,
|
|
311
|
-
after,
|
|
312
|
-
this._pendingEffectOutput,
|
|
313
|
-
terminalDirection,
|
|
314
|
-
);
|
|
315
|
-
this._rawTime = after;
|
|
316
|
-
this._setSampleTime(terminalDirection);
|
|
317
|
-
this._syncEffectActivity(terminalDirection);
|
|
318
|
-
this._resetSamplerCursors();
|
|
319
|
-
return this;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
reverse(): this {
|
|
323
|
-
this._assertValid();
|
|
324
|
-
this._timeScale = -Math.max(Number.EPSILON, Math.abs(this._timeScale));
|
|
325
|
-
return this;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
fadeTo(targetWeight: number, durationSeconds: number): this {
|
|
329
|
-
this._assertValid();
|
|
330
|
-
const target = nonNegativeNumber(targetWeight, 'Animation2DAction.fade target');
|
|
331
|
-
const duration = nonNegativeNumber(durationSeconds, 'Animation2DAction.fade duration');
|
|
332
|
-
this._scheduleFade(this._fadeFactor(this._owner.time), target, duration);
|
|
333
|
-
return this;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
fadeIn(durationSeconds: number): this {
|
|
337
|
-
this._assertValid();
|
|
338
|
-
const duration = nonNegativeNumber(durationSeconds, 'Animation2DAction.fade duration');
|
|
339
|
-
this._scheduleFade(0, this._weight > 0 ? this._weight : 1, duration);
|
|
340
|
-
return this;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
fadeOut(durationSeconds: number): this {
|
|
344
|
-
return this.fadeTo(0, durationSeconds);
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
crossFadeFrom(source: Animation2DActionRuntime, durationSeconds: number): this {
|
|
348
|
-
this._assertSibling(source);
|
|
349
|
-
source.play().fadeOut(durationSeconds);
|
|
350
|
-
this.play().fadeIn(durationSeconds);
|
|
351
|
-
return this;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
crossFadeTo(destination: Animation2DActionRuntime, durationSeconds: number): this {
|
|
355
|
-
this._assertSibling(destination);
|
|
356
|
-
destination.crossFadeFrom(this, durationSeconds);
|
|
357
|
-
return this;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
acceptsBinding(binding: Animation2DBinding): boolean {
|
|
361
|
-
const include = this._mask?.include;
|
|
362
|
-
if (include && include.length > 0) {
|
|
363
|
-
let accepted = false;
|
|
364
|
-
for (let index = 0; index < include.length; index++) {
|
|
365
|
-
if (include[index] === binding.id) {
|
|
366
|
-
accepted = true;
|
|
367
|
-
break;
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
if (!accepted) return false;
|
|
371
|
-
}
|
|
372
|
-
const exclude = this._mask?.exclude;
|
|
373
|
-
if (exclude) {
|
|
374
|
-
for (let index = 0; index < exclude.length; index++) {
|
|
375
|
-
if (exclude[index] === binding.id) return false;
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
return true;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
flushPendingEffects(out: Animation2DMutablePose): void {
|
|
382
|
-
for (let index = 0; index < this._pendingEffects.length; index++) {
|
|
383
|
-
out.emit(this._pendingEffects[index]!);
|
|
384
|
-
}
|
|
385
|
-
this._pendingEffects.length = 0;
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
advance(mixerDelta: number, out: Animation2DMutablePose): void {
|
|
389
|
-
if (!this._valid) return;
|
|
390
|
-
this._finishFade(this._owner.time);
|
|
391
|
-
this.flushPendingEffects(out);
|
|
392
|
-
if (this._paused || this._status !== 'running') return;
|
|
393
|
-
if (!this._effectsStarted) {
|
|
394
|
-
this._emitInitialEffects(out);
|
|
395
|
-
this._effectsStarted = true;
|
|
396
|
-
}
|
|
397
|
-
const actionDelta = mixerDelta * this._timeScale;
|
|
398
|
-
if (actionDelta === 0 || this.clip.duration === 0) return;
|
|
399
|
-
|
|
400
|
-
const before = this._rawTime;
|
|
401
|
-
let after = before + actionDelta;
|
|
402
|
-
let terminalDirection = 0;
|
|
403
|
-
const totalDuration = this._loop === 'once'
|
|
404
|
-
? this.clip.duration
|
|
405
|
-
: this._repetitions === Infinity
|
|
406
|
-
? Infinity
|
|
407
|
-
: this.clip.duration * this._repetitions;
|
|
408
|
-
if (totalDuration !== Infinity) {
|
|
409
|
-
if (actionDelta > 0 && after >= totalDuration) {
|
|
410
|
-
after = totalDuration;
|
|
411
|
-
terminalDirection = 1;
|
|
412
|
-
} else if (actionDelta < 0 && after <= 0) {
|
|
413
|
-
after = 0;
|
|
414
|
-
terminalDirection = -1;
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
this._emitEffectCrossings(before, after, out, terminalDirection);
|
|
419
|
-
this._rawTime = after;
|
|
420
|
-
this._setSampleTime(terminalDirection);
|
|
421
|
-
this._syncEffectActivity(terminalDirection);
|
|
422
|
-
if (terminalDirection !== 0) {
|
|
423
|
-
this._status = 'finished';
|
|
424
|
-
if (!this._clampWhenFinished) this._queueActiveExits();
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
/** @internal Allocates one checkpoint that can be reused for every update. */
|
|
429
|
-
createSynchronizedState(): Animation2DActionSynchronizedState {
|
|
430
|
-
return {
|
|
431
|
-
status: this._status,
|
|
432
|
-
paused: this._paused,
|
|
433
|
-
time: this._time,
|
|
434
|
-
rawTime: this._rawTime,
|
|
435
|
-
timeScale: this._timeScale,
|
|
436
|
-
weight: this._weight,
|
|
437
|
-
loop: this._loop,
|
|
438
|
-
repetitions: this._repetitions,
|
|
439
|
-
clampWhenFinished: this._clampWhenFinished,
|
|
440
|
-
blendMode: this._blendMode,
|
|
441
|
-
mask: this._mask,
|
|
442
|
-
layer: this._layer,
|
|
443
|
-
effectsStarted: this._effectsStarted,
|
|
444
|
-
fadeActive: this._fadeActive,
|
|
445
|
-
fadeStart: this._fadeStart,
|
|
446
|
-
fadeEnd: this._fadeEnd,
|
|
447
|
-
fadeFrom: this._fadeFrom,
|
|
448
|
-
fadeTo: this._fadeTo,
|
|
449
|
-
fadeValue: this._fadeValue,
|
|
450
|
-
effectActive: new Uint8Array(this._effectActive.length),
|
|
451
|
-
pendingEffects: [],
|
|
452
|
-
};
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
/** @internal Captures playhead, fade, and effect-cursor state without sampling. */
|
|
456
|
-
captureSynchronizedState(state: Animation2DActionSynchronizedState): void {
|
|
457
|
-
this._assertValid();
|
|
458
|
-
if (state.effectActive.length !== this._effectActive.length) {
|
|
459
|
-
throw new RangeError('Animation2D action checkpoint has an incompatible effect count.');
|
|
460
|
-
}
|
|
461
|
-
state.status = this._status;
|
|
462
|
-
state.paused = this._paused;
|
|
463
|
-
state.time = this._time;
|
|
464
|
-
state.rawTime = this._rawTime;
|
|
465
|
-
state.timeScale = this._timeScale;
|
|
466
|
-
state.weight = this._weight;
|
|
467
|
-
state.loop = this._loop;
|
|
468
|
-
state.repetitions = this._repetitions;
|
|
469
|
-
state.clampWhenFinished = this._clampWhenFinished;
|
|
470
|
-
state.blendMode = this._blendMode;
|
|
471
|
-
state.mask = this._mask;
|
|
472
|
-
state.layer = this._layer;
|
|
473
|
-
state.effectsStarted = this._effectsStarted;
|
|
474
|
-
state.fadeActive = this._fadeActive;
|
|
475
|
-
state.fadeStart = this._fadeStart;
|
|
476
|
-
state.fadeEnd = this._fadeEnd;
|
|
477
|
-
state.fadeFrom = this._fadeFrom;
|
|
478
|
-
state.fadeTo = this._fadeTo;
|
|
479
|
-
state.fadeValue = this._fadeValue;
|
|
480
|
-
state.effectActive.set(this._effectActive);
|
|
481
|
-
state.pendingEffects.length = 0;
|
|
482
|
-
for (const effect of this._pendingEffects) state.pendingEffects.push(effect);
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
/** @internal Restores an exact controller transaction checkpoint. */
|
|
486
|
-
restoreSynchronizedState(state: Animation2DActionSynchronizedState): void {
|
|
487
|
-
this._assertValid();
|
|
488
|
-
if (state.effectActive.length !== this._effectActive.length) {
|
|
489
|
-
throw new RangeError('Animation2D action checkpoint has an incompatible effect count.');
|
|
490
|
-
}
|
|
491
|
-
this._status = state.status;
|
|
492
|
-
this._paused = state.paused;
|
|
493
|
-
this._time = state.time;
|
|
494
|
-
this._rawTime = state.rawTime;
|
|
495
|
-
this._timeScale = state.timeScale;
|
|
496
|
-
this._weight = state.weight;
|
|
497
|
-
this._loop = state.loop;
|
|
498
|
-
this._repetitions = state.repetitions;
|
|
499
|
-
this._clampWhenFinished = state.clampWhenFinished;
|
|
500
|
-
this._blendMode = state.blendMode;
|
|
501
|
-
this._mask = state.mask;
|
|
502
|
-
this._layer = state.layer;
|
|
503
|
-
this._effectsStarted = state.effectsStarted;
|
|
504
|
-
this._fadeActive = state.fadeActive;
|
|
505
|
-
this._fadeStart = state.fadeStart;
|
|
506
|
-
this._fadeEnd = state.fadeEnd;
|
|
507
|
-
this._fadeFrom = state.fadeFrom;
|
|
508
|
-
this._fadeTo = state.fadeTo;
|
|
509
|
-
this._fadeValue = state.fadeValue;
|
|
510
|
-
this._effectActive.set(state.effectActive);
|
|
511
|
-
this._pendingEffects.length = 0;
|
|
512
|
-
for (const effect of state.pendingEffects) this._pendingEffects.push(effect);
|
|
513
|
-
this._resetSamplerCursors();
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
invalidate(): void {
|
|
517
|
-
if (!this._valid) return;
|
|
518
|
-
this._valid = false;
|
|
519
|
-
this._status = 'stopped';
|
|
520
|
-
this._paused = false;
|
|
521
|
-
this._fadeActive = false;
|
|
522
|
-
this._pendingEffects.length = 0;
|
|
523
|
-
this._effectActive.fill(0);
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
private _setSampleTime(terminalDirection: number): void {
|
|
527
|
-
const duration = this.clip.duration;
|
|
528
|
-
if (duration === 0) {
|
|
529
|
-
this._time = 0;
|
|
530
|
-
return;
|
|
531
|
-
}
|
|
532
|
-
if (this._loop === 'once') {
|
|
533
|
-
this._time = Math.min(duration, Math.max(0, this._rawTime));
|
|
534
|
-
return;
|
|
535
|
-
}
|
|
536
|
-
if (terminalDirection > 0 && this._loop === 'repeat') {
|
|
537
|
-
this._time = duration;
|
|
538
|
-
return;
|
|
539
|
-
}
|
|
540
|
-
const traversal = Math.floor(this._rawTime / duration);
|
|
541
|
-
let phase = this._rawTime - traversal * duration;
|
|
542
|
-
if (phase < 0) phase += duration;
|
|
543
|
-
if (this._loop === 'repeat') {
|
|
544
|
-
this._time = phase;
|
|
545
|
-
} else {
|
|
546
|
-
this._time = isEven(traversal) ? phase : duration - phase;
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
private _emitInitialEffects(out: EffectOutput): void {
|
|
551
|
-
for (let index = 0; index < this.runtimeEffects.length; index++) {
|
|
552
|
-
const active = effectActiveAt(this.runtimeEffects[index]!, this._time, this.clip.duration);
|
|
553
|
-
this._effectActive[index] = active ? 1 : 0;
|
|
554
|
-
if (active) out.emit(this.runtimeEffects[index]!.enterEvent);
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
private _emitEffectCrossings(
|
|
559
|
-
before: number,
|
|
560
|
-
after: number,
|
|
561
|
-
out: EffectOutput,
|
|
562
|
-
terminalDirection = 0,
|
|
563
|
-
): void {
|
|
564
|
-
if (before === after || this.runtimeEffects.length === 0) return;
|
|
565
|
-
if (this._loop === 'repeat') {
|
|
566
|
-
this._emitRepeatEffectCrossings(before, after, out, terminalDirection);
|
|
567
|
-
return;
|
|
568
|
-
}
|
|
569
|
-
if (this._loop === 'once') {
|
|
570
|
-
this._emitOnceEffectCrossings(before, after, out);
|
|
571
|
-
return;
|
|
572
|
-
}
|
|
573
|
-
this._emitPingPongEffectCrossings(before, after, out, terminalDirection);
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
private _emitOnceEffectCrossings(
|
|
577
|
-
before: number,
|
|
578
|
-
after: number,
|
|
579
|
-
out: EffectOutput,
|
|
580
|
-
): void {
|
|
581
|
-
for (let index = 0; index < this.runtimeEffects.length; index++) {
|
|
582
|
-
const effect = this.runtimeEffects[index]!;
|
|
583
|
-
if (after > before) {
|
|
584
|
-
if (effect.start > before && effect.start <= after) out.emit(effect.enterEvent);
|
|
585
|
-
if (effect.end > before && effect.end <= after) out.emit(effect.exitEvent);
|
|
586
|
-
} else {
|
|
587
|
-
if (effect.end < before && effect.end >= after) out.emit(effect.enterEvent);
|
|
588
|
-
if (effect.start < before && effect.start >= after) out.emit(effect.exitEvent);
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
private _emitRepeatEffectCrossings(
|
|
594
|
-
before: number,
|
|
595
|
-
after: number,
|
|
596
|
-
out: EffectOutput,
|
|
597
|
-
terminalDirection: number,
|
|
598
|
-
): void {
|
|
599
|
-
const duration = this.clip.duration;
|
|
600
|
-
const minimum = Math.min(before, after);
|
|
601
|
-
const maximum = Math.max(before, after);
|
|
602
|
-
const firstCycle = Math.floor(minimum / duration) - 1;
|
|
603
|
-
const lastCycle = Math.floor(maximum / duration) + 1;
|
|
604
|
-
for (let effectIndex = 0; effectIndex < this.runtimeEffects.length; effectIndex++) {
|
|
605
|
-
const effect = this.runtimeEffects[effectIndex]!;
|
|
606
|
-
if (effect.fullSpan) {
|
|
607
|
-
if (after > before) {
|
|
608
|
-
for (let cycle = firstCycle; cycle <= lastCycle; cycle++) {
|
|
609
|
-
const boundary = cycle * duration;
|
|
610
|
-
if (boundary > before && boundary <= after) {
|
|
611
|
-
if (terminalDirection > 0 && boundary === after) out.emit(effect.exitEvent);
|
|
612
|
-
else this._emitLoopEffect(effect, out);
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
} else {
|
|
616
|
-
for (let cycle = lastCycle; cycle >= firstCycle; cycle--) {
|
|
617
|
-
const boundary = cycle * duration;
|
|
618
|
-
if (boundary < before && boundary >= after) {
|
|
619
|
-
if (terminalDirection < 0 && boundary === after) out.emit(effect.exitEvent);
|
|
620
|
-
else this._emitLoopEffect(effect, out);
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
continue;
|
|
625
|
-
}
|
|
626
|
-
if (after > before) {
|
|
627
|
-
for (let cycle = firstCycle; cycle <= lastCycle; cycle++) {
|
|
628
|
-
const cycleStart = cycle * duration;
|
|
629
|
-
const enter = cycleStart + effect.start;
|
|
630
|
-
const exit = cycleStart + effect.end;
|
|
631
|
-
if (enter > before && enter <= after
|
|
632
|
-
&& !(terminalDirection > 0 && enter === after)) out.emit(effect.enterEvent);
|
|
633
|
-
if (exit > before && exit <= after) out.emit(effect.exitEvent);
|
|
634
|
-
}
|
|
635
|
-
} else {
|
|
636
|
-
for (let cycle = lastCycle; cycle >= firstCycle; cycle--) {
|
|
637
|
-
const cycleStart = cycle * duration;
|
|
638
|
-
const enter = cycleStart + effect.end;
|
|
639
|
-
const exit = cycleStart + effect.start;
|
|
640
|
-
if (enter < before && enter >= after
|
|
641
|
-
&& !(terminalDirection < 0 && enter === after)) out.emit(effect.enterEvent);
|
|
642
|
-
if (exit < before && exit >= after) out.emit(effect.exitEvent);
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
private _emitPingPongEffectCrossings(
|
|
649
|
-
before: number,
|
|
650
|
-
after: number,
|
|
651
|
-
out: EffectOutput,
|
|
652
|
-
terminalDirection: number,
|
|
653
|
-
): void {
|
|
654
|
-
const duration = this.clip.duration;
|
|
655
|
-
const minimum = Math.min(before, after);
|
|
656
|
-
const maximum = Math.max(before, after);
|
|
657
|
-
const firstTraversal = Math.floor(minimum / duration) - 1;
|
|
658
|
-
const lastTraversal = Math.floor(maximum / duration) + 1;
|
|
659
|
-
for (let effectIndex = 0; effectIndex < this.runtimeEffects.length; effectIndex++) {
|
|
660
|
-
const effect = this.runtimeEffects[effectIndex]!;
|
|
661
|
-
if (effect.fullSpan) {
|
|
662
|
-
if (after > before) {
|
|
663
|
-
for (let traversal = firstTraversal; traversal <= lastTraversal; traversal++) {
|
|
664
|
-
const boundary = traversal * duration;
|
|
665
|
-
if (boundary <= before || boundary > after) continue;
|
|
666
|
-
if (terminalDirection > 0 && boundary === after) out.emit(effect.exitEvent);
|
|
667
|
-
else this._emitLoopEffect(effect, out);
|
|
668
|
-
}
|
|
669
|
-
} else {
|
|
670
|
-
for (let traversal = lastTraversal; traversal >= firstTraversal; traversal--) {
|
|
671
|
-
const boundary = traversal * duration;
|
|
672
|
-
if (boundary >= before || boundary < after) continue;
|
|
673
|
-
if (terminalDirection < 0 && boundary === after) out.emit(effect.exitEvent);
|
|
674
|
-
else this._emitLoopEffect(effect, out);
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
continue;
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
if (after > before) {
|
|
681
|
-
for (let traversal = firstTraversal; traversal <= lastTraversal; traversal++) {
|
|
682
|
-
const traversalStart = traversal * duration;
|
|
683
|
-
const forward = isEven(traversal);
|
|
684
|
-
const enter = traversalStart + (forward ? effect.start : duration - effect.end);
|
|
685
|
-
const exit = traversalStart + (forward ? effect.end : duration - effect.start);
|
|
686
|
-
if (enter > before && enter <= after
|
|
687
|
-
&& !(terminalDirection > 0 && enter === after)) out.emit(effect.enterEvent);
|
|
688
|
-
if (exit > before && exit <= after) out.emit(effect.exitEvent);
|
|
689
|
-
}
|
|
690
|
-
} else {
|
|
691
|
-
for (let traversal = lastTraversal; traversal >= firstTraversal; traversal--) {
|
|
692
|
-
const traversalStart = traversal * duration;
|
|
693
|
-
const forward = isEven(traversal);
|
|
694
|
-
const forwardEnter = traversalStart
|
|
695
|
-
+ (forward ? effect.start : duration - effect.end);
|
|
696
|
-
const forwardExit = traversalStart
|
|
697
|
-
+ (forward ? effect.end : duration - effect.start);
|
|
698
|
-
if (forwardExit < before && forwardExit >= after
|
|
699
|
-
&& !(terminalDirection < 0 && forwardExit === after)) out.emit(effect.enterEvent);
|
|
700
|
-
if (forwardEnter < before && forwardEnter >= after) out.emit(effect.exitEvent);
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
private _emitLoopEffect(effect: RuntimeEffect, out: EffectOutput): void {
|
|
707
|
-
out.emit(effect.loopBehavior === 'restart' ? effect.restartEvent : effect.loopEvent);
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
private _syncEffectActivity(terminalDirection = 0): void {
|
|
711
|
-
for (let index = 0; index < this.runtimeEffects.length; index++) {
|
|
712
|
-
const effect = this.runtimeEffects[index]!;
|
|
713
|
-
const active = effect.fullSpan && this._loop === 'ping-pong'
|
|
714
|
-
? terminalDirection === 0
|
|
715
|
-
: effectActiveAt(effect, this._time, this.clip.duration);
|
|
716
|
-
this._effectActive[index] = active ? 1 : 0;
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
private _queueActiveExits(): void {
|
|
721
|
-
for (let index = 0; index < this._effectActive.length; index++) {
|
|
722
|
-
if (this._effectActive[index] === 0) continue;
|
|
723
|
-
this._pendingEffects.push(this.runtimeEffects[index]!.exitEvent);
|
|
724
|
-
this._effectActive[index] = 0;
|
|
725
|
-
}
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
private _scheduleFade(from: number, to: number, duration: number): void {
|
|
729
|
-
this._fadeFrom = from;
|
|
730
|
-
this._fadeTo = to;
|
|
731
|
-
this._fadeStart = this._owner.time;
|
|
732
|
-
this._fadeEnd = this._fadeStart + duration;
|
|
733
|
-
if (duration === 0) {
|
|
734
|
-
this._weight = to;
|
|
735
|
-
this._fadeValue = to;
|
|
736
|
-
this._fadeActive = false;
|
|
737
|
-
} else {
|
|
738
|
-
this._fadeValue = from;
|
|
739
|
-
this._fadeActive = true;
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
private _fadeFactor(time: number): number {
|
|
744
|
-
if (!this._fadeActive) return this._fadeValue;
|
|
745
|
-
if (time <= this._fadeStart) return this._fadeFrom;
|
|
746
|
-
if (time >= this._fadeEnd) return this._fadeTo;
|
|
747
|
-
const alpha = (time - this._fadeStart) / (this._fadeEnd - this._fadeStart);
|
|
748
|
-
return this._fadeFrom + (this._fadeTo - this._fadeFrom) * alpha;
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
private _finishFade(time: number): void {
|
|
752
|
-
if (!this._fadeActive || time < this._fadeEnd) return;
|
|
753
|
-
this._weight = this._fadeTo;
|
|
754
|
-
this._fadeValue = this._fadeTo;
|
|
755
|
-
this._fadeActive = false;
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
private _assertSibling(action: Animation2DActionRuntime): void {
|
|
759
|
-
this._assertValid();
|
|
760
|
-
if (action._owner !== this._owner || !action._valid) {
|
|
761
|
-
throw new RangeError('Animation2D cross-fade actions must belong to the same active mixer.');
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
private _clampSynchronizedTime(timeSeconds: number): number {
|
|
766
|
-
const next = finiteNumber(timeSeconds, 'Animation2DAction synchronized time');
|
|
767
|
-
if (this._loop === 'once') return Math.min(this.clip.duration, Math.max(0, next));
|
|
768
|
-
if (this._repetitions === Infinity) return next;
|
|
769
|
-
return Math.min(this.clip.duration * this._repetitions, Math.max(0, next));
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
private _terminalDirection(time: number): number {
|
|
773
|
-
if (this._loop === 'once') {
|
|
774
|
-
if (time === this.clip.duration && this._rawTime < time) return 1;
|
|
775
|
-
if (time === 0 && this._rawTime > time) return -1;
|
|
776
|
-
return 0;
|
|
777
|
-
}
|
|
778
|
-
if (this._repetitions === Infinity) return 0;
|
|
779
|
-
const totalDuration = this.clip.duration * this._repetitions;
|
|
780
|
-
if (time === totalDuration && this._rawTime < time) return 1;
|
|
781
|
-
if (time === 0 && this._rawTime > time) return -1;
|
|
782
|
-
return 0;
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
private _resetSamplerCursors(): void {
|
|
786
|
-
for (let index = 0; index < this.runtimeTracks.length; index++) {
|
|
787
|
-
this.runtimeTracks[index]!.sampler.resetCursor();
|
|
788
|
-
}
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
private _assertValid(): void {
|
|
792
|
-
this._owner.assertActive();
|
|
793
|
-
if (!this._valid) throw new Error(`Animation2D action "${this.id}" is no longer valid.`);
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
function effectEvent(
|
|
798
|
-
actionId: string,
|
|
799
|
-
clipId: string,
|
|
800
|
-
cue: Animation2DEffectCue,
|
|
801
|
-
lifecycle: Animation2DEffectLifecycle,
|
|
802
|
-
): Animation2DEffectEvent {
|
|
803
|
-
return { actionId, clipId, cue, lifecycle };
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
function effectActiveAt(effect: RuntimeEffect, time: number, duration: number): boolean {
|
|
807
|
-
if (effect.fullSpan) return time >= 0 && time < duration;
|
|
808
|
-
return time >= effect.start && time < effect.end;
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
function samplePingPongTime(rawTime: number, duration: number): number {
|
|
812
|
-
if (duration <= 0) return 0;
|
|
813
|
-
const traversal = Math.floor(rawTime / duration);
|
|
814
|
-
let phase = rawTime - traversal * duration;
|
|
815
|
-
if (phase < 0) phase += duration;
|
|
816
|
-
return isEven(traversal) ? phase : duration - phase;
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
function validateClip(clip: Animation2DClip): void {
|
|
820
|
-
if (clip.format !== 'haiyue-animation2d-clip@1') {
|
|
821
|
-
throw new RangeError(`Unsupported Animation2D clip format "${String(clip.format)}".`);
|
|
822
|
-
}
|
|
823
|
-
if (!clip.id) throw new RangeError('Animation2D clip id must not be empty.');
|
|
824
|
-
if (!Number.isFinite(clip.duration) || clip.duration < 0) {
|
|
825
|
-
throw new RangeError(`Animation2D clip duration must be finite and non-negative; received ${clip.duration}.`);
|
|
826
|
-
}
|
|
827
|
-
for (let index = 0; index < clip.tracks.length; index++) {
|
|
828
|
-
const track = clip.tracks[index]!;
|
|
829
|
-
const first = track.times[0];
|
|
830
|
-
const last = track.times[track.times.length - 1];
|
|
831
|
-
if (first !== undefined && (first < 0 || last! > clip.duration)) {
|
|
832
|
-
throw new RangeError(`Animation2D track "${track.id}" keys must lie within its clip.`);
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
function validateEffect(
|
|
838
|
-
cue: Animation2DEffectCue,
|
|
839
|
-
start: number,
|
|
840
|
-
end: number,
|
|
841
|
-
duration: number,
|
|
842
|
-
): void {
|
|
843
|
-
if (!cue.id) throw new RangeError('Animation2D effect cue id must not be empty.');
|
|
844
|
-
if (!Number.isFinite(start) || !Number.isFinite(end)
|
|
845
|
-
|| start < 0 || end < start || end > duration) {
|
|
846
|
-
throw new RangeError(`Animation2D effect "${cue.id}" interval must lie within its clip.`);
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
|
|
850
|
-
function validateRepetitions(value: number): number {
|
|
851
|
-
if (value === Infinity) return value;
|
|
852
|
-
if (!Number.isInteger(value) || value <= 0) {
|
|
853
|
-
throw new RangeError(`Animation2D repetitions must be a positive integer or Infinity; received ${value}.`);
|
|
854
|
-
}
|
|
855
|
-
return value;
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
function finiteNumber(value: number, property: string): number {
|
|
859
|
-
if (!Number.isFinite(value)) throw new RangeError(`${property} must be finite; received ${value}.`);
|
|
860
|
-
return value;
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
function nonNegativeNumber(value: number, property: string): number {
|
|
864
|
-
const result = finiteNumber(value, property);
|
|
865
|
-
if (result < 0) throw new RangeError(`${property} must be non-negative; received ${value}.`);
|
|
866
|
-
return result;
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
function integerNumber(value: number, property: string): number {
|
|
870
|
-
if (!Number.isInteger(value)) throw new RangeError(`${property} must be an integer; received ${value}.`);
|
|
871
|
-
return value;
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
function isEven(value: number): boolean {
|
|
875
|
-
return Math.abs(value % 2) === 0;
|
|
876
|
-
}
|