@aura3d/animation 1.0.6

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 (187) hide show
  1. package/README.md +19 -0
  2. package/dist/AnimationAction.d.ts +40 -0
  3. package/dist/AnimationAction.d.ts.map +1 -0
  4. package/dist/AnimationAction.js +143 -0
  5. package/dist/AnimationAction.js.map +1 -0
  6. package/dist/AnimationClip.d.ts +24 -0
  7. package/dist/AnimationClip.d.ts.map +1 -0
  8. package/dist/AnimationClip.js +45 -0
  9. package/dist/AnimationClip.js.map +1 -0
  10. package/dist/AnimationClipEvents.d.ts +57 -0
  11. package/dist/AnimationClipEvents.d.ts.map +1 -0
  12. package/dist/AnimationClipEvents.js +171 -0
  13. package/dist/AnimationClipEvents.js.map +1 -0
  14. package/dist/AnimationClipRegistry.d.ts +76 -0
  15. package/dist/AnimationClipRegistry.d.ts.map +1 -0
  16. package/dist/AnimationClipRegistry.js +130 -0
  17. package/dist/AnimationClipRegistry.js.map +1 -0
  18. package/dist/AnimationController.d.ts +168 -0
  19. package/dist/AnimationController.d.ts.map +1 -0
  20. package/dist/AnimationController.js +619 -0
  21. package/dist/AnimationController.js.map +1 -0
  22. package/dist/AnimationEvents.d.ts +10 -0
  23. package/dist/AnimationEvents.d.ts.map +1 -0
  24. package/dist/AnimationEvents.js +26 -0
  25. package/dist/AnimationEvents.js.map +1 -0
  26. package/dist/AnimationLayer.d.ts +27 -0
  27. package/dist/AnimationLayer.d.ts.map +1 -0
  28. package/dist/AnimationLayer.js +53 -0
  29. package/dist/AnimationLayer.js.map +1 -0
  30. package/dist/AnimationMixer.d.ts +54 -0
  31. package/dist/AnimationMixer.d.ts.map +1 -0
  32. package/dist/AnimationMixer.js +319 -0
  33. package/dist/AnimationMixer.js.map +1 -0
  34. package/dist/AnimationStateGraph.d.ts +2 -0
  35. package/dist/AnimationStateGraph.d.ts.map +1 -0
  36. package/dist/AnimationStateGraph.js +2 -0
  37. package/dist/AnimationStateGraph.js.map +1 -0
  38. package/dist/AnimationStateMachine.d.ts +59 -0
  39. package/dist/AnimationStateMachine.d.ts.map +1 -0
  40. package/dist/AnimationStateMachine.js +154 -0
  41. package/dist/AnimationStateMachine.js.map +1 -0
  42. package/dist/AnimationTrack.d.ts +23 -0
  43. package/dist/AnimationTrack.d.ts.map +1 -0
  44. package/dist/AnimationTrack.js +124 -0
  45. package/dist/AnimationTrack.js.map +1 -0
  46. package/dist/BlendTree.d.ts +23 -0
  47. package/dist/BlendTree.d.ts.map +1 -0
  48. package/dist/BlendTree.js +68 -0
  49. package/dist/BlendTree.js.map +1 -0
  50. package/dist/Bone.d.ts +20 -0
  51. package/dist/Bone.d.ts.map +1 -0
  52. package/dist/Bone.js +24 -0
  53. package/dist/Bone.js.map +1 -0
  54. package/dist/CrowdAnimation.d.ts +13 -0
  55. package/dist/CrowdAnimation.d.ts.map +1 -0
  56. package/dist/CrowdAnimation.js +14 -0
  57. package/dist/CrowdAnimation.js.map +1 -0
  58. package/dist/ECSAnimationBridge.d.ts +9 -0
  59. package/dist/ECSAnimationBridge.d.ts.map +1 -0
  60. package/dist/ECSAnimationBridge.js +24 -0
  61. package/dist/ECSAnimationBridge.js.map +1 -0
  62. package/dist/HumanoidRetargeting.d.ts +76 -0
  63. package/dist/HumanoidRetargeting.d.ts.map +1 -0
  64. package/dist/HumanoidRetargeting.js +331 -0
  65. package/dist/HumanoidRetargeting.js.map +1 -0
  66. package/dist/IK.d.ts +24 -0
  67. package/dist/IK.d.ts.map +1 -0
  68. package/dist/IK.js +76 -0
  69. package/dist/IK.js.map +1 -0
  70. package/dist/Keyframe.d.ts +50 -0
  71. package/dist/Keyframe.d.ts.map +1 -0
  72. package/dist/Keyframe.js +118 -0
  73. package/dist/Keyframe.js.map +1 -0
  74. package/dist/LocomotionController.d.ts +47 -0
  75. package/dist/LocomotionController.d.ts.map +1 -0
  76. package/dist/LocomotionController.js +106 -0
  77. package/dist/LocomotionController.js.map +1 -0
  78. package/dist/MotionMatchingFixtures.d.ts +58 -0
  79. package/dist/MotionMatchingFixtures.d.ts.map +1 -0
  80. package/dist/MotionMatchingFixtures.js +175 -0
  81. package/dist/MotionMatchingFixtures.js.map +1 -0
  82. package/dist/MotionQuality.d.ts +36 -0
  83. package/dist/MotionQuality.d.ts.map +1 -0
  84. package/dist/MotionQuality.js +117 -0
  85. package/dist/MotionQuality.js.map +1 -0
  86. package/dist/Retargeting.d.ts +12 -0
  87. package/dist/Retargeting.d.ts.map +1 -0
  88. package/dist/Retargeting.js +19 -0
  89. package/dist/Retargeting.js.map +1 -0
  90. package/dist/RootMotion.d.ts +21 -0
  91. package/dist/RootMotion.d.ts.map +1 -0
  92. package/dist/RootMotion.js +84 -0
  93. package/dist/RootMotion.js.map +1 -0
  94. package/dist/SceneAnimationBridge.d.ts +18 -0
  95. package/dist/SceneAnimationBridge.d.ts.map +1 -0
  96. package/dist/SceneAnimationBridge.js +69 -0
  97. package/dist/SceneAnimationBridge.js.map +1 -0
  98. package/dist/SecondaryAnimationFixtures.d.ts +55 -0
  99. package/dist/SecondaryAnimationFixtures.d.ts.map +1 -0
  100. package/dist/SecondaryAnimationFixtures.js +147 -0
  101. package/dist/SecondaryAnimationFixtures.js.map +1 -0
  102. package/dist/Skeleton.d.ts +9 -0
  103. package/dist/Skeleton.d.ts.map +1 -0
  104. package/dist/Skeleton.js +31 -0
  105. package/dist/Skeleton.js.map +1 -0
  106. package/dist/Skinning.d.ts +7 -0
  107. package/dist/Skinning.d.ts.map +1 -0
  108. package/dist/Skinning.js +12 -0
  109. package/dist/Skinning.js.map +1 -0
  110. package/dist/browser-index.d.ts +39 -0
  111. package/dist/browser-index.d.ts.map +1 -0
  112. package/dist/browser-index.js +34 -0
  113. package/dist/browser-index.js.map +1 -0
  114. package/dist/index.d.ts +40 -0
  115. package/dist/index.d.ts.map +1 -0
  116. package/dist/index.js +35 -0
  117. package/dist/index.js.map +1 -0
  118. package/dist/threejs-compatibility/AnimationAction.d.ts +16 -0
  119. package/dist/threejs-compatibility/AnimationAction.d.ts.map +1 -0
  120. package/dist/threejs-compatibility/AnimationAction.js +25 -0
  121. package/dist/threejs-compatibility/AnimationAction.js.map +1 -0
  122. package/dist/threejs-compatibility/AnimationClip.d.ts +14 -0
  123. package/dist/threejs-compatibility/AnimationClip.d.ts.map +1 -0
  124. package/dist/threejs-compatibility/AnimationClip.js +11 -0
  125. package/dist/threejs-compatibility/AnimationClip.js.map +1 -0
  126. package/dist/threejs-compatibility/AnimationDiagnostics.d.ts +44 -0
  127. package/dist/threejs-compatibility/AnimationDiagnostics.d.ts.map +1 -0
  128. package/dist/threejs-compatibility/AnimationDiagnostics.js +29 -0
  129. package/dist/threejs-compatibility/AnimationDiagnostics.js.map +1 -0
  130. package/dist/threejs-compatibility/AnimationMixer.d.ts +9 -0
  131. package/dist/threejs-compatibility/AnimationMixer.d.ts.map +1 -0
  132. package/dist/threejs-compatibility/AnimationMixer.js +24 -0
  133. package/dist/threejs-compatibility/AnimationMixer.js.map +1 -0
  134. package/dist/threejs-compatibility/MorphTargetMixer.d.ts +10 -0
  135. package/dist/threejs-compatibility/MorphTargetMixer.d.ts.map +1 -0
  136. package/dist/threejs-compatibility/MorphTargetMixer.js +10 -0
  137. package/dist/threejs-compatibility/MorphTargetMixer.js.map +1 -0
  138. package/dist/threejs-compatibility/Skeleton.d.ts +10 -0
  139. package/dist/threejs-compatibility/Skeleton.d.ts.map +1 -0
  140. package/dist/threejs-compatibility/Skeleton.js +8 -0
  141. package/dist/threejs-compatibility/Skeleton.js.map +1 -0
  142. package/dist/threejs-compatibility/SkinnedMesh.d.ts +11 -0
  143. package/dist/threejs-compatibility/SkinnedMesh.d.ts.map +1 -0
  144. package/dist/threejs-compatibility/SkinnedMesh.js +16 -0
  145. package/dist/threejs-compatibility/SkinnedMesh.js.map +1 -0
  146. package/dist/threejs-compatibility/index.d.ts +12 -0
  147. package/dist/threejs-compatibility/index.d.ts.map +1 -0
  148. package/dist/threejs-compatibility/index.js +8 -0
  149. package/dist/threejs-compatibility/index.js.map +1 -0
  150. package/package.json +17 -0
  151. package/src/AnimationAction.ts +166 -0
  152. package/src/AnimationClip.ts +63 -0
  153. package/src/AnimationClipEvents.ts +320 -0
  154. package/src/AnimationClipRegistry.ts +280 -0
  155. package/src/AnimationController.ts +967 -0
  156. package/src/AnimationEvents.ts +34 -0
  157. package/src/AnimationLayer.ts +73 -0
  158. package/src/AnimationMixer.ts +366 -0
  159. package/src/AnimationStateGraph.ts +8 -0
  160. package/src/AnimationStateMachine.ts +217 -0
  161. package/src/AnimationTrack.ts +176 -0
  162. package/src/BlendTree.ts +89 -0
  163. package/src/Bone.ts +35 -0
  164. package/src/CrowdAnimation.ts +25 -0
  165. package/src/ECSAnimationBridge.ts +30 -0
  166. package/src/HumanoidRetargeting.ts +476 -0
  167. package/src/IK.ts +107 -0
  168. package/src/Keyframe.ts +159 -0
  169. package/src/LocomotionController.ts +149 -0
  170. package/src/MotionMatchingFixtures.ts +254 -0
  171. package/src/MotionQuality.ts +156 -0
  172. package/src/Retargeting.ts +29 -0
  173. package/src/RootMotion.ts +124 -0
  174. package/src/SceneAnimationBridge.ts +80 -0
  175. package/src/SecondaryAnimationFixtures.ts +212 -0
  176. package/src/Skeleton.ts +34 -0
  177. package/src/Skinning.ts +18 -0
  178. package/src/browser-index.ts +55 -0
  179. package/src/index.ts +56 -0
  180. package/src/threejs-compatibility/AnimationAction.ts +27 -0
  181. package/src/threejs-compatibility/AnimationClip.ts +16 -0
  182. package/src/threejs-compatibility/AnimationDiagnostics.ts +42 -0
  183. package/src/threejs-compatibility/AnimationMixer.ts +24 -0
  184. package/src/threejs-compatibility/MorphTargetMixer.ts +16 -0
  185. package/src/threejs-compatibility/Skeleton.ts +9 -0
  186. package/src/threejs-compatibility/SkinnedMesh.ts +12 -0
  187. package/src/threejs-compatibility/index.ts +11 -0
