@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,26 @@
1
+ import type { Animation3DMixer } from '../../Animation3DMixer.js';
2
+ import type { Animation3DMixerRuntime } from './Mixer.js';
3
+
4
+ const MIXER_RUNTIMES = new WeakMap<
5
+ Animation3DMixer,
6
+ Animation3DMixerRuntime
7
+ >();
8
+
9
+ /** @internal Connects the public facade to controller-only runtime operations. */
10
+ export function registerAnimation3DMixerRuntime(
11
+ mixer: Animation3DMixer,
12
+ runtime: Animation3DMixerRuntime,
13
+ ): void {
14
+ MIXER_RUNTIMES.set(mixer, runtime);
15
+ }
16
+
17
+ /** @internal Used only by the state-machine facade integration. */
18
+ export function animation3DMixerRuntime(
19
+ mixer: Animation3DMixer,
20
+ ): Animation3DMixerRuntime {
21
+ const runtime = MIXER_RUNTIMES.get(mixer);
22
+ if (!runtime) {
23
+ throw new TypeError('Expected an Animation3DMixer facade instance.');
24
+ }
25
+ return runtime;
26
+ }
@@ -0,0 +1,562 @@
1
+ import type {
2
+ Animation3DBinding,
3
+ Animation3DBindingResolver,
4
+ Animation3DResolvedBinding,
5
+ } from '../../Animation3DBinding.js';
6
+ import type { Animation3DAction, Animation3DActionOptions } from '../../Animation3DAction.js';
7
+ import type { Animation3DClip } from '../../Animation3DClip.js';
8
+ import { Animation3DError } from '../../Animation3DError.js';
9
+ import type { Animation3DMixerState } from '../../Animation3DMixer.js';
10
+ import type { Animation3DMutablePose, Animation3DPose } from '../../Animation3DPose.js';
11
+ import {
12
+ Animation3DActionRuntime,
13
+ type Animation3DActionOwner,
14
+ type Animation3DActionTrackRuntime,
15
+ } from './Action.js';
16
+ import { normalizeQuaternion } from './TrackSampler.js';
17
+
18
+ interface BindingAccumulator {
19
+ readonly binding: Animation3DBinding;
20
+ readonly base: Float32Array;
21
+ readonly result: Float32Array;
22
+ readonly overrideSum: Float32Array;
23
+ readonly additiveSum: Float32Array;
24
+ readonly quaternionAnchor: Float32Array;
25
+ readonly additiveQuaternion: Float32Array;
26
+ references: number;
27
+ active: boolean;
28
+ overrideWeight: number;
29
+ quaternionAnchorSet: boolean;
30
+ additiveQuaternionUsed: boolean;
31
+ }
32
+
33
+ /**
34
+ * Contract-compatible Animation3D mixer runtime.
35
+ *
36
+ * Clips remain caller-owned immutable values. The mixer caches only samplers,
37
+ * blend accumulators, and resolver results; it never retains AssetHandles.
38
+ */
39
+ export class Animation3DMixerRuntime implements Animation3DActionOwner {
40
+ readonly resolver: Animation3DBindingResolver;
41
+
42
+ private readonly _actions: Animation3DActionRuntime[] = [];
43
+ private readonly _actionsById = new Map<string, Animation3DActionRuntime>();
44
+ private readonly _accumulators = new Map<string, BindingAccumulator>();
45
+ private readonly _accumulatorList: BindingAccumulator[] = [];
46
+ private readonly _resolvedBindings = new Map<string, Animation3DResolvedBinding | null>();
47
+ private _resolverRevision = Number.NaN;
48
+ private _state: Animation3DMixerState = 'active';
49
+ private _time = 0;
50
+ private _timeScale = 1;
51
+ private _nextActionId = 1;
52
+ private _synchronizedFrameOut: Animation3DMutablePose | null = null;
53
+ private _synchronizedPreviousTime = 0;
54
+
55
+ constructor(resolver: Animation3DBindingResolver) {
56
+ this.resolver = resolver;
57
+ }
58
+
59
+ get state(): Animation3DMixerState { return this._state; }
60
+ get actions(): readonly Animation3DAction[] { return this._actions; }
61
+ get liveBindingCount(): number { return this._accumulators.size; }
62
+ get time(): number { return this._time; }
63
+ get timeScale(): number { return this._timeScale; }
64
+ set timeScale(value: number) {
65
+ this.assertActive();
66
+ if (!Number.isFinite(value)) {
67
+ throw new RangeError(`Animation3DMixer.timeScale must be finite; received ${value}.`);
68
+ }
69
+ this._timeScale = value;
70
+ }
71
+
72
+ createAction(clip: Animation3DClip, options: Animation3DActionOptions = {}): Animation3DAction {
73
+ this.assertActive();
74
+ const clipId = typeof clip?.id === 'string' ? clip.id : '';
75
+ const id = options.id ?? `${clipId}:${this._nextActionId++}`;
76
+ if (!id) {
77
+ throw new Animation3DError(
78
+ 'invalid-action',
79
+ 'Animation3D action id must not be empty.',
80
+ { clipId },
81
+ );
82
+ }
83
+ if (this._actionsById.has(id)) {
84
+ throw new Animation3DError(
85
+ 'duplicate-action-id',
86
+ `Animation3D action id "${id}" already exists in this mixer.`,
87
+ { actionId: id },
88
+ );
89
+ }
90
+ const action = new Animation3DActionRuntime(this, clip, id, options);
91
+ for (let index = 0; index < action.runtimeTracks.length; index++) {
92
+ this._retainBinding(action.runtimeTracks[index]!.track.binding);
93
+ }
94
+ this._actions.push(action);
95
+ this._actionsById.set(id, action);
96
+ return action;
97
+ }
98
+
99
+ getAction(actionId: string): Animation3DAction | null {
100
+ this.assertActive();
101
+ return this._actionsById.get(actionId) ?? null;
102
+ }
103
+
104
+ removeAction(action: Animation3DAction | string): boolean {
105
+ this.assertActive();
106
+ const runtime = typeof action === 'string'
107
+ ? this._actionsById.get(action)
108
+ : action instanceof Animation3DActionRuntime
109
+ ? action
110
+ : undefined;
111
+ if (!runtime || this._actionsById.get(runtime.id) !== runtime) return false;
112
+ const index = this._actions.indexOf(runtime);
113
+ if (index >= 0) this._actions.splice(index, 1);
114
+ this._actionsById.delete(runtime.id);
115
+ for (let trackIndex = 0; trackIndex < runtime.runtimeTracks.length; trackIndex++) {
116
+ this._releaseBinding(runtime.runtimeTracks[trackIndex]!.track.binding);
117
+ }
118
+ runtime.invalidate();
119
+ return true;
120
+ }
121
+
122
+ stopAllActions(): this {
123
+ this.assertActive();
124
+ for (let index = 0; index < this._actions.length; index++) this._actions[index]!.stop();
125
+ return this;
126
+ }
127
+
128
+ update(deltaSeconds: number, out: Animation3DMutablePose): Animation3DPose {
129
+ this.assertActive();
130
+ this._requireIndependentClock();
131
+ if (!Number.isFinite(deltaSeconds)) {
132
+ throw new RangeError(`Animation3DMixer delta must be finite; received ${deltaSeconds}.`);
133
+ }
134
+ const previousTime = this._time;
135
+ const mixerDelta = deltaSeconds * this._timeScale;
136
+ this._time += mixerDelta;
137
+ out.reset(this._time);
138
+ this._advanceActions(mixerDelta, previousTime, this._time, out);
139
+ this._evaluateInto(out);
140
+ return out.seal();
141
+ }
142
+
143
+ evaluate(out: Animation3DMutablePose): Animation3DPose {
144
+ this.assertActive();
145
+ this._requireIndependentClock();
146
+ out.reset(this._time);
147
+ this._evaluateInto(out);
148
+ return out.seal();
149
+ }
150
+
151
+ setTime(timeSeconds: number, out: Animation3DMutablePose): Animation3DPose {
152
+ this.assertActive();
153
+ this._requireIndependentClock();
154
+ if (!Number.isFinite(timeSeconds)) {
155
+ throw new RangeError(`Animation3DMixer time must be finite; received ${timeSeconds}.`);
156
+ }
157
+ const previousTime = this._time;
158
+ const mixerDelta = timeSeconds - previousTime;
159
+ this._time = timeSeconds;
160
+ out.reset(this._time);
161
+ this._advanceActions(mixerDelta, previousTime, this._time, out);
162
+ this._evaluateInto(out);
163
+ return out.seal();
164
+ }
165
+
166
+ /**
167
+ * Opens an externally-clocked evaluation frame. Ordinary update/evaluate/
168
+ * setTime calls are rejected until the synchronized frame is closed.
169
+ */
170
+ beginSynchronizedFrame(timeSeconds: number, out: Animation3DMutablePose): void {
171
+ this.assertActive();
172
+ if (this._synchronizedFrameOut) {
173
+ throw new Error('Animation3D mixer already has an active synchronized frame.');
174
+ }
175
+ if (!Number.isFinite(timeSeconds)) {
176
+ throw new RangeError(`Animation3D synchronized frame time must be finite; received ${timeSeconds}.`);
177
+ }
178
+ this._synchronizedPreviousTime = this._time;
179
+ this._time = timeSeconds;
180
+ this._synchronizedFrameOut = out;
181
+ out.reset(timeSeconds);
182
+ }
183
+
184
+ endSynchronizedFrame(out: Animation3DMutablePose): Animation3DPose {
185
+ this.assertActive();
186
+ if (this._synchronizedFrameOut !== out) {
187
+ throw new Error('Animation3D synchronized frame output does not match the active frame.');
188
+ }
189
+ try {
190
+ this._evaluateInto(out);
191
+ const pose = out.seal();
192
+ this._synchronizedFrameOut = null;
193
+ this._synchronizedPreviousTime = this._time;
194
+ return pose;
195
+ } catch (error) {
196
+ this._time = this._synchronizedPreviousTime;
197
+ this._synchronizedFrameOut = null;
198
+ throw error;
199
+ }
200
+ }
201
+
202
+ cancelSynchronizedFrame(out: Animation3DMutablePose): void {
203
+ if (this._synchronizedFrameOut !== out) return;
204
+ this._time = this._synchronizedPreviousTime;
205
+ this._synchronizedFrameOut = null;
206
+ }
207
+
208
+ /** @internal Restores a completed frame when a sibling mixer in one controller transaction fails. */
209
+ rollbackCompletedSynchronizedFrame(timeSeconds: number): void {
210
+ this.assertActive();
211
+ if (this._synchronizedFrameOut) {
212
+ throw new Error('Animation3D mixer cannot roll back a completed frame while another frame is active.');
213
+ }
214
+ if (!Number.isFinite(timeSeconds)) {
215
+ throw new RangeError(`Animation3D rollback time must be finite; received ${timeSeconds}.`);
216
+ }
217
+ this._time = timeSeconds;
218
+ this._synchronizedPreviousTime = timeSeconds;
219
+ }
220
+
221
+ destroy(): void {
222
+ if (this._state === 'destroyed') return;
223
+ for (let index = 0; index < this._actions.length; index++) this._actions[index]!.invalidate();
224
+ this._actions.length = 0;
225
+ this._actionsById.clear();
226
+ this._accumulatorList.length = 0;
227
+ this._accumulators.clear();
228
+ this._resolvedBindings.clear();
229
+ this._synchronizedFrameOut = null;
230
+ this._synchronizedPreviousTime = 0;
231
+ this._state = 'destroyed';
232
+ }
233
+
234
+ assertActive(): void {
235
+ if (this._state !== 'active') {
236
+ throw new Animation3DError(
237
+ 'mixer-destroyed',
238
+ 'Animation3D mixer has been destroyed.',
239
+ );
240
+ }
241
+ }
242
+
243
+ private _requireIndependentClock(): void {
244
+ if (this._synchronizedFrameOut) {
245
+ throw new Error(
246
+ 'Animation3D mixer clock cannot advance during a controller-owned synchronized frame.',
247
+ );
248
+ }
249
+ }
250
+
251
+ private _advanceActions(
252
+ mixerDelta: number,
253
+ previousTime: number,
254
+ currentTime: number,
255
+ out: Animation3DMutablePose,
256
+ ): void {
257
+ for (let index = 0; index < this._actions.length; index++) {
258
+ this._actions[index]!.advance(mixerDelta, previousTime, currentTime, out);
259
+ }
260
+ }
261
+
262
+ private _evaluateInto(out: Animation3DMutablePose): void {
263
+ this._invalidateResolvedBindingsIfNeeded();
264
+ for (let index = 0; index < this._accumulatorList.length; index++) {
265
+ resetAccumulator(this._accumulatorList[index]!);
266
+ }
267
+
268
+ for (let actionIndex = 0; actionIndex < this._actions.length; actionIndex++) {
269
+ const action = this._actions[actionIndex]!;
270
+ const weight = action.effectiveWeight;
271
+ if (weight <= 0) continue;
272
+ const tracks = action.runtimeTracks;
273
+ for (let trackIndex = 0; trackIndex < tracks.length; trackIndex++) {
274
+ const runtimeTrack = tracks[trackIndex]!;
275
+ const binding = runtimeTrack.track.binding;
276
+ if (!action.acceptsBinding(binding)) continue;
277
+ const accumulator = this._accumulators.get(binding.id);
278
+ if (!accumulator) continue;
279
+ const sampled = runtimeTrack.sampler.sample(action.time);
280
+ accumulator.active = true;
281
+ if (action.blendMode === 'additive') {
282
+ accumulateAdditive(accumulator, runtimeTrack, sampled, weight);
283
+ } else {
284
+ accumulateOverride(accumulator, sampled, weight);
285
+ }
286
+ }
287
+ }
288
+
289
+ for (let index = 0; index < this._accumulatorList.length; index++) {
290
+ const accumulator = this._accumulatorList[index]!;
291
+ if (!accumulator.active) continue;
292
+ this._readBase(accumulator);
293
+ finalizeAccumulator(accumulator);
294
+ out.write(accumulator.binding, accumulator.result);
295
+ }
296
+ }
297
+
298
+ private _retainBinding(binding: Animation3DBinding): void {
299
+ const existing = this._accumulators.get(binding.id);
300
+ if (existing) {
301
+ if (existing.binding.valueSize !== binding.valueSize
302
+ || existing.binding.valueType !== binding.valueType) {
303
+ throw new RangeError(`Animation3D binding id "${binding.id}" has incompatible value contracts.`);
304
+ }
305
+ existing.references++;
306
+ return;
307
+ }
308
+ const size = binding.valueSize;
309
+ const accumulator: BindingAccumulator = {
310
+ binding,
311
+ base: new Float32Array(size),
312
+ result: new Float32Array(size),
313
+ overrideSum: new Float32Array(size),
314
+ additiveSum: new Float32Array(size),
315
+ quaternionAnchor: new Float32Array(4),
316
+ additiveQuaternion: new Float32Array([0, 0, 0, 1]),
317
+ references: 1,
318
+ active: false,
319
+ overrideWeight: 0,
320
+ quaternionAnchorSet: false,
321
+ additiveQuaternionUsed: false,
322
+ };
323
+ this._accumulators.set(binding.id, accumulator);
324
+ this._accumulatorList.push(accumulator);
325
+ }
326
+
327
+ private _releaseBinding(binding: Animation3DBinding): void {
328
+ const accumulator = this._accumulators.get(binding.id);
329
+ if (!accumulator) return;
330
+ accumulator.references--;
331
+ if (accumulator.references > 0) return;
332
+ this._accumulators.delete(binding.id);
333
+ this._resolvedBindings.delete(binding.id);
334
+ const index = this._accumulatorList.indexOf(accumulator);
335
+ if (index >= 0) this._accumulatorList.splice(index, 1);
336
+ }
337
+
338
+ private _invalidateResolvedBindingsIfNeeded(): void {
339
+ if (this._resolverRevision === this.resolver.revision) return;
340
+ this._resolverRevision = this.resolver.revision;
341
+ this._resolvedBindings.clear();
342
+ }
343
+
344
+ private _readBase(accumulator: BindingAccumulator): void {
345
+ const id = accumulator.binding.id;
346
+ let resolved = this._resolvedBindings.get(id);
347
+ if (resolved === undefined && !this._resolvedBindings.has(id)) {
348
+ resolved = this.resolver.resolve(accumulator.binding);
349
+ this._resolvedBindings.set(id, resolved);
350
+ }
351
+ if (resolved) {
352
+ resolved.read(accumulator.base);
353
+ return;
354
+ }
355
+ throw new Animation3DError(
356
+ 'resolver-miss',
357
+ `Animation3D binding resolver could not resolve "${id}".`,
358
+ { resolver: 'binding', bindingId: id },
359
+ );
360
+ }
361
+ }
362
+
363
+ function resetAccumulator(accumulator: BindingAccumulator): void {
364
+ accumulator.active = false;
365
+ accumulator.overrideWeight = 0;
366
+ accumulator.quaternionAnchorSet = false;
367
+ accumulator.additiveQuaternionUsed = false;
368
+ accumulator.overrideSum.fill(0);
369
+ accumulator.additiveSum.fill(0);
370
+ accumulator.additiveQuaternion[0] = 0;
371
+ accumulator.additiveQuaternion[1] = 0;
372
+ accumulator.additiveQuaternion[2] = 0;
373
+ accumulator.additiveQuaternion[3] = 1;
374
+ }
375
+
376
+ function accumulateOverride(
377
+ accumulator: BindingAccumulator,
378
+ sampled: Float32Array,
379
+ weight: number,
380
+ ): void {
381
+ if (accumulator.binding.valueType !== 'quaternion') {
382
+ for (let index = 0; index < sampled.length; index++) {
383
+ accumulator.overrideSum[index] = accumulator.overrideSum[index]! + sampled[index]! * weight;
384
+ }
385
+ accumulator.overrideWeight += weight;
386
+ return;
387
+ }
388
+
389
+ let sign = 1;
390
+ if (!accumulator.quaternionAnchorSet) {
391
+ accumulator.quaternionAnchor.set(sampled);
392
+ accumulator.quaternionAnchorSet = true;
393
+ } else {
394
+ const dot = accumulator.quaternionAnchor[0]! * sampled[0]!
395
+ + accumulator.quaternionAnchor[1]! * sampled[1]!
396
+ + accumulator.quaternionAnchor[2]! * sampled[2]!
397
+ + accumulator.quaternionAnchor[3]! * sampled[3]!;
398
+ if (dot < 0) sign = -1;
399
+ }
400
+ for (let index = 0; index < 4; index++) {
401
+ accumulator.overrideSum[index] = accumulator.overrideSum[index]!
402
+ + sampled[index]! * weight * sign;
403
+ }
404
+ accumulator.overrideWeight += weight;
405
+ }
406
+
407
+ function accumulateAdditive(
408
+ accumulator: BindingAccumulator,
409
+ runtimeTrack: Animation3DActionTrackRuntime,
410
+ sampled: Float32Array,
411
+ weight: number,
412
+ ): void {
413
+ if (accumulator.binding.valueType === 'quaternion') {
414
+ accumulateAdditiveQuaternion(
415
+ accumulator.additiveQuaternion,
416
+ sampled,
417
+ runtimeTrack.reference,
418
+ weight,
419
+ );
420
+ accumulator.additiveQuaternionUsed = true;
421
+ return;
422
+ }
423
+ for (let index = 0; index < sampled.length; index++) {
424
+ accumulator.additiveSum[index] = accumulator.additiveSum[index]!
425
+ + (sampled[index]! - runtimeTrack.reference[index]!) * weight;
426
+ }
427
+ }
428
+
429
+ function finalizeAccumulator(accumulator: BindingAccumulator): void {
430
+ const size = accumulator.binding.valueSize;
431
+ const overrideWeight = accumulator.overrideWeight;
432
+ if (accumulator.binding.valueType !== 'quaternion') {
433
+ if (overrideWeight > 0) {
434
+ if (overrideWeight < 1) {
435
+ const baseWeight = 1 - overrideWeight;
436
+ for (let index = 0; index < size; index++) {
437
+ accumulator.result[index] = accumulator.overrideSum[index]!
438
+ + accumulator.base[index]! * baseWeight;
439
+ }
440
+ } else {
441
+ const inverseWeight = 1 / overrideWeight;
442
+ for (let index = 0; index < size; index++) {
443
+ accumulator.result[index] = accumulator.overrideSum[index]! * inverseWeight;
444
+ }
445
+ }
446
+ } else {
447
+ accumulator.result.set(accumulator.base);
448
+ }
449
+ for (let index = 0; index < size; index++) {
450
+ accumulator.result[index] = accumulator.result[index]! + accumulator.additiveSum[index]!;
451
+ }
452
+ return;
453
+ }
454
+
455
+ if (overrideWeight > 0) {
456
+ accumulator.result.set(accumulator.overrideSum);
457
+ if (overrideWeight < 1) {
458
+ let sign = 1;
459
+ const anchorDot = accumulator.quaternionAnchor[0]! * accumulator.base[0]!
460
+ + accumulator.quaternionAnchor[1]! * accumulator.base[1]!
461
+ + accumulator.quaternionAnchor[2]! * accumulator.base[2]!
462
+ + accumulator.quaternionAnchor[3]! * accumulator.base[3]!;
463
+ if (anchorDot < 0) sign = -1;
464
+ const baseWeight = 1 - overrideWeight;
465
+ for (let index = 0; index < 4; index++) {
466
+ accumulator.result[index] = accumulator.result[index]!
467
+ + accumulator.base[index]! * baseWeight * sign;
468
+ }
469
+ }
470
+ normalizeQuaternion(accumulator.result);
471
+ } else {
472
+ accumulator.result.set(accumulator.base);
473
+ normalizeQuaternion(accumulator.result);
474
+ }
475
+ if (accumulator.additiveQuaternionUsed) {
476
+ multiplyQuaternionInPlace(accumulator.result, accumulator.additiveQuaternion);
477
+ normalizeQuaternion(accumulator.result);
478
+ }
479
+ }
480
+
481
+ function accumulateAdditiveQuaternion(
482
+ accumulated: Float32Array,
483
+ sampled: Float32Array,
484
+ reference: Float32Array,
485
+ weight: number,
486
+ ): void {
487
+ const rx = reference[0]!;
488
+ const ry = reference[1]!;
489
+ const rz = reference[2]!;
490
+ const rw = reference[3]!;
491
+ const inverseLengthSquared = 1 / Math.max(
492
+ Number.EPSILON,
493
+ rx * rx + ry * ry + rz * rz + rw * rw,
494
+ );
495
+ const ix = -rx * inverseLengthSquared;
496
+ const iy = -ry * inverseLengthSquared;
497
+ const iz = -rz * inverseLengthSquared;
498
+ const iw = rw * inverseLengthSquared;
499
+ const sx = sampled[0]!;
500
+ const sy = sampled[1]!;
501
+ const sz = sampled[2]!;
502
+ const sw = sampled[3]!;
503
+ let dx = iw * sx + ix * sw + iy * sz - iz * sy;
504
+ let dy = iw * sy - ix * sz + iy * sw + iz * sx;
505
+ let dz = iw * sz + ix * sy - iy * sx + iz * sw;
506
+ let dw = iw * sw - ix * sx - iy * sy - iz * sz;
507
+ if (dw < 0) {
508
+ dx = -dx;
509
+ dy = -dy;
510
+ dz = -dz;
511
+ dw = -dw;
512
+ }
513
+ dw = Math.min(1, Math.max(-1, dw));
514
+
515
+ let wx: number;
516
+ let wy: number;
517
+ let wz: number;
518
+ let ww: number;
519
+ if (dw > 0.9995) {
520
+ wx = dx * weight;
521
+ wy = dy * weight;
522
+ wz = dz * weight;
523
+ ww = 1 + (dw - 1) * weight;
524
+ const inverseLength = 1 / Math.max(Number.EPSILON, Math.hypot(wx, wy, wz, ww));
525
+ wx *= inverseLength;
526
+ wy *= inverseLength;
527
+ wz *= inverseLength;
528
+ ww *= inverseLength;
529
+ } else {
530
+ const theta = Math.acos(dw);
531
+ const scale = Math.sin(theta * weight) / Math.sin(theta);
532
+ wx = dx * scale;
533
+ wy = dy * scale;
534
+ wz = dz * scale;
535
+ ww = Math.cos(theta * weight);
536
+ }
537
+
538
+ const ax = accumulated[0]!;
539
+ const ay = accumulated[1]!;
540
+ const az = accumulated[2]!;
541
+ const aw = accumulated[3]!;
542
+ accumulated[0] = aw * wx + ax * ww + ay * wz - az * wy;
543
+ accumulated[1] = aw * wy - ax * wz + ay * ww + az * wx;
544
+ accumulated[2] = aw * wz + ax * wy - ay * wx + az * ww;
545
+ accumulated[3] = aw * ww - ax * wx - ay * wy - az * wz;
546
+ normalizeQuaternion(accumulated);
547
+ }
548
+
549
+ function multiplyQuaternionInPlace(target: Float32Array, right: Float32Array): void {
550
+ const ax = target[0]!;
551
+ const ay = target[1]!;
552
+ const az = target[2]!;
553
+ const aw = target[3]!;
554
+ const bx = right[0]!;
555
+ const by = right[1]!;
556
+ const bz = right[2]!;
557
+ const bw = right[3]!;
558
+ target[0] = aw * bx + ax * bw + ay * bz - az * by;
559
+ target[1] = aw * by - ax * bz + ay * bw + az * bx;
560
+ target[2] = aw * bz + ax * by - ay * bx + az * bw;
561
+ target[3] = aw * bw - ax * bx - ay * by - az * bz;
562
+ }
@@ -0,0 +1 @@
1
+ export { Animation3DPoseBuffer } from '../../Animation3DPoseBuffer.js';