@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.
Files changed (293) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +30 -0
  3. package/dist/animation/Animation2DComponent.d.ts +46 -0
  4. package/dist/animation/Animation2DExtensionRegistry.d.ts +27 -0
  5. package/dist/animation/Animation2DRenderSystem.d.ts +89 -0
  6. package/dist/animation/Animation2DRuntime.d.ts +99 -0
  7. package/dist/animation/Animation2DStateMachine.d.ts +13 -0
  8. package/dist/animation/Animation2DStateMachineComponent.d.ts +54 -0
  9. package/dist/animation/Animation2DStateMachineRuntime.d.ts +30 -0
  10. package/dist/animation/Animation2DStateMachineSystem.d.ts +14 -0
  11. package/dist/animation/Animation2DStateMachineVisualRuntime.d.ts +27 -0
  12. package/dist/animation/Animation2DSystem.d.ts +14 -0
  13. package/dist/animation/AnimationAssetLoader.d.ts +9 -0
  14. package/dist/animation/AnimationAudioClip.d.ts +26 -0
  15. package/dist/animation/AnimationPathTessellator.d.ts +52 -0
  16. package/dist/animation/AnimationTextRasterizer.d.ts +21 -0
  17. package/dist/animation/AnimationVisual2D.d.ts +68 -0
  18. package/dist/animation/HyaAnimation2DClipAdapter.d.ts +16 -0
  19. package/dist/animation/Particle2DDescriptorAdapter.d.ts +5 -0
  20. package/dist/animation/runtime/mixer/Action.d.ts +150 -0
  21. package/dist/animation/runtime/mixer/Mixer.d.ts +54 -0
  22. package/dist/animation/runtime/mixer/PoseBuffer.d.ts +23 -0
  23. package/dist/animation/runtime/mixer/Sampler.d.ts +17 -0
  24. package/dist/animation/runtime/mixer/Types.d.ts +101 -0
  25. package/dist/animation/runtime/mixer/index.d.ts +6 -0
  26. package/dist/animation-state-machine/AnimationStateMachine.d.ts +111 -0
  27. package/dist/animation-state-machine/AnimationStateMachineChannels.d.ts +23 -0
  28. package/dist/animation-state-machine/runtime/Animation2DStateMachineMixerAdapter.d.ts +51 -0
  29. package/dist/animation-state-machine/runtime/AnimationStateMachineBlendTreeWeights.d.ts +14 -0
  30. package/dist/animation-state-machine/runtime/AnimationStateMachineCompiler.d.ts +109 -0
  31. package/dist/animation-state-machine/runtime/AnimationStateMachineController.d.ts +103 -0
  32. package/dist/animation-state-machine/runtime/AnimationStateMachineMixerPort.d.ts +35 -0
  33. package/dist/animation-state-machine/runtime/index.d.ts +7 -0
  34. package/dist/animation.d.ts +15 -0
  35. package/dist/animation.js +1171 -0
  36. package/dist/animation3d/Animation3DAction.d.ts +46 -0
  37. package/dist/animation3d/Animation3DBinding.d.ts +85 -0
  38. package/dist/animation3d/Animation3DClip.d.ts +20 -0
  39. package/dist/animation3d/Animation3DError.d.ts +13 -0
  40. package/dist/animation3d/Animation3DMixer.d.ts +27 -0
  41. package/dist/animation3d/Animation3DPose.d.ts +40 -0
  42. package/dist/animation3d/Animation3DPoseBuffer.d.ts +24 -0
  43. package/dist/animation3d/Animation3DResource.d.ts +28 -0
  44. package/dist/animation3d/Animation3DStateMachine.d.ts +95 -0
  45. package/dist/animation3d/Animation3DStateMachineRuntime.d.ts +70 -0
  46. package/dist/animation3d/Animation3DTrack.d.ts +19 -0
  47. package/dist/animation3d/hya/HyaAnimation3DRuntime.d.ts +73 -0
  48. package/dist/animation3d/hya/HyaAnimation3DStateMachineRuntime.d.ts +65 -0
  49. package/dist/animation3d/hya/HyaAnimation3DTypes.d.ts +170 -0
  50. package/dist/animation3d/hya/index.d.ts +4 -0
  51. package/dist/animation3d/index.d.ts +14 -0
  52. package/dist/animation3d/runtime/integration/Animation3DStateMachineMixerAdapter.d.ts +81 -0
  53. package/dist/animation3d/runtime/integration/Animation3DStateMachineMixerIntegration.d.ts +39 -0
  54. package/dist/animation3d/runtime/integration/index.d.ts +2 -0
  55. package/dist/animation3d/runtime/mixer/Action.d.ts +150 -0
  56. package/dist/animation3d/runtime/mixer/Animation3DMixerRuntimeStore.d.ts +6 -0
  57. package/dist/animation3d/runtime/mixer/Mixer.d.ts +59 -0
  58. package/dist/animation3d/runtime/mixer/PoseBuffer.d.ts +1 -0
  59. package/dist/animation3d/runtime/mixer/TrackSampler.d.ts +24 -0
  60. package/dist/animation3d/runtime/mixer/index.d.ts +4 -0
  61. package/dist/animation3d/runtime/state-machine/Animation3DBlendTreeWeights.d.ts +1 -0
  62. package/dist/animation3d/runtime/state-machine/Animation3DStateMachineCompiler.d.ts +1 -0
  63. package/dist/animation3d/runtime/state-machine/Animation3DStateMachineController.d.ts +1 -0
  64. package/dist/animation3d/runtime/state-machine/Animation3DStateMachineMixerPort.d.ts +1 -0
  65. package/dist/animation3d/runtime/state-machine/index.d.ts +6 -0
  66. package/dist/animation3d.d.ts +5 -0
  67. package/dist/animation3d.js +1708 -0
  68. package/dist/benchmark.d.ts +30 -0
  69. package/dist/benchmark.js +119 -0
  70. package/dist/canvas-text/CanvasText2DRenderSystem.d.ts +24 -0
  71. package/dist/canvas-text/CanvasTextComponent.d.ts +18 -0
  72. package/dist/canvas-text.d.ts +4 -0
  73. package/dist/canvas-text.js +276 -0
  74. package/dist/chunks/2d-ui-animation-2d.generated-D4aHzFU2.js +4 -0
  75. package/dist/chunks/2d-ui-canvas-text-2d.generated-C0Eaej2m.js +4 -0
  76. package/dist/chunks/2d-ui-spine2d.generated-CUUi8xjl.js +4 -0
  77. package/dist/chunks/2d-ui-tilemap2d.generated-gebw4mX7.js +4 -0
  78. package/dist/chunks/Animation2DStateMachine-9IonguNa.js +3245 -0
  79. package/dist/chunks/AnimationStateMachineController-BIcAh-sT.js +1438 -0
  80. package/dist/chunks/GltfAnimation3DAdapter-Cu3rQQsW.js +2240 -0
  81. package/dist/chunks/GltfAnimationRuntime-CRHsLycN.js +631 -0
  82. package/dist/chunks/RenderSystem2DBase-DDT61dAu.js +227 -0
  83. package/dist/chunks/Spine2DRuntime-D9M9LAQR.js +3056 -0
  84. package/dist/chunks/SpineAssetParser-BSDmPge1.js +378 -0
  85. package/dist/chunks/gltfLoader-Dm22jLYB.js +2085 -0
  86. package/dist/chunks/pluginUtils-CvwroRMd.js +33 -0
  87. package/dist/experimental-gltf-worker.d.ts +4 -0
  88. package/dist/experimental-gltf-worker.js +138 -0
  89. package/dist/experimental-spine-worker.d.ts +4 -0
  90. package/dist/experimental-spine-worker.js +110 -0
  91. package/dist/gltf/GltfAccessorReader.d.ts +7 -0
  92. package/dist/gltf/GltfAnimation3DAdapter.d.ts +47 -0
  93. package/dist/gltf/GltfAnimationRuntime.d.ts +10 -0
  94. package/dist/gltf/GltfAssetWorkerClient.d.ts +20 -0
  95. package/dist/gltf/GltfCompatibilityReport.d.ts +70 -0
  96. package/dist/gltf/GltfConservativeBounds.d.ts +18 -0
  97. package/dist/gltf/GltfDracoDecoder.d.ts +4 -0
  98. package/dist/gltf/GltfExtensionAdapter.d.ts +54 -0
  99. package/dist/gltf/GltfLoaderContract.d.ts +249 -0
  100. package/dist/gltf/GltfLoaderErrors.d.ts +4 -0
  101. package/dist/gltf/GltfMaterialDescriptor.d.ts +23 -0
  102. package/dist/gltf/GltfMaterialEncoder.d.ts +20 -0
  103. package/dist/gltf/GltfMaterialLoader.d.ts +6 -0
  104. package/dist/gltf/GltfModelComponent.d.ts +72 -0
  105. package/dist/gltf/GltfModelSystem.d.ts +37 -0
  106. package/dist/gltf/GltfPlugin.d.ts +6 -0
  107. package/dist/gltf/GltfSchema.d.ts +225 -0
  108. package/dist/gltf/GltfUvSemanticPlanner.d.ts +33 -0
  109. package/dist/gltf/gltfLoader.d.ts +9 -0
  110. package/dist/gltf-animation3d.d.ts +3 -0
  111. package/dist/gltf-animation3d.js +8 -0
  112. package/dist/gltf-worker-runtime.d.ts +7 -0
  113. package/dist/gltf-worker-runtime.js +6981 -0
  114. package/dist/gltf.d.ts +12 -0
  115. package/dist/gltf.js +517 -0
  116. package/dist/grid/Grid2DComponent.d.ts +25 -0
  117. package/dist/grid.d.ts +2 -0
  118. package/dist/grid.js +56 -0
  119. package/dist/hya-state-machine.d.ts +7 -0
  120. package/dist/hya-state-machine.js +2934 -0
  121. package/dist/index.d.ts +2 -0
  122. package/dist/index.js +7 -0
  123. package/dist/internal/2d-ui-shader-artifact.js +870 -0
  124. package/dist/plugins/pluginUtils.d.ts +20 -0
  125. package/dist/plugins.d.ts +6 -0
  126. package/dist/shaders/generated/2d-ui-artifact.generated.d.ts +658 -0
  127. package/dist/spine/Spine2DComponent.d.ts +116 -0
  128. package/dist/spine/Spine2DGpuRenderer.d.ts +65 -0
  129. package/dist/spine/Spine2DRenderSystem.d.ts +27 -0
  130. package/dist/spine/Spine2DRuntime.d.ts +103 -0
  131. package/dist/spine/SpineAnimationBoneTimelines.d.ts +8 -0
  132. package/dist/spine/SpineAssetParser.d.ts +18 -0
  133. package/dist/spine/SpineAssetWorkerClient.d.ts +19 -0
  134. package/dist/spine/SpineAssetWorkerContract.d.ts +6 -0
  135. package/dist/spine/SpineAtlasParser.d.ts +21 -0
  136. package/dist/spine/SpineFloatBuilder.d.ts +15 -0
  137. package/dist/spine/SpinePathConstraintSolver.d.ts +32 -0
  138. package/dist/spine/SpinePlugin.d.ts +8 -0
  139. package/dist/spine/SpineSkeletonRuntime.d.ts +185 -0
  140. package/dist/spine/SpineSlotAnimation.d.ts +17 -0
  141. package/dist/spine/SpineTimelineRuntime.d.ts +25 -0
  142. package/dist/spine/SpineVertexBuilder.d.ts +61 -0
  143. package/dist/spine.d.ts +7 -0
  144. package/dist/spine.js +578 -0
  145. package/dist/tilemap/Tilemap2DComponent.d.ts +110 -0
  146. package/dist/tilemap/Tilemap2DRenderSystem.d.ts +11 -0
  147. package/dist/tilemap/Tilemap2DRenderer.d.ts +24 -0
  148. package/dist/tilemap/TilemapPlugin.d.ts +8 -0
  149. package/dist/tilemap.d.ts +6 -0
  150. package/dist/tilemap.js +535 -0
  151. package/dist/tween/Tween2DComponent.d.ts +70 -0
  152. package/dist/tween/Tween2DSystem.d.ts +12 -0
  153. package/dist/tween.d.ts +4 -0
  154. package/dist/tween.js +138 -0
  155. package/dist/utils/RenderSystem2DBase.d.ts +42 -0
  156. package/dist/utils/arrayAccess.d.ts +4 -0
  157. package/dist/utils/camera2d.d.ts +12 -0
  158. package/dist/utils/render2dGpu.d.ts +32 -0
  159. package/package.json +124 -0
  160. package/src/animation/Animation2DComponent.ts +135 -0
  161. package/src/animation/Animation2DExtensionRegistry.ts +52 -0
  162. package/src/animation/Animation2DRenderSystem.ts +1026 -0
  163. package/src/animation/Animation2DRuntime.ts +1326 -0
  164. package/src/animation/Animation2DStateMachine.ts +39 -0
  165. package/src/animation/Animation2DStateMachineComponent.ts +228 -0
  166. package/src/animation/Animation2DStateMachineRuntime.ts +141 -0
  167. package/src/animation/Animation2DStateMachineSystem.ts +60 -0
  168. package/src/animation/Animation2DStateMachineVisualRuntime.ts +282 -0
  169. package/src/animation/Animation2DSystem.ts +72 -0
  170. package/src/animation/AnimationAssetLoader.ts +84 -0
  171. package/src/animation/AnimationAudioClip.ts +140 -0
  172. package/src/animation/AnimationPathTessellator.ts +691 -0
  173. package/src/animation/AnimationTextRasterizer.ts +340 -0
  174. package/src/animation/AnimationVisual2D.ts +153 -0
  175. package/src/animation/HyaAnimation2DClipAdapter.ts +845 -0
  176. package/src/animation/Particle2DDescriptorAdapter.ts +35 -0
  177. package/src/animation/runtime/mixer/Action.ts +876 -0
  178. package/src/animation/runtime/mixer/Mixer.ts +505 -0
  179. package/src/animation/runtime/mixer/PoseBuffer.ts +105 -0
  180. package/src/animation/runtime/mixer/Sampler.ts +252 -0
  181. package/src/animation/runtime/mixer/Types.ts +138 -0
  182. package/src/animation/runtime/mixer/index.ts +31 -0
  183. package/src/animation-state-machine/AnimationStateMachine.ts +146 -0
  184. package/src/animation-state-machine/AnimationStateMachineChannels.ts +116 -0
  185. package/src/animation-state-machine/runtime/Animation2DStateMachineMixerAdapter.ts +197 -0
  186. package/src/animation-state-machine/runtime/AnimationStateMachineBlendTreeWeights.ts +503 -0
  187. package/src/animation-state-machine/runtime/AnimationStateMachineCompiler.ts +763 -0
  188. package/src/animation-state-machine/runtime/AnimationStateMachineController.ts +987 -0
  189. package/src/animation-state-machine/runtime/AnimationStateMachineMixerPort.ts +54 -0
  190. package/src/animation-state-machine/runtime/index.ts +47 -0
  191. package/src/animation.ts +33 -0
  192. package/src/animation3d/Animation3DAction.ts +73 -0
  193. package/src/animation3d/Animation3DBinding.ts +116 -0
  194. package/src/animation3d/Animation3DClip.ts +22 -0
  195. package/src/animation3d/Animation3DError.ts +34 -0
  196. package/src/animation3d/Animation3DMixer.ts +82 -0
  197. package/src/animation3d/Animation3DPose.ts +100 -0
  198. package/src/animation3d/Animation3DPoseBuffer.ts +85 -0
  199. package/src/animation3d/Animation3DResource.ts +49 -0
  200. package/src/animation3d/Animation3DStateMachine.ts +126 -0
  201. package/src/animation3d/Animation3DStateMachineRuntime.ts +191 -0
  202. package/src/animation3d/Animation3DTrack.ts +29 -0
  203. package/src/animation3d/hya/HyaAnimation3DRuntime.ts +756 -0
  204. package/src/animation3d/hya/HyaAnimation3DStateMachineRuntime.ts +618 -0
  205. package/src/animation3d/hya/HyaAnimation3DTypes.ts +168 -0
  206. package/src/animation3d/hya/index.ts +10 -0
  207. package/src/animation3d/index.ts +76 -0
  208. package/src/animation3d/runtime/integration/Animation3DStateMachineMixerAdapter.ts +325 -0
  209. package/src/animation3d/runtime/integration/Animation3DStateMachineMixerIntegration.ts +158 -0
  210. package/src/animation3d/runtime/integration/index.ts +9 -0
  211. package/src/animation3d/runtime/mixer/Action.ts +833 -0
  212. package/src/animation3d/runtime/mixer/Animation3DMixerRuntimeStore.ts +26 -0
  213. package/src/animation3d/runtime/mixer/Mixer.ts +562 -0
  214. package/src/animation3d/runtime/mixer/PoseBuffer.ts +1 -0
  215. package/src/animation3d/runtime/mixer/TrackSampler.ts +399 -0
  216. package/src/animation3d/runtime/mixer/index.ts +8 -0
  217. package/src/animation3d/runtime/state-machine/Animation3DBlendTreeWeights.ts +4 -0
  218. package/src/animation3d/runtime/state-machine/Animation3DStateMachineCompiler.ts +1 -0
  219. package/src/animation3d/runtime/state-machine/Animation3DStateMachineController.ts +1 -0
  220. package/src/animation3d/runtime/state-machine/Animation3DStateMachineMixerPort.ts +1 -0
  221. package/src/animation3d/runtime/state-machine/index.ts +45 -0
  222. package/src/animation3d.ts +5 -0
  223. package/src/benchmark.ts +168 -0
  224. package/src/canvas-text/CanvasText2DRenderSystem.ts +292 -0
  225. package/src/canvas-text/CanvasTextComponent.ts +47 -0
  226. package/src/canvas-text.ts +4 -0
  227. package/src/experimental-gltf-worker.ts +18 -0
  228. package/src/experimental-spine-worker.ts +9 -0
  229. package/src/gltf/GltfAccessorReader.ts +271 -0
  230. package/src/gltf/GltfAnimation3DAdapter.ts +680 -0
  231. package/src/gltf/GltfAnimationRuntime.ts +392 -0
  232. package/src/gltf/GltfAssetWorkerClient.ts +136 -0
  233. package/src/gltf/GltfCompatibilityReport.ts +214 -0
  234. package/src/gltf/GltfConservativeBounds.ts +219 -0
  235. package/src/gltf/GltfDracoDecoder.ts +251 -0
  236. package/src/gltf/GltfExtensionAdapter.ts +340 -0
  237. package/src/gltf/GltfLoaderContract.ts +333 -0
  238. package/src/gltf/GltfLoaderErrors.ts +59 -0
  239. package/src/gltf/GltfMaterialDescriptor.ts +134 -0
  240. package/src/gltf/GltfMaterialEncoder.ts +173 -0
  241. package/src/gltf/GltfMaterialLoader.ts +293 -0
  242. package/src/gltf/GltfModelComponent.ts +115 -0
  243. package/src/gltf/GltfModelSystem.ts +208 -0
  244. package/src/gltf/GltfPlugin.ts +84 -0
  245. package/src/gltf/GltfSchema.ts +229 -0
  246. package/src/gltf/GltfUvSemanticPlanner.ts +166 -0
  247. package/src/gltf/gltfLoader.ts +910 -0
  248. package/src/gltf-animation3d.ts +10 -0
  249. package/src/gltf-worker-runtime.ts +10 -0
  250. package/src/gltf.ts +56 -0
  251. package/src/grid/Grid2DComponent.ts +69 -0
  252. package/src/grid.ts +2 -0
  253. package/src/hya-state-machine.ts +19 -0
  254. package/src/index.ts +2 -0
  255. package/src/plugins/pluginUtils.ts +50 -0
  256. package/src/plugins.ts +6 -0
  257. package/src/shaders/generated/2d-ui-animation-2d.generated.wgsl +242 -0
  258. package/src/shaders/generated/2d-ui-artifact.generated.ts +867 -0
  259. package/src/shaders/generated/2d-ui-canvas-text-2d.generated.wgsl +38 -0
  260. package/src/shaders/generated/2d-ui-spine2d.generated.wgsl +41 -0
  261. package/src/shaders/generated/2d-ui-tilemap2d.generated.wgsl +36 -0
  262. package/src/spine/Spine2DComponent.ts +168 -0
  263. package/src/spine/Spine2DGpuRenderer.ts +449 -0
  264. package/src/spine/Spine2DRenderSystem.ts +199 -0
  265. package/src/spine/Spine2DRuntime.ts +1529 -0
  266. package/src/spine/SpineAnimationBoneTimelines.ts +30 -0
  267. package/src/spine/SpineAssetParser.ts +20 -0
  268. package/src/spine/SpineAssetWorkerClient.ts +112 -0
  269. package/src/spine/SpineAssetWorkerContract.ts +4 -0
  270. package/src/spine/SpineAtlasParser.ts +127 -0
  271. package/src/spine/SpineFloatBuilder.ts +66 -0
  272. package/src/spine/SpinePathConstraintSolver.ts +582 -0
  273. package/src/spine/SpinePlugin.ts +76 -0
  274. package/src/spine/SpineSkeletonRuntime.ts +521 -0
  275. package/src/spine/SpineSlotAnimation.ts +195 -0
  276. package/src/spine/SpineTimelineRuntime.ts +453 -0
  277. package/src/spine/SpineVertexBuilder.ts +686 -0
  278. package/src/spine.ts +7 -0
  279. package/src/tilemap/Tilemap2DComponent.ts +232 -0
  280. package/src/tilemap/Tilemap2DRenderSystem.ts +58 -0
  281. package/src/tilemap/Tilemap2DRenderer.ts +289 -0
  282. package/src/tilemap/TilemapPlugin.ts +75 -0
  283. package/src/tilemap.ts +6 -0
  284. package/src/tween/Tween2DComponent.ts +83 -0
  285. package/src/tween/Tween2DSystem.ts +78 -0
  286. package/src/tween.ts +4 -0
  287. package/src/types/earcut.d.ts +7 -0
  288. package/src/types/wgsl.d.ts +4 -0
  289. package/src/utils/RenderSystem2DBase.ts +164 -0
  290. package/src/utils/arrayAccess.ts +17 -0
  291. package/src/utils/camera2d.ts +68 -0
  292. package/src/utils/render2dGpu.ts +132 -0
  293. package/test/fixtures/gltf/animation-characterization.gltf +344 -0
