@memori.ai/memori-react 7.19.2 → 7.21.1

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 (111) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/dist/components/Avatar/AvatarView/AvatarComponent/Shadow/DynamicShadow.d.ts +3 -2
  3. package/dist/components/Avatar/AvatarView/AvatarComponent/Shadow/DynamicShadow.js +13 -6
  4. package/dist/components/Avatar/AvatarView/AvatarComponent/Shadow/DynamicShadow.js.map +1 -1
  5. package/dist/components/Avatar/AvatarView/AvatarComponent/avatarComponent.d.ts +14 -18
  6. package/dist/components/Avatar/AvatarView/AvatarComponent/avatarComponent.js +19 -77
  7. package/dist/components/Avatar/AvatarView/AvatarComponent/avatarComponent.js.map +1 -1
  8. package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.d.ts +17 -2
  9. package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js +95 -70
  10. package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js.map +1 -1
  11. package/dist/components/Avatar/AvatarView/AvatarComponent/components/controllers/AvatarAnimator.d.ts +65 -0
  12. package/dist/components/Avatar/AvatarView/AvatarComponent/components/controllers/AvatarAnimator.js +747 -0
  13. package/dist/components/Avatar/AvatarView/AvatarComponent/components/controllers/AvatarAnimator.js.map +1 -0
  14. package/dist/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.d.ts +9 -2
  15. package/dist/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.js +60 -2
  16. package/dist/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.js.map +1 -1
  17. package/dist/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.d.ts +3 -4
  18. package/dist/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.js +5 -11
  19. package/dist/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.js.map +1 -1
  20. package/dist/components/Avatar/AvatarView/AvatarComponent/constants.d.ts +13 -52
  21. package/dist/components/Avatar/AvatarView/AvatarComponent/constants.js +68 -70
  22. package/dist/components/Avatar/AvatarView/AvatarComponent/constants.js.map +1 -1
  23. package/dist/components/Avatar/AvatarView/index.d.ts +1 -1
  24. package/dist/components/Avatar/AvatarView/index.js +2 -2
  25. package/dist/components/Avatar/AvatarView/index.js.map +1 -1
  26. package/dist/components/ChatBubble/ChatBubble.css +9 -0
  27. package/dist/components/ChatBubble/ChatBubble.js +7 -1
  28. package/dist/components/ChatBubble/ChatBubble.js.map +1 -1
  29. package/dist/components/MemoriWidget/MemoriWidget.js +130 -62
  30. package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
  31. package/dist/components/UploadButton/UploadButton.js +2 -2
  32. package/dist/components/UploadButton/UploadButton.js.map +1 -1
  33. package/dist/components/WhyThisAnswer/WhyThisAnswer.css +43 -0
  34. package/dist/components/WhyThisAnswer/WhyThisAnswer.js +2 -1
  35. package/dist/components/WhyThisAnswer/WhyThisAnswer.js.map +1 -1
  36. package/dist/context/visemeContext.js +0 -39
  37. package/dist/context/visemeContext.js.map +1 -1
  38. package/dist/locales/de.json +1 -0
  39. package/dist/locales/en.json +1 -0
  40. package/dist/locales/es.json +1 -0
  41. package/dist/locales/fr.json +1 -0
  42. package/dist/locales/it.json +1 -0
  43. package/esm/components/Avatar/AvatarView/AvatarComponent/Shadow/DynamicShadow.d.ts +3 -2
  44. package/esm/components/Avatar/AvatarView/AvatarComponent/Shadow/DynamicShadow.js +13 -6
  45. package/esm/components/Avatar/AvatarView/AvatarComponent/Shadow/DynamicShadow.js.map +1 -1
  46. package/esm/components/Avatar/AvatarView/AvatarComponent/avatarComponent.d.ts +14 -18
  47. package/esm/components/Avatar/AvatarView/AvatarComponent/avatarComponent.js +20 -78
  48. package/esm/components/Avatar/AvatarView/AvatarComponent/avatarComponent.js.map +1 -1
  49. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.d.ts +17 -2
  50. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js +99 -74
  51. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js.map +1 -1
  52. package/esm/components/Avatar/AvatarView/AvatarComponent/components/controllers/AvatarAnimator.d.ts +65 -0
  53. package/esm/components/Avatar/AvatarView/AvatarComponent/components/controllers/AvatarAnimator.js +743 -0
  54. package/esm/components/Avatar/AvatarView/AvatarComponent/components/controllers/AvatarAnimator.js.map +1 -0
  55. package/esm/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.d.ts +9 -2
  56. package/esm/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.js +61 -3
  57. package/esm/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.js.map +1 -1
  58. package/esm/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.d.ts +3 -4
  59. package/esm/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.js +5 -11
  60. package/esm/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.js.map +1 -1
  61. package/esm/components/Avatar/AvatarView/AvatarComponent/constants.d.ts +13 -52
  62. package/esm/components/Avatar/AvatarView/AvatarComponent/constants.js +67 -69
  63. package/esm/components/Avatar/AvatarView/AvatarComponent/constants.js.map +1 -1
  64. package/esm/components/Avatar/AvatarView/index.d.ts +1 -1
  65. package/esm/components/Avatar/AvatarView/index.js +2 -2
  66. package/esm/components/Avatar/AvatarView/index.js.map +1 -1
  67. package/esm/components/ChatBubble/ChatBubble.css +9 -0
  68. package/esm/components/ChatBubble/ChatBubble.js +7 -1
  69. package/esm/components/ChatBubble/ChatBubble.js.map +1 -1
  70. package/esm/components/MemoriWidget/MemoriWidget.js +130 -62
  71. package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
  72. package/esm/components/UploadButton/UploadButton.js +2 -2
  73. package/esm/components/UploadButton/UploadButton.js.map +1 -1
  74. package/esm/components/WhyThisAnswer/WhyThisAnswer.css +43 -0
  75. package/esm/components/WhyThisAnswer/WhyThisAnswer.js +2 -1
  76. package/esm/components/WhyThisAnswer/WhyThisAnswer.js.map +1 -1
  77. package/esm/context/visemeContext.js +0 -39
  78. package/esm/context/visemeContext.js.map +1 -1
  79. package/esm/locales/de.json +1 -0
  80. package/esm/locales/en.json +1 -0
  81. package/esm/locales/es.json +1 -0
  82. package/esm/locales/fr.json +1 -0
  83. package/esm/locales/it.json +1 -0
  84. package/package.json +2 -2
  85. package/src/components/Avatar/AvatarView/AvatarComponent/Shadow/DynamicShadow.tsx +15 -8
  86. package/src/components/Avatar/AvatarView/AvatarComponent/avatarComponent.tsx +64 -219
  87. package/src/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.tsx +221 -124
  88. package/src/components/Avatar/AvatarView/AvatarComponent/components/controllers/AvatarAnimator.ts +1250 -0
  89. package/src/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.ts +164 -8
  90. package/src/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.tsx +19 -17
  91. package/src/components/Avatar/AvatarView/AvatarComponent/constants.ts +80 -79
  92. package/src/components/Avatar/AvatarView/index.tsx +1 -7
  93. package/src/components/ChatBubble/ChatBubble.css +9 -0
  94. package/src/components/ChatBubble/ChatBubble.tsx +14 -2
  95. package/src/components/MemoriWidget/MemoriWidget.tsx +168 -76
  96. package/src/components/UploadButton/UploadButton.tsx +4 -4
  97. package/src/components/UploadButton/__snapshots__/UploadButton.test.tsx.snap +1 -1
  98. package/src/components/WhyThisAnswer/WhyThisAnswer.css +43 -0
  99. package/src/components/WhyThisAnswer/WhyThisAnswer.stories.tsx +44 -3
  100. package/src/components/WhyThisAnswer/WhyThisAnswer.test.tsx +128 -8
  101. package/src/components/WhyThisAnswer/WhyThisAnswer.tsx +28 -3
  102. package/src/components/WhyThisAnswer/__snapshots__/WhyThisAnswer.test.tsx.snap +15 -1
  103. package/src/components/layouts/layouts.stories.tsx +0 -8
  104. package/src/context/visemeContext.tsx +40 -41
  105. package/src/index.stories.tsx +63 -65
  106. package/src/locales/de.json +1 -0
  107. package/src/locales/en.json +1 -0
  108. package/src/locales/es.json +1 -0
  109. package/src/locales/fr.json +1 -0
  110. package/src/locales/it.json +1 -0
  111. package/src/components/Avatar/AvatarView/AvatarComponent/components/controllers/AnimationController.ts +0 -308
