@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,30 @@
|
|
|
1
|
+
import { Spine2DComponent } from './spine/Spine2DComponent';
|
|
2
|
+
import { type SpineRuntime } from './spine/Spine2DRuntime';
|
|
3
|
+
import { type SpineTimelineSamplerState } from './spine/SpineTimelineRuntime';
|
|
4
|
+
/** Internal benchmark adapter. This file is built for the monorepo harness, not exported by the package. */
|
|
5
|
+
export declare function benchmarkSpineParse(data: {
|
|
6
|
+
bones: Array<{
|
|
7
|
+
name: string;
|
|
8
|
+
parent?: string;
|
|
9
|
+
}>;
|
|
10
|
+
slots: Array<{
|
|
11
|
+
name: string;
|
|
12
|
+
bone?: string;
|
|
13
|
+
}>;
|
|
14
|
+
skins?: object;
|
|
15
|
+
}, atlas: string): number;
|
|
16
|
+
export interface SpineAnimationBenchmarkState {
|
|
17
|
+
readonly component: Spine2DComponent;
|
|
18
|
+
readonly runtime: SpineRuntime;
|
|
19
|
+
readonly boneCount: number;
|
|
20
|
+
readonly slotCount: number;
|
|
21
|
+
readonly keyframeCount: number;
|
|
22
|
+
}
|
|
23
|
+
export declare function createSpineAnimationBenchmarkState(boneCount: number, slotCount: number, keyframeCount: number): SpineAnimationBenchmarkState;
|
|
24
|
+
export declare function benchmarkSpineAnimationSample(state: SpineAnimationBenchmarkState): number;
|
|
25
|
+
export declare function benchmarkSpineVertexBuild(state: SpineAnimationBenchmarkState): number;
|
|
26
|
+
export declare function benchmarkCompileSpineTimeline(frames: unknown[]): number;
|
|
27
|
+
export declare function benchmarkCreateSpineTimelineSamplerState(): SpineTimelineSamplerState;
|
|
28
|
+
export declare function benchmarkSampleSpineTimeline(frames: unknown[], time: number, key: string, fallback: number, samplerState?: SpineTimelineSamplerState): number;
|
|
29
|
+
export declare function benchmarkFindSpineFrame(frames: unknown[], time: number, samplerState?: SpineTimelineSamplerState): number;
|
|
30
|
+
export declare function benchmarkSampleSpineColor(frames: unknown[], time: number, fallback: [number, number, number, number], out: [number, number, number, number]): [number, number, number, number];
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { n as normalizeSpineData, p as parseAtlas } from './chunks/SpineAssetParser-BSDmPge1.js';
|
|
2
|
+
import { c as compileSpineTimelines, a as createSpineTimelineSamplerState, f as findCompiledFrameIndex, s as sampleCompiledColor, b as sampleCompiledTimeline, d as advanceSpineRuntime, e as sampleSpinePosesForBenchmark, g as buildSpineVertices, S as Spine2DComponent, h as createSpineRuntimeForBenchmark } from './chunks/Spine2DRuntime-D9M9LAQR.js';
|
|
3
|
+
import '@haiyue/engine';
|
|
4
|
+
import '@haiyue/engine/core';
|
|
5
|
+
import '@haiyue/engine/ecs';
|
|
6
|
+
import '@haiyue/engine/experimental/async';
|
|
7
|
+
|
|
8
|
+
/** Internal benchmark adapter. This file is built for the monorepo harness, not exported by the package. */
|
|
9
|
+
function benchmarkSpineParse(data, atlas) {
|
|
10
|
+
return normalizeSpineData(data).bones.length + parseAtlas(atlas).size;
|
|
11
|
+
}
|
|
12
|
+
function createSpineAnimationBenchmarkState(boneCount, slotCount, keyframeCount) {
|
|
13
|
+
const animationDuration = 2;
|
|
14
|
+
const frameStep = animationDuration / Math.max(1, keyframeCount - 1);
|
|
15
|
+
const bones = Array.from({ length: boneCount }, (_, boneIndex) => ({
|
|
16
|
+
name: `bone${boneIndex}`,
|
|
17
|
+
...(boneIndex > 0 ? { parent: `bone${boneIndex - 1}` } : {}),
|
|
18
|
+
x: boneIndex > 0 ? 1 : 0,
|
|
19
|
+
length: 1,
|
|
20
|
+
}));
|
|
21
|
+
const slots = Array.from({ length: slotCount }, (_, slotIndex) => ({
|
|
22
|
+
name: `slot${slotIndex}`,
|
|
23
|
+
bone: `bone${slotIndex % boneCount}`,
|
|
24
|
+
attachment: `region${slotIndex}`,
|
|
25
|
+
}));
|
|
26
|
+
const skin = {};
|
|
27
|
+
const slotAnimations = {};
|
|
28
|
+
const atlas = new Map();
|
|
29
|
+
for (let slotIndex = 0; slotIndex < slotCount; slotIndex++) {
|
|
30
|
+
const regionName = `region${slotIndex}`;
|
|
31
|
+
skin[`slot${slotIndex}`] = {
|
|
32
|
+
[regionName]: { type: 'region', name: regionName, path: regionName, width: 8, height: 8 },
|
|
33
|
+
};
|
|
34
|
+
slotAnimations[`slot${slotIndex}`] = {
|
|
35
|
+
rgba: [
|
|
36
|
+
{ time: 0, color: 'ffffffff', curve: [0.25, 1, 0.75, 0.8, 0.25, 1, 0.75, 0.7, 0.25, 1, 0.75, 0.6, 0.25, 1, 0.75, 1] },
|
|
37
|
+
{ time: animationDuration, color: '80a0c0ff' },
|
|
38
|
+
],
|
|
39
|
+
};
|
|
40
|
+
atlas.set(regionName, {
|
|
41
|
+
name: regionName,
|
|
42
|
+
page: 'page.png',
|
|
43
|
+
x: (slotIndex % 16) * 8,
|
|
44
|
+
y: Math.floor(slotIndex / 16) * 8,
|
|
45
|
+
width: 8,
|
|
46
|
+
height: 8,
|
|
47
|
+
originalWidth: 8,
|
|
48
|
+
originalHeight: 8,
|
|
49
|
+
offsetX: 0,
|
|
50
|
+
offsetY: 0,
|
|
51
|
+
rotate: 0,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
const boneAnimations = {};
|
|
55
|
+
for (let boneIndex = 0; boneIndex < boneCount; boneIndex++) {
|
|
56
|
+
const rotate = [];
|
|
57
|
+
const translate = [];
|
|
58
|
+
for (let frameIndex = 0; frameIndex < keyframeCount; frameIndex++) {
|
|
59
|
+
const time = frameIndex * frameStep;
|
|
60
|
+
const angle = Math.sin(frameIndex * 0.17 + boneIndex * 0.03) * 20;
|
|
61
|
+
const nextAngle = Math.sin((frameIndex + 1) * 0.17 + boneIndex * 0.03) * 20;
|
|
62
|
+
rotate.push(frameIndex + 1 < keyframeCount
|
|
63
|
+
? { time, angle, curve: [time + frameStep * 0.25, angle, time + frameStep * 0.75, nextAngle] }
|
|
64
|
+
: { time, angle });
|
|
65
|
+
translate.push({ time, x: Math.sin(frameIndex * 0.11) * 0.1, y: Math.cos(frameIndex * 0.13) * 0.1 });
|
|
66
|
+
}
|
|
67
|
+
boneAnimations[`bone${boneIndex}`] = { rotate, translate };
|
|
68
|
+
}
|
|
69
|
+
const data = normalizeSpineData({
|
|
70
|
+
bones,
|
|
71
|
+
slots,
|
|
72
|
+
skins: { default: skin },
|
|
73
|
+
animations: { benchmark: { bones: boneAnimations, slots: slotAnimations } },
|
|
74
|
+
});
|
|
75
|
+
const pages = new Map([[
|
|
76
|
+
'page.png',
|
|
77
|
+
{
|
|
78
|
+
image: null,
|
|
79
|
+
texture: null,
|
|
80
|
+
textureBindGroup: null,
|
|
81
|
+
width: 256,
|
|
82
|
+
height: 256,
|
|
83
|
+
},
|
|
84
|
+
]]);
|
|
85
|
+
return {
|
|
86
|
+
component: new Spine2DComponent({ animation: 'benchmark', loop: true }),
|
|
87
|
+
runtime: createSpineRuntimeForBenchmark(data, atlas, pages),
|
|
88
|
+
boneCount,
|
|
89
|
+
slotCount,
|
|
90
|
+
keyframeCount,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function benchmarkSpineAnimationSample(state) {
|
|
94
|
+
advanceSpineRuntime(state.component, 16);
|
|
95
|
+
return sampleSpinePosesForBenchmark(state.component, state.runtime);
|
|
96
|
+
}
|
|
97
|
+
function benchmarkSpineVertexBuild(state) {
|
|
98
|
+
advanceSpineRuntime(state.component, 16);
|
|
99
|
+
const result = buildSpineVertices(state.component, state.runtime);
|
|
100
|
+
return result.vertices.length + result.batches.length + result.vertexDirtyRanges.length;
|
|
101
|
+
}
|
|
102
|
+
function benchmarkCompileSpineTimeline(frames) {
|
|
103
|
+
return compileSpineTimelines({ benchmark: { timeline: frames } }).frameCount;
|
|
104
|
+
}
|
|
105
|
+
function benchmarkCreateSpineTimelineSamplerState() {
|
|
106
|
+
return createSpineTimelineSamplerState();
|
|
107
|
+
}
|
|
108
|
+
function benchmarkSampleSpineTimeline(frames, time, key, fallback, samplerState) {
|
|
109
|
+
return sampleCompiledTimeline(frames, time, key, fallback, 0, false, samplerState);
|
|
110
|
+
}
|
|
111
|
+
function benchmarkFindSpineFrame(frames, time, samplerState) {
|
|
112
|
+
return findCompiledFrameIndex(frames, time, samplerState);
|
|
113
|
+
}
|
|
114
|
+
function benchmarkSampleSpineColor(frames, time, fallback, out) {
|
|
115
|
+
return sampleCompiledColor(frames, time, fallback, out);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export { benchmarkCompileSpineTimeline, benchmarkCreateSpineTimelineSamplerState, benchmarkFindSpineFrame, benchmarkSampleSpineColor, benchmarkSampleSpineTimeline, benchmarkSpineAnimationSample, benchmarkSpineParse, benchmarkSpineVertexBuild, createSpineAnimationBenchmarkState };
|
|
119
|
+
//# sourceMappingURL=benchmark.js.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type IEngine, type RenderCommandContext } from '@haiyue/engine/extension-authoring';
|
|
2
|
+
import { Entity, type World } from '@haiyue/engine/ecs';
|
|
3
|
+
import { RenderSystem2DBase, type RenderSystem2DBaseOptions } from '../utils/RenderSystem2DBase';
|
|
4
|
+
export type CanvasText2DRenderSystemOptions = RenderSystem2DBaseOptions;
|
|
5
|
+
export declare class CanvasText2DRenderSystem extends RenderSystem2DBase {
|
|
6
|
+
private rendererReady;
|
|
7
|
+
private cameraGpu;
|
|
8
|
+
private objectLayout;
|
|
9
|
+
private textureGpu;
|
|
10
|
+
private shaderModule;
|
|
11
|
+
private pipelineLayout;
|
|
12
|
+
private pipelineCache;
|
|
13
|
+
private entityGpu;
|
|
14
|
+
constructor(engine: IEngine, cameraEntity: Entity, options?: CanvasText2DRenderSystemOptions);
|
|
15
|
+
record(world: World, context: RenderCommandContext): this;
|
|
16
|
+
destroy(): this;
|
|
17
|
+
protected releaseGpuResourcesForRecovery(): void;
|
|
18
|
+
private prepare;
|
|
19
|
+
private getPipeline;
|
|
20
|
+
private getEntityGpu;
|
|
21
|
+
private getTextureBindGroup;
|
|
22
|
+
private buildVertices;
|
|
23
|
+
private destroyEntityGpu;
|
|
24
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Component } from '@haiyue/engine';
|
|
2
|
+
import { CssMaterial, type CssMaterialStyle } from '@haiyue/engine/material';
|
|
3
|
+
export interface CanvasTextComponentOptions {
|
|
4
|
+
text?: string;
|
|
5
|
+
style?: CssMaterialStyle;
|
|
6
|
+
material?: CssMaterial;
|
|
7
|
+
}
|
|
8
|
+
export declare class CanvasTextComponent extends Component {
|
|
9
|
+
static UniqueCheckType: number;
|
|
10
|
+
static UniqueSymbol: symbol;
|
|
11
|
+
material: CssMaterial;
|
|
12
|
+
constructor(options?: CanvasTextComponentOptions);
|
|
13
|
+
get text(): string;
|
|
14
|
+
set text(value: string);
|
|
15
|
+
get style(): CssMaterialStyle;
|
|
16
|
+
set style(value: CssMaterialStyle);
|
|
17
|
+
clone(): CanvasTextComponent;
|
|
18
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { CanvasTextComponent } from './canvas-text/CanvasTextComponent';
|
|
2
|
+
export type { CanvasTextComponentOptions } from './canvas-text/CanvasTextComponent';
|
|
3
|
+
export { CanvasText2DRenderSystem } from './canvas-text/CanvasText2DRenderSystem';
|
|
4
|
+
export type { CanvasText2DRenderSystemOptions } from './canvas-text/CanvasText2DRenderSystem';
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { Component } from '@haiyue/engine';
|
|
2
|
+
import { UniqueCheckType } from '@haiyue/engine/ecs';
|
|
3
|
+
import { CssMaterial } from '@haiyue/engine/material';
|
|
4
|
+
import { beginRenderCommandPass, getExtensionGPUResourceTracker, requireEngineDevice } from '@haiyue/engine/extension-authoring';
|
|
5
|
+
import { Transform2D } from '@haiyue/engine/components';
|
|
6
|
+
import { R as RenderSystem2DBase, w as writeObjectMatrixIfChanged, d as destroyCamera2DGpu, a as destroyTexture2DGpu, c as createCamera2DGpu, b as createObject2DLayout, e as createTexture2DGpu } from './chunks/RenderSystem2DBase-DDT61dAu.js';
|
|
7
|
+
import { C as CanvasText2dWgsl } from './chunks/2d-ui-canvas-text-2d.generated-C0Eaej2m.js';
|
|
8
|
+
import 'wgpu-matrix';
|
|
9
|
+
|
|
10
|
+
class CanvasTextComponent extends Component {
|
|
11
|
+
static UniqueCheckType = UniqueCheckType.SYMBOL | UniqueCheckType.REPLACE;
|
|
12
|
+
static UniqueSymbol = Symbol.for('CanvasTextComponent');
|
|
13
|
+
material;
|
|
14
|
+
constructor(options = {}) {
|
|
15
|
+
super('CanvasTextComponent');
|
|
16
|
+
this.material = options.material ?? new CssMaterial({
|
|
17
|
+
...(options.text === undefined ? {} : { text: options.text }),
|
|
18
|
+
...(options.style === undefined ? {} : { style: options.style }),
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
get text() {
|
|
22
|
+
return this.material.text;
|
|
23
|
+
}
|
|
24
|
+
set text(value) {
|
|
25
|
+
this.material.setText(value);
|
|
26
|
+
}
|
|
27
|
+
get style() {
|
|
28
|
+
return this.material.style;
|
|
29
|
+
}
|
|
30
|
+
set style(value) {
|
|
31
|
+
this.material.setStyle(value);
|
|
32
|
+
}
|
|
33
|
+
clone() {
|
|
34
|
+
return new CanvasTextComponent({
|
|
35
|
+
text: this.text,
|
|
36
|
+
style: { ...this.style },
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const CANVAS_TEXT_2D_WGSL = CanvasText2dWgsl;
|
|
42
|
+
function textureSize(source) {
|
|
43
|
+
return {
|
|
44
|
+
width: Math.max(1, source instanceof HTMLImageElement ? source.naturalWidth || source.width : source.width),
|
|
45
|
+
height: Math.max(1, source instanceof HTMLImageElement ? source.naturalHeight || source.height : source.height),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
class CanvasText2DRenderSystem extends RenderSystem2DBase {
|
|
49
|
+
rendererReady = false;
|
|
50
|
+
cameraGpu;
|
|
51
|
+
objectLayout;
|
|
52
|
+
textureGpu;
|
|
53
|
+
shaderModule;
|
|
54
|
+
pipelineLayout;
|
|
55
|
+
pipelineCache = new Map();
|
|
56
|
+
entityGpu = new Map();
|
|
57
|
+
constructor(engine, cameraEntity, options = {}) {
|
|
58
|
+
super({ all: [CanvasTextComponent, Transform2D] }, engine, cameraEntity, options, 'CanvasText2DRenderSystem');
|
|
59
|
+
}
|
|
60
|
+
record(world, context) {
|
|
61
|
+
if (this.disabled)
|
|
62
|
+
return this;
|
|
63
|
+
const { device } = context;
|
|
64
|
+
if (!this.rendererReady)
|
|
65
|
+
this.prepare();
|
|
66
|
+
const liveEntities = this.beginLiveEntityTracking();
|
|
67
|
+
if (!this.writeCameraBuffer(device.queue, this.cameraGpu.buffer, context))
|
|
68
|
+
return this;
|
|
69
|
+
const { passEncoder, ownsPass } = beginRenderCommandPass(context);
|
|
70
|
+
passEncoder.setPipeline(this.getPipeline(context.view?.reverseZ ?? this.engine.reverseZ, context.view?.sampleCount ?? this.engine.msaaSamples));
|
|
71
|
+
passEncoder.setBindGroup(0, this.cameraGpu.bindGroup);
|
|
72
|
+
const entities = this.entitySet.get(world);
|
|
73
|
+
if (entities)
|
|
74
|
+
for (const entity of entities) {
|
|
75
|
+
if (!this.isEntityRenderable(entity))
|
|
76
|
+
continue;
|
|
77
|
+
const component = entity.getComponent(CanvasTextComponent);
|
|
78
|
+
if (!component)
|
|
79
|
+
continue;
|
|
80
|
+
const textureBindGroup = this.getTextureBindGroup(entity, component);
|
|
81
|
+
const gpu = this.getEntityGpu(entity);
|
|
82
|
+
const vertices = this.buildVertices(component, gpu);
|
|
83
|
+
let shouldUploadVertices = gpu.vertexDirty;
|
|
84
|
+
if (vertices.byteLength > gpu.vertexBufferSize) {
|
|
85
|
+
getExtensionGPUResourceTracker(this.engine)?.untrackBuffer(gpu.vertexBuffer);
|
|
86
|
+
gpu.vertexBuffer.destroy();
|
|
87
|
+
gpu.vertexBufferSize = Math.max(vertices.byteLength, gpu.vertexBufferSize * 2);
|
|
88
|
+
gpu.vertexBuffer = device.createBuffer({
|
|
89
|
+
size: gpu.vertexBufferSize,
|
|
90
|
+
usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
|
|
91
|
+
});
|
|
92
|
+
getExtensionGPUResourceTracker(this.engine)?.trackBuffer(gpu.vertexBuffer, 'CanvasText2D.vertexBuffer', gpu.vertexBufferSize);
|
|
93
|
+
shouldUploadVertices = true;
|
|
94
|
+
}
|
|
95
|
+
if (shouldUploadVertices) {
|
|
96
|
+
device.queue.writeBuffer(gpu.vertexBuffer, 0, vertices.buffer, vertices.byteOffset, vertices.byteLength);
|
|
97
|
+
gpu.vertexDirty = false;
|
|
98
|
+
}
|
|
99
|
+
const worldMatrix = this.getWorldMatrix2D(entity, context);
|
|
100
|
+
writeObjectMatrixIfChanged(device.queue, gpu.objectGpu, worldMatrix);
|
|
101
|
+
passEncoder.setBindGroup(1, gpu.objectGpu.bindGroup);
|
|
102
|
+
passEncoder.setBindGroup(2, textureBindGroup);
|
|
103
|
+
passEncoder.setVertexBuffer(0, gpu.vertexBuffer);
|
|
104
|
+
passEncoder.draw(6);
|
|
105
|
+
this.markEntityLive(entity);
|
|
106
|
+
}
|
|
107
|
+
if (ownsPass)
|
|
108
|
+
passEncoder.end();
|
|
109
|
+
this.releaseEntityGpuEntriesNotIn(this.entityGpu, gpu => this.destroyEntityGpu(gpu), liveEntities);
|
|
110
|
+
return this;
|
|
111
|
+
}
|
|
112
|
+
destroy() {
|
|
113
|
+
this.releaseGpuResourcesForRecovery();
|
|
114
|
+
return super.destroy();
|
|
115
|
+
}
|
|
116
|
+
releaseGpuResourcesForRecovery() {
|
|
117
|
+
if (this.cameraGpu)
|
|
118
|
+
destroyCamera2DGpu(this.cameraGpu);
|
|
119
|
+
if (this.textureGpu)
|
|
120
|
+
destroyTexture2DGpu(this.textureGpu);
|
|
121
|
+
this.destroyEntityGpuEntries(this.entityGpu, gpu => this.destroyEntityGpu(gpu));
|
|
122
|
+
this.pipelineCache.clear();
|
|
123
|
+
this.rendererReady = false;
|
|
124
|
+
}
|
|
125
|
+
prepare() {
|
|
126
|
+
this.rendererReady = true;
|
|
127
|
+
const device = requireEngineDevice(this.engine);
|
|
128
|
+
this.cameraGpu = createCamera2DGpu(device, getExtensionGPUResourceTracker(this.engine));
|
|
129
|
+
this.objectLayout = createObject2DLayout(device);
|
|
130
|
+
this.textureGpu = createTexture2DGpu(device, 0, getExtensionGPUResourceTracker(this.engine));
|
|
131
|
+
this.shaderModule = device.createShaderModule({ code: CANVAS_TEXT_2D_WGSL });
|
|
132
|
+
this.pipelineLayout = device.createPipelineLayout({
|
|
133
|
+
bindGroupLayouts: [this.cameraGpu.layout, this.objectLayout, this.textureGpu.layout],
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
getPipeline(reverseZ, sampleCount) {
|
|
137
|
+
const key = (reverseZ ? 1 : 0) | ((sampleCount > 1 ? 1 : 0) << 1);
|
|
138
|
+
const cached = this.pipelineCache.get(key);
|
|
139
|
+
if (cached)
|
|
140
|
+
return cached;
|
|
141
|
+
const device = requireEngineDevice(this.engine);
|
|
142
|
+
const { format } = this.engine;
|
|
143
|
+
const pipeline = device.createRenderPipeline({
|
|
144
|
+
layout: this.pipelineLayout,
|
|
145
|
+
vertex: {
|
|
146
|
+
module: this.shaderModule,
|
|
147
|
+
entryPoint: 'vs_main',
|
|
148
|
+
buffers: [{
|
|
149
|
+
arrayStride: 16,
|
|
150
|
+
attributes: [
|
|
151
|
+
{ shaderLocation: 0, offset: 0, format: 'float32x2' },
|
|
152
|
+
{ shaderLocation: 1, offset: 8, format: 'float32x2' },
|
|
153
|
+
],
|
|
154
|
+
}],
|
|
155
|
+
},
|
|
156
|
+
fragment: {
|
|
157
|
+
module: this.shaderModule,
|
|
158
|
+
entryPoint: 'fs_main',
|
|
159
|
+
targets: [{
|
|
160
|
+
format,
|
|
161
|
+
blend: {
|
|
162
|
+
color: { srcFactor: 'src-alpha', dstFactor: 'one-minus-src-alpha', operation: 'add' },
|
|
163
|
+
alpha: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha', operation: 'add' },
|
|
164
|
+
},
|
|
165
|
+
}],
|
|
166
|
+
},
|
|
167
|
+
primitive: { topology: 'triangle-list', cullMode: 'none' },
|
|
168
|
+
depthStencil: {
|
|
169
|
+
format: this.engine.getDepthFormat(reverseZ),
|
|
170
|
+
depthWriteEnabled: false,
|
|
171
|
+
depthCompare: 'always',
|
|
172
|
+
},
|
|
173
|
+
multisample: { count: sampleCount },
|
|
174
|
+
});
|
|
175
|
+
this.pipelineCache.set(key, pipeline);
|
|
176
|
+
return pipeline;
|
|
177
|
+
}
|
|
178
|
+
getEntityGpu(entity) {
|
|
179
|
+
return this.getOrCreateEntityGpu(this.entityGpu, entity, () => {
|
|
180
|
+
const device = requireEngineDevice(this.engine);
|
|
181
|
+
const gpu = {
|
|
182
|
+
vertexBuffer: device.createBuffer({ size: 96, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST }),
|
|
183
|
+
vertexBufferSize: 96,
|
|
184
|
+
vertexData: new Float32Array(24),
|
|
185
|
+
vertexDirty: true,
|
|
186
|
+
vertexWidth: 0,
|
|
187
|
+
vertexHeight: 0,
|
|
188
|
+
objectGpu: this.createObjectGpu(this.objectLayout),
|
|
189
|
+
texture: null,
|
|
190
|
+
textureSource: null,
|
|
191
|
+
textureVersion: -1,
|
|
192
|
+
textureWidth: 0,
|
|
193
|
+
textureHeight: 0,
|
|
194
|
+
textureBindGroup: null,
|
|
195
|
+
};
|
|
196
|
+
getExtensionGPUResourceTracker(this.engine)?.trackBuffer(gpu.vertexBuffer, 'CanvasText2D.vertexBuffer', gpu.vertexBufferSize);
|
|
197
|
+
return gpu;
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
getTextureBindGroup(entity, component) {
|
|
201
|
+
const device = requireEngineDevice(this.engine);
|
|
202
|
+
const source = component.material.texture;
|
|
203
|
+
if (!source || !(source instanceof ImageBitmap || source instanceof HTMLCanvasElement || source instanceof HTMLImageElement)) {
|
|
204
|
+
return this.textureGpu.fallbackBindGroup;
|
|
205
|
+
}
|
|
206
|
+
const gpu = this.getEntityGpu(entity);
|
|
207
|
+
const size = textureSize(source);
|
|
208
|
+
const textureVersion = component.material.textureVersion;
|
|
209
|
+
if (gpu.textureBindGroup &&
|
|
210
|
+
gpu.textureSource === source &&
|
|
211
|
+
gpu.textureVersion === textureVersion &&
|
|
212
|
+
gpu.textureWidth === size.width &&
|
|
213
|
+
gpu.textureHeight === size.height) {
|
|
214
|
+
return gpu.textureBindGroup;
|
|
215
|
+
}
|
|
216
|
+
const canReuseTexture = gpu.texture && gpu.textureWidth === size.width && gpu.textureHeight === size.height;
|
|
217
|
+
if (!canReuseTexture) {
|
|
218
|
+
if (gpu.texture)
|
|
219
|
+
getExtensionGPUResourceTracker(this.engine)?.untrackTexture(gpu.texture);
|
|
220
|
+
gpu.texture?.destroy();
|
|
221
|
+
const texture = device.createTexture({
|
|
222
|
+
size: [size.width, size.height],
|
|
223
|
+
format: 'rgba8unorm',
|
|
224
|
+
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,
|
|
225
|
+
});
|
|
226
|
+
gpu.texture = texture;
|
|
227
|
+
getExtensionGPUResourceTracker(this.engine)?.trackTexture(texture, 'CanvasText2D.texture', size.width * size.height * 4);
|
|
228
|
+
gpu.textureBindGroup = device.createBindGroup({
|
|
229
|
+
layout: this.textureGpu.layout,
|
|
230
|
+
entries: [
|
|
231
|
+
{ binding: 0, resource: texture.createView() },
|
|
232
|
+
{ binding: 1, resource: this.textureGpu.sampler },
|
|
233
|
+
],
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
const texture = gpu.texture;
|
|
237
|
+
const textureBindGroup = gpu.textureBindGroup;
|
|
238
|
+
if (!texture || !textureBindGroup)
|
|
239
|
+
throw new Error('CanvasText2D texture GPU state is incomplete.');
|
|
240
|
+
device.queue.copyExternalImageToTexture({ source }, { texture }, [size.width, size.height]);
|
|
241
|
+
gpu.textureSource = source;
|
|
242
|
+
gpu.textureVersion = textureVersion;
|
|
243
|
+
gpu.textureWidth = size.width;
|
|
244
|
+
gpu.textureHeight = size.height;
|
|
245
|
+
return textureBindGroup;
|
|
246
|
+
}
|
|
247
|
+
buildVertices(component, gpu) {
|
|
248
|
+
const width = Math.max(1, Number(component.style.width ?? 256));
|
|
249
|
+
const height = Math.max(1, Number(component.style.height ?? 96));
|
|
250
|
+
if (gpu.vertexWidth !== width || gpu.vertexHeight !== height) {
|
|
251
|
+
gpu.vertexWidth = width;
|
|
252
|
+
gpu.vertexHeight = height;
|
|
253
|
+
gpu.vertexData.set([
|
|
254
|
+
0, 0, 0, 1,
|
|
255
|
+
width, 0, 1, 1,
|
|
256
|
+
width, height, 1, 0,
|
|
257
|
+
0, 0, 0, 1,
|
|
258
|
+
width, height, 1, 0,
|
|
259
|
+
0, height, 0, 0,
|
|
260
|
+
]);
|
|
261
|
+
gpu.vertexDirty = true;
|
|
262
|
+
}
|
|
263
|
+
return gpu.vertexData;
|
|
264
|
+
}
|
|
265
|
+
destroyEntityGpu(gpu) {
|
|
266
|
+
getExtensionGPUResourceTracker(this.engine)?.untrackBuffer(gpu.vertexBuffer);
|
|
267
|
+
gpu.vertexBuffer.destroy();
|
|
268
|
+
this.destroyObjectGpu(gpu.objectGpu);
|
|
269
|
+
if (gpu.texture)
|
|
270
|
+
getExtensionGPUResourceTracker(this.engine)?.untrackTexture(gpu.texture);
|
|
271
|
+
gpu.texture?.destroy();
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export { CanvasText2DRenderSystem, CanvasTextComponent };
|
|
276
|
+
//# sourceMappingURL=canvas-text.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
var Animation2dWgsl = "// haiyue:builtin-render animation-2d\n// source: shader-language/builtin-components-2d-ui-family.json\n\nstruct CameraUniforms {\n viewProj : mat4x4<f32>,\n}\n\nstruct ObjectUniforms {\n model : mat4x4<f32>,\n color : vec4<f32>,\n params : vec4<f32>, // x: composite layer count, y: output offscreen source\n uvRect : vec4<f32>,\n compositeParams : array<vec4<f32>, 8>, // mode, operation, feather x/y\n compositeExpansion0 : vec4<f32>,\n compositeExpansion1 : vec4<f32>,\n gradientParams : vec4<f32>, // kind, stop count, opacity\n gradientGeometry : vec4<f32>, // start.xy, end.xy\n gradientColors : array<vec4<f32>, 8>,\n gradientOffsets0 : vec4<f32>,\n gradientOffsets1 : vec4<f32>,\n effectKinds0 : vec4<f32>,\n effectKinds1 : vec4<f32>,\n effectData : array<EffectData, 8>,\n}\n\nstruct EffectData {\n data0 : vec4<f32>,\n data1 : vec4<f32>,\n data2 : vec4<f32>,\n data3 : vec4<f32>,\n data4 : vec4<f32>,\n data5 : vec4<f32>,\n}\n\n@group(0) @binding(0) var<uniform> camera : CameraUniforms;\n@group(1) @binding(0) var<uniform> object : ObjectUniforms;\n@group(2) @binding(0) var baseTexture : texture_2d<f32>;\n@group(2) @binding(1) var baseSampler : sampler;\n@group(3) @binding(0) var compositeTexture0 : texture_2d<f32>;\n@group(3) @binding(1) var compositeTexture1 : texture_2d<f32>;\n@group(3) @binding(2) var compositeTexture2 : texture_2d<f32>;\n@group(3) @binding(3) var compositeTexture3 : texture_2d<f32>;\n@group(3) @binding(4) var compositeTexture4 : texture_2d<f32>;\n@group(3) @binding(5) var compositeTexture5 : texture_2d<f32>;\n@group(3) @binding(6) var compositeTexture6 : texture_2d<f32>;\n@group(3) @binding(7) var compositeTexture7 : texture_2d<f32>;\n@group(3) @binding(8) var compositeSampler : sampler;\n\nstruct VertexInput {\n @location(0) position : vec2<f32>,\n @location(1) uv : vec2<f32>,\n}\n\nstruct VertexOutput {\n @builtin(position) clipPos : vec4<f32>,\n @location(0) uv : vec2<f32>,\n @location(1) localPosition : vec2<f32>,\n}\n\n@vertex\nfn vs_main(input : VertexInput) -> VertexOutput {\n var out : VertexOutput;\n out.clipPos = camera.viewProj * object.model * vec4<f32>(input.position, 0.0, 1.0);\n out.uv = object.uvRect.xy + input.uv * object.uvRect.zw;\n out.localPosition = input.position;\n return out;\n}\n\nstruct EffectVertexOutput {\n @builtin(position) clipPos : vec4<f32>,\n @location(0) uv : vec2<f32>,\n @location(1) @interpolate(flat) effectIndex : u32,\n}\n\n@vertex\nfn vs_effect(@builtin(vertex_index) vertexIndex : u32, @builtin(instance_index) effectIndex : u32) -> EffectVertexOutput {\n let uv = vec2<f32>(f32((vertexIndex << 1u) & 2u), f32(vertexIndex & 2u));\n var out : EffectVertexOutput;\n out.clipPos = vec4<f32>(uv * vec2<f32>(2.0, -2.0) + vec2<f32>(-1.0, 1.0), 0.0, 1.0);\n out.uv = uv;\n out.effectIndex = effectIndex;\n return out;\n}\n\nfn decode_coverage(value : vec4<f32>, mode : f32) -> f32 {\n var coverage = select(value.a, dot(value.rgb, vec3<f32>(0.2126, 0.7152, 0.0722)), mode > 1.5);\n if ((mode > 0.5 && mode < 1.5) || mode > 2.5) { coverage = 1.0 - coverage; }\n return clamp(coverage, 0.0, 1.0);\n}\n\nfn filtered_coverage(\n source : texture_2d<f32>,\n uv : vec2<f32>,\n parameters : vec4<f32>,\n expansion : f32,\n) -> f32 {\n let dimensions = vec2<f32>(textureDimensions(source));\n let radius = max(vec2<f32>(abs(expansion)), parameters.zw);\n let stepUv = radius / max(dimensions, vec2<f32>(1.0));\n let center = decode_coverage(textureSample(source, compositeSampler, uv), parameters.x);\n if (max(radius.x, radius.y) < 0.001) { return center; }\n let a = decode_coverage(textureSample(source, compositeSampler, uv + vec2<f32>(-stepUv.x, -stepUv.y)), parameters.x);\n let b = decode_coverage(textureSample(source, compositeSampler, uv + vec2<f32>(0.0, -stepUv.y)), parameters.x);\n let c = decode_coverage(textureSample(source, compositeSampler, uv + vec2<f32>(stepUv.x, -stepUv.y)), parameters.x);\n let d = decode_coverage(textureSample(source, compositeSampler, uv + vec2<f32>(-stepUv.x, 0.0)), parameters.x);\n let e = decode_coverage(textureSample(source, compositeSampler, uv + vec2<f32>(stepUv.x, 0.0)), parameters.x);\n let f = decode_coverage(textureSample(source, compositeSampler, uv + vec2<f32>(-stepUv.x, stepUv.y)), parameters.x);\n let g = decode_coverage(textureSample(source, compositeSampler, uv + vec2<f32>(0.0, stepUv.y)), parameters.x);\n let h = decode_coverage(textureSample(source, compositeSampler, uv + vec2<f32>(stepUv.x, stepUv.y)), parameters.x);\n var expanded = center;\n if (expansion > 0.001) { expanded = max(center, max(max(max(a, b), max(c, d)), max(max(e, f), max(g, h)))); }\n if (expansion < -0.001) { expanded = min(center, min(min(min(a, b), min(c, d)), min(min(e, f), min(g, h)))); }\n if (max(parameters.z, parameters.w) < 0.001) { return expanded; }\n let blurred = (center * 2.0 + a + b + c + d + e + f + g + h) / 10.0;\n return mix(expanded, blurred, clamp(max(parameters.z, parameters.w), 0.0, 1.0));\n}\n\nfn combine_coverage(current : f32, next : f32, operation : f32) -> f32 {\n if (operation < 0.5) { return current + next * (1.0 - current); }\n if (operation < 1.5) { return max(0.0, current - next); }\n if (operation < 2.5) { return current * next; }\n return abs(current - next);\n}\n\nfn gradient_offset(index : i32) -> f32 {\n if (index < 4) { return object.gradientOffsets0[index]; }\n return object.gradientOffsets1[index - 4];\n}\n\nfn gradient_color(position : vec2<f32>) -> vec4<f32> {\n let start = object.gradientGeometry.xy;\n let delta = object.gradientGeometry.zw - start;\n var progress = dot(position - start, delta) / max(dot(delta, delta), 1e-6);\n if (object.gradientParams.x > 1.5) { progress = length(position - start) / max(length(delta), 1e-6); }\n progress = clamp(progress, 0.0, 1.0);\n var previousOffset = gradient_offset(0);\n var previousColor = object.gradientColors[0];\n for (var index = 1; index < 8; index++) {\n if (f32(index) >= object.gradientParams.y) { break; }\n let nextOffset = gradient_offset(index);\n let nextColor = object.gradientColors[index];\n if (progress <= nextOffset) {\n let local = clamp((progress - previousOffset) / max(nextOffset - previousOffset, 1e-6), 0.0, 1.0);\n return mix(previousColor, nextColor, local) * vec4<f32>(1.0, 1.0, 1.0, object.gradientParams.z);\n }\n previousOffset = nextOffset;\n previousColor = nextColor;\n }\n return previousColor * vec4<f32>(1.0, 1.0, 1.0, object.gradientParams.z);\n}\n\nfn effect_kind(index : u32) -> f32 {\n if (index < 4u) { return object.effectKinds0[index]; }\n return object.effectKinds1[index - 4u];\n}\n\nfn unpremultiply(value : vec4<f32>) -> vec4<f32> {\n if (value.a <= 1e-6) { return vec4<f32>(0.0); }\n return vec4<f32>(value.rgb / value.a, value.a);\n}\n\nfn apply_color_effect(value : vec4<f32>, index : u32) -> vec4<f32> {\n let kind = effect_kind(index);\n let data = object.effectData[index];\n var color = unpremultiply(value);\n if (kind < 1.5) {\n let luminance = dot(color.rgb, vec3<f32>(0.2126, 0.7152, 0.0722));\n let tinted = mix(data.data0.xyz, vec3<f32>(data.data0.w, data.data1.x, data.data1.y), luminance);\n color = vec4<f32>(mix(color.rgb, tinted, clamp(data.data1.z, 0.0, 1.0)), color.a);\n } else if (kind < 2.5) {\n color = vec4<f32>(data.data0.rgb, color.a);\n color.a = color.a * data.data0.a * clamp(data.data1.x, 0.0, 1.0);\n } else if (kind < 3.5) {\n color.a = color.a * clamp(data.data0.x, 0.0, 1.0);\n } else if (kind < 4.5) {\n let source = color;\n color = vec4<f32>(\n dot(source, data.data0) + data.data1.x,\n dot(source, vec4<f32>(data.data1.yzw, data.data2.x)) + data.data2.y,\n dot(source, vec4<f32>(data.data2.zw, data.data3.xy)) + data.data3.z,\n dot(source, vec4<f32>(data.data3.w, data.data4.xyz)) + data.data4.w\n );\n color = clamp(color, vec4<f32>(0.0), vec4<f32>(1.0));\n }\n return vec4<f32>(color.rgb * color.a, color.a);\n}\n\nfn sample_blurred(uv : vec2<f32>, radius : vec2<f32>) -> vec4<f32> {\n let dimensions = max(vec2<f32>(textureDimensions(baseTexture)), vec2<f32>(1.0));\n let stepUv = radius / dimensions;\n if (max(radius.x, radius.y) < 0.01) { return textureSampleLevel(baseTexture, baseSampler, uv, 0.0); }\n var value = textureSampleLevel(baseTexture, baseSampler, uv, 0.0) * 0.25;\n value += textureSampleLevel(baseTexture, baseSampler, uv + vec2<f32>(-stepUv.x, 0.0), 0.0) * 0.125;\n value += textureSampleLevel(baseTexture, baseSampler, uv + vec2<f32>(stepUv.x, 0.0), 0.0) * 0.125;\n value += textureSampleLevel(baseTexture, baseSampler, uv + vec2<f32>(0.0, -stepUv.y), 0.0) * 0.125;\n value += textureSampleLevel(baseTexture, baseSampler, uv + vec2<f32>(0.0, stepUv.y), 0.0) * 0.125;\n value += textureSampleLevel(baseTexture, baseSampler, uv + vec2<f32>(-stepUv.x, -stepUv.y), 0.0) * 0.0625;\n value += textureSampleLevel(baseTexture, baseSampler, uv + vec2<f32>(stepUv.x, -stepUv.y), 0.0) * 0.0625;\n value += textureSampleLevel(baseTexture, baseSampler, uv + vec2<f32>(-stepUv.x, stepUv.y), 0.0) * 0.0625;\n value += textureSampleLevel(baseTexture, baseSampler, uv + vec2<f32>(stepUv.x, stepUv.y), 0.0) * 0.0625;\n return value;\n}\n\n@fragment\nfn fs_effect(input : EffectVertexOutput) -> @location(0) vec4<f32> {\n let kind = effect_kind(input.effectIndex);\n let data = object.effectData[input.effectIndex];\n if (kind < 4.5) { return apply_color_effect(textureSampleLevel(baseTexture, baseSampler, input.uv, 0.0), input.effectIndex); }\n if (kind < 5.5) { return sample_blurred(input.uv, max(data.data0.xy, vec2<f32>(0.0))); }\n let dimensions = max(vec2<f32>(textureDimensions(baseTexture)), vec2<f32>(1.0));\n let shadowUv = input.uv - data.data1.yz / dimensions;\n let shadowCoverage = sample_blurred(shadowUv, vec2<f32>(max(data.data1.w, 0.0))).a;\n let shadowAlpha = clamp(shadowCoverage * data.data1.x * data.data0.a, 0.0, 1.0);\n let shadow = vec4<f32>(data.data0.rgb * shadowAlpha, shadowAlpha);\n let foreground = textureSampleLevel(baseTexture, baseSampler, input.uv, 0.0);\n return foreground + shadow * (1.0 - foreground.a);\n}\n\n@fragment\nfn fs_present(input : EffectVertexOutput) -> @location(0) vec4<f32> {\n return textureSampleLevel(baseTexture, baseSampler, input.uv, 0.0);\n}\n\n@fragment\nfn fs_main(input : VertexOutput) -> @location(0) vec4<f32> {\n var base = textureSample(baseTexture, baseSampler, input.uv) * object.color;\n if (object.gradientParams.x > 0.5) { base = gradient_color(input.localPosition) * object.color; }\n var coverage = 1.0;\n if (object.params.x > 0.5) {\n let uv = input.clipPos.xy / vec2<f32>(textureDimensions(compositeTexture0));\n coverage = select(0.0, 1.0, object.compositeParams[0].y > 0.5 && object.compositeParams[0].y < 2.5);\n coverage = combine_coverage(coverage, filtered_coverage(compositeTexture0, uv, object.compositeParams[0], object.compositeExpansion0.x), object.compositeParams[0].y);\n if (object.params.x > 1.5) { coverage = combine_coverage(coverage, filtered_coverage(compositeTexture1, uv, object.compositeParams[1], object.compositeExpansion0.y), object.compositeParams[1].y); }\n if (object.params.x > 2.5) { coverage = combine_coverage(coverage, filtered_coverage(compositeTexture2, uv, object.compositeParams[2], object.compositeExpansion0.z), object.compositeParams[2].y); }\n if (object.params.x > 3.5) { coverage = combine_coverage(coverage, filtered_coverage(compositeTexture3, uv, object.compositeParams[3], object.compositeExpansion0.w), object.compositeParams[3].y); }\n if (object.params.x > 4.5) { coverage = combine_coverage(coverage, filtered_coverage(compositeTexture4, uv, object.compositeParams[4], object.compositeExpansion1.x), object.compositeParams[4].y); }\n if (object.params.x > 5.5) { coverage = combine_coverage(coverage, filtered_coverage(compositeTexture5, uv, object.compositeParams[5], object.compositeExpansion1.y), object.compositeParams[5].y); }\n if (object.params.x > 6.5) { coverage = combine_coverage(coverage, filtered_coverage(compositeTexture6, uv, object.compositeParams[6], object.compositeExpansion1.z), object.compositeParams[6].y); }\n if (object.params.x > 7.5) { coverage = combine_coverage(coverage, filtered_coverage(compositeTexture7, uv, object.compositeParams[7], object.compositeExpansion1.w), object.compositeParams[7].y); }\n }\n return vec4<f32>(base.rgb, base.a * coverage);\n}\n";
|
|
2
|
+
|
|
3
|
+
export { Animation2dWgsl as A };
|
|
4
|
+
//# sourceMappingURL=2d-ui-animation-2d.generated-D4aHzFU2.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
var CanvasText2dWgsl = "// haiyue:builtin-render canvas-text-2d\n// source: shader-language/builtin-components-2d-ui-family.json\n\nstruct CameraUniforms {\n viewProj : mat4x4<f32>,\n}\n\nstruct ObjectUniforms {\n model : mat4x4<f32>,\n}\n\n@group(0) @binding(0) var<uniform> camera : CameraUniforms;\n@group(1) @binding(0) var<uniform> object : ObjectUniforms;\n@group(2) @binding(0) var textTexture : texture_2d<f32>;\n@group(2) @binding(1) var textSampler : sampler;\n\nstruct VertexInput {\n @location(0) position : vec2<f32>,\n @location(1) uv : vec2<f32>,\n}\n\nstruct VertexOutput {\n @builtin(position) clipPos : vec4<f32>,\n @location(0) uv : vec2<f32>,\n}\n\n@vertex\nfn vs_main(input : VertexInput) -> VertexOutput {\n var out : VertexOutput;\n out.clipPos = camera.viewProj * object.model * vec4<f32>(input.position, 0.0, 1.0);\n out.uv = input.uv;\n return out;\n}\n\n@fragment\nfn fs_main(input : VertexOutput) -> @location(0) vec4<f32> {\n return textureSample(textTexture, textSampler, input.uv);\n}\n";
|
|
2
|
+
|
|
3
|
+
export { CanvasText2dWgsl as C };
|
|
4
|
+
//# sourceMappingURL=2d-ui-canvas-text-2d.generated-C0Eaej2m.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
var spine2dWgsl = "// haiyue:builtin-render spine2d\n// source: shader-language/builtin-components-2d-ui-family.json\n\nstruct CameraUniforms {\n viewProj : mat4x4<f32>,\n}\n\nstruct ObjectUniforms {\n model : mat4x4<f32>,\n}\n\n@group(0) @binding(0) var<uniform> camera : CameraUniforms;\n@group(1) @binding(0) var<uniform> object : ObjectUniforms;\n@group(2) @binding(0) var atlasTexture : texture_2d<f32>;\n@group(2) @binding(1) var atlasSampler : sampler;\n\nstruct VertexInput {\n @location(0) position : vec2<f32>,\n @location(1) uv : vec2<f32>,\n @location(2) color : vec4<f32>,\n}\n\nstruct VertexOutput {\n @builtin(position) clipPos : vec4<f32>,\n @location(0) uv : vec2<f32>,\n @location(1) color : vec4<f32>,\n}\n\n@vertex\nfn vs_main(input : VertexInput) -> VertexOutput {\n var out : VertexOutput;\n out.clipPos = camera.viewProj * object.model * vec4<f32>(input.position, 0.0, 1.0);\n out.uv = input.uv;\n out.color = input.color;\n return out;\n}\n\n@fragment\nfn fs_main(input : VertexOutput) -> @location(0) vec4<f32> {\n return textureSample(atlasTexture, atlasSampler, input.uv) * input.color;\n}\n";
|
|
2
|
+
|
|
3
|
+
export { spine2dWgsl as s };
|
|
4
|
+
//# sourceMappingURL=2d-ui-spine2d.generated-CUUi8xjl.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
var tilemap2dWgsl = "// haiyue:builtin-render tilemap2d\n// source: shader-language/builtin-components-2d-ui-family.json\n\nstruct CameraUniforms {\n viewProj : mat4x4<f32>,\n}\n\nstruct ObjectUniforms {\n model : mat4x4<f32>,\n}\n\n@group(0) @binding(0) var<uniform> camera : CameraUniforms;\n@group(1) @binding(0) var<uniform> object : ObjectUniforms;\n\nstruct VertexInput {\n @location(0) position : vec2<f32>,\n @location(1) color : vec4<f32>,\n}\n\nstruct VertexOutput {\n @builtin(position) clipPos : vec4<f32>,\n @location(0) color : vec4<f32>,\n}\n\n@vertex\nfn vs_main(input : VertexInput) -> VertexOutput {\n var out : VertexOutput;\n out.clipPos = camera.viewProj * object.model * vec4<f32>(input.position, 0.0, 1.0);\n out.color = input.color;\n return out;\n}\n\n@fragment\nfn fs_main(input : VertexOutput) -> @location(0) vec4<f32> {\n return input.color;\n}\n";
|
|
2
|
+
|
|
3
|
+
export { tilemap2dWgsl as t };
|
|
4
|
+
//# sourceMappingURL=2d-ui-tilemap2d.generated-gebw4mX7.js.map
|