@@ -0,0 +1,280 @@
1
+ import {
2
+ normalizeClipEvents,
3
+ type AnimationClipEvent
4
+ } from "./AnimationClipEvents.js";
5
+
6
+ export type AnimationClipId = string;
7
+
8
+ export type AnimationTrackTarget =
9
+ | "translation"
10
+ | "rotation"
11
+ | "scale"
12
+ | "morph"
13
+ | "material"
14
+ | "visibility"
15
+ | (string & {});
16
+
17
+ export interface AnimationKeyframe<TValue = unknown> {
18
+ readonly time: number;
19
+ readonly value: TValue;
20
+ readonly easing?: string;
21
+ }
22
+
23
+ export interface AnimationTrack<TValue = unknown> {
24
+ readonly id?: string;
25
+ readonly target: string;
26
+ readonly property?: AnimationTrackTarget;
27
+ readonly keyframes?: readonly AnimationKeyframe<TValue>[];
28
+ readonly metadata?: Record<string, unknown>;
29
+ }
30
+
31
+ export interface AnimationClipSampleContext<
32
+ TClipId extends string = string,
33
+ TEvent extends AnimationClipEvent = AnimationClipEvent
34
+ > {
35
+ readonly clip: RegisteredAnimationClip<TClipId, TEvent>;
36
+ readonly time: number;
37
+ readonly normalizedTime: number;
38
+ readonly playbackState?: unknown;
39
+ }
40
+
41
+ export type AnimationClipSampler<
42
+ TPose = unknown,
43
+ TClipId extends string = string,
44
+ TEvent extends AnimationClipEvent = AnimationClipEvent
45
+ > = (context: AnimationClipSampleContext<TClipId, TEvent>) => TPose;
46
+
47
+ export interface AnimationClipDefinition<
48
+ TClipId extends string = string,
49
+ TEvent extends AnimationClipEvent = AnimationClipEvent,
50
+ TPose = unknown
51
+ > {
52
+ readonly id: TClipId;
53
+ readonly name?: string;
54
+ readonly duration: number;
55
+ readonly frameRate?: number;
56
+ readonly loop?: boolean;
57
+ readonly tags?: readonly string[];
58
+ readonly tracks?: readonly AnimationTrack[];
59
+ readonly events?: readonly TEvent[];
60
+ readonly sample?: AnimationClipSampler<TPose, TClipId, TEvent>;
61
+ readonly source?: string;
62
+ readonly metadata?: Record<string, unknown>;
63
+ }
64
+
65
+ export interface RegisteredAnimationClip<
66
+ TClipId extends string = string,
67
+ TEvent extends AnimationClipEvent = AnimationClipEvent,
68
+ TPose = unknown
69
+ > extends AnimationClipDefinition<TClipId, TEvent, TPose> {
70
+ readonly duration: number;
71
+ readonly loop: boolean;
72
+ readonly tags: readonly string[];
73
+ readonly tracks: readonly AnimationTrack[];
74
+ readonly events: readonly TEvent[];
75
+ readonly registryIndex: number;
76
+ }
77
+
78
+ export interface AnimationClipRegistryOptions {
79
+ readonly replace?: boolean;
80
+ }
81
+
82
+ export type AnimationClipRegistryDiagnosticSeverity = "info" | "warning" | "error";
83
+
84
+ export interface AnimationClipRegistryDiagnostic<TClipId extends string = string> {
85
+ readonly severity: AnimationClipRegistryDiagnosticSeverity;
86
+ readonly code: string;
87
+ readonly message: string;
88
+ readonly clipId?: TClipId;
89
+ }
90
+
91
+ export interface AnimationClipManifest<
92
+ TClipId extends string = string,
93
+ TEvent extends AnimationClipEvent = AnimationClipEvent,
94
+ TPose = unknown
95
+ > {
96
+ readonly clips: readonly AnimationClipDefinition<TClipId, TEvent, TPose>[];
97
+ }
98
+
99
+ export class AnimationClipRegistry<
100
+ TClipId extends string = string,
101
+ TEvent extends AnimationClipEvent = AnimationClipEvent,
102
+ TPose = unknown
103
+ > {
104
+ private readonly clips = new Map<TClipId, RegisteredAnimationClip<TClipId, TEvent, TPose>>();
105
+ private nextRegistryIndex = 0;
106
+
107
+ constructor(
108
+ clips: readonly AnimationClipDefinition<TClipId, TEvent, TPose>[] = [],
109
+ options: AnimationClipRegistryOptions = {}
110
+ ) {
111
+ this.registerMany(clips, options);
112
+ }
113
+
114
+ static fromManifest<
115
+ TClipId extends string = string,
116
+ TEvent extends AnimationClipEvent = AnimationClipEvent,
117
+ TPose = unknown
118
+ >(
119
+ manifest: AnimationClipManifest<TClipId, TEvent, TPose>,
120
+ options: AnimationClipRegistryOptions = {}
121
+ ): AnimationClipRegistry<TClipId, TEvent, TPose> {
122
+ return new AnimationClipRegistry(manifest.clips, options);
123
+ }
124
+
125
+ register(
126
+ definition: AnimationClipDefinition<TClipId, TEvent, TPose>,
127
+ options: AnimationClipRegistryOptions = {}
128
+ ): RegisteredAnimationClip<TClipId, TEvent, TPose> {
129
+ validateClipDefinition(definition);
130
+
131
+ if (!options.replace && this.clips.has(definition.id)) {
132
+ throw new Error(`Animation clip "${definition.id}" is already registered.`);
133
+ }
134
+
135
+ const registered: RegisteredAnimationClip<TClipId, TEvent, TPose> = {
136
+ ...definition,
137
+ duration: sanitizeDuration(definition.duration),
138
+ loop: definition.loop ?? true,
139
+ tags: [...(definition.tags ?? [])],
140
+ tracks: [...(definition.tracks ?? [])],
141
+ events: normalizeClipEvents(definition.events),
142
+ registryIndex: this.nextRegistryIndex
143
+ };
144
+
145
+ this.nextRegistryIndex += 1;
146
+ this.clips.set(registered.id, registered);
147
+ return registered;
148
+ }
149
+
150
+ registerMany(
151
+ definitions: readonly AnimationClipDefinition<TClipId, TEvent, TPose>[],
152
+ options: AnimationClipRegistryOptions = {}
153
+ ): readonly RegisteredAnimationClip<TClipId, TEvent, TPose>[] {
154
+ return definitions.map((definition) => this.register(definition, options));
155
+ }
156
+
157
+ get(id: TClipId): RegisteredAnimationClip<TClipId, TEvent, TPose> | undefined {
158
+ return this.clips.get(id);
159
+ }
160
+
161
+ require(id: TClipId): RegisteredAnimationClip<TClipId, TEvent, TPose> {
162
+ const clip = this.get(id);
163
+ if (!clip) {
164
+ throw new Error(`Animation clip "${id}" is not registered.`);
165
+ }
166
+
167
+ return clip;
168
+ }
169
+
170
+ has(id: TClipId): boolean {
171
+ return this.clips.has(id);
172
+ }
173
+
174
+ remove(id: TClipId): boolean {
175
+ return this.clips.delete(id);
176
+ }
177
+
178
+ clear(): void {
179
+ this.clips.clear();
180
+ }
181
+
182
+ ids(): readonly TClipId[] {
183
+ return [...this.clips.keys()];
184
+ }
185
+
186
+ list(): readonly RegisteredAnimationClip<TClipId, TEvent, TPose>[] {
187
+ return [...this.clips.values()].sort((a, b) => a.registryIndex - b.registryIndex);
188
+ }
189
+
190
+ findByTag(tag: string): readonly RegisteredAnimationClip<TClipId, TEvent, TPose>[] {
191
+ return this.list().filter((clip) => clip.tags.includes(tag));
192
+ }
193
+
194
+ toManifest(): AnimationClipManifest<TClipId, TEvent, TPose> {
195
+ return {
196
+ clips: this.list()
197
+ };
198
+ }
199
+
200
+ diagnose(): readonly AnimationClipRegistryDiagnostic<TClipId>[] {
201
+ const diagnostics: AnimationClipRegistryDiagnostic<TClipId>[] = [];
202
+
203
+ if (this.clips.size === 0) {
204
+ diagnostics.push({
205
+ severity: "warning",
206
+ code: "ANIMATION_REGISTRY_EMPTY",
207
+ message: "No animation clips are registered."
208
+ });
209
+ return diagnostics;
210
+ }
211
+
212
+ for (const clip of this.list()) {
213
+ if (clip.duration <= 0) {
214
+ diagnostics.push({
215
+ severity: "error",
216
+ code: "ANIMATION_CLIP_DURATION_INVALID",
217
+ message: `Animation clip "${clip.id}" must have a positive duration.`,
218
+ clipId: clip.id
219
+ });
220
+ }
221
+
222
+ if (clip.frameRate !== undefined && (!Number.isFinite(clip.frameRate) || clip.frameRate <= 0)) {
223
+ diagnostics.push({
224
+ severity: "warning",
225
+ code: "ANIMATION_CLIP_FRAME_RATE_INVALID",
226
+ message: `Animation clip "${clip.id}" has an invalid frame rate.`,
227
+ clipId: clip.id
228
+ });
229
+ }
230
+
231
+ if (clip.tracks.length === 0 && !clip.sample) {
232
+ diagnostics.push({
233
+ severity: "info",
234
+ code: "ANIMATION_CLIP_NO_SAMPLE_SOURCE",
235
+ message: `Animation clip "${clip.id}" has no tracks or sampler. capturePose() will return an empty pose for it.`,
236
+ clipId: clip.id
237
+ });
238
+ }
239
+
240
+ for (const event of clip.events) {
241
+ if (!Number.isFinite(event.time) || event.time < 0 || event.time > clip.duration) {
242
+ diagnostics.push({
243
+ severity: "warning",
244
+ code: "ANIMATION_CLIP_EVENT_TIME_OUT_OF_RANGE",
245
+ message: `Animation event "${event.name}" is outside the duration of clip "${clip.id}".`,
246
+ clipId: clip.id
247
+ });
248
+ }
249
+ }
250
+ }
251
+
252
+ return diagnostics;
253
+ }
254
+ }
255
+
256
+ export function createAnimationClipRegistry<
257
+ TClipId extends string = string,
258
+ TEvent extends AnimationClipEvent = AnimationClipEvent,
259
+ TPose = unknown
260
+ >(
261
+ clips: readonly AnimationClipDefinition<TClipId, TEvent, TPose>[] = [],
262
+ options: AnimationClipRegistryOptions = {}
263
+ ): AnimationClipRegistry<TClipId, TEvent, TPose> {
264
+ return new AnimationClipRegistry(clips, options);
265
+ }
266
+
267
+ function validateClipDefinition(definition: AnimationClipDefinition): void {
268
+ if (!definition.id) {
269
+ throw new Error("Animation clips must have a stable id.");
270
+ }
271
+
272
+ if (!Number.isFinite(definition.duration) || definition.duration < 0) {
273
+ throw new Error(`Animation clip "${definition.id}" has an invalid duration.`);
274
+ }
275
+ }
276
+
277
+ function sanitizeDuration(duration: number): number {
278
+ if (!Number.isFinite(duration) || duration < 0) return 0;
279
+ return duration;
280
+ }