@memori.ai/memori-react 7.19.2 → 7.21.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 (108) hide show
  1. package/CHANGELOG.md +45 -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.js +7 -1
  27. package/dist/components/ChatBubble/ChatBubble.js.map +1 -1
  28. package/dist/components/MemoriWidget/MemoriWidget.js +130 -62
  29. package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
  30. package/dist/components/UploadButton/UploadButton.js +2 -2
  31. package/dist/components/UploadButton/UploadButton.js.map +1 -1
  32. package/dist/components/WhyThisAnswer/WhyThisAnswer.css +43 -0
  33. package/dist/components/WhyThisAnswer/WhyThisAnswer.js +2 -1
  34. package/dist/components/WhyThisAnswer/WhyThisAnswer.js.map +1 -1
  35. package/dist/context/visemeContext.js +0 -39
  36. package/dist/context/visemeContext.js.map +1 -1
  37. package/dist/locales/de.json +1 -0
  38. package/dist/locales/en.json +1 -0
  39. package/dist/locales/es.json +1 -0
  40. package/dist/locales/fr.json +1 -0
  41. package/dist/locales/it.json +1 -0
  42. package/esm/components/Avatar/AvatarView/AvatarComponent/Shadow/DynamicShadow.d.ts +3 -2
  43. package/esm/components/Avatar/AvatarView/AvatarComponent/Shadow/DynamicShadow.js +13 -6
  44. package/esm/components/Avatar/AvatarView/AvatarComponent/Shadow/DynamicShadow.js.map +1 -1
  45. package/esm/components/Avatar/AvatarView/AvatarComponent/avatarComponent.d.ts +14 -18
  46. package/esm/components/Avatar/AvatarView/AvatarComponent/avatarComponent.js +20 -78
  47. package/esm/components/Avatar/AvatarView/AvatarComponent/avatarComponent.js.map +1 -1
  48. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.d.ts +17 -2
  49. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js +99 -74
  50. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js.map +1 -1
  51. package/esm/components/Avatar/AvatarView/AvatarComponent/components/controllers/AvatarAnimator.d.ts +65 -0
  52. package/esm/components/Avatar/AvatarView/AvatarComponent/components/controllers/AvatarAnimator.js +743 -0
  53. package/esm/components/Avatar/AvatarView/AvatarComponent/components/controllers/AvatarAnimator.js.map +1 -0
  54. package/esm/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.d.ts +9 -2
  55. package/esm/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.js +61 -3
  56. package/esm/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.js.map +1 -1
  57. package/esm/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.d.ts +3 -4
  58. package/esm/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.js +5 -11
  59. package/esm/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.js.map +1 -1
  60. package/esm/components/Avatar/AvatarView/AvatarComponent/constants.d.ts +13 -52
  61. package/esm/components/Avatar/AvatarView/AvatarComponent/constants.js +67 -69
  62. package/esm/components/Avatar/AvatarView/AvatarComponent/constants.js.map +1 -1
  63. package/esm/components/Avatar/AvatarView/index.d.ts +1 -1
  64. package/esm/components/Avatar/AvatarView/index.js +2 -2
  65. package/esm/components/Avatar/AvatarView/index.js.map +1 -1
  66. package/esm/components/ChatBubble/ChatBubble.js +7 -1
  67. package/esm/components/ChatBubble/ChatBubble.js.map +1 -1
  68. package/esm/components/MemoriWidget/MemoriWidget.js +130 -62
  69. package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
  70. package/esm/components/UploadButton/UploadButton.js +2 -2
  71. package/esm/components/UploadButton/UploadButton.js.map +1 -1
  72. package/esm/components/WhyThisAnswer/WhyThisAnswer.css +43 -0
  73. package/esm/components/WhyThisAnswer/WhyThisAnswer.js +2 -1
  74. package/esm/components/WhyThisAnswer/WhyThisAnswer.js.map +1 -1
  75. package/esm/context/visemeContext.js +0 -39
  76. package/esm/context/visemeContext.js.map +1 -1
  77. package/esm/locales/de.json +1 -0
  78. package/esm/locales/en.json +1 -0
  79. package/esm/locales/es.json +1 -0
  80. package/esm/locales/fr.json +1 -0
  81. package/esm/locales/it.json +1 -0
  82. package/package.json +2 -2
  83. package/src/components/Avatar/AvatarView/AvatarComponent/Shadow/DynamicShadow.tsx +15 -8
  84. package/src/components/Avatar/AvatarView/AvatarComponent/avatarComponent.tsx +64 -219
  85. package/src/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.tsx +221 -124
  86. package/src/components/Avatar/AvatarView/AvatarComponent/components/controllers/AvatarAnimator.ts +1250 -0
  87. package/src/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.ts +164 -8
  88. package/src/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.tsx +19 -17
  89. package/src/components/Avatar/AvatarView/AvatarComponent/constants.ts +80 -79
  90. package/src/components/Avatar/AvatarView/index.tsx +1 -7
  91. package/src/components/ChatBubble/ChatBubble.tsx +14 -2
  92. package/src/components/MemoriWidget/MemoriWidget.tsx +168 -76
  93. package/src/components/UploadButton/UploadButton.tsx +4 -4
  94. package/src/components/UploadButton/__snapshots__/UploadButton.test.tsx.snap +1 -1
  95. package/src/components/WhyThisAnswer/WhyThisAnswer.css +43 -0
  96. package/src/components/WhyThisAnswer/WhyThisAnswer.stories.tsx +44 -3
  97. package/src/components/WhyThisAnswer/WhyThisAnswer.test.tsx +128 -8
  98. package/src/components/WhyThisAnswer/WhyThisAnswer.tsx +28 -3
  99. package/src/components/WhyThisAnswer/__snapshots__/WhyThisAnswer.test.tsx.snap +15 -1
  100. package/src/components/layouts/layouts.stories.tsx +0 -8
  101. package/src/context/visemeContext.tsx +40 -41
  102. package/src/index.stories.tsx +63 -65
  103. package/src/locales/de.json +1 -0
  104. package/src/locales/en.json +1 -0
  105. package/src/locales/es.json +1 -0
  106. package/src/locales/fr.json +1 -0
  107. package/src/locales/it.json +1 -0
  108. 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