@haiyue/extensions 0.1.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/LICENSE +21 -0
- package/README.md +30 -0
- package/dist/animation/Animation2DComponent.d.ts +46 -0
- package/dist/animation/Animation2DExtensionRegistry.d.ts +27 -0
- package/dist/animation/Animation2DRenderSystem.d.ts +89 -0
- package/dist/animation/Animation2DRuntime.d.ts +99 -0
- package/dist/animation/Animation2DStateMachine.d.ts +13 -0
- package/dist/animation/Animation2DStateMachineComponent.d.ts +54 -0
- package/dist/animation/Animation2DStateMachineRuntime.d.ts +30 -0
- package/dist/animation/Animation2DStateMachineSystem.d.ts +14 -0
- package/dist/animation/Animation2DStateMachineVisualRuntime.d.ts +27 -0
- package/dist/animation/Animation2DSystem.d.ts +14 -0
- package/dist/animation/AnimationAssetLoader.d.ts +9 -0
- package/dist/animation/AnimationAudioClip.d.ts +26 -0
- package/dist/animation/AnimationPathTessellator.d.ts +52 -0
- package/dist/animation/AnimationTextRasterizer.d.ts +21 -0
- package/dist/animation/AnimationVisual2D.d.ts +68 -0
- package/dist/animation/HyaAnimation2DClipAdapter.d.ts +16 -0
- package/dist/animation/Particle2DDescriptorAdapter.d.ts +5 -0
- package/dist/animation/runtime/mixer/Action.d.ts +150 -0
- package/dist/animation/runtime/mixer/Mixer.d.ts +54 -0
- package/dist/animation/runtime/mixer/PoseBuffer.d.ts +23 -0
- package/dist/animation/runtime/mixer/Sampler.d.ts +17 -0
- package/dist/animation/runtime/mixer/Types.d.ts +101 -0
- package/dist/animation/runtime/mixer/index.d.ts +6 -0
- package/dist/animation-state-machine/AnimationStateMachine.d.ts +111 -0
- package/dist/animation-state-machine/AnimationStateMachineChannels.d.ts +23 -0
- package/dist/animation-state-machine/runtime/Animation2DStateMachineMixerAdapter.d.ts +51 -0
- package/dist/animation-state-machine/runtime/AnimationStateMachineBlendTreeWeights.d.ts +14 -0
- package/dist/animation-state-machine/runtime/AnimationStateMachineCompiler.d.ts +109 -0
- package/dist/animation-state-machine/runtime/AnimationStateMachineController.d.ts +103 -0
- package/dist/animation-state-machine/runtime/AnimationStateMachineMixerPort.d.ts +35 -0
- package/dist/animation-state-machine/runtime/index.d.ts +7 -0
- package/dist/animation.d.ts +15 -0
- package/dist/animation.js +1171 -0
- package/dist/animation3d/Animation3DAction.d.ts +46 -0
- package/dist/animation3d/Animation3DBinding.d.ts +85 -0
- package/dist/animation3d/Animation3DClip.d.ts +20 -0
- package/dist/animation3d/Animation3DError.d.ts +13 -0
- package/dist/animation3d/Animation3DMixer.d.ts +27 -0
- package/dist/animation3d/Animation3DPose.d.ts +40 -0
- package/dist/animation3d/Animation3DPoseBuffer.d.ts +24 -0
- package/dist/animation3d/Animation3DResource.d.ts +28 -0
- package/dist/animation3d/Animation3DStateMachine.d.ts +95 -0
- package/dist/animation3d/Animation3DStateMachineRuntime.d.ts +70 -0
- package/dist/animation3d/Animation3DTrack.d.ts +19 -0
- package/dist/animation3d/hya/HyaAnimation3DRuntime.d.ts +73 -0
- package/dist/animation3d/hya/HyaAnimation3DStateMachineRuntime.d.ts +65 -0
- package/dist/animation3d/hya/HyaAnimation3DTypes.d.ts +170 -0
- package/dist/animation3d/hya/index.d.ts +4 -0
- package/dist/animation3d/index.d.ts +14 -0
- package/dist/animation3d/runtime/integration/Animation3DStateMachineMixerAdapter.d.ts +81 -0
- package/dist/animation3d/runtime/integration/Animation3DStateMachineMixerIntegration.d.ts +39 -0
- package/dist/animation3d/runtime/integration/index.d.ts +2 -0
- package/dist/animation3d/runtime/mixer/Action.d.ts +150 -0
- package/dist/animation3d/runtime/mixer/Animation3DMixerRuntimeStore.d.ts +6 -0
- package/dist/animation3d/runtime/mixer/Mixer.d.ts +59 -0
- package/dist/animation3d/runtime/mixer/PoseBuffer.d.ts +1 -0
- package/dist/animation3d/runtime/mixer/TrackSampler.d.ts +24 -0
- package/dist/animation3d/runtime/mixer/index.d.ts +4 -0
- package/dist/animation3d/runtime/state-machine/Animation3DBlendTreeWeights.d.ts +1 -0
- package/dist/animation3d/runtime/state-machine/Animation3DStateMachineCompiler.d.ts +1 -0
- package/dist/animation3d/runtime/state-machine/Animation3DStateMachineController.d.ts +1 -0
- package/dist/animation3d/runtime/state-machine/Animation3DStateMachineMixerPort.d.ts +1 -0
- package/dist/animation3d/runtime/state-machine/index.d.ts +6 -0
- package/dist/animation3d.d.ts +5 -0
- package/dist/animation3d.js +1708 -0
- package/dist/benchmark.d.ts +30 -0
- package/dist/benchmark.js +119 -0
- package/dist/canvas-text/CanvasText2DRenderSystem.d.ts +24 -0
- package/dist/canvas-text/CanvasTextComponent.d.ts +18 -0
- package/dist/canvas-text.d.ts +4 -0
- package/dist/canvas-text.js +276 -0
- package/dist/chunks/2d-ui-animation-2d.generated-D4aHzFU2.js +4 -0
- package/dist/chunks/2d-ui-canvas-text-2d.generated-C0Eaej2m.js +4 -0
- package/dist/chunks/2d-ui-spine2d.generated-CUUi8xjl.js +4 -0
- package/dist/chunks/2d-ui-tilemap2d.generated-gebw4mX7.js +4 -0
- package/dist/chunks/Animation2DStateMachine-9IonguNa.js +3245 -0
- package/dist/chunks/AnimationStateMachineController-BIcAh-sT.js +1438 -0
- package/dist/chunks/GltfAnimation3DAdapter-Cu3rQQsW.js +2240 -0
- package/dist/chunks/GltfAnimationRuntime-CRHsLycN.js +631 -0
- package/dist/chunks/RenderSystem2DBase-DDT61dAu.js +227 -0
- package/dist/chunks/Spine2DRuntime-D9M9LAQR.js +3056 -0
- package/dist/chunks/SpineAssetParser-BSDmPge1.js +378 -0
- package/dist/chunks/gltfLoader-Dm22jLYB.js +2085 -0
- package/dist/chunks/pluginUtils-CvwroRMd.js +33 -0
- package/dist/experimental-gltf-worker.d.ts +4 -0
- package/dist/experimental-gltf-worker.js +138 -0
- package/dist/experimental-spine-worker.d.ts +4 -0
- package/dist/experimental-spine-worker.js +110 -0
- package/dist/gltf/GltfAccessorReader.d.ts +7 -0
- package/dist/gltf/GltfAnimation3DAdapter.d.ts +47 -0
- package/dist/gltf/GltfAnimationRuntime.d.ts +10 -0
- package/dist/gltf/GltfAssetWorkerClient.d.ts +20 -0
- package/dist/gltf/GltfCompatibilityReport.d.ts +70 -0
- package/dist/gltf/GltfConservativeBounds.d.ts +18 -0
- package/dist/gltf/GltfDracoDecoder.d.ts +4 -0
- package/dist/gltf/GltfExtensionAdapter.d.ts +54 -0
- package/dist/gltf/GltfLoaderContract.d.ts +249 -0
- package/dist/gltf/GltfLoaderErrors.d.ts +4 -0
- package/dist/gltf/GltfMaterialDescriptor.d.ts +23 -0
- package/dist/gltf/GltfMaterialEncoder.d.ts +20 -0
- package/dist/gltf/GltfMaterialLoader.d.ts +6 -0
- package/dist/gltf/GltfModelComponent.d.ts +72 -0
- package/dist/gltf/GltfModelSystem.d.ts +37 -0
- package/dist/gltf/GltfPlugin.d.ts +6 -0
- package/dist/gltf/GltfSchema.d.ts +225 -0
- package/dist/gltf/GltfUvSemanticPlanner.d.ts +33 -0
- package/dist/gltf/gltfLoader.d.ts +9 -0
- package/dist/gltf-animation3d.d.ts +3 -0
- package/dist/gltf-animation3d.js +8 -0
- package/dist/gltf-worker-runtime.d.ts +7 -0
- package/dist/gltf-worker-runtime.js +6981 -0
- package/dist/gltf.d.ts +12 -0
- package/dist/gltf.js +517 -0
- package/dist/grid/Grid2DComponent.d.ts +25 -0
- package/dist/grid.d.ts +2 -0
- package/dist/grid.js +56 -0
- package/dist/hya-state-machine.d.ts +7 -0
- package/dist/hya-state-machine.js +2934 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +7 -0
- package/dist/internal/2d-ui-shader-artifact.js +870 -0
- package/dist/plugins/pluginUtils.d.ts +20 -0
- package/dist/plugins.d.ts +6 -0
- package/dist/shaders/generated/2d-ui-artifact.generated.d.ts +658 -0
- package/dist/spine/Spine2DComponent.d.ts +116 -0
- package/dist/spine/Spine2DGpuRenderer.d.ts +65 -0
- package/dist/spine/Spine2DRenderSystem.d.ts +27 -0
- package/dist/spine/Spine2DRuntime.d.ts +103 -0
- package/dist/spine/SpineAnimationBoneTimelines.d.ts +8 -0
- package/dist/spine/SpineAssetParser.d.ts +18 -0
- package/dist/spine/SpineAssetWorkerClient.d.ts +19 -0
- package/dist/spine/SpineAssetWorkerContract.d.ts +6 -0
- package/dist/spine/SpineAtlasParser.d.ts +21 -0
- package/dist/spine/SpineFloatBuilder.d.ts +15 -0
- package/dist/spine/SpinePathConstraintSolver.d.ts +32 -0
- package/dist/spine/SpinePlugin.d.ts +8 -0
- package/dist/spine/SpineSkeletonRuntime.d.ts +185 -0
- package/dist/spine/SpineSlotAnimation.d.ts +17 -0
- package/dist/spine/SpineTimelineRuntime.d.ts +25 -0
- package/dist/spine/SpineVertexBuilder.d.ts +61 -0
- package/dist/spine.d.ts +7 -0
- package/dist/spine.js +578 -0
- package/dist/tilemap/Tilemap2DComponent.d.ts +110 -0
- package/dist/tilemap/Tilemap2DRenderSystem.d.ts +11 -0
- package/dist/tilemap/Tilemap2DRenderer.d.ts +24 -0
- package/dist/tilemap/TilemapPlugin.d.ts +8 -0
- package/dist/tilemap.d.ts +6 -0
- package/dist/tilemap.js +535 -0
- package/dist/tween/Tween2DComponent.d.ts +70 -0
- package/dist/tween/Tween2DSystem.d.ts +12 -0
- package/dist/tween.d.ts +4 -0
- package/dist/tween.js +138 -0
- package/dist/utils/RenderSystem2DBase.d.ts +42 -0
- package/dist/utils/arrayAccess.d.ts +4 -0
- package/dist/utils/camera2d.d.ts +12 -0
- package/dist/utils/render2dGpu.d.ts +32 -0
- package/package.json +124 -0
- package/src/animation/Animation2DComponent.ts +135 -0
- package/src/animation/Animation2DExtensionRegistry.ts +52 -0
- package/src/animation/Animation2DRenderSystem.ts +1026 -0
- package/src/animation/Animation2DRuntime.ts +1326 -0
- package/src/animation/Animation2DStateMachine.ts +39 -0
- package/src/animation/Animation2DStateMachineComponent.ts +228 -0
- package/src/animation/Animation2DStateMachineRuntime.ts +141 -0
- package/src/animation/Animation2DStateMachineSystem.ts +60 -0
- package/src/animation/Animation2DStateMachineVisualRuntime.ts +282 -0
- package/src/animation/Animation2DSystem.ts +72 -0
- package/src/animation/AnimationAssetLoader.ts +84 -0
- package/src/animation/AnimationAudioClip.ts +140 -0
- package/src/animation/AnimationPathTessellator.ts +691 -0
- package/src/animation/AnimationTextRasterizer.ts +340 -0
- package/src/animation/AnimationVisual2D.ts +153 -0
- package/src/animation/HyaAnimation2DClipAdapter.ts +845 -0
- package/src/animation/Particle2DDescriptorAdapter.ts +35 -0
- package/src/animation/runtime/mixer/Action.ts +876 -0
- package/src/animation/runtime/mixer/Mixer.ts +505 -0
- package/src/animation/runtime/mixer/PoseBuffer.ts +105 -0
- package/src/animation/runtime/mixer/Sampler.ts +252 -0
- package/src/animation/runtime/mixer/Types.ts +138 -0
- package/src/animation/runtime/mixer/index.ts +31 -0
- package/src/animation-state-machine/AnimationStateMachine.ts +146 -0
- package/src/animation-state-machine/AnimationStateMachineChannels.ts +116 -0
- package/src/animation-state-machine/runtime/Animation2DStateMachineMixerAdapter.ts +197 -0
- package/src/animation-state-machine/runtime/AnimationStateMachineBlendTreeWeights.ts +503 -0
- package/src/animation-state-machine/runtime/AnimationStateMachineCompiler.ts +763 -0
- package/src/animation-state-machine/runtime/AnimationStateMachineController.ts +987 -0
- package/src/animation-state-machine/runtime/AnimationStateMachineMixerPort.ts +54 -0
- package/src/animation-state-machine/runtime/index.ts +47 -0
- package/src/animation.ts +33 -0
- package/src/animation3d/Animation3DAction.ts +73 -0
- package/src/animation3d/Animation3DBinding.ts +116 -0
- package/src/animation3d/Animation3DClip.ts +22 -0
- package/src/animation3d/Animation3DError.ts +34 -0
- package/src/animation3d/Animation3DMixer.ts +82 -0
- package/src/animation3d/Animation3DPose.ts +100 -0
- package/src/animation3d/Animation3DPoseBuffer.ts +85 -0
- package/src/animation3d/Animation3DResource.ts +49 -0
- package/src/animation3d/Animation3DStateMachine.ts +126 -0
- package/src/animation3d/Animation3DStateMachineRuntime.ts +191 -0
- package/src/animation3d/Animation3DTrack.ts +29 -0
- package/src/animation3d/hya/HyaAnimation3DRuntime.ts +756 -0
- package/src/animation3d/hya/HyaAnimation3DStateMachineRuntime.ts +618 -0
- package/src/animation3d/hya/HyaAnimation3DTypes.ts +168 -0
- package/src/animation3d/hya/index.ts +10 -0
- package/src/animation3d/index.ts +76 -0
- package/src/animation3d/runtime/integration/Animation3DStateMachineMixerAdapter.ts +325 -0
- package/src/animation3d/runtime/integration/Animation3DStateMachineMixerIntegration.ts +158 -0
- package/src/animation3d/runtime/integration/index.ts +9 -0
- package/src/animation3d/runtime/mixer/Action.ts +833 -0
- package/src/animation3d/runtime/mixer/Animation3DMixerRuntimeStore.ts +26 -0
- package/src/animation3d/runtime/mixer/Mixer.ts +562 -0
- package/src/animation3d/runtime/mixer/PoseBuffer.ts +1 -0
- package/src/animation3d/runtime/mixer/TrackSampler.ts +399 -0
- package/src/animation3d/runtime/mixer/index.ts +8 -0
- package/src/animation3d/runtime/state-machine/Animation3DBlendTreeWeights.ts +4 -0
- package/src/animation3d/runtime/state-machine/Animation3DStateMachineCompiler.ts +1 -0
- package/src/animation3d/runtime/state-machine/Animation3DStateMachineController.ts +1 -0
- package/src/animation3d/runtime/state-machine/Animation3DStateMachineMixerPort.ts +1 -0
- package/src/animation3d/runtime/state-machine/index.ts +45 -0
- package/src/animation3d.ts +5 -0
- package/src/benchmark.ts +168 -0
- package/src/canvas-text/CanvasText2DRenderSystem.ts +292 -0
- package/src/canvas-text/CanvasTextComponent.ts +47 -0
- package/src/canvas-text.ts +4 -0
- package/src/experimental-gltf-worker.ts +18 -0
- package/src/experimental-spine-worker.ts +9 -0
- package/src/gltf/GltfAccessorReader.ts +271 -0
- package/src/gltf/GltfAnimation3DAdapter.ts +680 -0
- package/src/gltf/GltfAnimationRuntime.ts +392 -0
- package/src/gltf/GltfAssetWorkerClient.ts +136 -0
- package/src/gltf/GltfCompatibilityReport.ts +214 -0
- package/src/gltf/GltfConservativeBounds.ts +219 -0
- package/src/gltf/GltfDracoDecoder.ts +251 -0
- package/src/gltf/GltfExtensionAdapter.ts +340 -0
- package/src/gltf/GltfLoaderContract.ts +333 -0
- package/src/gltf/GltfLoaderErrors.ts +59 -0
- package/src/gltf/GltfMaterialDescriptor.ts +134 -0
- package/src/gltf/GltfMaterialEncoder.ts +173 -0
- package/src/gltf/GltfMaterialLoader.ts +293 -0
- package/src/gltf/GltfModelComponent.ts +115 -0
- package/src/gltf/GltfModelSystem.ts +208 -0
- package/src/gltf/GltfPlugin.ts +84 -0
- package/src/gltf/GltfSchema.ts +229 -0
- package/src/gltf/GltfUvSemanticPlanner.ts +166 -0
- package/src/gltf/gltfLoader.ts +910 -0
- package/src/gltf-animation3d.ts +10 -0
- package/src/gltf-worker-runtime.ts +10 -0
- package/src/gltf.ts +56 -0
- package/src/grid/Grid2DComponent.ts +69 -0
- package/src/grid.ts +2 -0
- package/src/hya-state-machine.ts +19 -0
- package/src/index.ts +2 -0
- package/src/plugins/pluginUtils.ts +50 -0
- package/src/plugins.ts +6 -0
- package/src/shaders/generated/2d-ui-animation-2d.generated.wgsl +242 -0
- package/src/shaders/generated/2d-ui-artifact.generated.ts +867 -0
- package/src/shaders/generated/2d-ui-canvas-text-2d.generated.wgsl +38 -0
- package/src/shaders/generated/2d-ui-spine2d.generated.wgsl +41 -0
- package/src/shaders/generated/2d-ui-tilemap2d.generated.wgsl +36 -0
- package/src/spine/Spine2DComponent.ts +168 -0
- package/src/spine/Spine2DGpuRenderer.ts +449 -0
- package/src/spine/Spine2DRenderSystem.ts +199 -0
- package/src/spine/Spine2DRuntime.ts +1529 -0
- package/src/spine/SpineAnimationBoneTimelines.ts +30 -0
- package/src/spine/SpineAssetParser.ts +20 -0
- package/src/spine/SpineAssetWorkerClient.ts +112 -0
- package/src/spine/SpineAssetWorkerContract.ts +4 -0
- package/src/spine/SpineAtlasParser.ts +127 -0
- package/src/spine/SpineFloatBuilder.ts +66 -0
- package/src/spine/SpinePathConstraintSolver.ts +582 -0
- package/src/spine/SpinePlugin.ts +76 -0
- package/src/spine/SpineSkeletonRuntime.ts +521 -0
- package/src/spine/SpineSlotAnimation.ts +195 -0
- package/src/spine/SpineTimelineRuntime.ts +453 -0
- package/src/spine/SpineVertexBuilder.ts +686 -0
- package/src/spine.ts +7 -0
- package/src/tilemap/Tilemap2DComponent.ts +232 -0
- package/src/tilemap/Tilemap2DRenderSystem.ts +58 -0
- package/src/tilemap/Tilemap2DRenderer.ts +289 -0
- package/src/tilemap/TilemapPlugin.ts +75 -0
- package/src/tilemap.ts +6 -0
- package/src/tween/Tween2DComponent.ts +83 -0
- package/src/tween/Tween2DSystem.ts +78 -0
- package/src/tween.ts +4 -0
- package/src/types/earcut.d.ts +7 -0
- package/src/types/wgsl.d.ts +4 -0
- package/src/utils/RenderSystem2DBase.ts +164 -0
- package/src/utils/arrayAccess.ts +17 -0
- package/src/utils/camera2d.ts +68 -0
- package/src/utils/render2dGpu.ts +132 -0
- package/test/fixtures/gltf/animation-characterization.gltf +344 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Component } from '@haiyue/engine';
|
|
2
|
+
import { Easing, type EasingFunction } from '@haiyue/engine/tween';
|
|
3
|
+
export type Tween2DEasingName = keyof typeof Easing;
|
|
4
|
+
export interface Tween2DProperties {
|
|
5
|
+
x?: number;
|
|
6
|
+
y?: number;
|
|
7
|
+
rotation?: number;
|
|
8
|
+
scaleX?: number;
|
|
9
|
+
scaleY?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface Tween2DComponentOptions {
|
|
12
|
+
from?: Tween2DProperties;
|
|
13
|
+
to?: Tween2DProperties;
|
|
14
|
+
duration?: number;
|
|
15
|
+
delay?: number;
|
|
16
|
+
easing?: Tween2DEasingName | EasingFunction | string;
|
|
17
|
+
removeOnComplete?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare class Tween2DComponent extends Component {
|
|
20
|
+
static UniqueCheckType: number;
|
|
21
|
+
static UniqueSymbol: symbol;
|
|
22
|
+
static editor: {
|
|
23
|
+
fields: {
|
|
24
|
+
from: {
|
|
25
|
+
type: string;
|
|
26
|
+
label: string;
|
|
27
|
+
rows: number;
|
|
28
|
+
};
|
|
29
|
+
to: {
|
|
30
|
+
type: string;
|
|
31
|
+
label: string;
|
|
32
|
+
rows: number;
|
|
33
|
+
};
|
|
34
|
+
duration: {
|
|
35
|
+
type: string;
|
|
36
|
+
label: string;
|
|
37
|
+
min: number;
|
|
38
|
+
step: number;
|
|
39
|
+
};
|
|
40
|
+
delay: {
|
|
41
|
+
type: string;
|
|
42
|
+
label: string;
|
|
43
|
+
min: number;
|
|
44
|
+
step: number;
|
|
45
|
+
};
|
|
46
|
+
easing: {
|
|
47
|
+
type: string;
|
|
48
|
+
label: string;
|
|
49
|
+
};
|
|
50
|
+
removeOnComplete: {
|
|
51
|
+
type: string;
|
|
52
|
+
label: string;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
from: Tween2DProperties | null;
|
|
57
|
+
to: Tween2DProperties;
|
|
58
|
+
duration: number;
|
|
59
|
+
delay: number;
|
|
60
|
+
easing: Tween2DEasingName | EasingFunction | string;
|
|
61
|
+
removeOnComplete: boolean;
|
|
62
|
+
elapsed: number;
|
|
63
|
+
started: boolean;
|
|
64
|
+
completed: boolean;
|
|
65
|
+
private _resolvedFrom;
|
|
66
|
+
constructor(options?: Tween2DComponentOptions);
|
|
67
|
+
resolveFrom(current: Tween2DProperties): Tween2DProperties;
|
|
68
|
+
getEasingFunction(): EasingFunction;
|
|
69
|
+
clone(): Tween2DComponent;
|
|
70
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { System, type World } from '@haiyue/engine';
|
|
2
|
+
export interface Tween2DSystemOptions {
|
|
3
|
+
priority?: number;
|
|
4
|
+
}
|
|
5
|
+
export declare class Tween2DSystem extends System {
|
|
6
|
+
private readonly completedEntities;
|
|
7
|
+
private readonly transformScratch;
|
|
8
|
+
constructor(options?: Tween2DSystemOptions);
|
|
9
|
+
update(world: World, _time: number, delta: number): this;
|
|
10
|
+
private updateEntity;
|
|
11
|
+
private apply;
|
|
12
|
+
}
|
package/dist/tween.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { Tween2DComponent } from './tween/Tween2DComponent';
|
|
2
|
+
export type { Tween2DComponentOptions, Tween2DEasingName, Tween2DProperties } from './tween/Tween2DComponent';
|
|
3
|
+
export { Tween2DSystem } from './tween/Tween2DSystem';
|
|
4
|
+
export type { Tween2DSystemOptions } from './tween/Tween2DSystem';
|
package/dist/tween.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { Component, System, Transform2D } from '@haiyue/engine';
|
|
2
|
+
import { UniqueCheckType } from '@haiyue/engine/ecs';
|
|
3
|
+
import { Easing } from '@haiyue/engine/tween';
|
|
4
|
+
|
|
5
|
+
class Tween2DComponent extends Component {
|
|
6
|
+
static UniqueCheckType = UniqueCheckType.SYMBOL | UniqueCheckType.REPLACE;
|
|
7
|
+
static UniqueSymbol = Symbol.for('Tween2DComponent');
|
|
8
|
+
static editor = {
|
|
9
|
+
fields: {
|
|
10
|
+
from: { type: 'json', label: 'From JSON', rows: 4 },
|
|
11
|
+
to: { type: 'json', label: 'To JSON', rows: 4 },
|
|
12
|
+
duration: { type: 'number', label: 'Duration ms', min: 0, step: 16 },
|
|
13
|
+
delay: { type: 'number', label: 'Delay ms', min: 0, step: 16 },
|
|
14
|
+
easing: { type: 'text', label: 'Easing' },
|
|
15
|
+
removeOnComplete: { type: 'boolean', label: 'Remove On Complete' },
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
from;
|
|
19
|
+
to;
|
|
20
|
+
duration;
|
|
21
|
+
delay;
|
|
22
|
+
easing;
|
|
23
|
+
removeOnComplete;
|
|
24
|
+
elapsed = 0;
|
|
25
|
+
started = false;
|
|
26
|
+
completed = false;
|
|
27
|
+
_resolvedFrom = {};
|
|
28
|
+
constructor(options = {}) {
|
|
29
|
+
super('Tween2DComponent');
|
|
30
|
+
this.from = options.from ? { ...options.from } : null;
|
|
31
|
+
this.to = { ...(options.to ?? {}) };
|
|
32
|
+
this.duration = Math.max(0, options.duration ?? 160);
|
|
33
|
+
this.delay = Math.max(0, options.delay ?? 0);
|
|
34
|
+
this.easing = options.easing ?? 'cubicOut';
|
|
35
|
+
this.removeOnComplete = options.removeOnComplete ?? true;
|
|
36
|
+
}
|
|
37
|
+
resolveFrom(current) {
|
|
38
|
+
if (this.started)
|
|
39
|
+
return this._resolvedFrom;
|
|
40
|
+
this._resolvedFrom = {};
|
|
41
|
+
for (const key of Object.keys(this.to)) {
|
|
42
|
+
this._resolvedFrom[key] = this.from?.[key] ?? current[key] ?? 0;
|
|
43
|
+
}
|
|
44
|
+
return this._resolvedFrom;
|
|
45
|
+
}
|
|
46
|
+
getEasingFunction() {
|
|
47
|
+
if (typeof this.easing === 'function')
|
|
48
|
+
return this.easing;
|
|
49
|
+
return Easing[this.easing] ?? Easing.linear;
|
|
50
|
+
}
|
|
51
|
+
clone() {
|
|
52
|
+
return new Tween2DComponent({
|
|
53
|
+
...(this.from ? { from: { ...this.from } } : {}),
|
|
54
|
+
to: { ...this.to },
|
|
55
|
+
duration: this.duration,
|
|
56
|
+
delay: this.delay,
|
|
57
|
+
easing: this.easing,
|
|
58
|
+
removeOnComplete: this.removeOnComplete,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function lerp(from, to, t) {
|
|
64
|
+
return from + (to - from) * t;
|
|
65
|
+
}
|
|
66
|
+
function readTransform(transform, out) {
|
|
67
|
+
out.x = transform.x;
|
|
68
|
+
out.y = transform.y;
|
|
69
|
+
out.rotation = transform.rotation;
|
|
70
|
+
out.scaleX = transform.scaleX;
|
|
71
|
+
out.scaleY = transform.scaleY;
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
74
|
+
class Tween2DSystem extends System {
|
|
75
|
+
completedEntities = [];
|
|
76
|
+
transformScratch = { x: 0, y: 0, rotation: 0, scaleX: 1, scaleY: 1 };
|
|
77
|
+
constructor(options = {}) {
|
|
78
|
+
super({ all: [Tween2DComponent, Transform2D] });
|
|
79
|
+
this.name = 'Tween2DSystem';
|
|
80
|
+
if (options.priority !== undefined)
|
|
81
|
+
this.priority = options.priority;
|
|
82
|
+
}
|
|
83
|
+
update(world, _time, delta) {
|
|
84
|
+
if (this.disabled)
|
|
85
|
+
return this;
|
|
86
|
+
this.completedEntities.length = 0;
|
|
87
|
+
const entities = this.entitySet.get(world);
|
|
88
|
+
if (entities) {
|
|
89
|
+
for (const entity of entities)
|
|
90
|
+
this.updateEntity(entity, delta);
|
|
91
|
+
}
|
|
92
|
+
for (const entity of this.completedEntities) {
|
|
93
|
+
const tween = entity.getComponent(Tween2DComponent);
|
|
94
|
+
if (tween?.completed && tween.removeOnComplete)
|
|
95
|
+
entity.removeComponent(tween);
|
|
96
|
+
}
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
updateEntity(entity, delta) {
|
|
100
|
+
const tween = entity.getComponent(Tween2DComponent);
|
|
101
|
+
const transform = entity.getComponent(Transform2D);
|
|
102
|
+
if (!tween || !transform || tween.completed)
|
|
103
|
+
return;
|
|
104
|
+
tween.elapsed += delta;
|
|
105
|
+
if (tween.elapsed < tween.delay)
|
|
106
|
+
return;
|
|
107
|
+
const from = tween.resolveFrom(readTransform(transform, this.transformScratch));
|
|
108
|
+
if (!tween.started) {
|
|
109
|
+
tween.started = true;
|
|
110
|
+
this.apply(transform, from, 0);
|
|
111
|
+
}
|
|
112
|
+
const duration = Math.max(1, tween.duration);
|
|
113
|
+
const raw = Math.min((tween.elapsed - tween.delay) / duration, 1);
|
|
114
|
+
const progress = tween.getEasingFunction()(raw);
|
|
115
|
+
this.apply(transform, from, progress, tween.to);
|
|
116
|
+
if (raw >= 1) {
|
|
117
|
+
tween.completed = true;
|
|
118
|
+
this.apply(transform, from, 1, tween.to);
|
|
119
|
+
if (tween.removeOnComplete)
|
|
120
|
+
this.completedEntities.push(entity);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
apply(transform, from, progress, to = from) {
|
|
124
|
+
if (to.x !== undefined)
|
|
125
|
+
transform.x = lerp(from.x ?? transform.x, to.x, progress);
|
|
126
|
+
if (to.y !== undefined)
|
|
127
|
+
transform.y = lerp(from.y ?? transform.y, to.y, progress);
|
|
128
|
+
if (to.rotation !== undefined)
|
|
129
|
+
transform.rotation = lerp(from.rotation ?? transform.rotation, to.rotation, progress);
|
|
130
|
+
if (to.scaleX !== undefined)
|
|
131
|
+
transform.scaleX = lerp(from.scaleX ?? transform.scaleX, to.scaleX, progress);
|
|
132
|
+
if (to.scaleY !== undefined)
|
|
133
|
+
transform.scaleY = lerp(from.scaleY ?? transform.scaleY, to.scaleY, progress);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export { Tween2DComponent, Tween2DSystem };
|
|
138
|
+
//# sourceMappingURL=tween.js.map
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type EntityHierarchyDisabledCache, type FrameData, type IEngine, type RenderCommandContext } from '@haiyue/engine/extension-authoring';
|
|
2
|
+
import { Camera2D } from '@haiyue/engine/components';
|
|
3
|
+
import { Entity, System, type SystemQuery } from '@haiyue/engine/ecs';
|
|
4
|
+
import { type Object2DGpu } from './render2dGpu';
|
|
5
|
+
export interface RenderSystem2DBaseOptions {
|
|
6
|
+
loadOp?: 'clear' | 'load';
|
|
7
|
+
priority?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare abstract class RenderSystem2DBase extends System {
|
|
10
|
+
protected readonly engine: IEngine;
|
|
11
|
+
protected cameraEntity: Entity;
|
|
12
|
+
protected readonly disabledHierarchyCache: EntityHierarchyDisabledCache;
|
|
13
|
+
protected readonly liveEntityIds: Set<number>;
|
|
14
|
+
loadOp: 'clear' | 'load';
|
|
15
|
+
readonly recoveryLabel: string;
|
|
16
|
+
readonly recoverySource: {
|
|
17
|
+
kind: 'component-render-system';
|
|
18
|
+
system: string;
|
|
19
|
+
};
|
|
20
|
+
private readonly unregisterRecovery;
|
|
21
|
+
protected constructor(rule: SystemQuery, engine: IEngine, cameraEntity: Entity, options?: RenderSystem2DBaseOptions, name?: string);
|
|
22
|
+
setCameraEntity(cameraEntity: Entity): this;
|
|
23
|
+
protected getCamera2D(context?: RenderCommandContext): Camera2D | null;
|
|
24
|
+
protected getFrameData(context: RenderCommandContext): FrameData;
|
|
25
|
+
protected computeCameraViewProjection(camera: Camera2D, context?: RenderCommandContext): Float32Array;
|
|
26
|
+
protected writeCameraBuffer(queue: GPUQueue, buffer: GPUBuffer, context?: RenderCommandContext): boolean;
|
|
27
|
+
protected getWorldMatrix2D(entity: Entity, context: RenderCommandContext): Float32Array;
|
|
28
|
+
private getCameraEntity;
|
|
29
|
+
protected isEntityRenderable(entity: Entity): boolean;
|
|
30
|
+
protected beginLiveEntityTracking(): Set<number>;
|
|
31
|
+
protected markEntityLive(entity: Entity | number): void;
|
|
32
|
+
protected createObjectGpu(layout: GPUBindGroupLayout): Object2DGpu;
|
|
33
|
+
protected destroyObjectGpu(objectGpu: Object2DGpu): void;
|
|
34
|
+
protected getOrCreateEntityGpu<T>(cache: Map<number, T>, entity: Entity, create: () => T): T;
|
|
35
|
+
protected releaseEntityGpuEntriesNotIn<T>(cache: Map<number, T>, destroy: (gpu: T) => void, liveEntities?: ReadonlySet<number>): void;
|
|
36
|
+
protected destroyEntityGpuEntries<T>(cache: Map<number, T>, destroy: (gpu: T) => void): void;
|
|
37
|
+
suspendForDeviceLoss(): void;
|
|
38
|
+
recoverGpuResource(_device: GPUDevice, signal: AbortSignal): void;
|
|
39
|
+
destroy(): this;
|
|
40
|
+
protected abstract releaseGpuResourcesForRecovery(): void;
|
|
41
|
+
protected restoreGpuResourcesAfterRecovery(): void;
|
|
42
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Reads an element whose presence is an internal runtime invariant. */
|
|
2
|
+
export declare function requiredItemAt<T>(values: ArrayLike<T>, index: number, label: string): T;
|
|
3
|
+
/** Reads a number whose presence is an internal runtime invariant. */
|
|
4
|
+
export declare function requiredNumberAt(values: ArrayLike<number>, index: number, label: string): number;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Camera2D, Entity } from '@haiyue/engine';
|
|
2
|
+
import { type IEngine } from '@haiyue/engine/core';
|
|
3
|
+
export interface Camera2DScratch {
|
|
4
|
+
viewMatrix: Float32Array;
|
|
5
|
+
viewProjMatrix: Float32Array;
|
|
6
|
+
}
|
|
7
|
+
export declare function createCamera2DScratch(): Camera2DScratch;
|
|
8
|
+
export declare function compute2DViewProjection(engine: IEngine, cameraEntity: Entity, camera: Camera2D, scratch?: Camera2DScratch): Float32Array;
|
|
9
|
+
export declare function write2DCameraBuffer(queue: GPUQueue, buffer: GPUBuffer, viewProj: Float32Array): void;
|
|
10
|
+
export declare const IDENTITY_2D_WORLD_MATRIX: Float32Array;
|
|
11
|
+
export type WorldMatrix2DFrameCache = Map<Entity, Float32Array>;
|
|
12
|
+
export declare function get2DEntityWorldMatrix(entity: Entity, cache?: WorldMatrix2DFrameCache): Float32Array;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type ExtensionGPUResourceTracker } from '@haiyue/engine/extension-authoring';
|
|
2
|
+
export interface Camera2DGpu {
|
|
3
|
+
layout: GPUBindGroupLayout;
|
|
4
|
+
buffer: GPUBuffer;
|
|
5
|
+
tracker?: ExtensionGPUResourceTracker;
|
|
6
|
+
bindGroup: GPUBindGroup;
|
|
7
|
+
}
|
|
8
|
+
export interface Object2DGpu {
|
|
9
|
+
buffer: GPUBuffer;
|
|
10
|
+
bindGroup: GPUBindGroup;
|
|
11
|
+
snapshot: Float32Array;
|
|
12
|
+
tracker?: ExtensionGPUResourceTracker;
|
|
13
|
+
}
|
|
14
|
+
export interface Texture2DGpu {
|
|
15
|
+
layout: GPUBindGroupLayout;
|
|
16
|
+
sampler: GPUSampler;
|
|
17
|
+
fallbackTexture: GPUTexture;
|
|
18
|
+
fallbackBindGroup: GPUBindGroup;
|
|
19
|
+
tracker?: ExtensionGPUResourceTracker;
|
|
20
|
+
}
|
|
21
|
+
export declare function createCamera2DLayout(device: GPUDevice): GPUBindGroupLayout;
|
|
22
|
+
export declare function createCamera2DGpu(device: GPUDevice, tracker?: ExtensionGPUResourceTracker, layout?: GPUBindGroupLayout): Camera2DGpu;
|
|
23
|
+
export declare function createObject2DLayout(device: GPUDevice): GPUBindGroupLayout;
|
|
24
|
+
export declare function createObject2DGpu(device: GPUDevice, layout: GPUBindGroupLayout, tracker?: ExtensionGPUResourceTracker): Object2DGpu;
|
|
25
|
+
export declare function createTexture2DGpu(device: GPUDevice, fallbackAlpha?: number, tracker?: ExtensionGPUResourceTracker): Texture2DGpu;
|
|
26
|
+
export declare function writeFloatBuffer(queue: GPUQueue, buffer: GPUBuffer, data: Float32Array): void;
|
|
27
|
+
export declare function matrixEquals(a: Float32Array, b: Float32Array): boolean;
|
|
28
|
+
export declare function createMatrixSnapshot(): Float32Array;
|
|
29
|
+
export declare function writeObjectMatrixIfChanged(queue: GPUQueue, gpu: Object2DGpu, matrix: Float32Array): boolean;
|
|
30
|
+
export declare function destroyCamera2DGpu(gpu: Camera2DGpu): void;
|
|
31
|
+
export declare function destroyObject2DGpu(gpu: Object2DGpu): void;
|
|
32
|
+
export declare function destroyTexture2DGpu(gpu: Texture2DGpu): void;
|
package/package.json
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@haiyue/extensions",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "Stable optional HaiYue runtimes for 2D/3D animation, glTF, Spine, tilemaps, text, tweening, and grids.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/HaiyueStudio/Engine.git",
|
|
10
|
+
"directory": "extensions"
|
|
11
|
+
},
|
|
12
|
+
"type": "module",
|
|
13
|
+
"main": "dist/index.js",
|
|
14
|
+
"module": "dist/index.js",
|
|
15
|
+
"types": "dist/index.d.ts",
|
|
16
|
+
"sideEffects": false,
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=22"
|
|
19
|
+
},
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public",
|
|
22
|
+
"tag": "latest"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"README.md",
|
|
26
|
+
"LICENSE",
|
|
27
|
+
"dist/**/*.js",
|
|
28
|
+
"dist/**/*.d.ts",
|
|
29
|
+
"test/fixtures/gltf/animation-characterization.gltf",
|
|
30
|
+
"src/**/*"
|
|
31
|
+
],
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"source": "./src/index.ts",
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"import": "./dist/index.js"
|
|
37
|
+
},
|
|
38
|
+
"./gltf": {
|
|
39
|
+
"source": "./src/gltf.ts",
|
|
40
|
+
"types": "./dist/gltf.d.ts",
|
|
41
|
+
"import": "./dist/gltf.js"
|
|
42
|
+
},
|
|
43
|
+
"./experimental/gltf-worker": {
|
|
44
|
+
"source": "./src/experimental-gltf-worker.ts",
|
|
45
|
+
"types": "./dist/experimental-gltf-worker.d.ts",
|
|
46
|
+
"import": "./dist/experimental-gltf-worker.js"
|
|
47
|
+
},
|
|
48
|
+
"./experimental/spine-worker": {
|
|
49
|
+
"source": "./src/experimental-spine-worker.ts",
|
|
50
|
+
"types": "./dist/experimental-spine-worker.d.ts",
|
|
51
|
+
"import": "./dist/experimental-spine-worker.js"
|
|
52
|
+
},
|
|
53
|
+
"./spine": {
|
|
54
|
+
"source": "./src/spine.ts",
|
|
55
|
+
"types": "./dist/spine.d.ts",
|
|
56
|
+
"import": "./dist/spine.js"
|
|
57
|
+
},
|
|
58
|
+
"./tilemap": {
|
|
59
|
+
"source": "./src/tilemap.ts",
|
|
60
|
+
"types": "./dist/tilemap.d.ts",
|
|
61
|
+
"import": "./dist/tilemap.js"
|
|
62
|
+
},
|
|
63
|
+
"./canvas-text": {
|
|
64
|
+
"source": "./src/canvas-text.ts",
|
|
65
|
+
"types": "./dist/canvas-text.d.ts",
|
|
66
|
+
"import": "./dist/canvas-text.js"
|
|
67
|
+
},
|
|
68
|
+
"./tween": {
|
|
69
|
+
"source": "./src/tween.ts",
|
|
70
|
+
"types": "./dist/tween.d.ts",
|
|
71
|
+
"import": "./dist/tween.js"
|
|
72
|
+
},
|
|
73
|
+
"./grid": {
|
|
74
|
+
"source": "./src/grid.ts",
|
|
75
|
+
"types": "./dist/grid.d.ts",
|
|
76
|
+
"import": "./dist/grid.js"
|
|
77
|
+
},
|
|
78
|
+
"./animation": {
|
|
79
|
+
"source": "./src/animation.ts",
|
|
80
|
+
"types": "./dist/animation.d.ts",
|
|
81
|
+
"import": "./dist/animation.js"
|
|
82
|
+
},
|
|
83
|
+
"./hya-state-machine": {
|
|
84
|
+
"source": "./src/hya-state-machine.ts",
|
|
85
|
+
"types": "./dist/hya-state-machine.d.ts",
|
|
86
|
+
"import": "./dist/hya-state-machine.js"
|
|
87
|
+
},
|
|
88
|
+
"./animation3d": {
|
|
89
|
+
"source": "./src/animation3d.ts",
|
|
90
|
+
"types": "./dist/animation3d.d.ts",
|
|
91
|
+
"import": "./dist/animation3d.js"
|
|
92
|
+
},
|
|
93
|
+
"./gltf-animation3d": {
|
|
94
|
+
"source": "./src/gltf-animation3d.ts",
|
|
95
|
+
"types": "./dist/gltf-animation3d.d.ts",
|
|
96
|
+
"import": "./dist/gltf-animation3d.js"
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"scripts": {
|
|
100
|
+
"build": "node ../scripts/build-rollup-once.mjs && node ../scripts/build-rollup-once.mjs rollup.worker.config.js",
|
|
101
|
+
"build:animation-runtime-tests": "node -e \"require('node:fs').rmSync('dist-test', { recursive: true, force: true })\" && tsc -p tsconfig.animation-runtime-tests.json",
|
|
102
|
+
"test": "npm run build && npm run build:animation-runtime-tests && node --test --test-concurrency=1 \"test/**/*.test.mjs\"",
|
|
103
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.animation3d-type-tests.json && tsc -p tsconfig.animation-runtime-tests.json --noEmit"
|
|
104
|
+
},
|
|
105
|
+
"dependencies": {
|
|
106
|
+
"draco3dgltf": "^1.5.7",
|
|
107
|
+
"earcut": "^3.0.2",
|
|
108
|
+
"wgpu-matrix": "^3.0.0"
|
|
109
|
+
},
|
|
110
|
+
"peerDependencies": {
|
|
111
|
+
"@haiyue/animation-spec": ">=0.1.0 <0.2.0",
|
|
112
|
+
"@haiyue/engine": ">=0.1.0 <0.2.0"
|
|
113
|
+
},
|
|
114
|
+
"devDependencies": {
|
|
115
|
+
"@haiyue/animation-spec": "0.1.0",
|
|
116
|
+
"@haiyue/engine": "0.1.0",
|
|
117
|
+
"@rollup/plugin-node-resolve": "^15.0.0",
|
|
118
|
+
"@rollup/plugin-typescript": "^11.0.0",
|
|
119
|
+
"@webgpu/types": "^0.1.40",
|
|
120
|
+
"rollup": "^4.0.0",
|
|
121
|
+
"tslib": "^2.6.0",
|
|
122
|
+
"typescript": "^5.2.0"
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { AnimationSource, ParsedAnimation } from '@haiyue/animation-spec';
|
|
2
|
+
import { parseAnimation } from '@haiyue/animation-spec';
|
|
3
|
+
import { Component, type Entity, type World } from '@haiyue/engine';
|
|
4
|
+
import { ComponentLifecycleFlags, UniqueCheckType } from '@haiyue/engine/ecs';
|
|
5
|
+
import type { Animation2DRuntime } from './Animation2DRuntime';
|
|
6
|
+
import type { Animation2DExtensionRegistry } from './Animation2DExtensionRegistry';
|
|
7
|
+
|
|
8
|
+
export interface Animation2DComponentOptions {
|
|
9
|
+
autoplay?: boolean;
|
|
10
|
+
loop?: boolean;
|
|
11
|
+
speed?: number;
|
|
12
|
+
startTime?: number;
|
|
13
|
+
runtimeExtensions?: Animation2DExtensionRegistry;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface Animation2DRuntimeStats {
|
|
17
|
+
readonly nodeCount: number;
|
|
18
|
+
readonly visualCount: number;
|
|
19
|
+
readonly unsupportedComponentCount: number;
|
|
20
|
+
readonly pendingResourceCount: number;
|
|
21
|
+
readonly failedResourceCount: number;
|
|
22
|
+
readonly textCount: number;
|
|
23
|
+
readonly particleCount: number;
|
|
24
|
+
readonly audioCount: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class Animation2DComponent extends Component {
|
|
28
|
+
static override UniqueCheckType = UniqueCheckType.SYMBOL | UniqueCheckType.REPLACE;
|
|
29
|
+
static override UniqueSymbol = Symbol.for('Animation2DComponent');
|
|
30
|
+
static override Lifecycle = ComponentLifecycleFlags.EntityRemoveComponent | ComponentLifecycleFlags.EntityRemoveFromWorld;
|
|
31
|
+
|
|
32
|
+
readonly animation: ParsedAnimation;
|
|
33
|
+
playing: boolean;
|
|
34
|
+
loop: boolean;
|
|
35
|
+
speed: number;
|
|
36
|
+
currentTime: number;
|
|
37
|
+
completed = false;
|
|
38
|
+
readonly runtimeExtensions: Animation2DExtensionRegistry | undefined;
|
|
39
|
+
_runtime: Animation2DRuntime | null = null;
|
|
40
|
+
_needsApply = true;
|
|
41
|
+
_forceParticleSeek = false;
|
|
42
|
+
|
|
43
|
+
constructor(source: AnimationSource | ParsedAnimation, options: Animation2DComponentOptions = {}) {
|
|
44
|
+
super('Animation2DComponent');
|
|
45
|
+
this.animation = isParsed(source) ? source : parseAnimation(source);
|
|
46
|
+
this.playing = options.autoplay ?? true;
|
|
47
|
+
this.loop = options.loop ?? this.animation.endBehavior === 'loop';
|
|
48
|
+
this.speed = finiteSpeed(options.speed ?? 1);
|
|
49
|
+
this.currentTime = clampTime(options.startTime ?? 0, this.animation.duration);
|
|
50
|
+
this.runtimeExtensions = options.runtimeExtensions;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
get runtimeStats(): Animation2DRuntimeStats {
|
|
54
|
+
return this._runtime?.stats ?? {
|
|
55
|
+
nodeCount: 0,
|
|
56
|
+
visualCount: 0,
|
|
57
|
+
unsupportedComponentCount: 0,
|
|
58
|
+
pendingResourceCount: 0,
|
|
59
|
+
failedResourceCount: 0,
|
|
60
|
+
textCount: 0,
|
|
61
|
+
particleCount: 0,
|
|
62
|
+
audioCount: 0,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
play(): this {
|
|
67
|
+
if (this.completed) {
|
|
68
|
+
this.currentTime = 0;
|
|
69
|
+
this._needsApply = true;
|
|
70
|
+
this._forceParticleSeek = true;
|
|
71
|
+
}
|
|
72
|
+
this.playing = true;
|
|
73
|
+
this.completed = false;
|
|
74
|
+
this._runtime?.setPlaying(true);
|
|
75
|
+
return this;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
pause(): this {
|
|
79
|
+
this.playing = false;
|
|
80
|
+
this._runtime?.setPlaying(false);
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
seek(seconds: number): this {
|
|
85
|
+
this.currentTime = clampTime(seconds, this.animation.duration);
|
|
86
|
+
this.completed = false;
|
|
87
|
+
this._needsApply = true;
|
|
88
|
+
this._forceParticleSeek = true;
|
|
89
|
+
return this;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
setSpeed(speed: number): this {
|
|
93
|
+
this.speed = finiteSpeed(speed);
|
|
94
|
+
return this;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
onEntityRemoveComponent(_entity: Entity, component: Component): void {
|
|
98
|
+
if (component === this) this._disposeRuntime();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
onEntityRemoveFromWorld(_entity: Entity, _world: World): void {
|
|
102
|
+
this._disposeRuntime();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
override clone(): Animation2DComponent {
|
|
106
|
+
const clone = new Animation2DComponent(this.animation, {
|
|
107
|
+
autoplay: this.playing,
|
|
108
|
+
loop: this.loop,
|
|
109
|
+
speed: this.speed,
|
|
110
|
+
startTime: this.currentTime,
|
|
111
|
+
...(this.runtimeExtensions ? { runtimeExtensions: this.runtimeExtensions } : {}),
|
|
112
|
+
});
|
|
113
|
+
clone.disabled = this.disabled;
|
|
114
|
+
return clone;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
_disposeRuntime(): void {
|
|
118
|
+
this._runtime?.destroy();
|
|
119
|
+
this._runtime = null;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function isParsed(source: AnimationSource | ParsedAnimation): source is ParsedAnimation {
|
|
124
|
+
return typeof source === 'object' && source !== null && 'source' in source;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function finiteSpeed(value: number): number {
|
|
128
|
+
if (!Number.isFinite(value) || value < 0) throw new RangeError('Animation2DComponent speed must be finite and non-negative.');
|
|
129
|
+
return value;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function clampTime(value: number, duration: number): number {
|
|
133
|
+
if (!Number.isFinite(value)) throw new RangeError('Animation2DComponent time must be finite.');
|
|
134
|
+
return Math.max(0, Math.min(duration, value));
|
|
135
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AnimationComponent,
|
|
3
|
+
AnimationNode,
|
|
4
|
+
ParsedAnimation,
|
|
5
|
+
} from '@haiyue/animation-spec';
|
|
6
|
+
import type { Entity } from '@haiyue/engine';
|
|
7
|
+
|
|
8
|
+
export interface Animation2DExtensionContext {
|
|
9
|
+
readonly animation: ParsedAnimation;
|
|
10
|
+
readonly node: Readonly<AnimationNode>;
|
|
11
|
+
readonly component: Readonly<AnimationComponent>;
|
|
12
|
+
/** Anchor-adjusted parent for entities created by the extension. */
|
|
13
|
+
readonly parent: Entity;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface Animation2DExtensionInstance {
|
|
17
|
+
/** Deterministic composition-time update; implementations must tolerate seeks and loop wrap. */
|
|
18
|
+
apply?(timeSeconds: number, opacity: number): void;
|
|
19
|
+
setOpacity?(opacity: number): void;
|
|
20
|
+
destroy?(): void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface Animation2DExtensionHandler {
|
|
24
|
+
/** Component type or namespaced extension id implemented by this handler. */
|
|
25
|
+
readonly id: string;
|
|
26
|
+
create(context: Animation2DExtensionContext): Animation2DExtensionInstance | void;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Instance-owned registry; unregister tokens only remove the handler that created them. */
|
|
30
|
+
export class Animation2DExtensionRegistry {
|
|
31
|
+
private readonly _handlers = new Map<string, Animation2DExtensionHandler>();
|
|
32
|
+
|
|
33
|
+
register(handler: Animation2DExtensionHandler): () => void {
|
|
34
|
+
if (!handler.id.trim()) throw new TypeError('Animation runtime extension id must not be empty.');
|
|
35
|
+
if (this._handlers.has(handler.id)) throw new Error(`Animation runtime extension "${handler.id}" is already registered.`);
|
|
36
|
+
this._handlers.set(handler.id, handler);
|
|
37
|
+
let active = true;
|
|
38
|
+
return () => {
|
|
39
|
+
if (!active) return;
|
|
40
|
+
active = false;
|
|
41
|
+
if (this._handlers.get(handler.id) === handler) this._handlers.delete(handler.id);
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
get(id: string): Animation2DExtensionHandler | undefined {
|
|
46
|
+
return this._handlers.get(id);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
has(id: string): boolean {
|
|
50
|
+
return this._handlers.has(id);
|
|
51
|
+
}
|
|
52
|
+
}
|