@@ -0,0 +1,399 @@
1
+ import type { Animation3DTrack } from '../../Animation3DTrack.js';
2
+ import { Animation3DError } from '../../Animation3DError.js';
3
+
4
+ const SLERP_LINEAR_THRESHOLD = 0.9995;
5
+
6
+ /**
7
+ * Stateful, allocation-free sampler for one immutable track.
8
+ *
9
+ * The sampler owns one reusable output buffer and a key cursor optimized for
10
+ * coherent playback. Callers may provide another destination when needed.
11
+ */
12
+ export class Animation3DTrackSampler {
13
+ readonly track: Animation3DTrack;
14
+ readonly valueSize: number;
15
+ readonly output: Float32Array;
16
+
17
+ private _cursor = 0;
18
+
19
+ constructor(track: Animation3DTrack) {
20
+ validateAnimation3DTrack(track);
21
+ this.track = track;
22
+ this.valueSize = track.binding.valueSize;
23
+ this.output = new Float32Array(this.valueSize);
24
+ }
25
+
26
+ sample(timeSeconds: number, out: Float32Array = this.output): Float32Array {
27
+ if (!Number.isFinite(timeSeconds)) {
28
+ throw new RangeError(`Animation3D track sample time must be finite; received ${timeSeconds}.`);
29
+ }
30
+ if (out.length < this.valueSize) {
31
+ throw new RangeError(
32
+ `Animation3D track output requires ${this.valueSize} values; received ${out.length}.`,
33
+ );
34
+ }
35
+
36
+ const times = this.track.times;
37
+ const keyCount = times.length;
38
+ if (keyCount === 1 || timeSeconds <= times[0]!) {
39
+ this._copyKeyValue(0, out);
40
+ this._cursor = 0;
41
+ return out;
42
+ }
43
+ const lastIndex = keyCount - 1;
44
+ if (timeSeconds >= times[lastIndex]!) {
45
+ this._copyKeyValue(lastIndex, out);
46
+ this._cursor = Math.max(0, lastIndex - 1);
47
+ return out;
48
+ }
49
+
50
+ const keyIndex = this._findInterval(timeSeconds);
51
+ if (this.track.interpolation === 'step') {
52
+ this._copyKeyValue(keyIndex, out);
53
+ return out;
54
+ }
55
+
56
+ const startTime = times[keyIndex]!;
57
+ const endTime = times[keyIndex + 1]!;
58
+ const alpha = (timeSeconds - startTime) / (endTime - startTime);
59
+ if (this.track.interpolation === 'cubic-spline') {
60
+ this._sampleCubic(keyIndex, endTime - startTime, alpha, out);
61
+ } else if (this.track.binding.valueType === 'quaternion') {
62
+ this._sampleQuaternionLinear(keyIndex, alpha, out);
63
+ } else {
64
+ this._sampleLinear(keyIndex, alpha, out);
65
+ }
66
+ return out;
67
+ }
68
+
69
+ resetCursor(): void {
70
+ this._cursor = 0;
71
+ }
72
+
73
+ private _findInterval(timeSeconds: number): number {
74
+ const times = this.track.times;
75
+ let cursor = Math.min(this._cursor, times.length - 2);
76
+ if (timeSeconds >= times[cursor]! && timeSeconds < times[cursor + 1]!) {
77
+ return cursor;
78
+ }
79
+
80
+ if (timeSeconds >= times[cursor + 1]!) {
81
+ while (cursor + 2 < times.length && timeSeconds >= times[cursor + 1]!) cursor++;
82
+ this._cursor = cursor;
83
+ return cursor;
84
+ }
85
+
86
+ let low = 0;
87
+ let high = cursor;
88
+ while (low <= high) {
89
+ const middle = (low + high) >>> 1;
90
+ if (timeSeconds < times[middle]!) {
91
+ high = middle - 1;
92
+ } else if (timeSeconds >= times[middle + 1]!) {
93
+ low = middle + 1;
94
+ } else {
95
+ this._cursor = middle;
96
+ return middle;
97
+ }
98
+ }
99
+ this._cursor = Math.max(0, low);
100
+ return this._cursor;
101
+ }
102
+
103
+ private _copyKeyValue(keyIndex: number, out: Float32Array): void {
104
+ const size = this.valueSize;
105
+ const values = this.track.values;
106
+ const offset = this.track.interpolation === 'cubic-spline'
107
+ ? keyIndex * size * 3 + size
108
+ : keyIndex * size;
109
+ for (let component = 0; component < size; component++) {
110
+ out[component] = values[offset + component]!;
111
+ }
112
+ if (this.track.binding.valueType === 'quaternion') normalizeQuaternion(out);
113
+ }
114
+
115
+ private _sampleLinear(keyIndex: number, alpha: number, out: Float32Array): void {
116
+ const size = this.valueSize;
117
+ const values = this.track.values;
118
+ const startOffset = keyIndex * size;
119
+ const endOffset = startOffset + size;
120
+ for (let component = 0; component < size; component++) {
121
+ const start = values[startOffset + component]!;
122
+ out[component] = start + (values[endOffset + component]! - start) * alpha;
123
+ }
124
+ }
125
+
126
+ private _sampleQuaternionLinear(keyIndex: number, alpha: number, out: Float32Array): void {
127
+ const values = this.track.values;
128
+ const startOffset = keyIndex * 4;
129
+ const endOffset = startOffset + 4;
130
+ const ax = values[startOffset]!;
131
+ const ay = values[startOffset + 1]!;
132
+ const az = values[startOffset + 2]!;
133
+ const aw = values[startOffset + 3]!;
134
+ let bx = values[endOffset]!;
135
+ let by = values[endOffset + 1]!;
136
+ let bz = values[endOffset + 2]!;
137
+ let bw = values[endOffset + 3]!;
138
+ let dot = ax * bx + ay * by + az * bz + aw * bw;
139
+
140
+ if (dot < 0) {
141
+ dot = -dot;
142
+ bx = -bx;
143
+ by = -by;
144
+ bz = -bz;
145
+ bw = -bw;
146
+ }
147
+ dot = Math.min(1, Math.max(-1, dot));
148
+
149
+ if (dot > SLERP_LINEAR_THRESHOLD) {
150
+ out[0] = ax + (bx - ax) * alpha;
151
+ out[1] = ay + (by - ay) * alpha;
152
+ out[2] = az + (bz - az) * alpha;
153
+ out[3] = aw + (bw - aw) * alpha;
154
+ normalizeQuaternion(out);
155
+ return;
156
+ }
157
+
158
+ const theta = Math.acos(dot);
159
+ const sinTheta = Math.sin(theta);
160
+ const startWeight = Math.sin((1 - alpha) * theta) / sinTheta;
161
+ const endWeight = Math.sin(alpha * theta) / sinTheta;
162
+ out[0] = ax * startWeight + bx * endWeight;
163
+ out[1] = ay * startWeight + by * endWeight;
164
+ out[2] = az * startWeight + bz * endWeight;
165
+ out[3] = aw * startWeight + bw * endWeight;
166
+ normalizeQuaternion(out);
167
+ }
168
+
169
+ private _sampleCubic(
170
+ keyIndex: number,
171
+ keyDuration: number,
172
+ alpha: number,
173
+ out: Float32Array,
174
+ ): void {
175
+ const size = this.valueSize;
176
+ const values = this.track.values;
177
+ const startGroup = keyIndex * size * 3;
178
+ const endGroup = startGroup + size * 3;
179
+ const startValue = startGroup + size;
180
+ const startOutTangent = startGroup + size * 2;
181
+ const endInTangent = endGroup;
182
+ const endValue = endGroup + size;
183
+ const alpha2 = alpha * alpha;
184
+ const alpha3 = alpha2 * alpha;
185
+ const h00 = 2 * alpha3 - 3 * alpha2 + 1;
186
+ const h10 = alpha3 - 2 * alpha2 + alpha;
187
+ const h01 = -2 * alpha3 + 3 * alpha2;
188
+ const h11 = alpha3 - alpha2;
189
+
190
+ for (let component = 0; component < size; component++) {
191
+ out[component] = h00 * values[startValue + component]!
192
+ + h10 * keyDuration * values[startOutTangent + component]!
193
+ + h01 * values[endValue + component]!
194
+ + h11 * keyDuration * values[endInTangent + component]!;
195
+ }
196
+ if (this.track.binding.valueType === 'quaternion') normalizeQuaternion(out);
197
+ }
198
+ }
199
+
200
+ /** @internal Shared by clip admission and direct sampler construction. */
201
+ export function validateAnimation3DTrack(
202
+ track: Animation3DTrack,
203
+ clipDuration = Infinity,
204
+ ): void {
205
+ const trackId = typeof track?.id === 'string' ? track.id : '';
206
+ const fail = (message: string): never => {
207
+ throw new Animation3DError(
208
+ 'invalid-track',
209
+ message,
210
+ { trackId },
211
+ );
212
+ };
213
+ if (!track || typeof track !== 'object') {
214
+ fail('Animation3D track must be an object.');
215
+ }
216
+ if (trackId.trim().length === 0) {
217
+ fail('Animation3D track id must not be empty.');
218
+ }
219
+ if (!track.binding || typeof track.binding !== 'object') {
220
+ fail(`Animation3D track "${trackId}" requires a binding.`);
221
+ }
222
+ if (typeof track.binding.id !== 'string' || track.binding.id.trim().length === 0) {
223
+ fail(`Animation3D track "${trackId}" binding id must not be empty.`);
224
+ }
225
+ validateBindingTarget(track, fail);
226
+ const size = track.binding.valueSize;
227
+ if (!Number.isInteger(size) || size <= 0) {
228
+ fail(`Animation3D binding valueSize must be a positive integer; received ${size}.`);
229
+ }
230
+ const fixedSize = fixedBindingValueSize(track.binding.valueType);
231
+ if (fixedSize !== null && Number.isNaN(fixedSize)) {
232
+ fail(`Animation3D track "${trackId}" has an unsupported binding value type.`);
233
+ }
234
+ if (fixedSize !== null && size !== fixedSize) {
235
+ fail(
236
+ `Animation3D ${track.binding.valueType} binding requires ${fixedSize} values; received ${size}.`,
237
+ );
238
+ }
239
+ if (track.binding.valueType === 'weights' && !Number.isSafeInteger(size)) {
240
+ fail(`Animation3D weights binding valueSize must be a positive safe integer; received ${size}.`);
241
+ }
242
+ validateBindingPath(track, size, fail);
243
+ if (
244
+ track.interpolation !== 'step'
245
+ && track.interpolation !== 'linear'
246
+ && track.interpolation !== 'cubic-spline'
247
+ ) {
248
+ fail(`Animation3D track "${trackId}" has an unsupported interpolation.`);
249
+ }
250
+ if (!(track.times instanceof Float32Array)) {
251
+ fail(`Animation3D track "${trackId}" times must be a Float32Array.`);
252
+ }
253
+ if (!(track.values instanceof Float32Array)) {
254
+ fail(`Animation3D track "${trackId}" values must be a Float32Array.`);
255
+ }
256
+ if (track.times.length === 0) {
257
+ fail(`Animation3D track "${trackId}" must contain at least one key.`);
258
+ }
259
+ for (let index = 0; index < track.times.length; index++) {
260
+ const time = track.times[index]!;
261
+ if (!Number.isFinite(time) || time < 0 || time > clipDuration
262
+ || (index > 0 && time <= track.times[index - 1]!)) {
263
+ fail(
264
+ `Animation3D track "${trackId}" key times must be finite, non-negative, `
265
+ + 'strictly increasing, and within the clip duration.',
266
+ );
267
+ }
268
+ }
269
+ const stride = track.interpolation === 'cubic-spline' ? size * 3 : size;
270
+ const expectedValues = track.times.length * stride;
271
+ if (track.values.length !== expectedValues) {
272
+ fail(
273
+ `Animation3D track "${trackId}" requires ${expectedValues} values; received ${track.values.length}.`,
274
+ );
275
+ }
276
+ for (let index = 0; index < track.values.length; index++) {
277
+ if (!Number.isFinite(track.values[index])) {
278
+ fail(`Animation3D track "${trackId}" values must be finite.`);
279
+ }
280
+ }
281
+ if (track.binding.valueType === 'quaternion') {
282
+ const groupStride = track.interpolation === 'cubic-spline' ? size * 3 : size;
283
+ const valueOffset = track.interpolation === 'cubic-spline' ? size : 0;
284
+ for (let keyIndex = 0; keyIndex < track.times.length; keyIndex++) {
285
+ const offset = keyIndex * groupStride + valueOffset;
286
+ const length = Math.hypot(
287
+ track.values[offset]!,
288
+ track.values[offset + 1]!,
289
+ track.values[offset + 2]!,
290
+ track.values[offset + 3]!,
291
+ );
292
+ if (length <= Number.EPSILON) {
293
+ fail(`Animation3D track "${trackId}" contains a zero-length quaternion key.`);
294
+ }
295
+ }
296
+ }
297
+ }
298
+
299
+ function validateBindingTarget(
300
+ track: Animation3DTrack,
301
+ fail: (message: string) => never,
302
+ ): void {
303
+ const { target } = track.binding;
304
+ if (!target || typeof target !== 'object') {
305
+ fail(`Animation3D track "${track.id}" binding requires a target.`);
306
+ }
307
+ if (target.kind === 'node-id') {
308
+ if (typeof target.nodeId !== 'string' || target.nodeId.trim().length === 0) {
309
+ fail(`Animation3D track "${track.id}" node-id target must not be empty.`);
310
+ }
311
+ return;
312
+ }
313
+ if (target.kind === 'node-path') {
314
+ if (!Array.isArray(target.segments)
315
+ || target.segments.some(segment => typeof segment !== 'string')) {
316
+ fail(`Animation3D track "${track.id}" node-path target must contain string segments.`);
317
+ }
318
+ return;
319
+ }
320
+ if (target.kind === 'slot') {
321
+ if (typeof target.slot !== 'string' || target.slot.trim().length === 0) {
322
+ fail(`Animation3D track "${track.id}" slot target must not be empty.`);
323
+ }
324
+ return;
325
+ }
326
+ fail(`Animation3D track "${track.id}" has an unsupported binding target.`);
327
+ }
328
+
329
+ function validateBindingPath(
330
+ track: Animation3DTrack,
331
+ size: number,
332
+ fail: (message: string) => never,
333
+ ): void {
334
+ const { binding } = track;
335
+ if (binding.path === 'transform.translation') {
336
+ if (binding.valueType !== 'vec3' || size !== 3) {
337
+ fail('Animation3D translation tracks require a vec3 binding.');
338
+ }
339
+ return;
340
+ }
341
+ if (binding.path === 'transform.rotation') {
342
+ if (binding.valueType !== 'quaternion' || size !== 4) {
343
+ fail('Animation3D rotation tracks require a quaternion binding.');
344
+ }
345
+ return;
346
+ }
347
+ if (binding.path === 'transform.scale') {
348
+ if (binding.valueType !== 'vec3' || size !== 3) {
349
+ fail('Animation3D scale tracks require a vec3 binding.');
350
+ }
351
+ return;
352
+ }
353
+ if (binding.path === 'morph.weights') {
354
+ if (binding.valueType !== 'weights') {
355
+ fail('Animation3D morph tracks require a weights binding.');
356
+ }
357
+ return;
358
+ }
359
+ if (binding.path === 'property') {
360
+ if (String(binding.valueType) === 'weights'
361
+ || typeof binding.component !== 'string'
362
+ || binding.component.trim().length === 0
363
+ || typeof binding.property !== 'string'
364
+ || binding.property.trim().length === 0) {
365
+ fail('Animation3D property tracks require component, property, and a fixed value type.');
366
+ }
367
+ return;
368
+ }
369
+ fail(`Animation3D track "${track.id}" has an unsupported binding path.`);
370
+ }
371
+
372
+ function fixedBindingValueSize(valueType: string): number | null {
373
+ if (valueType === 'scalar') return 1;
374
+ if (valueType === 'vec2') return 2;
375
+ if (valueType === 'vec3') return 3;
376
+ if (valueType === 'vec4' || valueType === 'quaternion') return 4;
377
+ if (valueType === 'weights') return null;
378
+ return Number.NaN;
379
+ }
380
+
381
+ export function normalizeQuaternion(value: Float32Array): void {
382
+ const x = value[0]!;
383
+ const y = value[1]!;
384
+ const z = value[2]!;
385
+ const w = value[3]!;
386
+ const length = Math.hypot(x, y, z, w);
387
+ if (length <= Number.EPSILON) {
388
+ value[0] = 0;
389
+ value[1] = 0;
390
+ value[2] = 0;
391
+ value[3] = 1;
392
+ return;
393
+ }
394
+ const inverseLength = 1 / length;
395
+ value[0] = x * inverseLength;
396
+ value[1] = y * inverseLength;
397
+ value[2] = z * inverseLength;
398
+ value[3] = w * inverseLength;
399
+ }
@@ -0,0 +1,8 @@
1
+ export {
2
+ Animation3DActionRuntime,
3
+ type Animation3DActionOwner,
4
+ type Animation3DActionTrackRuntime,
5
+ } from './Action.js';
6
+ export { Animation3DMixerRuntime } from './Mixer.js';
7
+ export { Animation3DPoseBuffer } from './PoseBuffer.js';
8
+ export { Animation3DTrackSampler } from './TrackSampler.js';
@@ -0,0 +1,4 @@
1
+ export {
2
+ evaluateAnimation3DBlend1DWeights,
3
+ evaluateAnimation3DBlend2DWeights,
4
+ } from '../../../animation-state-machine/runtime/AnimationStateMachineBlendTreeWeights.js';
@@ -0,0 +1 @@
1
+ export * from '../../../animation-state-machine/runtime/AnimationStateMachineCompiler.js';
@@ -0,0 +1 @@
1
+ export * from '../../../animation-state-machine/runtime/AnimationStateMachineController.js';
@@ -0,0 +1 @@
1
+ export * from '../../../animation-state-machine/runtime/AnimationStateMachineMixerPort.js';
@@ -0,0 +1,45 @@
1
+ export {
2
+ evaluateAnimation3DBlend1DWeights,
3
+ evaluateAnimation3DBlend2DWeights,
4
+ } from './Animation3DBlendTreeWeights.js';
5
+ export {
6
+ Animation3DStateMachineValidationError,
7
+ compileAnimation3DStateMachine,
8
+ compileAnimation3DStateMachineDefinition,
9
+ validateAnimation3DStateMachineDefinition,
10
+ } from './Animation3DStateMachineCompiler.js';
11
+ export type {
12
+ Animation3DStateMachineValidationCode,
13
+ Animation3DStateMachineValidationIssue,
14
+ CompiledAnimation3DBlend1DChild,
15
+ CompiledAnimation3DBlend1DMotion,
16
+ CompiledAnimation3DBlend2DChild,
17
+ CompiledAnimation3DBlend2DMotion,
18
+ CompiledAnimation3DClipMotion,
19
+ CompiledAnimation3DCondition,
20
+ CompiledAnimation3DConditionOperator,
21
+ CompiledAnimation3DLayer,
22
+ CompiledAnimation3DMotion,
23
+ CompiledAnimation3DParameter,
24
+ CompiledAnimation3DParameterType,
25
+ CompiledAnimation3DState,
26
+ CompiledAnimation3DStateMachine,
27
+ CompiledAnimation3DTransition,
28
+ } from './Animation3DStateMachineCompiler.js';
29
+ export {
30
+ Animation3DStateMachineController,
31
+ createAnimation3DStateMachineController,
32
+ } from './Animation3DStateMachineController.js';
33
+ export type {
34
+ Animation3DStateMachineControllerOptions,
35
+ Animation3DStateMachineControllerStatus,
36
+ Animation3DStateMachineLayerSnapshot,
37
+ } from './Animation3DStateMachineController.js';
38
+ export type {
39
+ AnimationStateMachineActionHandle,
40
+ AnimationStateMachineActionOptions,
41
+ AnimationStateMachineMixerPort,
42
+ Animation3DStateMachineActionHandle,
43
+ Animation3DStateMachineActionOptions,
44
+ Animation3DStateMachineMixerPort,
45
+ } from './Animation3DStateMachineMixerPort.js';
@@ -0,0 +1,5 @@
1
+ /** Stable, source-independent 3D animation runtime. */
2
+ export * from './animation3d/index.js';
3
+ /** Stable HYA adapter for the source-independent 3D runtime. */
4
+ export { HyaAnimation3DRuntime, createHyaAnimation3DRuntime } from './animation3d/hya/HyaAnimation3DRuntime.js';
5
+ export type * from './animation3d/hya/HyaAnimation3DTypes.js';
@@ -0,0 +1,168 @@
1
+ import { parseAtlas } from './spine/SpineAtlasParser';
2
+ import { normalizeSpineData } from './spine/SpineSkeletonRuntime';
3
+ import { Spine2DComponent } from './spine/Spine2DComponent';
4
+ import {
5
+ advanceSpineRuntime,
6
+ buildSpineVertices,
7
+ createSpineRuntimeForBenchmark,
8
+ sampleSpinePosesForBenchmark,
9
+ type SpineRuntime,
10
+ } from './spine/Spine2DRuntime';
11
+ import type { AtlasPageGpu } from './spine/Spine2DGpuRenderer';
12
+ import type { AtlasRegion } from './spine/SpineAtlasParser';
13
+ import {
14
+ compileSpineTimelines,
15
+ createSpineTimelineSamplerState,
16
+ findCompiledFrameIndex,
17
+ sampleCompiledColor,
18
+ sampleCompiledTimeline,
19
+ type SpineTimelineSamplerState,
20
+ } from './spine/SpineTimelineRuntime';
21
+
22
+ /** Internal benchmark adapter. This file is built for the monorepo harness, not exported by the package. */
23
+ export function benchmarkSpineParse(
24
+ data: { bones: Array<{ name: string; parent?: string }>; slots: Array<{ name: string; bone?: string }>; skins?: object },
25
+ atlas: string,
26
+ ): number {
27
+ return normalizeSpineData(data).bones.length + parseAtlas(atlas).size;
28
+ }
29
+
30
+ export interface SpineAnimationBenchmarkState {
31
+ readonly component: Spine2DComponent;
32
+ readonly runtime: SpineRuntime;
33
+ readonly boneCount: number;
34
+ readonly slotCount: number;
35
+ readonly keyframeCount: number;
36
+ }
37
+
38
+ export function createSpineAnimationBenchmarkState(
39
+ boneCount: number,
40
+ slotCount: number,
41
+ keyframeCount: number,
42
+ ): SpineAnimationBenchmarkState {
43
+ const animationDuration = 2;
44
+ const frameStep = animationDuration / Math.max(1, keyframeCount - 1);
45
+ const bones = Array.from({ length: boneCount }, (_, boneIndex) => ({
46
+ name: `bone${boneIndex}`,
47
+ ...(boneIndex > 0 ? { parent: `bone${boneIndex - 1}` } : {}),
48
+ x: boneIndex > 0 ? 1 : 0,
49
+ length: 1,
50
+ }));
51
+ const slots = Array.from({ length: slotCount }, (_, slotIndex) => ({
52
+ name: `slot${slotIndex}`,
53
+ bone: `bone${slotIndex % boneCount}`,
54
+ attachment: `region${slotIndex}`,
55
+ }));
56
+ const skin: Record<string, Record<string, object>> = {};
57
+ const slotAnimations: Record<string, object> = {};
58
+ const atlas = new Map<string, AtlasRegion>();
59
+ for (let slotIndex = 0; slotIndex < slotCount; slotIndex++) {
60
+ const regionName = `region${slotIndex}`;
61
+ skin[`slot${slotIndex}`] = {
62
+ [regionName]: { type: 'region', name: regionName, path: regionName, width: 8, height: 8 },
63
+ };
64
+ slotAnimations[`slot${slotIndex}`] = {
65
+ rgba: [
66
+ { 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] },
67
+ { time: animationDuration, color: '80a0c0ff' },
68
+ ],
69
+ };
70
+ atlas.set(regionName, {
71
+ name: regionName,
72
+ page: 'page.png',
73
+ x: (slotIndex % 16) * 8,
74
+ y: Math.floor(slotIndex / 16) * 8,
75
+ width: 8,
76
+ height: 8,
77
+ originalWidth: 8,
78
+ originalHeight: 8,
79
+ offsetX: 0,
80
+ offsetY: 0,
81
+ rotate: 0,
82
+ });
83
+ }
84
+ const boneAnimations: Record<string, object> = {};
85
+ for (let boneIndex = 0; boneIndex < boneCount; boneIndex++) {
86
+ const rotate = [];
87
+ const translate = [];
88
+ for (let frameIndex = 0; frameIndex < keyframeCount; frameIndex++) {
89
+ const time = frameIndex * frameStep;
90
+ const angle = Math.sin(frameIndex * 0.17 + boneIndex * 0.03) * 20;
91
+ const nextAngle = Math.sin((frameIndex + 1) * 0.17 + boneIndex * 0.03) * 20;
92
+ rotate.push(frameIndex + 1 < keyframeCount
93
+ ? { time, angle, curve: [time + frameStep * 0.25, angle, time + frameStep * 0.75, nextAngle] }
94
+ : { time, angle });
95
+ translate.push({ time, x: Math.sin(frameIndex * 0.11) * 0.1, y: Math.cos(frameIndex * 0.13) * 0.1 });
96
+ }
97
+ boneAnimations[`bone${boneIndex}`] = { rotate, translate };
98
+ }
99
+ const data = normalizeSpineData({
100
+ bones,
101
+ slots,
102
+ skins: { default: skin },
103
+ animations: { benchmark: { bones: boneAnimations, slots: slotAnimations } },
104
+ });
105
+ const pages = new Map<string, AtlasPageGpu>([[
106
+ 'page.png',
107
+ {
108
+ image: null as unknown as HTMLImageElement,
109
+ texture: null as unknown as GPUTexture,
110
+ textureBindGroup: null as unknown as GPUBindGroup,
111
+ width: 256,
112
+ height: 256,
113
+ },
114
+ ]]);
115
+ return {
116
+ component: new Spine2DComponent({ animation: 'benchmark', loop: true }),
117
+ runtime: createSpineRuntimeForBenchmark(data, atlas, pages),
118
+ boneCount,
119
+ slotCount,
120
+ keyframeCount,
121
+ };
122
+ }
123
+
124
+ export function benchmarkSpineAnimationSample(state: SpineAnimationBenchmarkState): number {
125
+ advanceSpineRuntime(state.component, 16);
126
+ return sampleSpinePosesForBenchmark(state.component, state.runtime);
127
+ }
128
+
129
+ export function benchmarkSpineVertexBuild(state: SpineAnimationBenchmarkState): number {
130
+ advanceSpineRuntime(state.component, 16);
131
+ const result = buildSpineVertices(state.component, state.runtime);
132
+ return result.vertices.length + result.batches.length + result.vertexDirtyRanges.length;
133
+ }
134
+
135
+ export function benchmarkCompileSpineTimeline(frames: unknown[]): number {
136
+ return compileSpineTimelines({ benchmark: { timeline: frames } }).frameCount;
137
+ }
138
+
139
+ export function benchmarkCreateSpineTimelineSamplerState(): SpineTimelineSamplerState {
140
+ return createSpineTimelineSamplerState();
141
+ }
142
+
143
+ export function benchmarkSampleSpineTimeline(
144
+ frames: unknown[],
145
+ time: number,
146
+ key: string,
147
+ fallback: number,
148
+ samplerState?: SpineTimelineSamplerState,
149
+ ): number {
150
+ return sampleCompiledTimeline(frames, time, key, fallback, 0, false, samplerState);
151
+ }
152
+
153
+ export function benchmarkFindSpineFrame(
154
+ frames: unknown[],
155
+ time: number,
156
+ samplerState?: SpineTimelineSamplerState,
157
+ ): number {
158
+ return findCompiledFrameIndex(frames, time, samplerState);
159
+ }
160
+
161
+ export function benchmarkSampleSpineColor(
162
+ frames: unknown[],
163
+ time: number,
164
+ fallback: [number, number, number, number],
165
+ out: [number, number, number, number],
166
+ ): [number, number, number, number] {
167
+ return sampleCompiledColor(frames, time, fallback, out);
168
+ }