@haiyue/extensions 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -0
- package/dist/animation/Animation2DComponent.d.ts +18 -0
- package/dist/animation/Animation2DExtensionRegistry.d.ts +7 -0
- package/dist/animation/Animation2DRenderSystem.d.ts +6 -0
- package/dist/animation/Animation2DRuntime.d.ts +6 -2
- package/dist/animation/AnimationTextRasterizer.d.ts +4 -0
- package/dist/animation/AnimationVisual2D.d.ts +58 -2
- package/dist/animation/interaction/InteractionRuntime.d.ts +83 -0
- package/dist/animation/interaction/runtime-types.d.ts +257 -0
- package/dist/animation.d.ts +3 -1
- package/dist/animation.js +551 -59
- package/dist/animation3d.js +1 -1
- package/dist/canvas-text.js +1 -1
- package/dist/chunks/2d-ui-animation-2d.generated-FpziAeGJ.js +4 -0
- package/dist/chunks/2d-ui-indexed-sprite.generated-DmKR0CC3.js +4 -0
- package/dist/chunks/Animation2DStateMachine-BHcA6Cu3.js +18212 -0
- package/dist/chunks/{AnimationStateMachineController-BIcAh-sT.js → AnimationStateMachineController-4sKaqh9E.js} +2 -2
- package/dist/chunks/AnimationVisual2D-8y3qp0_U.js +230 -0
- package/dist/chunks/{RenderSystem2DBase-DDT61dAu.js → RenderSystem2DBase-CF2s00vg.js} +2 -2
- package/dist/controls/VirtualJoystickControls.d.ts +46 -0
- package/dist/controls/contracts.d.ts +91 -0
- package/dist/controls.d.ts +2 -0
- package/dist/controls.js +358 -0
- package/dist/deformable-animation/runtime/DeformableMesh2DRuntimeExtension.d.ts +11 -0
- package/dist/deformable-animation/runtime/DeformableMesh2DSampler.d.ts +11 -0
- package/dist/deformable-animation.d.ts +5 -0
- package/dist/deformable-animation.js +316 -0
- package/dist/experimental-indexed-sprite.d.ts +5 -0
- package/dist/experimental-indexed-sprite.js +482 -0
- package/dist/gltf-worker-runtime.js +9 -9
- package/dist/hya-state-machine.js +3 -2
- package/dist/index.js +1 -1
- package/dist/indexed-sprite/AtlasLayout.d.ts +2 -0
- package/dist/indexed-sprite/IndexedSpriteRenderer.d.ts +23 -0
- package/dist/indexed-sprite/contracts.d.ts +89 -0
- package/dist/internal/2d-ui-shader-artifact.js +232 -23
- package/dist/ray-tracing/acceleration/bvh.d.ts +37 -0
- package/dist/ray-tracing/acceleration/index.d.ts +6 -0
- package/dist/ray-tracing/acceleration/pack.d.ts +152 -0
- package/dist/ray-tracing/acceleration/query.d.ts +4 -0
- package/dist/ray-tracing/acceleration/runtime.d.ts +30 -0
- package/dist/ray-tracing/acceleration/tlas.d.ts +4 -0
- package/dist/ray-tracing/acceleration/types.d.ts +165 -0
- package/dist/ray-tracing/denoise/index.d.ts +3 -0
- package/dist/ray-tracing/denoise/layout.d.ts +9 -0
- package/dist/ray-tracing/denoise/runtime.d.ts +23 -0
- package/dist/ray-tracing/denoise/types.d.ts +28 -0
- package/dist/ray-tracing/hybrid/contract.d.ts +2 -0
- package/dist/ray-tracing/hybrid/index.d.ts +5 -0
- package/dist/ray-tracing/hybrid/layout.d.ts +17 -0
- package/dist/ray-tracing/hybrid/plan.d.ts +2 -0
- package/dist/ray-tracing/hybrid/runtime.d.ts +31 -0
- package/dist/ray-tracing/hybrid/shaders/hybrid-artifact.generated.d.ts +625 -0
- package/dist/ray-tracing/hybrid/types.d.ts +144 -0
- package/dist/ray-tracing/lifecycle/device-recovery.d.ts +31 -0
- package/dist/ray-tracing/lifecycle/index.d.ts +2 -0
- package/dist/ray-tracing/lifecycle/types.d.ts +37 -0
- package/dist/ray-tracing/material/index.d.ts +2 -0
- package/dist/ray-tracing/material/pack.d.ts +5 -0
- package/dist/ray-tracing/material/types.d.ts +63 -0
- package/dist/ray-tracing/reference/index.d.ts +122 -0
- package/dist/ray-tracing/renderer/index.d.ts +7 -0
- package/dist/ray-tracing/renderer/layout.d.ts +20 -0
- package/dist/ray-tracing/renderer/plan.d.ts +2 -0
- package/dist/ray-tracing/renderer/reference.d.ts +17 -0
- package/dist/ray-tracing/renderer/runtime.d.ts +39 -0
- package/dist/ray-tracing/renderer/scene.d.ts +4 -0
- package/dist/ray-tracing/renderer/types.d.ts +115 -0
- package/dist/ray-tracing/sampling/index.d.ts +8 -0
- package/dist/ray-tracing/sampling/layout.d.ts +12 -0
- package/dist/ray-tracing/sampling/plan.d.ts +5 -0
- package/dist/ray-tracing/sampling/revision.d.ts +15 -0
- package/dist/ray-tracing/sampling/runtime.d.ts +44 -0
- package/dist/ray-tracing/sampling/sequence.d.ts +2 -0
- package/dist/ray-tracing/sampling/types.d.ts +96 -0
- package/dist/ray-tracing/scene/index.d.ts +41 -0
- package/dist/ray-tracing/traversal/index.d.ts +4 -0
- package/dist/ray-tracing/traversal/layout.d.ts +16 -0
- package/dist/ray-tracing/traversal/plan.d.ts +2 -0
- package/dist/ray-tracing/traversal/runtime.d.ts +25 -0
- package/dist/ray-tracing/traversal/types.d.ts +79 -0
- package/dist/ray-tracing/worker/client.d.ts +25 -0
- package/dist/ray-tracing/worker/index.d.ts +5 -0
- package/dist/ray-tracing/worker/runtime.d.ts +11 -0
- package/dist/ray-tracing/worker/serialization.d.ts +16 -0
- package/dist/ray-tracing/worker/source.d.ts +1 -0
- package/dist/ray-tracing/worker/types.d.ts +91 -0
- package/dist/ray-tracing.d.ts +17 -0
- package/dist/ray-tracing.js +7666 -0
- package/dist/spine.js +1 -1
- package/dist/tilemap.js +1 -1
- package/package.json +26 -23
- package/dist/animation/Animation2DStateMachineVisualRuntime.d.ts +0 -27
- package/dist/animation/Particle2DDescriptorAdapter.d.ts +0 -5
- package/dist/animation3d/Animation3DResource.d.ts +0 -28
- package/dist/animation3d/hya/HyaAnimation3DStateMachineRuntime.d.ts +0 -65
- package/dist/animation3d/hya/index.d.ts +0 -4
- package/dist/animation3d/runtime/integration/Animation3DStateMachineMixerAdapter.d.ts +0 -81
- package/dist/animation3d/runtime/integration/Animation3DStateMachineMixerIntegration.d.ts +0 -39
- package/dist/animation3d/runtime/integration/index.d.ts +0 -2
- package/dist/animation3d/runtime/mixer/Action.d.ts +0 -150
- package/dist/animation3d/runtime/mixer/Animation3DMixerRuntimeStore.d.ts +0 -6
- package/dist/animation3d/runtime/mixer/Mixer.d.ts +0 -59
- package/dist/animation3d/runtime/mixer/PoseBuffer.d.ts +0 -1
- package/dist/animation3d/runtime/mixer/TrackSampler.d.ts +0 -24
- package/dist/animation3d/runtime/mixer/index.d.ts +0 -4
- package/dist/animation3d/runtime/state-machine/Animation3DBlendTreeWeights.d.ts +0 -1
- package/dist/animation3d/runtime/state-machine/Animation3DStateMachineCompiler.d.ts +0 -1
- package/dist/animation3d/runtime/state-machine/Animation3DStateMachineController.d.ts +0 -1
- package/dist/animation3d/runtime/state-machine/Animation3DStateMachineMixerPort.d.ts +0 -1
- package/dist/animation3d/runtime/state-machine/index.d.ts +0 -6
- package/dist/benchmark.d.ts +0 -30
- package/dist/chunks/2d-ui-animation-2d.generated-D4aHzFU2.js +0 -4
- package/dist/chunks/Animation2DStateMachine-9IonguNa.js +0 -3245
- package/dist/gltf/GltfAccessorReader.d.ts +0 -7
- package/dist/gltf/GltfDracoDecoder.d.ts +0 -4
- package/dist/gltf/GltfLoaderErrors.d.ts +0 -4
- package/dist/gltf/GltfMaterialDescriptor.d.ts +0 -23
- package/dist/gltf/GltfMaterialLoader.d.ts +0 -6
- package/dist/gltf-worker-runtime.d.ts +0 -7
- package/dist/plugins/pluginUtils.d.ts +0 -20
- package/dist/plugins.d.ts +0 -6
- package/dist/shaders/generated/2d-ui-artifact.generated.d.ts +0 -658
- package/dist/spine/Spine2DGpuRenderer.d.ts +0 -65
- package/dist/spine/Spine2DRuntime.d.ts +0 -103
- package/dist/spine/SpineAnimationBoneTimelines.d.ts +0 -8
- package/dist/spine/SpineFloatBuilder.d.ts +0 -15
- package/dist/spine/SpinePathConstraintSolver.d.ts +0 -32
- package/dist/spine/SpineSkeletonRuntime.d.ts +0 -185
- package/dist/spine/SpineSlotAnimation.d.ts +0 -17
- package/dist/spine/SpineTimelineRuntime.d.ts +0 -25
- package/dist/spine/SpineVertexBuilder.d.ts +0 -61
- package/dist/tilemap/Tilemap2DRenderer.d.ts +0 -24
- package/dist/utils/arrayAccess.d.ts +0 -4
- package/dist/utils/camera2d.d.ts +0 -12
- package/src/animation/Animation2DComponent.ts +0 -135
- package/src/animation/Animation2DExtensionRegistry.ts +0 -52
- package/src/animation/Animation2DRenderSystem.ts +0 -1026
- package/src/animation/Animation2DRuntime.ts +0 -1326
- package/src/animation/Animation2DStateMachine.ts +0 -39
- package/src/animation/Animation2DStateMachineComponent.ts +0 -228
- package/src/animation/Animation2DStateMachineRuntime.ts +0 -141
- package/src/animation/Animation2DStateMachineSystem.ts +0 -60
- package/src/animation/Animation2DStateMachineVisualRuntime.ts +0 -282
- package/src/animation/Animation2DSystem.ts +0 -72
- package/src/animation/AnimationAssetLoader.ts +0 -84
- package/src/animation/AnimationAudioClip.ts +0 -140
- package/src/animation/AnimationPathTessellator.ts +0 -691
- package/src/animation/AnimationTextRasterizer.ts +0 -340
- package/src/animation/AnimationVisual2D.ts +0 -153
- package/src/animation/HyaAnimation2DClipAdapter.ts +0 -845
- package/src/animation/Particle2DDescriptorAdapter.ts +0 -35
- package/src/animation/runtime/mixer/Action.ts +0 -876
- package/src/animation/runtime/mixer/Mixer.ts +0 -505
- package/src/animation/runtime/mixer/PoseBuffer.ts +0 -105
- package/src/animation/runtime/mixer/Sampler.ts +0 -252
- package/src/animation/runtime/mixer/Types.ts +0 -138
- package/src/animation/runtime/mixer/index.ts +0 -31
- package/src/animation-state-machine/AnimationStateMachine.ts +0 -146
- package/src/animation-state-machine/AnimationStateMachineChannels.ts +0 -116
- package/src/animation-state-machine/runtime/Animation2DStateMachineMixerAdapter.ts +0 -197
- package/src/animation-state-machine/runtime/AnimationStateMachineBlendTreeWeights.ts +0 -503
- package/src/animation-state-machine/runtime/AnimationStateMachineCompiler.ts +0 -763
- package/src/animation-state-machine/runtime/AnimationStateMachineController.ts +0 -987
- package/src/animation-state-machine/runtime/AnimationStateMachineMixerPort.ts +0 -54
- package/src/animation-state-machine/runtime/index.ts +0 -47
- package/src/animation.ts +0 -33
- package/src/animation3d/Animation3DAction.ts +0 -73
- package/src/animation3d/Animation3DBinding.ts +0 -116
- package/src/animation3d/Animation3DClip.ts +0 -22
- package/src/animation3d/Animation3DError.ts +0 -34
- package/src/animation3d/Animation3DMixer.ts +0 -82
- package/src/animation3d/Animation3DPose.ts +0 -100
- package/src/animation3d/Animation3DPoseBuffer.ts +0 -85
- package/src/animation3d/Animation3DResource.ts +0 -49
- package/src/animation3d/Animation3DStateMachine.ts +0 -126
- package/src/animation3d/Animation3DStateMachineRuntime.ts +0 -191
- package/src/animation3d/Animation3DTrack.ts +0 -29
- package/src/animation3d/hya/HyaAnimation3DRuntime.ts +0 -756
- package/src/animation3d/hya/HyaAnimation3DStateMachineRuntime.ts +0 -618
- package/src/animation3d/hya/HyaAnimation3DTypes.ts +0 -168
- package/src/animation3d/hya/index.ts +0 -10
- package/src/animation3d/index.ts +0 -76
- package/src/animation3d/runtime/integration/Animation3DStateMachineMixerAdapter.ts +0 -325
- package/src/animation3d/runtime/integration/Animation3DStateMachineMixerIntegration.ts +0 -158
- package/src/animation3d/runtime/integration/index.ts +0 -9
- package/src/animation3d/runtime/mixer/Action.ts +0 -833
- package/src/animation3d/runtime/mixer/Animation3DMixerRuntimeStore.ts +0 -26
- package/src/animation3d/runtime/mixer/Mixer.ts +0 -562
- package/src/animation3d/runtime/mixer/PoseBuffer.ts +0 -1
- package/src/animation3d/runtime/mixer/TrackSampler.ts +0 -399
- package/src/animation3d/runtime/mixer/index.ts +0 -8
- package/src/animation3d/runtime/state-machine/Animation3DBlendTreeWeights.ts +0 -4
- package/src/animation3d/runtime/state-machine/Animation3DStateMachineCompiler.ts +0 -1
- package/src/animation3d/runtime/state-machine/Animation3DStateMachineController.ts +0 -1
- package/src/animation3d/runtime/state-machine/Animation3DStateMachineMixerPort.ts +0 -1
- package/src/animation3d/runtime/state-machine/index.ts +0 -45
- package/src/animation3d.ts +0 -5
- package/src/benchmark.ts +0 -168
- package/src/canvas-text/CanvasText2DRenderSystem.ts +0 -292
- package/src/canvas-text/CanvasTextComponent.ts +0 -47
- package/src/canvas-text.ts +0 -4
- package/src/experimental-gltf-worker.ts +0 -18
- package/src/experimental-spine-worker.ts +0 -9
- package/src/gltf/GltfAccessorReader.ts +0 -271
- package/src/gltf/GltfAnimation3DAdapter.ts +0 -680
- package/src/gltf/GltfAnimationRuntime.ts +0 -392
- package/src/gltf/GltfAssetWorkerClient.ts +0 -136
- package/src/gltf/GltfCompatibilityReport.ts +0 -214
- package/src/gltf/GltfConservativeBounds.ts +0 -219
- package/src/gltf/GltfDracoDecoder.ts +0 -251
- package/src/gltf/GltfExtensionAdapter.ts +0 -340
- package/src/gltf/GltfLoaderContract.ts +0 -333
- package/src/gltf/GltfLoaderErrors.ts +0 -59
- package/src/gltf/GltfMaterialDescriptor.ts +0 -134
- package/src/gltf/GltfMaterialEncoder.ts +0 -173
- package/src/gltf/GltfMaterialLoader.ts +0 -293
- package/src/gltf/GltfModelComponent.ts +0 -115
- package/src/gltf/GltfModelSystem.ts +0 -208
- package/src/gltf/GltfPlugin.ts +0 -84
- package/src/gltf/GltfSchema.ts +0 -229
- package/src/gltf/GltfUvSemanticPlanner.ts +0 -166
- package/src/gltf/gltfLoader.ts +0 -910
- package/src/gltf-animation3d.ts +0 -10
- package/src/gltf-worker-runtime.ts +0 -10
- package/src/gltf.ts +0 -56
- package/src/grid/Grid2DComponent.ts +0 -69
- package/src/grid.ts +0 -2
- package/src/hya-state-machine.ts +0 -19
- package/src/index.ts +0 -2
- package/src/plugins/pluginUtils.ts +0 -50
- package/src/plugins.ts +0 -6
- package/src/shaders/generated/2d-ui-animation-2d.generated.wgsl +0 -242
- package/src/shaders/generated/2d-ui-artifact.generated.ts +0 -867
- package/src/shaders/generated/2d-ui-canvas-text-2d.generated.wgsl +0 -38
- package/src/shaders/generated/2d-ui-spine2d.generated.wgsl +0 -41
- package/src/shaders/generated/2d-ui-tilemap2d.generated.wgsl +0 -36
- package/src/spine/Spine2DComponent.ts +0 -168
- package/src/spine/Spine2DGpuRenderer.ts +0 -449
- package/src/spine/Spine2DRenderSystem.ts +0 -199
- package/src/spine/Spine2DRuntime.ts +0 -1529
- package/src/spine/SpineAnimationBoneTimelines.ts +0 -30
- package/src/spine/SpineAssetParser.ts +0 -20
- package/src/spine/SpineAssetWorkerClient.ts +0 -112
- package/src/spine/SpineAssetWorkerContract.ts +0 -4
- package/src/spine/SpineAtlasParser.ts +0 -127
- package/src/spine/SpineFloatBuilder.ts +0 -66
- package/src/spine/SpinePathConstraintSolver.ts +0 -582
- package/src/spine/SpinePlugin.ts +0 -76
- package/src/spine/SpineSkeletonRuntime.ts +0 -521
- package/src/spine/SpineSlotAnimation.ts +0 -195
- package/src/spine/SpineTimelineRuntime.ts +0 -453
- package/src/spine/SpineVertexBuilder.ts +0 -686
- package/src/spine.ts +0 -7
- package/src/tilemap/Tilemap2DComponent.ts +0 -232
- package/src/tilemap/Tilemap2DRenderSystem.ts +0 -58
- package/src/tilemap/Tilemap2DRenderer.ts +0 -289
- package/src/tilemap/TilemapPlugin.ts +0 -75
- package/src/tilemap.ts +0 -6
- package/src/tween/Tween2DComponent.ts +0 -83
- package/src/tween/Tween2DSystem.ts +0 -78
- package/src/tween.ts +0 -4
- package/src/types/earcut.d.ts +0 -7
- package/src/types/wgsl.d.ts +0 -4
- package/src/utils/RenderSystem2DBase.ts +0 -164
- package/src/utils/arrayAccess.ts +0 -17
- package/src/utils/camera2d.ts +0 -68
- package/src/utils/render2dGpu.ts +0 -132
- package/test/fixtures/gltf/animation-characterization.gltf +0 -344
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { DEFORMABLE_MESH_2D_EXTENSION_ID, decodeDeformableMesh2DData } from '@haiyue/animation-spec/deformable2d';
|
|
2
|
+
import { AnimationFormatError } from '@haiyue/animation-spec';
|
|
3
|
+
import { Entity, Transform2D, Geometry2D } from '@haiyue/engine';
|
|
4
|
+
import { A as AnimationVisual2D } from './chunks/AnimationVisual2D-8y3qp0_U.js';
|
|
5
|
+
import '@haiyue/engine/ecs';
|
|
6
|
+
|
|
7
|
+
function sampleDeformableMesh2DDrawable(times, drawable, time, targetRuntimePositions) {
|
|
8
|
+
if (targetRuntimePositions.length !== drawable.vertexCount * 2)
|
|
9
|
+
throw new RangeError('Deformable sample target does not match drawable vertex count.');
|
|
10
|
+
const frame = findFrame(times, time);
|
|
11
|
+
const nextFrame = Math.min(frame + 1, times.length - 1);
|
|
12
|
+
const startTime = times[frame];
|
|
13
|
+
const endTime = times[nextFrame];
|
|
14
|
+
const progress = nextFrame === frame || endTime <= startTime ? 0 : clamp((time - startTime) / (endTime - startTime), 0, 1);
|
|
15
|
+
const stride = drawable.vertexCount * 2;
|
|
16
|
+
const startOffset = frame * stride;
|
|
17
|
+
const nextOffset = nextFrame * stride;
|
|
18
|
+
for (let index = 0; index < stride; index += 2) {
|
|
19
|
+
targetRuntimePositions[index] = mix(drawable.positions[startOffset + index], drawable.positions[nextOffset + index], progress);
|
|
20
|
+
// HYA stores screen-y-down coordinates; Animation2D geometry uses local y-up.
|
|
21
|
+
targetRuntimePositions[index + 1] = -mix(drawable.positions[startOffset + index + 1], drawable.positions[nextOffset + index + 1], progress);
|
|
22
|
+
}
|
|
23
|
+
return Object.freeze({
|
|
24
|
+
opacity: mix(drawable.opacities[frame], drawable.opacities[nextFrame], progress),
|
|
25
|
+
renderOrder: drawable.renderOrders[frame],
|
|
26
|
+
frame,
|
|
27
|
+
nextFrame,
|
|
28
|
+
progress,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/** Samples optional HYDM 1.2 RGBA tracks into caller-owned pose storage without allocating. */
|
|
32
|
+
function sampleDeformableMesh2DDrawableColors(drawable, sample, targetMultiplyColors, targetScreenColors, targetOffset = 0) {
|
|
33
|
+
if (!Number.isSafeInteger(targetOffset) || targetOffset < 0 || targetOffset + 4 > targetMultiplyColors.length || targetOffset + 4 > targetScreenColors.length) {
|
|
34
|
+
throw new RangeError('Deformable color sample target requires four writable values.');
|
|
35
|
+
}
|
|
36
|
+
sampleColorTrack(drawable.multiplyColors, sample, targetMultiplyColors, targetOffset, [1, 1, 1, 1]);
|
|
37
|
+
sampleColorTrack(drawable.screenColors, sample, targetScreenColors, targetOffset, [0, 0, 0, 0]);
|
|
38
|
+
}
|
|
39
|
+
function sampleColorTrack(track, sample, target, targetOffset, fallback) {
|
|
40
|
+
const startOffset = sample.frame * 4;
|
|
41
|
+
const nextOffset = sample.nextFrame * 4;
|
|
42
|
+
for (let index = 0; index < 4; index++) {
|
|
43
|
+
const start = track?.[startOffset + index] ?? fallback[index];
|
|
44
|
+
const next = track?.[nextOffset + index] ?? fallback[index];
|
|
45
|
+
target[targetOffset + index] = mix(start, next, sample.progress);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function findFrame(times, time) {
|
|
49
|
+
if (time <= times[0])
|
|
50
|
+
return 0;
|
|
51
|
+
if (time >= times[times.length - 1])
|
|
52
|
+
return times.length - 1;
|
|
53
|
+
let low = 0;
|
|
54
|
+
let high = times.length - 1;
|
|
55
|
+
while (low + 1 < high) {
|
|
56
|
+
const middle = (low + high) >>> 1;
|
|
57
|
+
if (times[middle] <= time)
|
|
58
|
+
low = middle;
|
|
59
|
+
else
|
|
60
|
+
high = middle;
|
|
61
|
+
}
|
|
62
|
+
return low;
|
|
63
|
+
}
|
|
64
|
+
function mix(a, b, progress) { return a + (b - a) * progress; }
|
|
65
|
+
function clamp(value, minimum, maximum) { return Math.max(minimum, Math.min(maximum, value)); }
|
|
66
|
+
|
|
67
|
+
function createDeformableMesh2DRuntimeExtension(options = {}) {
|
|
68
|
+
return {
|
|
69
|
+
id: DEFORMABLE_MESH_2D_EXTENSION_ID,
|
|
70
|
+
create(context) {
|
|
71
|
+
return new DeformableMesh2DRuntimeInstance(context, options);
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
class DeformableMesh2DRuntimeInstance {
|
|
76
|
+
context;
|
|
77
|
+
options;
|
|
78
|
+
// Keep an explicit transform at the extension boundary. TransformStore marks
|
|
79
|
+
// transform-less entities as non-transform parents, so two consecutive
|
|
80
|
+
// transform-less runtime nodes would otherwise drop the owning HYA model's
|
|
81
|
+
// world transform before it reaches the drawable entities.
|
|
82
|
+
root = new Entity('HYA deformable mesh runtime').addComponent(new Transform2D());
|
|
83
|
+
controller = new AbortController();
|
|
84
|
+
assetHandles = [];
|
|
85
|
+
drawables = [];
|
|
86
|
+
onOwnerAbort = () => this.destroy();
|
|
87
|
+
state = 'loading';
|
|
88
|
+
lastTime = 0;
|
|
89
|
+
lastOpacity = 1;
|
|
90
|
+
destroyed = false;
|
|
91
|
+
constructor(context, options) {
|
|
92
|
+
this.context = context;
|
|
93
|
+
this.options = options;
|
|
94
|
+
context.parent.addChild(this.root);
|
|
95
|
+
context.signal.addEventListener('abort', this.onOwnerAbort, { once: true });
|
|
96
|
+
this.emitStatus();
|
|
97
|
+
if (context.signal.aborted) {
|
|
98
|
+
this.destroy();
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
void this.load();
|
|
102
|
+
}
|
|
103
|
+
apply(timeSeconds, opacity) {
|
|
104
|
+
this.lastTime = timeSeconds;
|
|
105
|
+
this.lastOpacity = opacity;
|
|
106
|
+
if (this.state !== 'ready')
|
|
107
|
+
return;
|
|
108
|
+
for (const item of this.drawables) {
|
|
109
|
+
const sample = sampleDeformableMesh2DDrawable(this.data.times, item.source, timeSeconds, item.positions);
|
|
110
|
+
sampleDeformableMesh2DDrawableColors(item.source, sample, item.multiplyColor, item.screenColor);
|
|
111
|
+
item.geometry.markDirty();
|
|
112
|
+
for (const visual of item.visuals) {
|
|
113
|
+
// Cubism's setup-mask pass samples the source mesh texture alpha but
|
|
114
|
+
// deliberately ignores drawable/model opacity. Keep the main visual's
|
|
115
|
+
// sampled opacity while mask-only clones remain fully contributing.
|
|
116
|
+
visual.color[3] = visual.sourceOnly ? 1 : sample.opacity * opacity;
|
|
117
|
+
visual.setDrawableColors(item.multiplyColor, item.screenColor);
|
|
118
|
+
visual.setOrder(sample.renderOrder);
|
|
119
|
+
visual.revision++;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
setOpacity(opacity) {
|
|
124
|
+
this.apply(this.lastTime, opacity);
|
|
125
|
+
}
|
|
126
|
+
destroy() {
|
|
127
|
+
if (this.destroyed)
|
|
128
|
+
return;
|
|
129
|
+
this.destroyed = true;
|
|
130
|
+
this.state = 'destroyed';
|
|
131
|
+
this.controller.abort('deformable-runtime-destroyed');
|
|
132
|
+
this.context.signal.removeEventListener('abort', this.onOwnerAbort);
|
|
133
|
+
for (const handle of this.assetHandles.splice(0))
|
|
134
|
+
handle.release();
|
|
135
|
+
this.drawables.length = 0;
|
|
136
|
+
this.root.destroy();
|
|
137
|
+
this.emitStatus();
|
|
138
|
+
}
|
|
139
|
+
data = null;
|
|
140
|
+
async load() {
|
|
141
|
+
try {
|
|
142
|
+
const manager = this.context.assetManager;
|
|
143
|
+
if (!manager)
|
|
144
|
+
throw new AnimationFormatError('E_ANIMATION_INVALID_FORMAT', 'Deformable mesh runtime requires an AssetManager.', '$runtime.assetManager');
|
|
145
|
+
const component = this.context.component;
|
|
146
|
+
const dataResource = this.context.animation.resources.find(resource => resource.id === component.dataResource);
|
|
147
|
+
if (!dataResource || dataResource.type !== 'binary')
|
|
148
|
+
throw new AnimationFormatError('E_ANIMATION_INVALID_FORMAT', `Deformable data resource "${component.dataResource}" is missing or not binary.`, '$.resources');
|
|
149
|
+
const textureResources = component.textures.map((id, index) => {
|
|
150
|
+
const resource = this.context.animation.resources.find(candidate => candidate.id === id);
|
|
151
|
+
if (!resource || resource.type !== 'image')
|
|
152
|
+
throw new AnimationFormatError('E_ANIMATION_INVALID_FORMAT', `Texture resource "${id}" is missing or not an image.`, `$.nodes[].components[].textures[${index}]`);
|
|
153
|
+
return resource;
|
|
154
|
+
});
|
|
155
|
+
const dataHandle = await manager.load(`deformable2d:${dataResource.integrity ?? dataResource.uri}`, async (signal) => {
|
|
156
|
+
const response = await fetch(dataResource.uri, signal ? { signal } : {});
|
|
157
|
+
if (!response.ok)
|
|
158
|
+
throw new Error(`Deformable sidecar request failed with HTTP ${response.status}.`);
|
|
159
|
+
return response.arrayBuffer();
|
|
160
|
+
}, () => { }, { signal: this.controller.signal });
|
|
161
|
+
if (this.destroyed) {
|
|
162
|
+
dataHandle.release();
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
this.assetHandles.push(dataHandle);
|
|
166
|
+
const data = decodeDeformableMesh2DData(dataHandle.value);
|
|
167
|
+
if (Math.abs(data.canvasWidth - this.context.animation.canvas.width) > 1e-6
|
|
168
|
+
|| Math.abs(data.canvasHeight - this.context.animation.canvas.height) > 1e-6
|
|
169
|
+
|| Math.abs(data.duration - this.context.animation.duration) > 1e-6) {
|
|
170
|
+
throw new AnimationFormatError('E_ANIMATION_INVALID_FORMAT', 'Deformable sidecar canvas/duration does not match HYA.', '$.resources');
|
|
171
|
+
}
|
|
172
|
+
for (let index = 0; index < data.drawables.length; index++) {
|
|
173
|
+
if (data.drawables[index].textureIndex >= textureResources.length)
|
|
174
|
+
throw new AnimationFormatError('E_ANIMATION_INVALID_FORMAT', 'Drawable texture index exceeds component texture resources.', `$.drawables[${index}].textureIndex`);
|
|
175
|
+
}
|
|
176
|
+
const textureHandles = [];
|
|
177
|
+
for (let index = 0; index < textureResources.length; index++) {
|
|
178
|
+
const resource = textureResources[index];
|
|
179
|
+
try {
|
|
180
|
+
textureHandles.push(await manager.loadTexture(resource.uri, {
|
|
181
|
+
label: `DeformableMesh2D:${resource.id}`,
|
|
182
|
+
// AnimationVisual2D currently composites display-encoded 2D colors
|
|
183
|
+
// into an rgba8unorm canvas. An sRGB texture view would decode the
|
|
184
|
+
// authored bytes to linear values and make the result visibly dark.
|
|
185
|
+
// Preserve the source bytes here to match Canvas/WebGL Live2D output.
|
|
186
|
+
format: 'rgba8unorm',
|
|
187
|
+
// Cubism 5.2-and-earlier blend factors and linear texture filtering
|
|
188
|
+
// both operate on premultiplied texels.
|
|
189
|
+
premultipliedAlpha: true,
|
|
190
|
+
cacheKey: resource.integrity ?? resource.uri,
|
|
191
|
+
signal: this.controller.signal,
|
|
192
|
+
}));
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
for (const handle of textureHandles)
|
|
196
|
+
handle.release();
|
|
197
|
+
throw new Error(`Texture ${index} failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (this.destroyed) {
|
|
201
|
+
for (const handle of textureHandles)
|
|
202
|
+
handle.release();
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
this.assetHandles.push(...textureHandles);
|
|
206
|
+
this.data = data;
|
|
207
|
+
this.createVisuals(data, textureHandles);
|
|
208
|
+
this.state = 'ready';
|
|
209
|
+
this.apply(this.lastTime, this.lastOpacity);
|
|
210
|
+
this.emitStatus();
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
if (this.controller.signal.aborted || this.destroyed)
|
|
214
|
+
return;
|
|
215
|
+
for (const handle of this.assetHandles.splice(0))
|
|
216
|
+
handle.release();
|
|
217
|
+
this.data = null;
|
|
218
|
+
this.drawables.length = 0;
|
|
219
|
+
this.root.destroy();
|
|
220
|
+
this.state = 'error';
|
|
221
|
+
this.emitStatus(error instanceof Error ? error.message : String(error));
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
createVisuals(data, textures) {
|
|
225
|
+
const maskGroups = createRuntimeMaskGroups(data.drawables);
|
|
226
|
+
const groupByKey = new Map(maskGroups.map(group => [maskGroupKey(group.sources), group]));
|
|
227
|
+
const runtimeById = new Map();
|
|
228
|
+
const compositeFor = (drawable) => {
|
|
229
|
+
if (drawable.masks.length === 0)
|
|
230
|
+
return undefined;
|
|
231
|
+
const group = groupByKey.get(maskGroupKey(drawable.masks));
|
|
232
|
+
if (!group)
|
|
233
|
+
throw new AnimationFormatError('E_ANIMATION_INVALID_FORMAT', 'Drawable mask group could not be resolved.', `$.drawables[id=${JSON.stringify(drawable.id)}].masks`);
|
|
234
|
+
return {
|
|
235
|
+
layers: [{
|
|
236
|
+
kind: 'mask',
|
|
237
|
+
source: group.id,
|
|
238
|
+
mode: drawable.maskMode,
|
|
239
|
+
operation: 'add',
|
|
240
|
+
}],
|
|
241
|
+
};
|
|
242
|
+
};
|
|
243
|
+
const createVisual = (drawable, geometry, sourceOnly, nodeId) => {
|
|
244
|
+
// A Cubism drawable used as a mask source is rendered directly into the
|
|
245
|
+
// clipping buffer. Its own clipping context must not recursively affect
|
|
246
|
+
// that setup-mask pass.
|
|
247
|
+
const composite = sourceOnly ? undefined : compositeFor(drawable);
|
|
248
|
+
return new AnimationVisual2D({
|
|
249
|
+
geometry,
|
|
250
|
+
uvs: drawable.uvs,
|
|
251
|
+
color: [1, 1, 1, 1],
|
|
252
|
+
instanceId: this.context.instanceId,
|
|
253
|
+
nodeId,
|
|
254
|
+
order: drawable.renderOrders[0],
|
|
255
|
+
blendMode: drawable.blendMode,
|
|
256
|
+
textureAlphaMode: 'premultiplied',
|
|
257
|
+
culling: drawable.culling,
|
|
258
|
+
sourceOnly,
|
|
259
|
+
...(composite ? { composite } : {}),
|
|
260
|
+
textureHandle: textures[drawable.textureIndex],
|
|
261
|
+
requiresTexture: true,
|
|
262
|
+
});
|
|
263
|
+
};
|
|
264
|
+
for (const drawable of data.drawables) {
|
|
265
|
+
const positions = new Float32Array(drawable.vertexCount * 2);
|
|
266
|
+
sampleDeformableMesh2DDrawable(data.times, drawable, this.lastTime, positions);
|
|
267
|
+
const geometry = new Geometry2D(positions, drawable.indices);
|
|
268
|
+
const visible = createVisual(drawable, geometry, false, `draw:${drawable.id}`);
|
|
269
|
+
this.root.addChild(new Entity(`Drawable ${drawable.id}`).addComponent(visible));
|
|
270
|
+
const runtime = {
|
|
271
|
+
source: drawable,
|
|
272
|
+
geometry,
|
|
273
|
+
positions,
|
|
274
|
+
multiplyColor: new Float32Array(4),
|
|
275
|
+
screenColor: new Float32Array(4),
|
|
276
|
+
visuals: [visible],
|
|
277
|
+
};
|
|
278
|
+
runtimeById.set(drawable.id, runtime);
|
|
279
|
+
this.drawables.push(runtime);
|
|
280
|
+
}
|
|
281
|
+
for (const group of maskGroups) {
|
|
282
|
+
for (const sourceId of group.sources) {
|
|
283
|
+
const runtime = runtimeById.get(sourceId);
|
|
284
|
+
if (!runtime)
|
|
285
|
+
throw new AnimationFormatError('E_ANIMATION_INVALID_FORMAT', 'Mask group references a missing drawable.', `$.drawables[id=${JSON.stringify(sourceId)}]`);
|
|
286
|
+
const mask = createVisual(runtime.source, runtime.geometry, true, group.id);
|
|
287
|
+
this.root.addChild(new Entity(`Mask group ${group.id} source ${sourceId}`).addComponent(mask));
|
|
288
|
+
runtime.visuals.push(mask);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
emitStatus(error) {
|
|
293
|
+
this.options.onStatus?.(Object.freeze({ state: this.state, drawableCount: this.drawables.length, ...(error ? { error } : {}) }));
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
function createRuntimeMaskGroups(drawables) {
|
|
297
|
+
const groups = new Map();
|
|
298
|
+
for (const drawable of drawables) {
|
|
299
|
+
if (drawable.masks.length === 0)
|
|
300
|
+
continue;
|
|
301
|
+
const sources = Object.freeze([...drawable.masks].sort((left, right) => left.localeCompare(right)));
|
|
302
|
+
const key = maskGroupKey(sources);
|
|
303
|
+
if (!groups.has(key))
|
|
304
|
+
groups.set(key, Object.freeze({ id: `mask-group:${key}`, sources }));
|
|
305
|
+
}
|
|
306
|
+
return Object.freeze([...groups.values()]);
|
|
307
|
+
}
|
|
308
|
+
function maskGroupKey(sources) {
|
|
309
|
+
return [...sources]
|
|
310
|
+
.sort((left, right) => left.localeCompare(right))
|
|
311
|
+
.map(source => `${source.length}:${source}`)
|
|
312
|
+
.join('|');
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
export { createDeformableMesh2DRuntimeExtension, sampleDeformableMesh2DDrawable };
|
|
316
|
+
//# sourceMappingURL=deformable-animation.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { prepareIndexedSpriteAtlas } from './indexed-sprite/AtlasLayout';
|
|
2
|
+
export { IndexedSpriteRenderer } from './indexed-sprite/IndexedSpriteRenderer';
|
|
3
|
+
export type { IndexedSpriteRendererOptions } from './indexed-sprite/IndexedSpriteRenderer';
|
|
4
|
+
export { DEFAULT_INDEXED_SPRITE_ATLAS_LIMITS } from './indexed-sprite/contracts';
|
|
5
|
+
export type { IndexedSpriteAtlasLayout, IndexedSpriteAtlasLimits, IndexedSpriteAtlasPage, IndexedSpriteAtlasPlacement, IndexedSpriteBlend, IndexedSpriteDrawCommand, IndexedSpritePaletteDescriptor, IndexedSpritePlaneDescriptor, IndexedSpritePlaneFormat, IndexedSpriteRendererStats, IndexedSpriteSampling, } from './indexed-sprite/contracts';
|