@@ -0,0 +1,747 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AvatarAnimator = void 0;
4
+ const three_1 = require("three");
5
+ const constants_1 = require("../../constants");
6
+ class AvatarAnimator {
7
+ constructor() {
8
+ this.mixer = null;
9
+ this.actions = {};
10
+ this.animations = new Map();
11
+ this.currentAnimation = null;
12
+ this.currentSequence = null;
13
+ this.sequenceIndex = 0;
14
+ this.isTransitioning = false;
15
+ this.timeScale = 1.0;
16
+ this.fadeInDuration = 0.8;
17
+ this.fadeOutDuration = 0.8;
18
+ this.avatarType = 'CUSTOM_GLB';
19
+ this.eventListeners = {
20
+ start: [],
21
+ complete: [],
22
+ loop: [],
23
+ transition: [],
24
+ error: [],
25
+ };
26
+ this.initialized = false;
27
+ this.idleRotationCount = 0;
28
+ this.currentIdleAnimation = null;
29
+ this.idleRotationLimit = 5;
30
+ this.lastAnimationTime = null;
31
+ }
32
+ async initialize(scene, preloadedActions, animations = [], avatarType = 'CUSTOM_GLB') {
33
+ if (this.initialized || this.mixer) {
34
+ console.warn('[AvatarAnimator] Already initialized, ignoring duplicate initialization');
35
+ return;
36
+ }
37
+ this.mixer = new three_1.AnimationMixer(scene);
38
+ this.avatarType = avatarType;
39
+ this.actions = {};
40
+ this.registerClipsDirectly(animations);
41
+ Object.entries(preloadedActions).forEach(([name, action]) => {
42
+ if (!this.actions[name]) {
43
+ this.actions[name] = action;
44
+ this.registerAnimation(name, action);
45
+ }
46
+ });
47
+ this.setupMixerEvents();
48
+ const idleAnimations = ['Idle1', 'Idle2', 'Idle3', 'Idle4', 'Idle5'];
49
+ let startedSuccessfully = false;
50
+ for (const idleName of idleAnimations) {
51
+ if (this.actions[idleName]) {
52
+ try {
53
+ const idleAction = this.actions[idleName];
54
+ idleAction.reset();
55
+ idleAction.setEffectiveTimeScale(1);
56
+ idleAction.setEffectiveWeight(1);
57
+ idleAction.setLoop(Infinity, Infinity);
58
+ idleAction.play();
59
+ this.currentAnimation = idleName;
60
+ this.currentIdleAnimation = idleName;
61
+ this.idleRotationCount = 0;
62
+ startedSuccessfully = true;
63
+ break;
64
+ }
65
+ catch (error) {
66
+ console.error(`Error starting ${idleName}:`, error);
67
+ }
68
+ }
69
+ }
70
+ if (!startedSuccessfully) {
71
+ console.warn('[AvatarAnimator] Could not start any idle animation directly');
72
+ }
73
+ this.initialized = true;
74
+ }
75
+ registerClipsDirectly(clips) {
76
+ if (!this.mixer)
77
+ return;
78
+ clips.forEach(clip => {
79
+ var _a;
80
+ const action = (_a = this.mixer) === null || _a === void 0 ? void 0 : _a.clipAction(clip);
81
+ if (!action) {
82
+ console.warn(`[AvatarAnimator] Failed to create action for clip: ${clip.name}`);
83
+ return;
84
+ }
85
+ this.actions[clip.name] = action;
86
+ this.registerAnimation(clip.name, action);
87
+ });
88
+ }
89
+ registerAnimations(actions, clips = []) {
90
+ const allAnimationNames = new Set();
91
+ clips.forEach(clip => allAnimationNames.add(clip.name));
92
+ Object.keys(actions).forEach(name => allAnimationNames.add(name));
93
+ clips.forEach(clip => {
94
+ if (this.mixer) {
95
+ const action = this.mixer.clipAction(clip);
96
+ this.actions[clip.name] = action;
97
+ this.registerAnimation(clip.name, action);
98
+ }
99
+ });
100
+ Object.entries(actions).forEach(([name, action]) => {
101
+ if (!this.actions[name]) {
102
+ this.actions[name] = action;
103
+ this.registerAnimation(name, action);
104
+ }
105
+ });
106
+ const idleAnimations = this.getAnimationsByCategory('IDLE');
107
+ const loadingAnimations = this.getAnimationsByCategory('LOADING');
108
+ const actionAnimations = this.getAnimationsByCategory('ACTION');
109
+ }
110
+ registerAnimation(name, action) {
111
+ const duration = action.getClip().duration;
112
+ let category = 'ACTION';
113
+ let defaultLoopCount = 1;
114
+ let canLoop = false;
115
+ const lowerName = name.toLowerCase();
116
+ if (lowerName.includes('idle')) {
117
+ category = 'IDLE';
118
+ defaultLoopCount = 0;
119
+ canLoop = true;
120
+ }
121
+ else if (lowerName.includes('loading') || lowerName.includes('wait')) {
122
+ category = 'LOADING';
123
+ defaultLoopCount = 0;
124
+ canLoop = true;
125
+ }
126
+ this.animations.set(name, {
127
+ name,
128
+ category,
129
+ duration,
130
+ canLoop,
131
+ defaultLoopCount,
132
+ });
133
+ }
134
+ play(animationName, options = {}) {
135
+ var _a, _b, _c, _d;
136
+ try {
137
+ if (!this.initialized || !this.mixer) {
138
+ console.warn(`[AvatarAnimator] Cannot play ${animationName} - not initialized`);
139
+ return;
140
+ }
141
+ const nextAction = this.actions[animationName];
142
+ if (!nextAction) {
143
+ console.warn(`[AvatarAnimator] Animation not found: ${animationName}`);
144
+ if (options.fallbackToIdle !== false) {
145
+ const fallbackAnim = Object.keys(this.actions)[0];
146
+ if (fallbackAnim) {
147
+ this.play(fallbackAnim, { ...options, fallbackToIdle: false });
148
+ }
149
+ }
150
+ return;
151
+ }
152
+ const animInfo = this.getAnimationInfo(animationName);
153
+ if (!animInfo) {
154
+ console.warn(`[AvatarAnimator] Animation info not found: ${animationName}`);
155
+ if (options.fallbackToIdle !== false) {
156
+ this.idle();
157
+ }
158
+ return;
159
+ }
160
+ if (this.currentAnimation === animationName &&
161
+ !this.isTransitioning &&
162
+ options.loopCount === undefined) {
163
+ return;
164
+ }
165
+ if (this.isTransitioning) {
166
+ if (this.currentAnimation) {
167
+ const currentAction = this.actions[this.currentAnimation];
168
+ if (currentAction) {
169
+ currentAction.fadeOut(0.1);
170
+ }
171
+ }
172
+ }
173
+ const fadeIn = (_a = options.fadeInDuration) !== null && _a !== void 0 ? _a : this.fadeInDuration;
174
+ const fadeOut = (_b = options.fadeOutDuration) !== null && _b !== void 0 ? _b : this.fadeOutDuration;
175
+ const loopCount = (_c = options.loopCount) !== null && _c !== void 0 ? _c : animInfo.defaultLoopCount;
176
+ const timeScale = (_d = options.timeScale) !== null && _d !== void 0 ? _d : this.timeScale;
177
+ const isIdleAnimation = animInfo.category === 'IDLE';
178
+ if (isIdleAnimation) {
179
+ this.currentIdleAnimation = animationName;
180
+ this.idleRotationCount = 0;
181
+ }
182
+ this.emit('transition', {
183
+ from: this.currentAnimation,
184
+ to: animationName,
185
+ });
186
+ if (this.currentAnimation) {
187
+ const currentAction = this.actions[this.currentAnimation];
188
+ if (currentAction) {
189
+ if (this.currentAnimation === animationName) {
190
+ currentAction.stop();
191
+ }
192
+ else {
193
+ currentAction.fadeOut(fadeOut);
194
+ }
195
+ }
196
+ }
197
+ nextAction.reset();
198
+ nextAction.fadeIn(fadeIn);
199
+ nextAction.timeScale = timeScale;
200
+ nextAction.enabled = true;
201
+ if (loopCount === 0) {
202
+ nextAction.setLoop(Infinity, Infinity);
203
+ }
204
+ else {
205
+ nextAction.setLoop(loopCount > 1 ? loopCount : three_1.LoopOnce, loopCount > 1 ? loopCount : 1);
206
+ nextAction.clampWhenFinished = true;
207
+ }
208
+ nextAction.play();
209
+ this.currentAnimation = animationName;
210
+ this.isTransitioning = true;
211
+ const transitionDuration = Math.max(fadeIn, fadeOut) * 1000;
212
+ setTimeout(() => {
213
+ this.isTransitioning = false;
214
+ }, transitionDuration);
215
+ this.emit('start', {
216
+ animation: animationName,
217
+ category: animInfo.category,
218
+ loopCount,
219
+ });
220
+ }
221
+ catch (error) {
222
+ console.error(`[AvatarAnimator] Error in play method for ${animationName}:`, error);
223
+ if (options.fallbackToIdle !== false) {
224
+ try {
225
+ this.idle();
226
+ }
227
+ catch (recoveryError) {
228
+ console.error('[AvatarAnimator] Failed to recover with idle animation:', recoveryError);
229
+ }
230
+ }
231
+ }
232
+ }
233
+ execute(command) {
234
+ if (!this.initialized) {
235
+ console.warn('[AvatarAnimator] Cannot execute - not initialized');
236
+ return;
237
+ }
238
+ try {
239
+ let loopCount;
240
+ const loopMatch = command.match(/\[loop=(\d+)\]/);
241
+ if (loopMatch) {
242
+ loopCount = parseInt(loopMatch[1], 10);
243
+ command = command.replace(loopMatch[0], '').trim();
244
+ }
245
+ if (command.includes('->')) {
246
+ const sequence = command.split('->').map(s => s.trim());
247
+ this.playSequence(sequence, { loopCount });
248
+ }
249
+ else {
250
+ this.play(command, { loopCount });
251
+ }
252
+ }
253
+ catch (error) {
254
+ console.error('[AvatarAnimator] Error executing animation command:', error);
255
+ this.emit('error', { error, command });
256
+ this.idle();
257
+ }
258
+ }
259
+ processChatEmission(chatEmission, isLoading) {
260
+ if (!this.initialized) {
261
+ console.warn('[AvatarAnimator] Cannot process chat emission - not initialized');
262
+ return;
263
+ }
264
+ const wasInLoadingState = this.getAnimationCategory() === 'LOADING';
265
+ if (isLoading) {
266
+ if (wasInLoadingState) {
267
+ return;
268
+ }
269
+ this.loading();
270
+ return;
271
+ }
272
+ if (!chatEmission) {
273
+ if (this.getAnimationCategory() === 'IDLE') {
274
+ return;
275
+ }
276
+ this.idle(wasInLoadingState
277
+ ? { fadeInDuration: 1.2, fadeOutDuration: 1.0 }
278
+ : undefined);
279
+ return;
280
+ }
281
+ const sequenceMatch = chatEmission.match(/<output class="animation-sequence">(.*?)<\/output>/);
282
+ const animationMatch = chatEmission.match(/<output class="animation">(.*?)(\[loop=(\d+)\])?<\/output>/);
283
+ const emotionMatch = chatEmission.match(/<output class="memori-emotion">(.*?)<\/output>/);
284
+ const transitionOptions = this.calculateTransitionOptions();
285
+ if (sequenceMatch && sequenceMatch[1]) {
286
+ const sequence = sequenceMatch[1].trim();
287
+ if (this.currentSequence &&
288
+ this.currentSequence.join('->') === sequence &&
289
+ this.sequenceIndex < this.currentSequence.length) {
290
+ return;
291
+ }
292
+ this.executeWithTransition(sequence, transitionOptions);
293
+ return;
294
+ }
295
+ if (animationMatch && animationMatch[1]) {
296
+ const animation = animationMatch[1].trim();
297
+ let loopCount;
298
+ if (animationMatch[3]) {
299
+ loopCount = parseInt(animationMatch[3], 10);
300
+ }
301
+ this.play(animation, {
302
+ ...transitionOptions,
303
+ loopCount,
304
+ });
305
+ return;
306
+ }
307
+ if (emotionMatch && emotionMatch[1]) {
308
+ const emotion = emotionMatch[1].trim();
309
+ console.log('[AvatarAnimator] Processing emotion:', emotion);
310
+ let matchingAnimations = [];
311
+ if (constants_1.MAPPING_EMOTIONS_ITALIAN_TO_ENGLISH.find(item => item.english === emotion)) {
312
+ console.log('[AvatarAnimator] Found emotion in English mapping');
313
+ let matchingEmotions = constants_1.MAPPING_EMOTIONS_ITALIAN_TO_ENGLISH.filter(item => item.english === emotion);
314
+ console.log('[AvatarAnimator] Matching emotions:', matchingEmotions);
315
+ matchingAnimations = this.getAllAnimationNames().filter(name => matchingEmotions.some(emotion => name.toLowerCase().startsWith(emotion.italian.toLowerCase())));
316
+ }
317
+ else {
318
+ console.log('[AvatarAnimator] Using generalized emotion matching approach');
319
+ matchingAnimations = this.getAllAnimationNames().filter(name => name.toLowerCase().startsWith(emotion.toLowerCase()));
320
+ }
321
+ console.log('[AvatarAnimator] Found matching animations:', matchingAnimations);
322
+ if (matchingAnimations.length > 0) {
323
+ const randomIndex = Math.floor(Math.random() * matchingAnimations.length);
324
+ const animationToPlay = matchingAnimations[randomIndex];
325
+ console.log('[AvatarAnimator] Selected animation to play:', animationToPlay);
326
+ this.play(animationToPlay, transitionOptions);
327
+ return;
328
+ }
329
+ else {
330
+ console.log('[AvatarAnimator] No matching animations found for emotion:', emotion);
331
+ }
332
+ }
333
+ if (this.getAnimationCategory() !== 'IDLE') {
334
+ this.idle(transitionOptions);
335
+ }
336
+ }
337
+ calculateTransitionOptions() {
338
+ var _a, _b;
339
+ const options = {
340
+ fadeInDuration: this.fadeInDuration,
341
+ fadeOutDuration: this.fadeOutDuration,
342
+ timeScale: this.timeScale,
343
+ };
344
+ const currentCategory = this.getAnimationCategory();
345
+ const currentAction = this.currentAnimation
346
+ ? this.actions[this.currentAnimation]
347
+ : null;
348
+ options.fadeOutDuration = 0.8;
349
+ options.fadeInDuration = 0.8;
350
+ if (currentAction) {
351
+ const clip = currentAction.getClip();
352
+ const progress = currentAction.time / clip.duration;
353
+ if (progress > 0.75) {
354
+ options.fadeOutDuration = Math.max(0.4, ((_a = options.fadeOutDuration) !== null && _a !== void 0 ? _a : 0.8) * 0.8);
355
+ }
356
+ else if (progress < 0.25) {
357
+ options.fadeInDuration = Math.max(0.4, ((_b = options.fadeInDuration) !== null && _b !== void 0 ? _b : 0.8) * 0.8);
358
+ }
359
+ }
360
+ return options;
361
+ }
362
+ executeWithTransition(command, options = {}) {
363
+ if (!this.initialized) {
364
+ console.warn('[AvatarAnimator] Cannot execute - not initialized');
365
+ return;
366
+ }
367
+ try {
368
+ let loopCount;
369
+ const loopMatch = command.match(/\[loop=(\d+)\]/);
370
+ if (loopMatch) {
371
+ loopCount = parseInt(loopMatch[1], 10);
372
+ command = command.replace(loopMatch[0], '').trim();
373
+ }
374
+ if (command.includes('->')) {
375
+ const sequence = command.split('->').map(s => s.trim());
376
+ const sequenceOptions = {
377
+ ...options,
378
+ loopCount: loopCount || 1,
379
+ };
380
+ this.playSequence(sequence, sequenceOptions);
381
+ }
382
+ else {
383
+ this.play(command, {
384
+ ...options,
385
+ loopCount,
386
+ });
387
+ }
388
+ }
389
+ catch (error) {
390
+ console.error('[AvatarAnimator] Error executing animation command:', error);
391
+ this.emit('error', { error, command });
392
+ this.idle();
393
+ }
394
+ }
395
+ idle(options = {}) {
396
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
397
+ const idleAnimations = this.getAnimationsByCategory('IDLE');
398
+ if (idleAnimations.length > 0) {
399
+ let availableIdles = idleAnimations;
400
+ if (this.getAnimationCategory() === 'IDLE') {
401
+ availableIdles = idleAnimations.filter(info => info.name !== this.currentAnimation);
402
+ if (availableIdles.length === 0) {
403
+ availableIdles = idleAnimations;
404
+ }
405
+ }
406
+ const randomIndex = Math.floor(Math.random() * availableIdles.length);
407
+ const selectedIdle = availableIdles[randomIndex].name;
408
+ const transitionOptions = {
409
+ fadeInDuration: (_a = options.fadeInDuration) !== null && _a !== void 0 ? _a : 0.7,
410
+ fadeOutDuration: (_b = options.fadeOutDuration) !== null && _b !== void 0 ? _b : 0.7,
411
+ timeScale: (_c = options.timeScale) !== null && _c !== void 0 ? _c : 0.9,
412
+ loopCount: 0,
413
+ ...options,
414
+ };
415
+ transitionOptions.loopCount = 0;
416
+ this.play(selectedIdle, transitionOptions);
417
+ this.currentIdleAnimation = selectedIdle;
418
+ this.idleRotationCount = 0;
419
+ return;
420
+ }
421
+ else {
422
+ console.warn('[AvatarAnimator] No idle animations available, checking fallback options');
423
+ const loopableAnimations = Array.from(this.animations.values())
424
+ .filter(info => info.canLoop)
425
+ .map(info => info.name);
426
+ if (loopableAnimations.length > 0) {
427
+ const randomIndex = Math.floor(Math.random() * loopableAnimations.length);
428
+ const fallbackAnimation = loopableAnimations[randomIndex];
429
+ this.play(fallbackAnimation, {
430
+ loopCount: 0,
431
+ fadeInDuration: (_d = options.fadeInDuration) !== null && _d !== void 0 ? _d : 0.7,
432
+ fadeOutDuration: (_e = options.fadeOutDuration) !== null && _e !== void 0 ? _e : 0.7,
433
+ timeScale: (_f = options.timeScale) !== null && _f !== void 0 ? _f : 0.9,
434
+ });
435
+ this.currentIdleAnimation = fallbackAnimation;
436
+ this.idleRotationCount = 0;
437
+ }
438
+ else if (Object.keys(this.actions).length > 0) {
439
+ const firstAnimation = Object.keys(this.actions)[0];
440
+ this.play(firstAnimation, {
441
+ loopCount: 0,
442
+ fadeInDuration: (_g = options.fadeInDuration) !== null && _g !== void 0 ? _g : 0.7,
443
+ fadeOutDuration: (_h = options.fadeOutDuration) !== null && _h !== void 0 ? _h : 0.7,
444
+ timeScale: (_j = options.timeScale) !== null && _j !== void 0 ? _j : 0.9,
445
+ });
446
+ this.currentIdleAnimation = firstAnimation;
447
+ this.idleRotationCount = 0;
448
+ }
449
+ }
450
+ }
451
+ loading(options = {}) {
452
+ var _a, _b, _c;
453
+ const randomLoading = this.getRandomAnimation('LOADING');
454
+ if (randomLoading) {
455
+ const transitionOptions = {
456
+ loopCount: 0,
457
+ fadeInDuration: (_a = options.fadeInDuration) !== null && _a !== void 0 ? _a : 0.8,
458
+ fadeOutDuration: (_b = options.fadeOutDuration) !== null && _b !== void 0 ? _b : 0.8,
459
+ timeScale: (_c = options.timeScale) !== null && _c !== void 0 ? _c : this.timeScale,
460
+ ...options,
461
+ };
462
+ transitionOptions.loopCount = 0;
463
+ this.play(randomLoading, transitionOptions);
464
+ }
465
+ else {
466
+ console.warn('[AvatarAnimator] No loading animations available, using idle instead');
467
+ this.idle(options);
468
+ }
469
+ }
470
+ playSequence(sequence, options = {}) {
471
+ var _a;
472
+ if (!sequence || sequence.length === 0) {
473
+ console.warn('[AvatarAnimator] Empty animation sequence provided');
474
+ return;
475
+ }
476
+ if (sequence.length > 5) {
477
+ console.warn(`[AvatarAnimator] Sequence too long (${sequence.length}), limiting to 5 animations`);
478
+ sequence = sequence.slice(0, 5);
479
+ }
480
+ const validSequence = sequence.filter(name => this.actions[name]);
481
+ if (validSequence.length === 0) {
482
+ console.error('[AvatarAnimator] No valid animations in sequence, defaulting to idle');
483
+ this.idle();
484
+ return;
485
+ }
486
+ if (this.isTransitioning) {
487
+ setTimeout(() => {
488
+ this.playSequence(sequence, options);
489
+ }, 100);
490
+ return;
491
+ }
492
+ this.currentSequence = [...validSequence];
493
+ this.sequenceIndex = 0;
494
+ const firstAnimationOptions = {
495
+ fadeInDuration: 0.6,
496
+ fadeOutDuration: 0.6,
497
+ loopCount: 1,
498
+ timeScale: (_a = options.timeScale) !== null && _a !== void 0 ? _a : this.timeScale,
499
+ };
500
+ const firstAnimation = validSequence[0];
501
+ this.play(firstAnimation, firstAnimationOptions);
502
+ }
503
+ forceIdle() {
504
+ const idleAnimations = this.getAnimationsByCategory('IDLE');
505
+ if (idleAnimations.length > 0) {
506
+ const forcedIdle = idleAnimations[0].name;
507
+ this.play(forcedIdle, {
508
+ loopCount: 0,
509
+ fadeInDuration: 0.8,
510
+ fadeOutDuration: 0.8,
511
+ });
512
+ this.currentIdleAnimation = forcedIdle;
513
+ this.idleRotationCount = 0;
514
+ }
515
+ else {
516
+ console.error('[AvatarAnimator] No idle animations available for forced transition');
517
+ }
518
+ }
519
+ update(delta) {
520
+ if (!this.initialized || !this.mixer)
521
+ return;
522
+ const clampedDelta = Math.min(delta, 0.1);
523
+ this.mixer.update(clampedDelta);
524
+ if (this.isTransitioning) {
525
+ return;
526
+ }
527
+ if (this.currentSequence && this.currentAnimation) {
528
+ const currentAction = this.actions[this.currentAnimation];
529
+ if (currentAction) {
530
+ const clipDuration = currentAction.getClip().duration;
531
+ const progress = currentAction.time / clipDuration;
532
+ if (progress > 0.85 && !this.isTransitioning) {
533
+ if (this.sequenceIndex < this.currentSequence.length - 1) {
534
+ this.sequenceIndex++;
535
+ const nextAnimation = this.currentSequence[this.sequenceIndex];
536
+ this.play(nextAnimation, {
537
+ fadeInDuration: 0.5,
538
+ fadeOutDuration: 0.5,
539
+ loopCount: 1,
540
+ });
541
+ }
542
+ else {
543
+ this.currentSequence = null;
544
+ this.sequenceIndex = 0;
545
+ this.idle({
546
+ fadeInDuration: 0.7,
547
+ fadeOutDuration: 0.7,
548
+ });
549
+ }
550
+ }
551
+ }
552
+ }
553
+ if (this.currentAnimation &&
554
+ this.currentIdleAnimation &&
555
+ this.getAnimationCategory() === 'IDLE') {
556
+ const currentAction = this.actions[this.currentAnimation];
557
+ if (currentAction) {
558
+ const clipDuration = currentAction.getClip().duration;
559
+ const currentTime = currentAction.time % clipDuration;
560
+ const previousTime = this.lastAnimationTime || 0;
561
+ if (previousTime > currentTime + 0.1) {
562
+ this.idleRotationCount++;
563
+ if (this.idleRotationCount >= this.idleRotationLimit) {
564
+ this.idleRotationCount = 0;
565
+ this.idle({
566
+ fadeInDuration: 0.6,
567
+ fadeOutDuration: 0.6,
568
+ });
569
+ }
570
+ }
571
+ this.lastAnimationTime = currentTime;
572
+ }
573
+ }
574
+ }
575
+ isAnimationPlaying(animationName) {
576
+ if (!this.actions[animationName])
577
+ return false;
578
+ const action = this.actions[animationName];
579
+ return action.isRunning() && action.getEffectiveWeight() > 0.1;
580
+ }
581
+ setupMixerEvents() {
582
+ if (!this.mixer) {
583
+ console.warn('[AvatarAnimator] Cannot setup mixer events - mixer not initialized');
584
+ return;
585
+ }
586
+ this.mixer.addEventListener('loop', event => {
587
+ const action = event.action;
588
+ if (!action || !this.currentAnimation)
589
+ return;
590
+ if (action === this.actions[this.currentAnimation]) {
591
+ this.emit('loop', { animation: this.currentAnimation });
592
+ }
593
+ });
594
+ this.mixer.addEventListener('finished', event => {
595
+ const action = event.action;
596
+ if (!action || !this.currentAnimation)
597
+ return;
598
+ if (action === this.actions[this.currentAnimation]) {
599
+ if (this.isTransitioning) {
600
+ return;
601
+ }
602
+ this.emit('complete', { animation: this.currentAnimation });
603
+ setTimeout(() => {
604
+ var _a;
605
+ if (this.currentSequence &&
606
+ this.sequenceIndex < this.currentSequence.length - 1) {
607
+ this.sequenceIndex++;
608
+ this.play(this.currentSequence[this.sequenceIndex], {
609
+ fadeInDuration: 0.5,
610
+ fadeOutDuration: 0.5,
611
+ loopCount: 1,
612
+ });
613
+ }
614
+ else if (this.currentSequence &&
615
+ this.sequenceIndex >= this.currentSequence.length - 1) {
616
+ this.currentSequence = null;
617
+ this.sequenceIndex = 0;
618
+ this.idle({
619
+ fadeInDuration: 0.7,
620
+ fadeOutDuration: 0.7,
621
+ });
622
+ }
623
+ else if (this.currentAnimation &&
624
+ ((_a = this.getAnimationInfo(this.currentAnimation)) === null || _a === void 0 ? void 0 : _a.category) !== 'IDLE') {
625
+ this.idle({
626
+ fadeInDuration: 0.7,
627
+ fadeOutDuration: 0.7,
628
+ });
629
+ }
630
+ }, 50);
631
+ }
632
+ });
633
+ }
634
+ handleSequenceProgressionIfNeeded() {
635
+ if (!this.currentSequence ||
636
+ !this.currentAnimation ||
637
+ this.sequenceIndex >= this.currentSequence.length - 1) {
638
+ return;
639
+ }
640
+ const currentAction = this.actions[this.currentAnimation];
641
+ if (!currentAction)
642
+ return;
643
+ const clipDuration = currentAction.getClip().duration;
644
+ const progress = currentAction.time / clipDuration;
645
+ if (progress > 0.9 && !this.isTransitioning) {
646
+ this.sequenceIndex++;
647
+ if (this.sequenceIndex < this.currentSequence.length) {
648
+ const nextAnimation = this.currentSequence[this.sequenceIndex];
649
+ this.play(nextAnimation, {
650
+ fadeInDuration: 0.3,
651
+ fadeOutDuration: 0.3,
652
+ loopCount: 1,
653
+ });
654
+ }
655
+ else {
656
+ this.currentSequence = null;
657
+ this.sequenceIndex = 0;
658
+ this.idle();
659
+ }
660
+ }
661
+ }
662
+ handleIdleRotationIfNeeded() {
663
+ if (!this.currentAnimation ||
664
+ !this.currentIdleAnimation ||
665
+ this.getAnimationCategory() !== 'IDLE') {
666
+ return;
667
+ }
668
+ const currentAction = this.actions[this.currentAnimation];
669
+ if (!currentAction)
670
+ return;
671
+ const clipDuration = currentAction.getClip().duration;
672
+ const currentTime = currentAction.time % clipDuration;
673
+ const previousTime = this.lastAnimationTime || 0;
674
+ if (previousTime > currentTime + 0.1) {
675
+ this.idleRotationCount++;
676
+ if (this.idleRotationCount >= this.idleRotationLimit) {
677
+ this.idleRotationCount = 0;
678
+ this.idle();
679
+ }
680
+ }
681
+ this.lastAnimationTime = currentTime;
682
+ }
683
+ setTimeScale(timeScale) {
684
+ this.timeScale = timeScale;
685
+ if (this.currentAnimation) {
686
+ const currentAction = this.actions[this.currentAnimation];
687
+ if (currentAction) {
688
+ currentAction.timeScale = timeScale;
689
+ }
690
+ }
691
+ }
692
+ getRandomAnimation(category, exclude = []) {
693
+ const filteredAnimations = Array.from(this.animations.values()).filter(info => info.category === category && !exclude.includes(info.name));
694
+ if (filteredAnimations.length === 0)
695
+ return null;
696
+ const randomIndex = Math.floor(Math.random() * filteredAnimations.length);
697
+ return filteredAnimations[randomIndex].name;
698
+ }
699
+ getAnimationInfo(name) {
700
+ return this.animations.get(name) || null;
701
+ }
702
+ getAnimationCategory() {
703
+ var _a;
704
+ if (!this.currentAnimation)
705
+ return null;
706
+ return ((_a = this.getAnimationInfo(this.currentAnimation)) === null || _a === void 0 ? void 0 : _a.category) || null;
707
+ }
708
+ on(event, callback) {
709
+ if (this.eventListeners[event]) {
710
+ this.eventListeners[event].push(callback);
711
+ }
712
+ }
713
+ off(event, callback) {
714
+ if (this.eventListeners[event]) {
715
+ this.eventListeners[event] = this.eventListeners[event].filter(cb => cb !== callback);
716
+ }
717
+ }
718
+ emit(event, data) {
719
+ if (this.eventListeners[event]) {
720
+ this.eventListeners[event].forEach(callback => {
721
+ try {
722
+ callback(data);
723
+ }
724
+ catch (error) {
725
+ console.error(`Error in ${event} event handler:`, error);
726
+ }
727
+ });
728
+ }
729
+ }
730
+ getCurrentAnimationName() {
731
+ return this.currentAnimation;
732
+ }
733
+ getAvatarType() {
734
+ return this.avatarType;
735
+ }
736
+ isInitialized() {
737
+ return this.initialized;
738
+ }
739
+ getAllAnimationNames() {
740
+ return Array.from(this.animations.keys());
741
+ }
742
+ getAnimationsByCategory(category) {
743
+ return Array.from(this.animations.values()).filter(info => info.category === category);
744
+ }
745
+ }
746
+ exports.AvatarAnimator = AvatarAnimator;
747
+ //# sourceMappingURL=AvatarAnimator.js.map