@sage-rsc/talking-head-react 1.1.0 → 1.1.2
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.
- package/dist/index.cjs +2 -2
- package/dist/index.js +686 -551
- package/package.json +1 -1
- package/src/lib/talkinghead.mjs +275 -55
package/dist/index.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { jsxs as Pe, jsx as me } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef as Me, useRef as
|
|
2
|
+
import { forwardRef as Me, useRef as D, useState as ce, useEffect as de, useCallback as T, useImperativeHandle as Ee, useLayoutEffect as Xe } from "react";
|
|
3
3
|
import * as f from "three";
|
|
4
4
|
import { OrbitControls as Ye } from "three/addons/controls/OrbitControls.js";
|
|
5
5
|
import { GLTFLoader as je } from "three/addons/loaders/GLTFLoader.js";
|
|
6
6
|
import { DRACOLoader as Qe } from "three/addons/loaders/DRACOLoader.js";
|
|
7
|
-
import { FBXLoader as
|
|
7
|
+
import { FBXLoader as De } from "three/addons/loaders/FBXLoader.js";
|
|
8
8
|
import { RoomEnvironment as qe } from "three/addons/environments/RoomEnvironment.js";
|
|
9
|
-
import
|
|
10
|
-
let m, re,
|
|
9
|
+
import _e from "three/addons/libs/stats.module.js";
|
|
10
|
+
let m, re, he;
|
|
11
11
|
const A = [0, 0, 0, 0], w = new f.Vector3(), ze = new f.Vector3(), ne = new f.Vector3(), Ce = new f.Vector3();
|
|
12
12
|
new f.Plane();
|
|
13
13
|
new f.Ray();
|
|
14
14
|
new f.Euler();
|
|
15
|
-
const ie = new f.Quaternion(),
|
|
15
|
+
const ie = new f.Quaternion(), Oe = new f.Quaternion(), fe = new f.Matrix4(), xe = new f.Matrix4();
|
|
16
16
|
new f.Vector3();
|
|
17
|
-
const He = new f.Vector3(0, 0, 1),
|
|
17
|
+
const He = new f.Vector3(0, 0, 1), Ke = new f.Vector3(1, 0, 0), Je = new f.Vector3(0, 1, 0), $e = new f.Vector3(0, 0, 1);
|
|
18
18
|
class et {
|
|
19
19
|
constructor(t = null) {
|
|
20
20
|
this.opt = Object.assign({
|
|
@@ -192,7 +192,7 @@ class et {
|
|
|
192
192
|
const l = this.armature.getObjectByName(s.bone);
|
|
193
193
|
if (!l) throw new Error("Bone '" + s.bone + "' not found in #" + o + " exclude.");
|
|
194
194
|
if (Number.isNaN(s.radius) && s.radius >= 0) throw new Error("Radius must be a non-negative number in #" + o + " exclude.");
|
|
195
|
-
const
|
|
195
|
+
const u = {
|
|
196
196
|
bone: l,
|
|
197
197
|
// Bone object
|
|
198
198
|
radius: s.radius,
|
|
@@ -203,9 +203,9 @@ class et {
|
|
|
203
203
|
};
|
|
204
204
|
if (s.deltaLocal) {
|
|
205
205
|
if (!Array.isArray(s.deltaLocal) || s.deltaLocal.length !== 3 || s.deltaLocal.some((r) => Number.isNaN(r))) throw new Error("deltaLocal must be an array of three numbers in #" + o + " exclude.");
|
|
206
|
-
|
|
206
|
+
u.deltaLocal = [...s.deltaLocal];
|
|
207
207
|
}
|
|
208
|
-
i.excludes.push(
|
|
208
|
+
i.excludes.push(u);
|
|
209
209
|
});
|
|
210
210
|
}
|
|
211
211
|
this.showHelpers();
|
|
@@ -282,8 +282,8 @@ class et {
|
|
|
282
282
|
m = this.dict[o.boneParent.name], m && (m.children || (m.children = []), m.children.push(o));
|
|
283
283
|
}), this.objectsUpdate = [];
|
|
284
284
|
const n = /* @__PURE__ */ new WeakSet(), i = (o) => o.parent?.isBone ? [o, ...i(o.parent)] : [o], s = (o) => {
|
|
285
|
-
i(o).forEach((
|
|
286
|
-
n.has(
|
|
285
|
+
i(o).forEach((u) => {
|
|
286
|
+
n.has(u) || (this.objectsUpdate.push(u), n.add(u));
|
|
287
287
|
});
|
|
288
288
|
};
|
|
289
289
|
this.data.forEach((o) => {
|
|
@@ -308,12 +308,12 @@ class et {
|
|
|
308
308
|
i(t?.isScene, "First parameter must be Scene."), this.scene = t, i(e?.isObject3D, "Second parameter must be the armature Object3D."), this.armature = e, i(Array.isArray(n), "Third parameter must be an array of bone configs."), this.config = n, this.config.forEach((s, o) => {
|
|
309
309
|
const l = "Config item #" + o + ": ";
|
|
310
310
|
i(s.bone, l + "Bone not specified.");
|
|
311
|
-
const
|
|
312
|
-
i(typeof
|
|
313
|
-
const r = this.armature.getObjectByName(
|
|
314
|
-
i(r, l + "Bone '" +
|
|
315
|
-
const
|
|
316
|
-
name:
|
|
311
|
+
const u = s.bone;
|
|
312
|
+
i(typeof u == "string" && u.length > 0, l + "Bone name must be a non-empty string.");
|
|
313
|
+
const r = this.armature.getObjectByName(u);
|
|
314
|
+
i(r, l + "Bone '" + u + "' not found."), i(r.parent?.isBone, l + "Bone must have a parent bone."), i(this.data.every((a) => a.bone !== r), l + "Bone '" + u + "' already exists."), r.updateMatrixWorld(!0);
|
|
315
|
+
const h = {
|
|
316
|
+
name: u,
|
|
317
317
|
// Bone name
|
|
318
318
|
bone: r,
|
|
319
319
|
// Bone object
|
|
@@ -338,9 +338,9 @@ class et {
|
|
|
338
338
|
ea: [0, 0, 0, 0]
|
|
339
339
|
// External acceleration [m/s^2]
|
|
340
340
|
};
|
|
341
|
-
|
|
341
|
+
h.boneParent.matrixWorld.decompose(w, ie, ne), w.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(Oe.setFromUnitVectors(He, w).invert()).normalize(), h.qWorldInverseYaw = ie.clone().normalize(), this.data.push(h), this.dict[u] = h;
|
|
342
342
|
try {
|
|
343
|
-
this.setValue(
|
|
343
|
+
this.setValue(u, "type", s.type), this.setValue(u, "stiffness", s.stiffness), this.setValue(u, "damping", s.damping), this.setValue(u, "external", s.external), this.setValue(u, "limits", s.limits), this.setValue(u, "excludes", s.excludes), this.setValue(u, "deltaLocal", s.deltaLocal), this.setValue(u, "deltaWorld", s.deltaWorld), this.setValue(u, "pivot", s.pivot), this.setValue(u, "helper", s.helper);
|
|
344
344
|
} catch (a) {
|
|
345
345
|
i(!1, l + a);
|
|
346
346
|
}
|
|
@@ -369,9 +369,9 @@ class et {
|
|
|
369
369
|
o.vBasis.y + A[1],
|
|
370
370
|
o.vBasis.z - A[2]
|
|
371
371
|
);
|
|
372
|
-
else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(w, ie, ne), w.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(
|
|
372
|
+
else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(w, ie, ne), w.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(Oe.setFromUnitVectors(He, w).invert()).normalize(), o.boneParent.quaternion.multiply(ie.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(A[0] / o.l), ie.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(ie)), o.isY && (m = o.l / 3, m = m * Math.tanh(A[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(A[2] / o.l), ie.setFromAxisAngle(Ke, -m), o.boneParent.quaternion.multiply(ie)), o.isT && (m = 1.5 * Math.tanh(A[3] * 1.5), ie.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(ie)), o.boneParent.updateWorldMatrix(!1, !0), o.excludes && this.opt.isExcludes)
|
|
373
373
|
for (n = 0, s = o.excludes.length; n < s; n++)
|
|
374
|
-
m = o.excludes[n], ne.set(0, 0, 0), m.deltaLocal && (ne.x += m.deltaLocal[0], ne.y += m.deltaLocal[1], ne.z += m.deltaLocal[2]), ne.applyMatrix4(m.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ne.applyMatrix4(xe), w.copy(o.bone.position), !(w.distanceToSquared(ne) >= m.radiusSq) && (
|
|
374
|
+
m = o.excludes[n], ne.set(0, 0, 0), m.deltaLocal && (ne.x += m.deltaLocal[0], ne.y += m.deltaLocal[1], ne.z += m.deltaLocal[2]), ne.applyMatrix4(m.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ne.applyMatrix4(xe), w.copy(o.bone.position), !(w.distanceToSquared(ne) >= m.radiusSq) && (he = w.length(), re = ne.length(), !(re > m.radius + he) && (re < Math.abs(m.radius - he) || (re = (re * re + he * he - m.radiusSq) / (2 * re), ne.normalize(), Ce.copy(ne).multiplyScalar(re), re = Math.sqrt(he * he - re * re), w.subVectors(w, Ce).projectOnPlane(ne).normalize().multiplyScalar(re), ze.subVectors(o.vBasis, Ce).projectOnPlane(ne).normalize(), he = ze.dot(w), he < 0 && (he = Math.sqrt(re * re - he * he), ze.multiplyScalar(he), w.add(ze)), w.add(Ce).normalize(), ne.copy(o.bone.position).normalize(), ie.setFromUnitVectors(ne, w), o.boneParent.quaternion.premultiply(ie), o.boneParent.updateWorldMatrix(!1, !0))));
|
|
375
375
|
}
|
|
376
376
|
this.helpers.isActive && this.updateHelpers();
|
|
377
377
|
}
|
|
@@ -408,9 +408,9 @@ class et {
|
|
|
408
408
|
);
|
|
409
409
|
}), m = this.helpers.points, m.bones.length) {
|
|
410
410
|
this.helpers.isActive = !0;
|
|
411
|
-
const e = new f.BufferGeometry(), n = m.bones.map((
|
|
411
|
+
const e = new f.BufferGeometry(), n = m.bones.map((u) => [0, 0, 0]).flat();
|
|
412
412
|
e.setAttribute("position", new f.Float32BufferAttribute(n, 3));
|
|
413
|
-
const i = new f.Color(this.opt.helperBoneColor1), s = new f.Color(this.opt.helperBoneColor2), o = m.pivots.map((
|
|
413
|
+
const i = new f.Color(this.opt.helperBoneColor1), s = new f.Color(this.opt.helperBoneColor2), o = m.pivots.map((u) => u && this.opt.isPivots ? [s.r, s.g, s.b] : [i.r, i.g, i.b]).flat();
|
|
414
414
|
e.setAttribute("color", new f.Float32BufferAttribute(o, 3));
|
|
415
415
|
const l = new f.PointsMaterial({
|
|
416
416
|
depthTest: !1,
|
|
@@ -423,9 +423,9 @@ class et {
|
|
|
423
423
|
m.object = new f.Points(e, l), m.object.renderOrder = 998, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
|
|
424
424
|
}
|
|
425
425
|
if (m = this.helpers.lines, m.bones.length) {
|
|
426
|
-
const e = new f.BufferGeometry(), n = m.bones.map((
|
|
426
|
+
const e = new f.BufferGeometry(), n = m.bones.map((u) => [0, 0, 0, 0, 0, 0]).flat();
|
|
427
427
|
e.setAttribute("position", new f.Float32BufferAttribute(n, 3));
|
|
428
|
-
const i = new f.Color(this.opt.helperLinkColor1), s = new f.Color(this.opt.helperLinkColor2), o = m.bones.map((
|
|
428
|
+
const i = new f.Color(this.opt.helperLinkColor1), s = new f.Color(this.opt.helperLinkColor2), o = m.bones.map((u) => [i.r, i.g, i.b, s.r, s.g, s.b]).flat();
|
|
429
429
|
e.setAttribute("color", new f.Float32BufferAttribute(o, 3));
|
|
430
430
|
const l = new f.LineBasicMaterial({
|
|
431
431
|
vertexColors: !0,
|
|
@@ -519,13 +519,13 @@ class tt {
|
|
|
519
519
|
phonemeBoundaries: []
|
|
520
520
|
}, i = 1024, s = 512, o = Math.floor((t.length - i) / s) + 1;
|
|
521
521
|
for (let l = 0; l < o; l++) {
|
|
522
|
-
const
|
|
522
|
+
const u = l * s, r = Math.min(u + i, t.length), h = t.slice(u, r), a = this.calculateEnergy(h);
|
|
523
523
|
n.energy.push(a);
|
|
524
|
-
const c = this.calculateSpectralCentroid(
|
|
524
|
+
const c = this.calculateSpectralCentroid(h);
|
|
525
525
|
n.spectralCentroid.push(c);
|
|
526
|
-
const d = this.calculateZeroCrossingRate(
|
|
526
|
+
const d = this.calculateZeroCrossingRate(h);
|
|
527
527
|
n.zeroCrossingRate.push(d);
|
|
528
|
-
const g = this.calculateMFCC(
|
|
528
|
+
const g = this.calculateMFCC(h);
|
|
529
529
|
n.mfcc.push(g);
|
|
530
530
|
}
|
|
531
531
|
return n.onsets = this.detectOnsets(n.energy), n.phonemeBoundaries = this.detectPhonemeBoundaries(n), n;
|
|
@@ -597,19 +597,19 @@ class tt {
|
|
|
597
597
|
for (; s & o; )
|
|
598
598
|
s ^= o, o >>= 1;
|
|
599
599
|
if (s ^= o, i < s) {
|
|
600
|
-
const l = n[i * 2],
|
|
601
|
-
n[i * 2] = n[s * 2], n[i * 2 + 1] = n[s * 2 + 1], n[s * 2] = l, n[s * 2 + 1] =
|
|
600
|
+
const l = n[i * 2], u = n[i * 2 + 1];
|
|
601
|
+
n[i * 2] = n[s * 2], n[i * 2 + 1] = n[s * 2 + 1], n[s * 2] = l, n[s * 2 + 1] = u;
|
|
602
602
|
}
|
|
603
603
|
}
|
|
604
604
|
for (let i = 2; i <= e; i <<= 1) {
|
|
605
605
|
const s = -2 * Math.PI / i, o = Math.cos(s), l = Math.sin(s);
|
|
606
|
-
for (let
|
|
607
|
-
let r = 1,
|
|
606
|
+
for (let u = 0; u < e; u += i) {
|
|
607
|
+
let r = 1, h = 0;
|
|
608
608
|
for (let a = 0; a < i / 2; a++) {
|
|
609
|
-
const c = n[(
|
|
610
|
-
n[(
|
|
611
|
-
const b = r * o -
|
|
612
|
-
r = b,
|
|
609
|
+
const c = n[(u + a) * 2], d = n[(u + a) * 2 + 1], g = n[(u + a + i / 2) * 2] * r - n[(u + a + i / 2) * 2 + 1] * h, x = n[(u + a + i / 2) * 2] * h + n[(u + a + i / 2) * 2 + 1] * r;
|
|
610
|
+
n[(u + a) * 2] = c + g, n[(u + a) * 2 + 1] = d + x, n[(u + a + i / 2) * 2] = c - g, n[(u + a + i / 2) * 2 + 1] = d - x;
|
|
611
|
+
const b = r * o - h * l, I = r * l + h * o;
|
|
612
|
+
r = b, h = I;
|
|
613
613
|
}
|
|
614
614
|
}
|
|
615
615
|
}
|
|
@@ -624,8 +624,8 @@ class tt {
|
|
|
624
624
|
const e = [];
|
|
625
625
|
let s = -0.1;
|
|
626
626
|
for (let o = 1; o < t.length; o++) {
|
|
627
|
-
const l = t[o] - t[o - 1],
|
|
628
|
-
l > 0.1 &&
|
|
627
|
+
const l = t[o] - t[o - 1], u = o * 0.023;
|
|
628
|
+
l > 0.1 && u - s > 0.1 && (e.push(u), s = u);
|
|
629
629
|
}
|
|
630
630
|
return e;
|
|
631
631
|
}
|
|
@@ -637,8 +637,8 @@ class tt {
|
|
|
637
637
|
detectPhonemeBoundaries(t) {
|
|
638
638
|
const e = [], { energy: n, spectralCentroid: i, zeroCrossingRate: s } = t;
|
|
639
639
|
for (let o = 1; o < n.length; o++) {
|
|
640
|
-
const l = o * 0.023,
|
|
641
|
-
|
|
640
|
+
const l = o * 0.023, u = Math.abs(n[o] - n[o - 1]), r = Math.abs(i[o] - i[o - 1]), h = Math.abs(s[o] - s[o - 1]);
|
|
641
|
+
u + r * 0.1 + h * 0.5 > 0.2 && e.push(l);
|
|
642
642
|
}
|
|
643
643
|
return e;
|
|
644
644
|
}
|
|
@@ -654,14 +654,14 @@ class tt {
|
|
|
654
654
|
t.phonemeBoundaries, t.onsets;
|
|
655
655
|
const s = [];
|
|
656
656
|
let o = 0;
|
|
657
|
-
for (let
|
|
658
|
-
const r = i[
|
|
657
|
+
for (let u = 0; u < i.length; u++) {
|
|
658
|
+
const r = i[u], h = this.estimateWordDuration(r, n / i.length);
|
|
659
659
|
s.push({
|
|
660
660
|
word: r,
|
|
661
661
|
startTime: o,
|
|
662
|
-
endTime: o +
|
|
663
|
-
duration:
|
|
664
|
-
}), o +=
|
|
662
|
+
endTime: o + h,
|
|
663
|
+
duration: h
|
|
664
|
+
}), o += h;
|
|
665
665
|
}
|
|
666
666
|
const l = this.generateVisemeTimings(t, e, n);
|
|
667
667
|
return {
|
|
@@ -701,27 +701,27 @@ class tt {
|
|
|
701
701
|
const i = [], s = t.phonemeBoundaries;
|
|
702
702
|
t.onsets;
|
|
703
703
|
const o = this.textToVisemes(e);
|
|
704
|
-
let l = 0,
|
|
704
|
+
let l = 0, u = 0;
|
|
705
705
|
for (let r = 0; r < s.length && l < o.length; r++) {
|
|
706
|
-
const
|
|
706
|
+
const h = s[r], a = o[l], c = t.energy[Math.floor(h / 0.023)] || 0, d = this.calculateVisemeDuration(a, c);
|
|
707
707
|
i.push({
|
|
708
708
|
viseme: a,
|
|
709
|
-
startTime:
|
|
710
|
-
endTime:
|
|
709
|
+
startTime: u,
|
|
710
|
+
endTime: u + d,
|
|
711
711
|
duration: d,
|
|
712
712
|
intensity: Math.min(1, c * 2)
|
|
713
713
|
// Map energy to viseme intensity
|
|
714
|
-
}),
|
|
714
|
+
}), u += d, l++;
|
|
715
715
|
}
|
|
716
716
|
for (; l < o.length; ) {
|
|
717
|
-
const r = o[l],
|
|
717
|
+
const r = o[l], h = this.calculateVisemeDuration(r, 0.5);
|
|
718
718
|
i.push({
|
|
719
719
|
viseme: r,
|
|
720
|
-
startTime:
|
|
721
|
-
endTime:
|
|
722
|
-
duration:
|
|
720
|
+
startTime: u,
|
|
721
|
+
endTime: u + h,
|
|
722
|
+
duration: h,
|
|
723
723
|
intensity: 0.6
|
|
724
|
-
}),
|
|
724
|
+
}), u += h, l++;
|
|
725
725
|
}
|
|
726
726
|
return i;
|
|
727
727
|
}
|
|
@@ -775,16 +775,16 @@ class tt {
|
|
|
775
775
|
let o = 0;
|
|
776
776
|
for (; o < s.length; ) {
|
|
777
777
|
let l = !1;
|
|
778
|
-
for (let
|
|
779
|
-
const r = s.substr(o,
|
|
778
|
+
for (let u = 3; u >= 2; u--) {
|
|
779
|
+
const r = s.substr(o, u);
|
|
780
780
|
if (e[r]) {
|
|
781
|
-
n.push(e[r]), o +=
|
|
781
|
+
n.push(e[r]), o += u, l = !0;
|
|
782
782
|
break;
|
|
783
783
|
}
|
|
784
784
|
}
|
|
785
785
|
if (!l) {
|
|
786
|
-
const
|
|
787
|
-
e[
|
|
786
|
+
const u = s[o];
|
|
787
|
+
e[u] && n.push(e[u]), o++;
|
|
788
788
|
}
|
|
789
789
|
}
|
|
790
790
|
}
|
|
@@ -1206,11 +1206,11 @@ class nt {
|
|
|
1206
1206
|
};
|
|
1207
1207
|
Object.keys(this.rules).forEach((e) => {
|
|
1208
1208
|
this.rules[e] = this.rules[e].map((n) => {
|
|
1209
|
-
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i),
|
|
1209
|
+
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), u = n.substring(i + 1, s), r = n.substring(s + 1, o), h = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
|
|
1210
1210
|
let c = "";
|
|
1211
1211
|
c += [...l].map((g) => t[g] || g).join("");
|
|
1212
|
-
const d = [...
|
|
1213
|
-
return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c),
|
|
1212
|
+
const d = [...u];
|
|
1213
|
+
return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c), h.length && h.split(" ").forEach((g) => {
|
|
1214
1214
|
a.visemes.push(g);
|
|
1215
1215
|
}), a;
|
|
1216
1216
|
});
|
|
@@ -1324,8 +1324,8 @@ class nt {
|
|
|
1324
1324
|
*/
|
|
1325
1325
|
convertDecade(t) {
|
|
1326
1326
|
const e = parseInt(t), n = !isNaN(e) && t.length === 2, i = !isNaN(e) && t.length > 2 && e > 0 && e <= 3e3, s = i && e % 1e3 === 0 ? Math.floor(e / 1e3) : null, o = i && !s ? Math.floor(e / 100) : null, l = n || i ? Math.floor(e % 100 / 10) * 10 : null;
|
|
1327
|
-
let
|
|
1328
|
-
return s ?
|
|
1327
|
+
let u = [];
|
|
1328
|
+
return s ? u.push(this.convertNumberToWords(s).trim(), "thousands") : (o && u.push(this.convertNumberToWords(o).trim()), l ? u.push(this.decades[l] || this.convertNumberToWords(l).trim() + "s") : o ? u.push("hundreds") : u.push(t)), u.join(" ");
|
|
1329
1329
|
}
|
|
1330
1330
|
/**
|
|
1331
1331
|
* Convert ordinal number to text.
|
|
@@ -1376,9 +1376,9 @@ class nt {
|
|
|
1376
1376
|
const s = i[e.i], o = this.rules[s];
|
|
1377
1377
|
if (o)
|
|
1378
1378
|
for (let l = 0; l < o.length; l++) {
|
|
1379
|
-
const
|
|
1380
|
-
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(
|
|
1381
|
-
|
|
1379
|
+
const u = o[l];
|
|
1380
|
+
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(u.regex)) {
|
|
1381
|
+
u.visemes.forEach((a) => {
|
|
1382
1382
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === a) {
|
|
1383
1383
|
const c = 0.7 * (this.visemeDurations[a] || 1);
|
|
1384
1384
|
e.durations[e.durations.length - 1] += c, n += c;
|
|
@@ -1386,7 +1386,7 @@ class nt {
|
|
|
1386
1386
|
const c = this.visemeDurations[a] || 1;
|
|
1387
1387
|
e.visemes.push(a), e.times.push(n), e.durations.push(c), n += c;
|
|
1388
1388
|
}
|
|
1389
|
-
}), e.i +=
|
|
1389
|
+
}), e.i += u.move;
|
|
1390
1390
|
break;
|
|
1391
1391
|
}
|
|
1392
1392
|
}
|
|
@@ -1616,11 +1616,11 @@ class ot {
|
|
|
1616
1616
|
};
|
|
1617
1617
|
Object.keys(this.rules).forEach((e) => {
|
|
1618
1618
|
this.rules[e] = this.rules[e].map((n) => {
|
|
1619
|
-
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i),
|
|
1619
|
+
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), u = n.substring(i + 1, s), r = n.substring(s + 1, o), h = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
|
|
1620
1620
|
let c = "";
|
|
1621
1621
|
c += [...l].map((g) => t[g] || g).join("");
|
|
1622
|
-
const d = [...
|
|
1623
|
-
return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c),
|
|
1622
|
+
const d = [...u];
|
|
1623
|
+
return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c), h.length && h.split(" ").forEach((g) => {
|
|
1624
1624
|
a.visemes.push(g);
|
|
1625
1625
|
}), a;
|
|
1626
1626
|
});
|
|
@@ -1732,8 +1732,8 @@ class ot {
|
|
|
1732
1732
|
const s = i[e.i], o = this.rules[s];
|
|
1733
1733
|
if (o) {
|
|
1734
1734
|
let l = !1;
|
|
1735
|
-
for (let
|
|
1736
|
-
const r = o[
|
|
1735
|
+
for (let u = 0; u < o.length; u++) {
|
|
1736
|
+
const r = o[u];
|
|
1737
1737
|
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(r.regex)) {
|
|
1738
1738
|
r.visemes.forEach((c) => {
|
|
1739
1739
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === c) {
|
|
@@ -2131,11 +2131,11 @@ class at {
|
|
|
2131
2131
|
};
|
|
2132
2132
|
Object.keys(this.rules).forEach((e) => {
|
|
2133
2133
|
this.rules[e] = this.rules[e].map((n) => {
|
|
2134
|
-
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i),
|
|
2134
|
+
const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), u = n.substring(i + 1, s), r = n.substring(s + 1, o), h = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
|
|
2135
2135
|
let c = "";
|
|
2136
2136
|
c += [...l].map((g) => t[g] || g).join("");
|
|
2137
|
-
const d = [...
|
|
2138
|
-
return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c, "i"),
|
|
2137
|
+
const d = [...u];
|
|
2138
|
+
return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c, "i"), h.length && h.split(" ").forEach((g) => {
|
|
2139
2139
|
g && a.visemes.push(g);
|
|
2140
2140
|
}), a;
|
|
2141
2141
|
});
|
|
@@ -2267,8 +2267,8 @@ class at {
|
|
|
2267
2267
|
const s = i[e.i], o = this.rules[s];
|
|
2268
2268
|
if (o) {
|
|
2269
2269
|
let l = !1;
|
|
2270
|
-
for (let
|
|
2271
|
-
const r = o[
|
|
2270
|
+
for (let u = 0; u < o.length; u++) {
|
|
2271
|
+
const r = o[u];
|
|
2272
2272
|
if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(r.regex)) {
|
|
2273
2273
|
r.visemes.forEach((c) => {
|
|
2274
2274
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === c) {
|
|
@@ -2381,10 +2381,10 @@ class lt {
|
|
|
2381
2381
|
const e = [];
|
|
2382
2382
|
let n = parseFloat(t);
|
|
2383
2383
|
if (n === void 0) return t;
|
|
2384
|
-
let i = (s, o, l,
|
|
2384
|
+
let i = (s, o, l, u, r) => {
|
|
2385
2385
|
if (s < o) return s;
|
|
2386
|
-
const
|
|
2387
|
-
return e.push(l + (
|
|
2386
|
+
const h = Math.floor(s / o);
|
|
2387
|
+
return e.push(l + (h === 1 ? u : this.numberToFinnishWords(h.toString()) + r)), s - h * o;
|
|
2388
2388
|
};
|
|
2389
2389
|
if (n < 0 && (e.push("miinus "), n = Math.abs(n)), n = i(n, 1e9, " ", "miljardi", " miljardia"), n = i(n, 1e6, " ", "miljoona", " miljoonaa"), n = i(n, 1e3, "", "tuhat", "tuhatta"), n = i(n, 100, " ", "sata", "sataa"), n > 20 && (n = i(n, 10, "", "", "kymmentä")), n >= 1) {
|
|
2390
2390
|
let s = Math.floor(n);
|
|
@@ -2436,11 +2436,11 @@ class lt {
|
|
|
2436
2436
|
return e;
|
|
2437
2437
|
}
|
|
2438
2438
|
}
|
|
2439
|
-
const
|
|
2439
|
+
const ht = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2440
2440
|
__proto__: null,
|
|
2441
2441
|
LipsyncFi: lt
|
|
2442
2442
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2443
|
-
class
|
|
2443
|
+
class ut {
|
|
2444
2444
|
/**
|
|
2445
2445
|
* @constructor
|
|
2446
2446
|
*/
|
|
@@ -2559,10 +2559,10 @@ class ht {
|
|
|
2559
2559
|
const e = [];
|
|
2560
2560
|
let n = parseFloat(t);
|
|
2561
2561
|
if (n === void 0) return t;
|
|
2562
|
-
let i = (s, o, l,
|
|
2562
|
+
let i = (s, o, l, u, r) => {
|
|
2563
2563
|
if (s < o) return s;
|
|
2564
|
-
const
|
|
2565
|
-
return
|
|
2564
|
+
const h = Math.floor(s / o);
|
|
2565
|
+
return h === 1 ? e.push(this.numbers[1]) : e.push(this.numberToLithuanianWords(h.toString())), h % 10 === 1 ? e.push(l) : h % 10 === 0 || h % 100 > 10 && h % 100 < 20 ? e.push(r) : e.push(u), s - h * o;
|
|
2566
2566
|
};
|
|
2567
2567
|
n < 0 && (e.push("minus"), n = Math.abs(n)), n = i(n, 1e9, "milijardas", "milijardai", "milijardų"), n = i(n, 1e6, "milijonas", "milijonai", "milijonų"), n = i(n, 1e3, "tūkstantis", "tūkstančiai", "tūkstančių"), n = i(n, 100, "šimtas", "šimtai", "šimtų");
|
|
2568
2568
|
for (let s = this.tens.length - 1; s >= 1; s--)
|
|
@@ -2608,11 +2608,11 @@ class ht {
|
|
|
2608
2608
|
const o = i[s].toLowerCase(), l = this.visemes[o];
|
|
2609
2609
|
if (l)
|
|
2610
2610
|
if (e.visemes.length && e.visemes[e.visemes.length - 1] === l) {
|
|
2611
|
-
const
|
|
2612
|
-
e.durations[e.durations.length - 1] +=
|
|
2611
|
+
const u = 0.7 * (this.durations[o] || 1);
|
|
2612
|
+
e.durations[e.durations.length - 1] += u, n += u;
|
|
2613
2613
|
} else {
|
|
2614
|
-
const
|
|
2615
|
-
e.visemes.push(l), e.times.push(n), e.durations.push(
|
|
2614
|
+
const u = this.durations[o] || 1;
|
|
2615
|
+
e.visemes.push(l), e.times.push(n), e.durations.push(u), n += u;
|
|
2616
2616
|
}
|
|
2617
2617
|
else
|
|
2618
2618
|
n += this.pauses[i[s]] || 0;
|
|
@@ -2622,12 +2622,12 @@ class ht {
|
|
|
2622
2622
|
}
|
|
2623
2623
|
const ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2624
2624
|
__proto__: null,
|
|
2625
|
-
LipsyncLt:
|
|
2625
|
+
LipsyncLt: ut
|
|
2626
2626
|
}, Symbol.toStringTag, { value: "Module" })), dt = new URL("data:text/javascript;base64,Y2xhc3MgUGxheWJhY2tXb3JrbGV0IGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHsKICBzdGF0aWMgRlNNID0gewogICAgSURMRTogMCwKICAgIFBMQVlJTkc6IDEsCiAgfTsKCiAgY29uc3RydWN0b3Iob3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMucG9ydC5vbm1lc3NhZ2UgPSB0aGlzLmhhbmRsZU1lc3NhZ2UuYmluZCh0aGlzKTsKCiAgICB0aGlzLl9zYW1wbGVSYXRlID0gb3B0aW9ucz8ucHJvY2Vzc29yT3B0aW9ucz8uc2FtcGxlUmF0ZSB8fCBzYW1wbGVSYXRlOwogICAgdGhpcy5fc2NhbGUgPSAxIC8gMzI3Njg7IC8vIFBDTTE2IC0+IGZsb2F0CgogICAgLy8gU2lsZW5jZSBkZXRlY3Rpb24gdGhyZXNob2xkICgxIHNlY29uZCkgYXMgYSBmYWxsYmFjayBzYWZldHkgbmV0CiAgICBjb25zdCBzaWxlbmNlRHVyYXRpb25TZWNvbmRzID0gMS4wOwogICAgdGhpcy5fc2lsZW5jZVRocmVzaG9sZEJsb2NrcyA9IE1hdGguY2VpbCgodGhpcy5fc2FtcGxlUmF0ZSAqIHNpbGVuY2VEdXJhdGlvblNlY29uZHMpIC8gMTI4KTsKCiAgICAvLyBNZXRyaWNzIGNvbmZpZ3VyYXRpb24gdmlhIG9wdGlvbnMKICAgIGNvbnN0IG1ldHJpY3NDZmcgPSBvcHRpb25zPy5wcm9jZXNzb3JPcHRpb25zPy5tZXRyaWNzIHx8IHt9OwogICAgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSBtZXRyaWNzQ2ZnLmVuYWJsZWQgIT09IGZhbHNlOwogICAgY29uc3QgaW50ZXJ2YWxIeiA9ICh0eXBlb2YgbWV0cmljc0NmZy5pbnRlcnZhbEh6ID09PSAibnVtYmVyIiAmJiBtZXRyaWNzQ2ZnLmludGVydmFsSHogPiAwKQogICAgICA/IG1ldHJpY3NDZmcuaW50ZXJ2YWxIeiA6IDI7CiAgICAvLyBNZXRyaWNzIHN0YXRlIChsb3ctb3ZlcmhlYWQpCiAgICB0aGlzLl9mcmFtZXNQcm9jZXNzZWQgPSAwOwogICAgdGhpcy5fdW5kZXJydW5CbG9ja3MgPSAwOwogICAgdGhpcy5fbWF4UXVldWVTYW1wbGVzID0gMDsKICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSAwOwogICAgLy8gQ29udmVydCB0byBmcmFtZXMgYmV0d2VlbiByZXBvcnRzCiAgICB0aGlzLl9tZXRyaWNzSW50ZXJ2YWxGcmFtZXMgPSBNYXRoLm1heCgxMjgsIE1hdGgucm91bmQodGhpcy5fc2FtcGxlUmF0ZSAvIGludGVydmFsSHopKTsKCiAgICB0aGlzLnJlc2V0KCk7CiAgfQoKICAvKioKICAgKiBSZXNldHMgdGhlIHdvcmtsZXQgdG8gaXRzIGluaXRpYWwgSURMRSBzdGF0ZS4KICAgKi8KICByZXNldCgpIHsKICAgIHRoaXMuX2J1ZmZlclF1ZXVlID0gW107CiAgICB0aGlzLl9jdXJyZW50Q2h1bmsgPSBudWxsOwogICAgdGhpcy5fY3VycmVudENodW5rT2Zmc2V0ID0gMDsKICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFOwoKICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IGZhbHNlOwogICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsKICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IGZhbHNlOwogICAgLy8gUmVzZXQgbWF4IHF1ZXVlIHRyYWNrZXIgb25seSB3aGVuIGdvaW5nIGlkbGUKICAgIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IDA7CiAgfQoKICBoYW5kbGVNZXNzYWdlKGV2ZW50KSB7CiAgICBjb25zdCB7IHR5cGUsIGRhdGEgfSA9IGV2ZW50LmRhdGE7CgogICAgLy8gSU5URVJSVVBUOiBUaGUgbWFpbiB0aHJlYWQgd2FudHMgdG8gc3RvcCBpbW1lZGlhdGVseS4KICAgIGlmICh0eXBlID09PSAic3RvcCIpIHsKICAgICAgdGhpcy5yZXNldCgpOwogICAgICAvLyBTZW5kIGZpbmFsIG1ldHJpY3Mgc2hvd2luZyBjbGVhcmVkIHN0YXRlCiAgICAgIGlmICh0aGlzLl9tZXRyaWNzRW5hYmxlZCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICB0eXBlOiAibWV0cmljcyIsCiAgICAgICAgICAgIGRhdGE6IHsKICAgICAgICAgICAgICBzdGF0ZTogUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFLAogICAgICAgICAgICAgIHF1ZXVlZFNhbXBsZXM6IDAsCiAgICAgICAgICAgICAgcXVldWVkTXM6IDAsCiAgICAgICAgICAgICAgbWF4UXVldWVkTXM6IE1hdGgucm91bmQoKHRoaXMuX21heFF1ZXVlU2FtcGxlcyAvIHRoaXMuX3NhbXBsZVJhdGUpICogMTAwMCksCiAgICAgICAgICAgICAgdW5kZXJydW5CbG9ja3M6IHRoaXMuX3VuZGVycnVuQmxvY2tzLAogICAgICAgICAgICAgIGZyYW1lc1Byb2Nlc3NlZDogdGhpcy5fZnJhbWVzUHJvY2Vzc2VkCiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKF8pIHsgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBNYWluIHRocmVhZCBoYXMgc2lnbmFsZWQgdGhhdCBubyBtb3JlIGF1ZGlvIGNodW5rcyB3aWxsIGJlIHNlbnQgZm9yIHRoaXMgdXR0ZXJhbmNlLgogICAgaWYgKHR5cGUgPT09ICJuby1tb3JlLWRhdGEiKSB7CiAgICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IHRydWU7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBVcGRhdGUgbWV0cmljcyBjb25maWd1cmF0aW9uIGF0IHJ1bnRpbWUKICAgIGlmICh0eXBlID09PSAiY29uZmlnLW1ldHJpY3MiICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICJvYmplY3QiKSB7CiAgICAgIGlmICgiZW5hYmxlZCIgaW4gZGF0YSkgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSAhIWRhdGEuZW5hYmxlZDsKICAgICAgaWYgKHR5cGVvZiBkYXRhLmludGVydmFsSHogPT09ICJudW1iZXIiICYmIGRhdGEuaW50ZXJ2YWxIeiA+IDApIHsKICAgICAgICBjb25zdCBpbnRlcnZhbEh6ID0gZGF0YS5pbnRlcnZhbEh6OwogICAgICAgIHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcyA9IE1hdGgubWF4KDEyOCwgTWF0aC5yb3VuZCh0aGlzLl9zYW1wbGVSYXRlIC8gaW50ZXJ2YWxIeikpOwogICAgICB9CiAgICAgIC8vIFJlc2V0IHBhY2luZyBzbyB0aGUgbmV4dCByZXBvcnQgYWxpZ25zIHdpdGggbmV3IGludGVydmFsCiAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBOZXcgYXVkaW8gZGF0YSBoYXMgYXJyaXZlZC4KICAgIGlmICh0eXBlID09PSAiYXVkaW9EYXRhIiAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5fbm9Nb3JlRGF0YVJlY2VpdmVkID0gZmFsc2U7CiAgICAgIC8vIElmIHdlIHdlcmUgaWRsZSwgdGhpcyBuZXcgZGF0YSBraWNrcyBvZmYgdGhlIHBsYXliYWNrLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uSURMRSkgewogICAgICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HOwogICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7IHR5cGU6ICJwbGF5YmFjay1zdGFydGVkIiB9KTsKICAgICAgfQoKICAgICAgLy8gV2Ugb25seSBxdWV1ZSBkYXRhIGlmIHdlIGFyZSBpbiB0aGUgUExBWUlORyBzdGF0ZS4gVGhpcyBwcmV2ZW50cwogICAgICAvLyBkYXRhIGZyb20gYSBwcmV2aW91cywgaW50ZXJydXB0ZWQgc3RyZWFtIGZyb20gbGluZ2VyaW5nLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uUExBWUlORykgewogICAgICAgIC8vIFN0b3JlIGFzIEludDE2QXJyYXkgdmlldyB0byBhdm9pZCBjb25zdHJ1Y3RpbmcgaXQgaW4gcHJvY2VzcygpCiAgICAgICAgdGhpcy5fYnVmZmVyUXVldWUucHVzaChuZXcgSW50MTZBcnJheShkYXRhKSk7CiAgICAgICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsgLy8gUmVzZXQgc2lsZW5jZSBjb3VudGVyIG9uIG5ldyBkYXRhCiAgICAgIH0KICAgIH0KICB9CgogIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICBjb25zdCBvdXRwdXRDaGFubmVsID0gb3V0cHV0c1swXT8uWzBdOwogICAgaWYgKCFvdXRwdXRDaGFubmVsKSB7CiAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIGFsaXZlIGV2ZW4gaWYgb3V0cHV0IGlzIHRlbXBvcmFyaWx5IGRpc2Nvbm5lY3RlZAogICAgfQoKICAgIC8vIElmIHdlIGFyZSBub3QgcGxheWluZywganVzdCBvdXRwdXQgc2lsZW5jZSBhbmQgd2FpdC4KICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HKSB7CiAgICAgIG91dHB1dENoYW5uZWwuZmlsbCgwKTsKICAgICAgcmV0dXJuIHRydWU7IC8vIEFsd2F5cyByZXR1cm4gdHJ1ZSB0byBrZWVwIHRoZSBwcm9jZXNzb3IgYWxpdmUKICAgIH0KCiAgICAvLyBDb3JlIFBMQVlJTkcgTG9naWMKICAgIGNvbnN0IGJsb2NrU2l6ZSA9IG91dHB1dENoYW5uZWwubGVuZ3RoOwogICAgbGV0IHNhbXBsZXNDb3BpZWQgPSAwOwoKICAgIHdoaWxlIChzYW1wbGVzQ29waWVkIDwgYmxvY2tTaXplKSB7CiAgICAgIGlmICghdGhpcy5fY3VycmVudENodW5rIHx8IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCA+PSB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoKSB7CiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHRoaXMuX2N1cnJlbnRDaHVuayA9IHRoaXMuX2J1ZmZlclF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBCdWZmZXIgaXMgZW1wdHkuIENoZWNrIGZvciBlbmQgY29uZGl0aW9ucy4KICAgICAgICAgIGNvbnN0IGlzVGltZWRPdXQgPSB0aGlzLl9zaWxlbmNlRnJhbWVzQ291bnQgPiB0aGlzLl9zaWxlbmNlVGhyZXNob2xkQmxvY2tzOwoKICAgICAgICAgIGlmICh0aGlzLl9ub01vcmVEYXRhUmVjZWl2ZWQgfHwgaXNUaW1lZE91dCkgewogICAgICAgICAgICAvLyBFTkQgT0YgUExBWUJBQ0s6IEVpdGhlciBleHBsaWNpdGx5IHNpZ25hbGVkIG9yIHRpbWVkIG91dC4KICAgICAgICAgICAgaWYgKCF0aGlzLl9oYXNTZW50RW5kZWQpIHsKICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAicGxheWJhY2stZW5kZWQiIH0pOwogICAgICAgICAgICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2VuZCBmaW5hbCBtZXRyaWNzIHNob3dpbmcgY2xlYXJlZCBzdGF0ZQogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHsKICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgICAgdHlwZTogIm1ldHJpY3MiLAogICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU6IFBsYXliYWNrV29ya2xldC5GU00uSURMRSwKICAgICAgICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzOiAwLAogICAgICAgICAgICAgICAgICAgIHF1ZXVlZE1zOiAwLAogICAgICAgICAgICAgICAgICAgIG1heFF1ZXVlZE1zOiBNYXRoLnJvdW5kKCh0aGlzLl9tYXhRdWV1ZVNhbXBsZXMgLyB0aGlzLl9zYW1wbGVSYXRlKSAqIDEwMDApLAogICAgICAgICAgICAgICAgICAgIHVuZGVycnVuQmxvY2tzOiB0aGlzLl91bmRlcnJ1bkJsb2NrcywKICAgICAgICAgICAgICAgICAgICBmcmFtZXNQcm9jZXNzZWQ6IHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZAogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9IGNhdGNoIChfKSB7IH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnJlc2V0KCk7IC8vIFJlc2V0IHRvIElETEUgc3RhdGUgZm9yIHJldXNlCiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEJVRkZFUiBVTkRFUlJVTiAoTEFHKTogUGxheSBzaWxlbmNlIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEuCiAgICAgICAgICAgIHRoaXMuX3NpbGVuY2VGcmFtZXNDb3VudCsrOwogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHRoaXMuX3VuZGVycnVuQmxvY2tzKys7CiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIElmIHdlIGhhdmUgYSBjaHVuayAoY291bGQgYmUgYSBuZXcgb25lIGZyb20gdGhlIGxvZ2ljIGFib3ZlKSwgcHJvY2VzcyBpdC4KICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDaHVuaykgewogICAgICAgIGNvbnN0IHNhbXBsZXNUb0NvcHkgPSBNYXRoLm1pbigKICAgICAgICAgIGJsb2NrU2l6ZSAtIHNhbXBsZXNDb3BpZWQsCiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoIC0gdGhpcy5fY3VycmVudENodW5rT2Zmc2V0CiAgICAgICAgKTsKICAgICAgICAvLyBEaXJlY3RseSB3cml0ZSB0byBvdXRwdXRDaGFubmVsIHRvIGF2b2lkIGV4dHJhIGNvcHkKICAgICAgICBjb25zdCBzcmMgPSB0aGlzLl9jdXJyZW50Q2h1bms7CiAgICAgICAgY29uc3QgYmFzZVNyYyA9IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldDsKICAgICAgICBjb25zdCBiYXNlRHN0ID0gc2FtcGxlc0NvcGllZDsKICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWxlOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtcGxlc1RvQ29weTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXRDaGFubmVsW2Jhc2VEc3QgKyBpXSA9IHNyY1tiYXNlU3JjICsgaV0gKiBzY2FsZTsKICAgICAgICB9CgogICAgICAgIHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCArPSBzYW1wbGVzVG9Db3B5OwogICAgICAgIHNhbXBsZXNDb3BpZWQgKz0gc2FtcGxlc1RvQ29weTsKICAgICAgfQogICAgfQoKICAgIC8vIFplcm8tZmlsbCB0aGUgcmVtYWluZGVyLCBpZiBhbnksIG9uY2UgcGVyIGJsb2NrCiAgICBpZiAoc2FtcGxlc0NvcGllZCA8IGJsb2NrU2l6ZSkgewogICAgICBvdXRwdXRDaGFubmVsLmZpbGwoMCwgc2FtcGxlc0NvcGllZCk7CiAgICB9CgogICAgLy8gVXBkYXRlIG1ldHJpY3MgKG9wdGlvbmFsKQogICAgaWYgKHRoaXMuX21ldHJpY3NFbmFibGVkKSB7CiAgICAgIHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZCArPSBibG9ja1NpemU7CgogICAgICAvLyBUcmFjayBxdWV1ZSBkZXB0aCBpbiBzYW1wbGVzIChhcHByb3hpbWF0ZSkKICAgICAgbGV0IHF1ZXVlZFNhbXBsZXMgPSAwOwogICAgICBpZiAodGhpcy5fY3VycmVudENodW5rKSBxdWV1ZWRTYW1wbGVzICs9IE1hdGgubWF4KDAsIHRoaXMuX2N1cnJlbnRDaHVuay5sZW5ndGggLSB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aDsgaSsrKSBxdWV1ZWRTYW1wbGVzICs9IHRoaXMuX2J1ZmZlclF1ZXVlW2ldLmxlbmd0aDsKICAgICAgaWYgKHF1ZXVlZFNhbXBsZXMgPiB0aGlzLl9tYXhRdWV1ZVNhbXBsZXMpIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IHF1ZXVlZFNhbXBsZXM7CgogICAgICAvLyBQZXJpb2RpY2FsbHkgc2VuZCBtZXRyaWNzIHRvIG1haW4gdGhyZWFkCiAgICAgIGlmICh0aGlzLl9mcmFtZXNQcm9jZXNzZWQgLSB0aGlzLl9sYXN0TWV0cmljc1NlbnRBdEZyYW1lID49IHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcykgewogICAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgIHR5cGU6ICJtZXRyaWNzIiwKICAgICAgICAgICAgZGF0YTogewogICAgICAgICAgICAgIHN0YXRlOiB0aGlzLl9zdGF0ZSwKICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzLAogICAgICAgICAgICAgIHF1ZXVlZE1zOiBNYXRoLnJvdW5kKChxdWV1ZWRTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICBtYXhRdWV1ZWRNczogTWF0aC5yb3VuZCgodGhpcy5fbWF4UXVldWVTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICB1bmRlcnJ1bkJsb2NrczogdGhpcy5fdW5kZXJydW5CbG9ja3MsCiAgICAgICAgICAgICAgZnJhbWVzUHJvY2Vzc2VkOiB0aGlzLl9mcmFtZXNQcm9jZXNzZWQKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSBjYXRjaCAoXykgeyB9CiAgICAgICAgLy8gRG9uJ3QgcmVzZXQgbWF4IHRyYWNrZXIgLSBrZWVwIHNlc3Npb24gcGVhayB1bnRpbCBpZGxlCiAgICAgIH0KICAgIH0KCiAgICAvLyBBTFdBWVMgcmV0dXJuIHRydWUgdG8ga2VlcCB0aGUgcHJvY2Vzc29yIGFsaXZlIGZvciByZXVzZS4KICAgIHJldHVybiB0cnVlOwogIH0KfQoKcmVnaXN0ZXJQcm9jZXNzb3IoInBsYXliYWNrLXdvcmtsZXQiLCBQbGF5YmFja1dvcmtsZXQpOwo=", import.meta.url), Ue = {
|
|
2627
2627
|
en: it,
|
|
2628
2628
|
de: st,
|
|
2629
2629
|
fr: rt,
|
|
2630
|
-
fi:
|
|
2630
|
+
fi: ht,
|
|
2631
2631
|
lt: ct
|
|
2632
2632
|
}, Q = new f.Quaternion(), V = new f.Euler(), ve = new f.Vector3(), Re = new f.Vector3(), We = new f.Box3();
|
|
2633
2633
|
new f.Matrix4();
|
|
@@ -2763,7 +2763,7 @@ class Be {
|
|
|
2763
2763
|
avatarOnlyCamera: null,
|
|
2764
2764
|
statsNode: null,
|
|
2765
2765
|
statsStyle: null
|
|
2766
|
-
}, Object.assign(this.opt, e || {}), this.opt.statsNode && (this.stats = new
|
|
2766
|
+
}, Object.assign(this.opt, e || {}), this.opt.statsNode && (this.stats = new _e(), this.opt.statsStyle && (this.stats.dom.style.cssText = this.opt.statsStyle), this.opt.statsNode.appendChild(this.stats.dom)), this.poseTemplates = {
|
|
2767
2767
|
side: {
|
|
2768
2768
|
standing: !0,
|
|
2769
2769
|
props: {
|
|
@@ -3569,15 +3569,15 @@ class Be {
|
|
|
3569
3569
|
"RightArm.scale": { x: 0, y: 0, z: 0 }
|
|
3570
3570
|
}
|
|
3571
3571
|
}, ["Left", "Right"].forEach((l) => {
|
|
3572
|
-
["Leg", "UpLeg", "Arm", "ForeArm", "Hand"].forEach((
|
|
3573
|
-
this.poseDelta.props[l +
|
|
3574
|
-
}), ["HandThumb", "HandIndex", "HandMiddle", "HandRing", "HandPinky"].forEach((
|
|
3575
|
-
this.poseDelta.props[l +
|
|
3572
|
+
["Leg", "UpLeg", "Arm", "ForeArm", "Hand"].forEach((u) => {
|
|
3573
|
+
this.poseDelta.props[l + u + ".quaternion"] = { x: 0, y: 0, z: 0 };
|
|
3574
|
+
}), ["HandThumb", "HandIndex", "HandMiddle", "HandRing", "HandPinky"].forEach((u) => {
|
|
3575
|
+
this.poseDelta.props[l + u + "1.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[l + u + "2.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[l + u + "3.quaternion"] = { x: 0, y: 0, z: 0 };
|
|
3576
3576
|
});
|
|
3577
3577
|
});
|
|
3578
3578
|
const n = /* @__PURE__ */ new Set();
|
|
3579
3579
|
Object.values(this.poseTemplates).forEach((l) => {
|
|
3580
|
-
Object.keys(this.propsToThreeObjects(l.props)).forEach((
|
|
3580
|
+
Object.keys(this.propsToThreeObjects(l.props)).forEach((u) => n.add(u));
|
|
3581
3581
|
}), Object.keys(this.poseDelta.props).forEach((l) => {
|
|
3582
3582
|
n.add(l);
|
|
3583
3583
|
}), this.posePropNames = [...n], this.poseName = "side", this.poseWeightOnLeft = !0, this.gesture = null, this.poseCurrentTemplate = this.poseTemplates[this.poseName], this.poseStraight = this.propsToThreeObjects(this.poseTemplates.straight.props), this.poseBase = this.poseFactory(this.poseCurrentTemplate), this.poseTarget = this.poseFactory(this.poseCurrentTemplate), this.poseAvatar = null, this.avatarHeight = 1.7, this.animTemplateEyes = {
|
|
@@ -4101,7 +4101,7 @@ class Be {
|
|
|
4101
4101
|
RightHand: "RightForeArm",
|
|
4102
4102
|
RightHandMiddle1: "RightHand"
|
|
4103
4103
|
}, o = [];
|
|
4104
|
-
Object.entries(s).forEach((l,
|
|
4104
|
+
Object.entries(s).forEach((l, u) => {
|
|
4105
4105
|
const r = new f.Bone();
|
|
4106
4106
|
r.name = l[0], l[1] ? this.ikMesh.getObjectByName(l[1]).add(r) : this.ikMesh.add(r), o.push(r);
|
|
4107
4107
|
}), this.ikMesh.bind(new f.Skeleton(o)), this.dynamicbones = new et(), this.isStreaming = !1, this.streamWorkletNode = null, this.streamAudioStartTime = null, this.streamWaitForAudioChunks = !0, this.streamLipsyncLang = null, this.streamLipsyncType = "visemes", this.streamLipsyncQueue = [];
|
|
@@ -4150,9 +4150,9 @@ class Be {
|
|
|
4150
4150
|
let e = 3 * t.length / 4;
|
|
4151
4151
|
t[t.length - 1] === "=" && (e--, t[t.length - 2] === "=" && e--);
|
|
4152
4152
|
const n = new ArrayBuffer(e), i = new Uint8Array(n);
|
|
4153
|
-
let s, o = 0, l,
|
|
4153
|
+
let s, o = 0, l, u, r, h;
|
|
4154
4154
|
for (s = 0; s < t.length; s += 4)
|
|
4155
|
-
l = this.b64Lookup[t.charCodeAt(s)],
|
|
4155
|
+
l = this.b64Lookup[t.charCodeAt(s)], u = this.b64Lookup[t.charCodeAt(s + 1)], r = this.b64Lookup[t.charCodeAt(s + 2)], h = this.b64Lookup[t.charCodeAt(s + 3)], i[o++] = l << 2 | u >> 4, i[o++] = (u & 15) << 4 | r >> 2, i[o++] = (r & 3) << 6 | h & 63;
|
|
4156
4156
|
return n;
|
|
4157
4157
|
}
|
|
4158
4158
|
/**
|
|
@@ -4193,8 +4193,8 @@ class Be {
|
|
|
4193
4193
|
const e = {};
|
|
4194
4194
|
for (let [n, i] of Object.entries(t)) {
|
|
4195
4195
|
const s = n.split(".");
|
|
4196
|
-
let o = Array.isArray(i.x) ? this.gaussianRandom(...i.x) : i.x, l = Array.isArray(i.y) ? this.gaussianRandom(...i.y) : i.y,
|
|
4197
|
-
s[1] === "position" || s[1] === "scale" ? e[n] = new f.Vector3(o, l,
|
|
4196
|
+
let o = Array.isArray(i.x) ? this.gaussianRandom(...i.x) : i.x, l = Array.isArray(i.y) ? this.gaussianRandom(...i.y) : i.y, u = Array.isArray(i.z) ? this.gaussianRandom(...i.z) : i.z;
|
|
4197
|
+
s[1] === "position" || s[1] === "scale" ? e[n] = new f.Vector3(o, l, u) : s[1] === "rotation" ? (n = s[0] + ".quaternion", e[n] = new f.Quaternion().setFromEuler(new f.Euler(o, l, u, "XYZ")).normalize()) : s[1] === "quaternion" && (e[n] = new f.Quaternion(o, l, u, i.w).normalize());
|
|
4198
4198
|
}
|
|
4199
4199
|
return e;
|
|
4200
4200
|
}
|
|
@@ -4222,23 +4222,23 @@ class Be {
|
|
|
4222
4222
|
t.forEach((s) => {
|
|
4223
4223
|
if (!i && s.morphTargetDictionary.hasOwnProperty(e)) return;
|
|
4224
4224
|
const o = s.geometry;
|
|
4225
|
-
let l = null,
|
|
4226
|
-
for (const [r,
|
|
4225
|
+
let l = null, u = null;
|
|
4226
|
+
for (const [r, h] of Object.entries(n))
|
|
4227
4227
|
if (s.morphTargetDictionary.hasOwnProperty(r)) {
|
|
4228
4228
|
const a = s.morphTargetDictionary[r], c = o.morphAttributes.position[a], d = o.morphAttributes.normal?.[a];
|
|
4229
|
-
l || (l = new f.Float32BufferAttribute(c.count * 3, 3), d && (
|
|
4229
|
+
l || (l = new f.Float32BufferAttribute(c.count * 3, 3), d && (u = new f.Float32BufferAttribute(c.count * 3, 3)));
|
|
4230
4230
|
for (let g = 0; g < c.count; g++) {
|
|
4231
|
-
const x = l.getX(g) + c.getX(g) *
|
|
4231
|
+
const x = l.getX(g) + c.getX(g) * h, b = l.getY(g) + c.getY(g) * h, I = l.getZ(g) + c.getZ(g) * h;
|
|
4232
4232
|
l.setXYZ(g, x, b, I);
|
|
4233
4233
|
}
|
|
4234
4234
|
if (d)
|
|
4235
4235
|
for (let g = 0; g < c.count; g++) {
|
|
4236
|
-
const x =
|
|
4237
|
-
|
|
4236
|
+
const x = u.getX(g) + d.getX(g) * h, b = u.getY(g) + d.getY(g) * h, I = u.getZ(g) + d.getZ(g) * h;
|
|
4237
|
+
u.setXYZ(g, x, b, I);
|
|
4238
4238
|
}
|
|
4239
4239
|
}
|
|
4240
4240
|
if (l) {
|
|
4241
|
-
o.morphAttributes.position.push(l),
|
|
4241
|
+
o.morphAttributes.position.push(l), u && o.morphAttributes.normal.push(u);
|
|
4242
4242
|
const r = o.morphAttributes.position.length - 1;
|
|
4243
4243
|
s.morphTargetInfluences[r] = 0, s.morphTargetDictionary[e] = r;
|
|
4244
4244
|
}
|
|
@@ -4268,7 +4268,7 @@ class Be {
|
|
|
4268
4268
|
throw new Error("Blend shapes not found");
|
|
4269
4269
|
const o = new Set(this.mtCustoms);
|
|
4270
4270
|
this.morphs.forEach((r) => {
|
|
4271
|
-
Object.keys(r.morphTargetDictionary).forEach((
|
|
4271
|
+
Object.keys(r.morphTargetDictionary).forEach((h) => o.add(h));
|
|
4272
4272
|
}), this.mtExtras.forEach((r) => {
|
|
4273
4273
|
o.has(r.key) || (this.addMixedMorphTarget(this.morphs, r.key, r.mix), o.add(r.key));
|
|
4274
4274
|
});
|
|
@@ -4295,16 +4295,16 @@ class Be {
|
|
|
4295
4295
|
ms: [],
|
|
4296
4296
|
is: []
|
|
4297
4297
|
}, l[r].value = l[r].baseline, l[r].applied = l[r].baseline;
|
|
4298
|
-
const
|
|
4299
|
-
|
|
4300
|
-
l[r][a] =
|
|
4298
|
+
const h = this.mtAvatar[r];
|
|
4299
|
+
h && ["fixed", "system", "systemd", "realtime", "base", "v", "value", "applied"].forEach((a) => {
|
|
4300
|
+
l[r][a] = h[a];
|
|
4301
4301
|
}), this.morphs.forEach((a) => {
|
|
4302
4302
|
const c = a.morphTargetDictionary[r];
|
|
4303
4303
|
c !== void 0 && (l[r].ms.push(a.morphTargetInfluences), l[r].is.push(c), a.morphTargetInfluences[c] = l[r].applied);
|
|
4304
4304
|
});
|
|
4305
4305
|
}), this.mtAvatar = l, this.poseAvatar = { props: {} }, this.posePropNames.forEach((r) => {
|
|
4306
|
-
const
|
|
4307
|
-
this.poseAvatar.props[r] = a[
|
|
4306
|
+
const h = r.split("."), a = this.armature.getObjectByName(h[0]);
|
|
4307
|
+
this.poseAvatar.props[r] = a[h[1]], this.poseBase.props.hasOwnProperty(r) ? this.poseAvatar.props[r].copy(this.poseBase.props[r]) : this.poseBase.props[r] = this.poseAvatar.props[r].clone(), this.poseDelta.props.hasOwnProperty(r) && !this.poseTarget.props.hasOwnProperty(r) && (this.poseTarget.props[r] = this.poseAvatar.props[r].clone()), this.poseTarget.props[r].t = this.animClock, this.poseTarget.props[r].d = 2e3;
|
|
4308
4308
|
}), this.ikMesh.traverse((r) => {
|
|
4309
4309
|
r.isBone && r.position.copy(this.armature.getObjectByName(r.name).position);
|
|
4310
4310
|
}), this.isAvatarOnly ? this.scene && this.scene.add(this.armature) : (this.scene.add(i.scene), this.scene.add(this.lightAmbient), this.scene.add(this.lightDirect), this.scene.add(this.lightSpot), this.lightSpot.target = this.armature.getObjectByName("Head")), t.hasOwnProperty("modelDynamicBones"))
|
|
@@ -4314,8 +4314,8 @@ class Be {
|
|
|
4314
4314
|
console.error("Dynamic bones setup failed: " + r);
|
|
4315
4315
|
}
|
|
4316
4316
|
this.objectLeftToeBase = this.armature.getObjectByName("LeftToeBase"), this.objectRightToeBase = this.armature.getObjectByName("RightToeBase"), this.objectLeftEye = this.armature.getObjectByName("LeftEye"), this.objectRightEye = this.armature.getObjectByName("RightEye"), this.objectLeftArm = this.armature.getObjectByName("LeftArm"), this.objectRightArm = this.armature.getObjectByName("RightArm"), this.objectHips = this.armature.getObjectByName("Hips"), this.objectHead = this.armature.getObjectByName("Head"), this.objectNeck = this.armature.getObjectByName("Neck");
|
|
4317
|
-
const
|
|
4318
|
-
this.objectLeftEye.getWorldPosition(
|
|
4317
|
+
const u = new f.Vector3();
|
|
4318
|
+
this.objectLeftEye.getWorldPosition(u), this.avatarHeight = u.y + 0.2, this.viewName || this.setView(this.opt.cameraView), this.setMood(this.avatar.avatarMood || this.moodName || this.opt.avatarMood), this.avatar.body === "M" && this.poseTemplates.wide && (this.poseName = "wide", this.setPoseFromTemplate(this.poseTemplates.wide, 0), console.log("Set initial male-appropriate pose: wide")), this.initializeFBXAnimationLoader(), this.bodyMovement && this.bodyMovement !== "idle" && this.applyBodyMovementAnimation(), this.start();
|
|
4319
4319
|
}
|
|
4320
4320
|
/**
|
|
4321
4321
|
* Get view names.
|
|
@@ -4343,22 +4343,22 @@ class Be {
|
|
|
4343
4343
|
return;
|
|
4344
4344
|
}
|
|
4345
4345
|
if (this.viewName = t || this.viewName, e = e || {}, this.isAvatarOnly) return;
|
|
4346
|
-
const n = e.hasOwnProperty("cameraX") ? e.cameraX : this.opt.cameraX, i = e.hasOwnProperty("cameraY") ? e.cameraY : this.opt.cameraY, s = e.hasOwnProperty("cameraDistance") ? e.cameraDistance : this.opt.cameraDistance, o = e.hasOwnProperty("cameraRotateX") ? e.cameraRotateX : this.opt.cameraRotateX, l = e.hasOwnProperty("cameraRotateY") ? e.cameraRotateY : this.opt.cameraRotateY,
|
|
4347
|
-
let r = -n * Math.tan(
|
|
4346
|
+
const n = e.hasOwnProperty("cameraX") ? e.cameraX : this.opt.cameraX, i = e.hasOwnProperty("cameraY") ? e.cameraY : this.opt.cameraY, s = e.hasOwnProperty("cameraDistance") ? e.cameraDistance : this.opt.cameraDistance, o = e.hasOwnProperty("cameraRotateX") ? e.cameraRotateX : this.opt.cameraRotateX, l = e.hasOwnProperty("cameraRotateY") ? e.cameraRotateY : this.opt.cameraRotateY, u = this.camera.fov * (Math.PI / 180);
|
|
4347
|
+
let r = -n * Math.tan(u / 2), h = (1 - i) * Math.tan(u / 2), a = s;
|
|
4348
4348
|
switch (this.viewName) {
|
|
4349
4349
|
case "head":
|
|
4350
|
-
a += 2,
|
|
4350
|
+
a += 2, h = h * a + 4 * this.avatarHeight / 5;
|
|
4351
4351
|
break;
|
|
4352
4352
|
case "upper":
|
|
4353
|
-
a += 4.5,
|
|
4353
|
+
a += 4.5, h = h * a + 2 * this.avatarHeight / 3;
|
|
4354
4354
|
break;
|
|
4355
4355
|
case "mid":
|
|
4356
|
-
a += 8,
|
|
4356
|
+
a += 8, h = h * a + this.avatarHeight / 3;
|
|
4357
4357
|
break;
|
|
4358
4358
|
default:
|
|
4359
|
-
a += 12,
|
|
4359
|
+
a += 12, h = h * a;
|
|
4360
4360
|
}
|
|
4361
|
-
r = r * a, this.controlsEnd = new f.Vector3(r,
|
|
4361
|
+
r = r * a, this.controlsEnd = new f.Vector3(r, h, 0), this.cameraEnd = new f.Vector3(r, h, a).applyEuler(new f.Euler(o, l, 0)), this.cameraClock === null && (this.controls.target.copy(this.controlsEnd), this.camera.position.copy(this.cameraEnd)), this.controlsStart = this.controls.target.clone(), this.cameraStart = this.camera.position.clone(), this.cameraClock = 0;
|
|
4362
4362
|
}
|
|
4363
4363
|
/**
|
|
4364
4364
|
* Change light colors and intensities.
|
|
@@ -4455,17 +4455,17 @@ class Be {
|
|
|
4455
4455
|
"HandMiddle",
|
|
4456
4456
|
"HandRing",
|
|
4457
4457
|
"HandPinky"
|
|
4458
|
-
].forEach((
|
|
4459
|
-
a === 0 ? (this.poseDelta.props[o +
|
|
4458
|
+
].forEach((h, a) => {
|
|
4459
|
+
a === 0 ? (this.poseDelta.props[o + h + "1.quaternion"].x = 0, this.poseDelta.props[o + h + "2.quaternion"].z = (o === "Left" ? -1 : 1) * n.applied, this.poseDelta.props[o + h + "3.quaternion"].z = (o === "Left" ? -1 : 1) * n.applied) : (this.poseDelta.props[o + h + "1.quaternion"].x = n.applied, this.poseDelta.props[o + h + "2.quaternion"].x = 1.5 * n.applied, this.poseDelta.props[o + h + "3.quaternion"].x = 1.5 * n.applied);
|
|
4460
4460
|
});
|
|
4461
4461
|
break;
|
|
4462
4462
|
case "chestInhale":
|
|
4463
|
-
const l = n.applied / 20,
|
|
4464
|
-
this.poseDelta.props["Spine1.scale"] =
|
|
4463
|
+
const l = n.applied / 20, u = { x: l, y: l / 2, z: 3 * l }, r = { x: 1 / (1 + l) - 1, y: 1 / (1 + l / 2) - 1, z: 1 / (1 + 3 * l) - 1 };
|
|
4464
|
+
this.poseDelta.props["Spine1.scale"] = u, this.poseDelta.props["Neck.scale"] = r, this.poseDelta.props["LeftArm.scale"] = r, this.poseDelta.props["RightArm.scale"] = r;
|
|
4465
4465
|
break;
|
|
4466
4466
|
default:
|
|
4467
|
-
for (let
|
|
4468
|
-
n.ms[
|
|
4467
|
+
for (let h = 0, a = n.ms.length; h < a; h++)
|
|
4468
|
+
n.ms[h][n.is[h]] = n.applied;
|
|
4469
4469
|
}
|
|
4470
4470
|
}
|
|
4471
4471
|
}
|
|
@@ -4480,8 +4480,8 @@ class Be {
|
|
|
4480
4480
|
return Object.entries(t).forEach((i, s) => {
|
|
4481
4481
|
const o = i[0].split(".");
|
|
4482
4482
|
if (o[1] === "position" || o[1] === "rotation" || o[1] === "quaternion") {
|
|
4483
|
-
const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0],
|
|
4484
|
-
n += (s ? ", " : "") + "'" + l + "':{", n += "x:" + Math.round(
|
|
4483
|
+
const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0], u = i[1].isQuaternion ? new f.Euler().setFromQuaternion(i[1]) : i[1];
|
|
4484
|
+
n += (s ? ", " : "") + "'" + l + "':{", n += "x:" + Math.round(u.x * e) / e, n += ", y:" + Math.round(u.y * e) / e, n += ", z:" + Math.round(u.z * e) / e, n += "}";
|
|
4485
4485
|
}
|
|
4486
4486
|
}), n += "}", n;
|
|
4487
4487
|
}
|
|
@@ -4551,8 +4551,8 @@ class Be {
|
|
|
4551
4551
|
if (n ? (this.poseCurrentTemplate = this.poseTemplates.oneknee, setTimeout(() => {
|
|
4552
4552
|
this.setPoseFromTemplate(t, e);
|
|
4553
4553
|
}, o)) : this.poseCurrentTemplate = t || this.poseCurrentTemplate, this.poseTarget = this.poseFactory(this.poseCurrentTemplate, o), this.poseWeightOnLeft = !0, (!i && !s || i && s) && (this.poseTarget.props = this.mirrorPose(this.poseTarget.props), this.poseWeightOnLeft = !this.poseWeightOnLeft), this.gesture)
|
|
4554
|
-
for (let [l,
|
|
4555
|
-
this.poseTarget.props.hasOwnProperty(l) && (this.poseTarget.props[l].copy(
|
|
4554
|
+
for (let [l, u] of Object.entries(this.gesture))
|
|
4555
|
+
this.poseTarget.props.hasOwnProperty(l) && (this.poseTarget.props[l].copy(u), this.poseTarget.props[l].t = u.t, this.poseTarget.props[l].d = u.d);
|
|
4556
4556
|
Object.keys(this.poseDelta.props).forEach((l) => {
|
|
4557
4557
|
this.poseTarget.props.hasOwnProperty(l) || (this.poseTarget.props[l] = this.poseBase.props[l].clone(), this.poseTarget.props[l].t = this.animClock, this.poseTarget.props[l].d = o);
|
|
4558
4558
|
});
|
|
@@ -4666,43 +4666,31 @@ class Be {
|
|
|
4666
4666
|
x: this.armature.position.x,
|
|
4667
4667
|
y: this.armature.position.y,
|
|
4668
4668
|
z: this.armature.position.z
|
|
4669
|
-
}, console.log("Original position stored:", this.originalPosition))
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
y: t,
|
|
4675
|
-
// Set to the upward offset directly
|
|
4676
|
-
z: 0
|
|
4677
|
-
// Keep centered horizontally
|
|
4678
|
-
}, this.armature.position.set(
|
|
4679
|
-
this.lockedPosition.x,
|
|
4680
|
-
this.lockedPosition.y,
|
|
4681
|
-
this.lockedPosition.z
|
|
4682
|
-
), console.log("BEFORE: Avatar position was:", this.armature.position.x, this.armature.position.y, this.armature.position.z), console.log("AFTER: Avatar position moved up and locked at:", this.lockedPosition), console.log("Current view:", this.viewName);
|
|
4669
|
+
}, console.log("Original position stored:", this.originalPosition)), this.lockedPosition = {
|
|
4670
|
+
x: this.armature.position.x,
|
|
4671
|
+
y: this.armature.position.y,
|
|
4672
|
+
z: this.armature.position.z
|
|
4673
|
+
}, console.log("Avatar position locked at current position:", this.lockedPosition);
|
|
4683
4674
|
}
|
|
4684
4675
|
/**
|
|
4685
|
-
* Unlock avatar position and
|
|
4676
|
+
* Unlock avatar position and restore original position.
|
|
4686
4677
|
*/
|
|
4687
4678
|
unlockAvatarPosition() {
|
|
4688
|
-
this.armature && (this.armature.position.set(
|
|
4679
|
+
this.armature && this.originalPosition ? (this.armature.position.set(
|
|
4680
|
+
this.originalPosition.x,
|
|
4681
|
+
this.originalPosition.y,
|
|
4682
|
+
this.originalPosition.z
|
|
4683
|
+
), console.log("Avatar position restored to original:", this.originalPosition)) : this.armature && (this.armature.position.set(0, 0, 0), console.log("Avatar position reset to center (0,0,0)")), this.lockedPosition = null, this.originalPosition = null, console.log("Avatar position unlocked");
|
|
4689
4684
|
}
|
|
4690
4685
|
/**
|
|
4691
4686
|
* Ensure avatar stays at locked position.
|
|
4692
4687
|
*/
|
|
4693
4688
|
maintainLockedPosition() {
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
this.lockedPosition.z
|
|
4700
|
-
) : t > n && this.armature.position.set(
|
|
4701
|
-
this.lockedPosition.x,
|
|
4702
|
-
n,
|
|
4703
|
-
this.lockedPosition.z
|
|
4704
|
-
), this.armature.position.x = this.lockedPosition.x, this.armature.position.z = this.lockedPosition.z;
|
|
4705
|
-
}
|
|
4689
|
+
this.lockedPosition && this.armature && this.armature.position.set(
|
|
4690
|
+
this.lockedPosition.x,
|
|
4691
|
+
this.lockedPosition.y,
|
|
4692
|
+
this.lockedPosition.z
|
|
4693
|
+
);
|
|
4706
4694
|
}
|
|
4707
4695
|
/**
|
|
4708
4696
|
* Create body movement animation.
|
|
@@ -4997,11 +4985,11 @@ class Be {
|
|
|
4997
4985
|
else if (l.hasOwnProperty("alt")) {
|
|
4998
4986
|
let r = l.alt[0];
|
|
4999
4987
|
if (l.alt.length > 1) {
|
|
5000
|
-
const
|
|
4988
|
+
const h = Math.random();
|
|
5001
4989
|
let a = 0;
|
|
5002
4990
|
for (let c = 0; c < l.alt.length; c++) {
|
|
5003
4991
|
let d = this.valueFn(l.alt[c].p);
|
|
5004
|
-
if (a += d === void 0 ? (1 - a) / (l.alt.length - 1 - c) : d,
|
|
4992
|
+
if (a += d === void 0 ? (1 - a) / (l.alt.length - 1 - c) : d, h < a) {
|
|
5005
4993
|
r = l.alt[c];
|
|
5006
4994
|
break;
|
|
5007
4995
|
}
|
|
@@ -5011,19 +4999,19 @@ class Be {
|
|
|
5011
4999
|
continue;
|
|
5012
5000
|
} else
|
|
5013
5001
|
break;
|
|
5014
|
-
let
|
|
5015
|
-
if (Array.isArray(
|
|
5016
|
-
l.dt.forEach((r,
|
|
5002
|
+
let u = this.valueFn(l.delay) || 0;
|
|
5003
|
+
if (Array.isArray(u) && (u = this.gaussianRandom(...u)), l.hasOwnProperty("dt"))
|
|
5004
|
+
l.dt.forEach((r, h) => {
|
|
5017
5005
|
let a = this.valueFn(r);
|
|
5018
|
-
Array.isArray(a) && (a = this.gaussianRandom(...a)), o.ts[
|
|
5006
|
+
Array.isArray(a) && (a = this.gaussianRandom(...a)), o.ts[h + 1] = o.ts[h] + a;
|
|
5019
5007
|
});
|
|
5020
5008
|
else {
|
|
5021
|
-
let r = Object.values(l.vs).reduce((
|
|
5009
|
+
let r = Object.values(l.vs).reduce((h, a) => a.length > h ? a.length : h, 0);
|
|
5022
5010
|
o.ts = Array(r + 1).fill(0);
|
|
5023
5011
|
}
|
|
5024
|
-
s ? o.ts = o.ts.map((r) =>
|
|
5025
|
-
for (let [r,
|
|
5026
|
-
const a = this.getBaselineValue(r), c =
|
|
5012
|
+
s ? o.ts = o.ts.map((r) => u + r * n) : o.ts = o.ts.map((r) => this.animClock + u + r * n), l.vs && l.vs.pose && console.log("Pose being selected from vs.pose:", l.vs.pose, "for avatar body:", this.avatar?.body);
|
|
5013
|
+
for (let [r, h] of Object.entries(l.vs)) {
|
|
5014
|
+
const a = this.getBaselineValue(r), c = h.map((d) => (d = this.valueFn(d), d === null ? null : typeof d == "function" ? d : typeof d == "string" || d instanceof String ? r === "pose" && this.avatar && this.avatar.body === "M" && (d === "hip" || d === "side") ? (console.log("Intercepting pose", d, "in animation factory, overriding to wide for male avatar"), "wide") : d.slice() : Array.isArray(d) ? r === "gesture" ? d.slice() : (a === void 0 ? 0 : a) + i * this.gaussianRandom(...d) : typeof d == "boolean" ? d : d instanceof Object && d.constructor === Object ? Object.assign({}, d) : (a === void 0 ? 0 : a) + i * d));
|
|
5027
5015
|
r === "eyesRotateY" ? (o.vs.eyeLookOutLeft = [null, ...c.map((d) => d > 0 ? d : 0)], o.vs.eyeLookInLeft = [null, ...c.map((d) => d > 0 ? 0 : -d)], o.vs.eyeLookOutRight = [null, ...c.map((d) => d > 0 ? 0 : -d)], o.vs.eyeLookInRight = [null, ...c.map((d) => d > 0 ? d : 0)]) : r === "eyesRotateX" ? (o.vs.eyesLookDown = [null, ...c.map((d) => d > 0 ? d : 0)], o.vs.eyesLookUp = [null, ...c.map((d) => d > 0 ? 0 : -d)]) : o.vs[r] = [null, ...c];
|
|
5028
5016
|
}
|
|
5029
5017
|
for (let r of Object.keys(o.vs))
|
|
@@ -5105,8 +5093,8 @@ class Be {
|
|
|
5105
5093
|
if (this.isSpeaking)
|
|
5106
5094
|
for (l = 0, this.audioAnalyzerNode.getByteFrequencyData(this.volumeFrequencyData), n = 2, s = 10; n < s; n++)
|
|
5107
5095
|
this.volumeFrequencyData[n] > l && (l = this.volumeFrequencyData[n]);
|
|
5108
|
-
let
|
|
5109
|
-
const
|
|
5096
|
+
let u = null, r = null;
|
|
5097
|
+
const h = [];
|
|
5110
5098
|
for (n = 0, s = this.animQueue.length; n < s; n++) {
|
|
5111
5099
|
const a = this.animQueue[n];
|
|
5112
5100
|
if (!(!a || !a.ts || !a.ts.length || this.animClock < a.ts[0])) {
|
|
@@ -5133,12 +5121,12 @@ class Be {
|
|
|
5133
5121
|
g.newvalue *= 1 + l / 255 - 0.5;
|
|
5134
5122
|
}
|
|
5135
5123
|
g.needsUpdate = !0;
|
|
5136
|
-
} else c === "eyeContact" && d[i] !== null &&
|
|
5124
|
+
} else c === "eyeContact" && d[i] !== null && u !== !1 ? u = !!d[i] : c === "headMove" && d[i] !== null && r !== !1 ? d[i] === 0 ? r = !1 : (Math.random() < d[i] && (r = !0), d[i] = null) : d[i] !== null && (h.push({ mt: c, val: d[i] }), d[i] = null);
|
|
5137
5125
|
i === o ? (a.hasOwnProperty("mood") && this.setMood(a.mood), a.loop ? (o = this.isSpeaking && (a.template.name === "head" || a.template.name === "eyes") ? 4 : 1, this.animQueue[n] = this.animFactory(a.template, a.loop > 0 ? a.loop - 1 : a.loop, 1, 1 / o)) : (this.animQueue.splice(n--, 1), s--)) : a.ndx = i - 1;
|
|
5138
5126
|
}
|
|
5139
5127
|
}
|
|
5140
|
-
for (let a = 0, c =
|
|
5141
|
-
switch (i =
|
|
5128
|
+
for (let a = 0, c = h.length; a < c; a++)
|
|
5129
|
+
switch (i = h[a].val, h[a].mt) {
|
|
5142
5130
|
case "speak":
|
|
5143
5131
|
this.speakText(i);
|
|
5144
5132
|
break;
|
|
@@ -5184,7 +5172,7 @@ class Be {
|
|
|
5184
5172
|
}, i.x ? new f.Vector3(i.x, i.y, i.z) : null, !0, i.d);
|
|
5185
5173
|
break;
|
|
5186
5174
|
}
|
|
5187
|
-
if ((
|
|
5175
|
+
if ((u || r) && (V.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), V.x = Math.max(-0.9, Math.min(0.9, 2 * V.x - 0.5)), V.y = Math.max(-0.9, Math.min(0.9, -2.5 * V.y)), u ? (Object.assign(this.mtAvatar.eyesLookDown, { system: V.x < 0 ? -V.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: V.x < 0 ? 0 : V.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: V.y < 0 ? -V.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: V.y < 0 ? 0 : V.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: V.y < 0 ? 0 : V.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: V.y < 0 ? -V.y : 0, needsUpdate: !0 }), r && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
|
|
5188
5176
|
name: "headmove",
|
|
5189
5177
|
dt: [[1e3, 2e3], [1e3, 2e3, 1, 2], [1e3, 2e3], [1e3, 2e3, 1, 2]],
|
|
5190
5178
|
vs: {
|
|
@@ -5205,7 +5193,7 @@ class Be {
|
|
|
5205
5193
|
eyeLookOutRight: [null, 0],
|
|
5206
5194
|
eyeContact: [0]
|
|
5207
5195
|
}
|
|
5208
|
-
})))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (n = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], i = this.mtAvatar[n], i.needsUpdate || Object.assign(i, { base: (this.mood.baseline[n] || 0) + (1 + l / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) &&
|
|
5196
|
+
})))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (n = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], i = this.mtAvatar[n], i.needsUpdate || Object.assign(i, { base: (this.mood.baseline[n] || 0) + (1 + l / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) && u ? l > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = l) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), n = this.volumeHeadTarget - this.volumeHeadCurrent, i = Math.abs(n), i > 1e-4 && (o = i * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / i) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(n) * Math.min(i, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (Q.setFromAxisAngle(mt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(Q)), We.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(ve), ve.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(Re), Re.sub(this.armature.position), this.objectHips.position.y -= We.min.y / 2, this.objectHips.position.x -= (ve.x + Re.x) / 4, this.objectHips.position.z -= (ve.z + Re.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
|
|
5209
5197
|
this.stats && this.stats.end();
|
|
5210
5198
|
else {
|
|
5211
5199
|
if (this.cameraClock !== null && this.cameraClock < 1e3) {
|
|
@@ -5272,24 +5260,24 @@ class Be {
|
|
|
5272
5260
|
*/
|
|
5273
5261
|
speakText(t, e = null, n = null, i = null) {
|
|
5274
5262
|
e = e || {};
|
|
5275
|
-
const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, l = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug,
|
|
5276
|
-
let
|
|
5263
|
+
const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, l = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug, u = /[\p{Extended_Pictographic}]/ug, r = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
|
|
5264
|
+
let h = "", a = "", c = 0, d = [], g = [];
|
|
5277
5265
|
const x = Array.from(this.segmenter.segment(t), (b) => b.segment);
|
|
5278
5266
|
for (let b = 0; b < x.length; b++) {
|
|
5279
5267
|
const I = b === x.length - 1, B = x[b].match(l);
|
|
5280
5268
|
let p = x[b].match(s);
|
|
5281
|
-
const M = x[b].match(
|
|
5282
|
-
if (p && !I && !M && x[b + 1].match(s) && (p = !1), n && (
|
|
5269
|
+
const M = x[b].match(u), z = x[b].match(o);
|
|
5270
|
+
if (p && !I && !M && x[b + 1].match(s) && (p = !1), n && (h += x[b]), B && (!i || i.every((y) => b < y[0] || b > y[1])) && (a += x[b]), (z || p || I) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && d.push({
|
|
5283
5271
|
mark: c,
|
|
5284
5272
|
word: a
|
|
5285
|
-
})),
|
|
5273
|
+
})), h.length && (g.push({
|
|
5286
5274
|
mark: c,
|
|
5287
5275
|
template: { name: "subtitles" },
|
|
5288
5276
|
ts: [0],
|
|
5289
5277
|
vs: {
|
|
5290
|
-
subtitles: [
|
|
5278
|
+
subtitles: [h]
|
|
5291
5279
|
}
|
|
5292
|
-
}),
|
|
5280
|
+
}), h = ""), a.length)) {
|
|
5293
5281
|
const y = this.lipsyncWordsToVisemes(a, r);
|
|
5294
5282
|
if (y && y.visemes && y.visemes.length) {
|
|
5295
5283
|
const E = y.times[y.visemes.length - 1] + y.durations[y.visemes.length - 1];
|
|
@@ -5395,22 +5383,22 @@ class Be {
|
|
|
5395
5383
|
if (t.words) {
|
|
5396
5384
|
let o = [];
|
|
5397
5385
|
for (let l = 0; l < t.words.length; l++) {
|
|
5398
|
-
const
|
|
5399
|
-
let
|
|
5400
|
-
if (
|
|
5386
|
+
const u = t.words[l], r = t.wtimes[l];
|
|
5387
|
+
let h = t.wdurations[l];
|
|
5388
|
+
if (u.length && (n && o.push({
|
|
5401
5389
|
template: { name: "subtitles" },
|
|
5402
5390
|
ts: [r],
|
|
5403
5391
|
vs: {
|
|
5404
|
-
subtitles: [" " +
|
|
5392
|
+
subtitles: [" " + u]
|
|
5405
5393
|
}
|
|
5406
5394
|
}), !t.visemes)) {
|
|
5407
|
-
const a = this.lipsyncPreProcessText(
|
|
5395
|
+
const a = this.lipsyncPreProcessText(u, i), c = this.lipsyncWordsToVisemes(a, i);
|
|
5408
5396
|
if (c && c.visemes && c.visemes.length) {
|
|
5409
|
-
const d = c.times[c.visemes.length - 1] + c.durations[c.visemes.length - 1], g = Math.min(
|
|
5410
|
-
let x = 0.6 + this.convertRange(g, [0,
|
|
5411
|
-
if (
|
|
5397
|
+
const d = c.times[c.visemes.length - 1] + c.durations[c.visemes.length - 1], g = Math.min(h, Math.max(0, h - c.visemes.length * 150));
|
|
5398
|
+
let x = 0.6 + this.convertRange(g, [0, h], [0, 0.4]);
|
|
5399
|
+
if (h = Math.min(h, c.visemes.length * 200), d > 0)
|
|
5412
5400
|
for (let b = 0; b < c.visemes.length; b++) {
|
|
5413
|
-
const I = r + c.times[b] / d *
|
|
5401
|
+
const I = r + c.times[b] / d * h, B = c.durations[b] / d * h;
|
|
5414
5402
|
o.push({
|
|
5415
5403
|
template: { name: "viseme" },
|
|
5416
5404
|
ts: [I - Math.min(60, 2 * B / 3), I + Math.min(25, B / 2), I + B + Math.min(60, B / 2)],
|
|
@@ -5424,22 +5412,22 @@ class Be {
|
|
|
5424
5412
|
}
|
|
5425
5413
|
if (t.visemes)
|
|
5426
5414
|
for (let l = 0; l < t.visemes.length; l++) {
|
|
5427
|
-
const
|
|
5415
|
+
const u = t.visemes[l], r = t.vtimes[l], h = t.vdurations[l];
|
|
5428
5416
|
o.push({
|
|
5429
5417
|
template: { name: "viseme" },
|
|
5430
|
-
ts: [r - 2 *
|
|
5418
|
+
ts: [r - 2 * h / 3, r + h / 2, r + h + h / 2],
|
|
5431
5419
|
vs: {
|
|
5432
|
-
["viseme_" +
|
|
5420
|
+
["viseme_" + u]: [null, u === "PP" || u === "FF" ? 0.9 : 0.6, 0]
|
|
5433
5421
|
}
|
|
5434
5422
|
});
|
|
5435
5423
|
}
|
|
5436
5424
|
if (t.markers)
|
|
5437
5425
|
for (let l = 0; l < t.markers.length; l++) {
|
|
5438
|
-
const
|
|
5426
|
+
const u = t.markers[l], r = t.mtimes[l];
|
|
5439
5427
|
o.push({
|
|
5440
5428
|
template: { name: "markers" },
|
|
5441
5429
|
ts: [r],
|
|
5442
|
-
vs: { function: [
|
|
5430
|
+
vs: { function: [u] }
|
|
5443
5431
|
});
|
|
5444
5432
|
}
|
|
5445
5433
|
o.length && (s.anim = o);
|
|
@@ -5459,7 +5447,7 @@ class Be {
|
|
|
5459
5447
|
if (this.isAudioPlaying = !0, this.audioPlaylist.length) {
|
|
5460
5448
|
const e = this.audioPlaylist.shift();
|
|
5461
5449
|
if (this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
|
|
5462
|
-
const s = this.audioCtx.resume(), o = new Promise((l,
|
|
5450
|
+
const s = this.audioCtx.resume(), o = new Promise((l, u) => setTimeout(() => u("p2"), 1e3));
|
|
5463
5451
|
try {
|
|
5464
5452
|
await Promise.race([s, o]);
|
|
5465
5453
|
} catch {
|
|
@@ -5491,11 +5479,11 @@ class Be {
|
|
|
5491
5479
|
*/
|
|
5492
5480
|
async synthesizeWithBrowserTTS(t) {
|
|
5493
5481
|
return new Promise((e, n) => {
|
|
5494
|
-
const i = t.text.map((p) => p.word).join(" "), s = new SpeechSynthesisUtterance(i), o = t.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", l = (t.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate,
|
|
5495
|
-
s.lang = o, s.rate = Math.max(0.1, Math.min(10, l)), s.pitch = Math.max(0, Math.min(2,
|
|
5496
|
-
const
|
|
5497
|
-
if (a &&
|
|
5498
|
-
const p =
|
|
5482
|
+
const i = t.text.map((p) => p.word).join(" "), s = new SpeechSynthesisUtterance(i), o = t.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", l = (t.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate, u = (t.pitch || this.avatar.ttsPitch || this.opt.ttsPitch || 1) + this.mood.speech.deltaPitch, r = (t.volume || this.avatar.ttsVolume || this.opt.ttsVolume || 1) + this.mood.speech.deltaVolume;
|
|
5483
|
+
s.lang = o, s.rate = Math.max(0.1, Math.min(10, l)), s.pitch = Math.max(0, Math.min(2, u)), s.volume = Math.max(0, Math.min(1, r));
|
|
5484
|
+
const h = speechSynthesis.getVoices(), a = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
|
|
5485
|
+
if (a && h.length > 0) {
|
|
5486
|
+
const p = h.find((M) => M.name.includes(a) || M.lang === o);
|
|
5499
5487
|
p && (s.voice = p);
|
|
5500
5488
|
}
|
|
5501
5489
|
const c = i.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (c / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", x = this.lipsyncPreProcessText(i, g), b = this.lipsyncWordsToVisemes(x, g);
|
|
@@ -5556,15 +5544,15 @@ class Be {
|
|
|
5556
5544
|
throw new Error(`ElevenLabs TTS error: ${s.status} ${s.statusText}`);
|
|
5557
5545
|
const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
|
|
5558
5546
|
console.log("Using text-based lip-sync for debugging...");
|
|
5559
|
-
const
|
|
5547
|
+
const u = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
|
|
5560
5548
|
let r;
|
|
5561
5549
|
try {
|
|
5562
5550
|
console.log("Lip-sync modules available:", {
|
|
5563
5551
|
hasLipsync: !!this.lipsync,
|
|
5564
5552
|
lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
|
|
5565
|
-
lipsyncLang:
|
|
5553
|
+
lipsyncLang: u
|
|
5566
5554
|
});
|
|
5567
|
-
const c = this.lipsyncPreProcessText(e,
|
|
5555
|
+
const c = this.lipsyncPreProcessText(e, u), d = this.lipsyncWordsToVisemes(c, u);
|
|
5568
5556
|
if (console.log("Lip-sync data:", {
|
|
5569
5557
|
processedText: c,
|
|
5570
5558
|
lipsyncData: d,
|
|
@@ -5617,12 +5605,12 @@ class Be {
|
|
|
5617
5605
|
visemes: r.visemes ? r.visemes.slice(0, 3) : []
|
|
5618
5606
|
// Show first 3 visemes for debugging
|
|
5619
5607
|
});
|
|
5620
|
-
const
|
|
5608
|
+
const h = [];
|
|
5621
5609
|
if (r.visemes && r.visemes.length > 0) {
|
|
5622
5610
|
console.log("ElevenLabs: Generating lip-sync animation from", r.visemes.length, "visemes");
|
|
5623
5611
|
for (let c = 0; c < r.visemes.length; c++) {
|
|
5624
5612
|
const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, b = d.intensity;
|
|
5625
|
-
|
|
5613
|
+
h.push({
|
|
5626
5614
|
template: { name: "viseme" },
|
|
5627
5615
|
ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
|
|
5628
5616
|
vs: {
|
|
@@ -5630,11 +5618,11 @@ class Be {
|
|
|
5630
5618
|
}
|
|
5631
5619
|
});
|
|
5632
5620
|
}
|
|
5633
|
-
console.log("ElevenLabs: Generated",
|
|
5621
|
+
console.log("ElevenLabs: Generated", h.length, "lip-sync animation frames");
|
|
5634
5622
|
} else
|
|
5635
5623
|
console.warn("ElevenLabs: No visemes available for lip-sync animation");
|
|
5636
|
-
const a = [...t.anim, ...
|
|
5637
|
-
console.log("ElevenLabs: Combined animation frames:", a.length, "(original:", t.anim.length, "+ lipsync:",
|
|
5624
|
+
const a = [...t.anim, ...h];
|
|
5625
|
+
console.log("ElevenLabs: Combined animation frames:", a.length, "(original:", t.anim.length, "+ lipsync:", h.length, ")"), this.audioPlaylist.push({ anim: a, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
|
|
5638
5626
|
}
|
|
5639
5627
|
/**
|
|
5640
5628
|
* Synthesize speech using Deepgram Aura-2 TTS
|
|
@@ -5654,15 +5642,15 @@ class Be {
|
|
|
5654
5642
|
throw new Error(`Deepgram TTS error: ${s.status} ${s.statusText}`);
|
|
5655
5643
|
const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
|
|
5656
5644
|
console.log("Using text-based lip-sync for Deepgram...");
|
|
5657
|
-
const
|
|
5645
|
+
const u = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
|
|
5658
5646
|
let r;
|
|
5659
5647
|
try {
|
|
5660
5648
|
console.log("Lip-sync modules available:", {
|
|
5661
5649
|
hasLipsync: !!this.lipsync,
|
|
5662
5650
|
lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
|
|
5663
|
-
lipsyncLang:
|
|
5651
|
+
lipsyncLang: u
|
|
5664
5652
|
});
|
|
5665
|
-
const c = this.lipsyncPreProcessText(e,
|
|
5653
|
+
const c = this.lipsyncPreProcessText(e, u), d = this.lipsyncWordsToVisemes(c, u);
|
|
5666
5654
|
if (console.log("Lip-sync data:", {
|
|
5667
5655
|
processedText: c,
|
|
5668
5656
|
lipsyncData: d,
|
|
@@ -5715,12 +5703,12 @@ class Be {
|
|
|
5715
5703
|
visemes: r.visemes ? r.visemes.slice(0, 3) : []
|
|
5716
5704
|
// Show first 3 visemes for debugging
|
|
5717
5705
|
});
|
|
5718
|
-
const
|
|
5706
|
+
const h = [];
|
|
5719
5707
|
if (r.visemes && r.visemes.length > 0) {
|
|
5720
5708
|
console.log("Deepgram: Generating lip-sync animation from", r.visemes.length, "visemes");
|
|
5721
5709
|
for (let c = 0; c < r.visemes.length; c++) {
|
|
5722
5710
|
const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, b = d.intensity;
|
|
5723
|
-
|
|
5711
|
+
h.push({
|
|
5724
5712
|
template: { name: "viseme" },
|
|
5725
5713
|
ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
|
|
5726
5714
|
vs: {
|
|
@@ -5728,11 +5716,11 @@ class Be {
|
|
|
5728
5716
|
}
|
|
5729
5717
|
});
|
|
5730
5718
|
}
|
|
5731
|
-
console.log("Deepgram: Generated",
|
|
5719
|
+
console.log("Deepgram: Generated", h.length, "lip-sync animation frames");
|
|
5732
5720
|
} else
|
|
5733
5721
|
console.warn("Deepgram: No visemes available for lip-sync animation");
|
|
5734
|
-
const a = [...t.anim, ...
|
|
5735
|
-
console.log("Deepgram: Combined animation frames:", a.length, "(original:", t.anim.length, "+ lipsync:",
|
|
5722
|
+
const a = [...t.anim, ...h];
|
|
5723
|
+
console.log("Deepgram: Combined animation frames:", a.length, "(original:", t.anim.length, "+ lipsync:", h.length, ")"), this.audioPlaylist.push({ anim: a, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
|
|
5736
5724
|
}
|
|
5737
5725
|
/**
|
|
5738
5726
|
* Synthesize speech using Azure TTS
|
|
@@ -5758,20 +5746,20 @@ class Be {
|
|
|
5758
5746
|
throw new Error(`Azure TTS error: ${s.status} ${s.statusText}`);
|
|
5759
5747
|
const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
|
|
5760
5748
|
console.log("Analyzing audio for precise lip-sync...");
|
|
5761
|
-
const
|
|
5749
|
+
const u = await this.audioAnalyzer.analyzeAudio(l, e);
|
|
5762
5750
|
console.log("Azure TTS Audio Analysis:", {
|
|
5763
5751
|
text: e,
|
|
5764
5752
|
audioDuration: l.duration,
|
|
5765
|
-
visemeCount:
|
|
5766
|
-
wordCount:
|
|
5753
|
+
visemeCount: u.visemes.length,
|
|
5754
|
+
wordCount: u.words.length,
|
|
5767
5755
|
features: {
|
|
5768
|
-
onsets:
|
|
5769
|
-
boundaries:
|
|
5756
|
+
onsets: u.features.onsets.length,
|
|
5757
|
+
boundaries: u.features.phonemeBoundaries.length
|
|
5770
5758
|
}
|
|
5771
5759
|
});
|
|
5772
5760
|
const r = [];
|
|
5773
|
-
for (let a = 0; a <
|
|
5774
|
-
const c =
|
|
5761
|
+
for (let a = 0; a < u.visemes.length; a++) {
|
|
5762
|
+
const c = u.visemes[a], d = c.startTime * 1e3, g = c.duration * 1e3, x = c.intensity;
|
|
5775
5763
|
r.push({
|
|
5776
5764
|
template: { name: "viseme" },
|
|
5777
5765
|
ts: [d - Math.min(60, 2 * g / 3), d + Math.min(25, g / 2), d + g + Math.min(60, g / 2)],
|
|
@@ -5780,8 +5768,8 @@ class Be {
|
|
|
5780
5768
|
}
|
|
5781
5769
|
});
|
|
5782
5770
|
}
|
|
5783
|
-
const
|
|
5784
|
-
this.audioPlaylist.push({ anim:
|
|
5771
|
+
const h = [...t.anim, ...r];
|
|
5772
|
+
this.audioPlaylist.push({ anim: h, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
|
|
5785
5773
|
}
|
|
5786
5774
|
/**
|
|
5787
5775
|
* Synthesize speech using external TTS service (Google Cloud, etc.)
|
|
@@ -5820,24 +5808,24 @@ class Be {
|
|
|
5820
5808
|
if (i.status === 200 && s && s.audioContent) {
|
|
5821
5809
|
const o = this.b64ToArrayBuffer(s.audioContent), l = await this.audioCtx.decodeAudioData(o);
|
|
5822
5810
|
this.speakWithHands();
|
|
5823
|
-
const
|
|
5811
|
+
const u = [0];
|
|
5824
5812
|
let r = 0;
|
|
5825
5813
|
t.text.forEach((c, d) => {
|
|
5826
5814
|
if (d > 0) {
|
|
5827
|
-
let g =
|
|
5828
|
-
s.timepoints[r] && (g = s.timepoints[r].timeSeconds * 1e3, s.timepoints[r].markName === "" + c.mark && r++),
|
|
5815
|
+
let g = u[u.length - 1];
|
|
5816
|
+
s.timepoints[r] && (g = s.timepoints[r].timeSeconds * 1e3, s.timepoints[r].markName === "" + c.mark && r++), u.push(g);
|
|
5829
5817
|
}
|
|
5830
5818
|
});
|
|
5831
|
-
const
|
|
5832
|
-
|
|
5819
|
+
const h = [{ mark: 0, time: 0 }];
|
|
5820
|
+
u.forEach((c, d) => {
|
|
5833
5821
|
if (d > 0) {
|
|
5834
|
-
let g = c -
|
|
5835
|
-
|
|
5822
|
+
let g = c - u[d - 1];
|
|
5823
|
+
h[d - 1].duration = g, h.push({ mark: d, time: c });
|
|
5836
5824
|
}
|
|
5837
5825
|
});
|
|
5838
5826
|
let a = 1e3 * l.duration;
|
|
5839
|
-
a > this.opt.ttsTrimEnd && (a = a - this.opt.ttsTrimEnd),
|
|
5840
|
-
const d =
|
|
5827
|
+
a > this.opt.ttsTrimEnd && (a = a - this.opt.ttsTrimEnd), h[h.length - 1].duration = a - h[h.length - 1].time, t.anim.forEach((c) => {
|
|
5828
|
+
const d = h[c.mark];
|
|
5841
5829
|
if (d)
|
|
5842
5830
|
for (let g = 0; g < c.ts.length; g++)
|
|
5843
5831
|
c.ts[g] = d.time + c.ts[g] * d.duration + this.opt.ttsTrimStart;
|
|
@@ -5920,10 +5908,10 @@ class Be {
|
|
|
5920
5908
|
}
|
|
5921
5909
|
if (!this.workletLoaded)
|
|
5922
5910
|
try {
|
|
5923
|
-
const l = this.audioCtx.audioWorklet.addModule(dt.href),
|
|
5924
|
-
(r,
|
|
5911
|
+
const l = this.audioCtx.audioWorklet.addModule(dt.href), u = new Promise(
|
|
5912
|
+
(r, h) => setTimeout(() => h(new Error("Worklet loading timed out")), 5e3)
|
|
5925
5913
|
);
|
|
5926
|
-
await Promise.race([l,
|
|
5914
|
+
await Promise.race([l, u]), this.workletLoaded = !0;
|
|
5927
5915
|
} catch (l) {
|
|
5928
5916
|
throw console.error("Failed to load audio worklet:", l), new Error("Failed to initialize streaming speech");
|
|
5929
5917
|
}
|
|
@@ -5936,8 +5924,8 @@ class Be {
|
|
|
5936
5924
|
if (l.data.type === "playback-started" && (this.isSpeaking = !0, this.stateName = "speaking", this.streamWaitForAudioChunks && (this.streamAudioStartTime = this.animClock), this._processStreamLipsyncQueue(), this.speakWithHands(), this.onAudioStart))
|
|
5937
5925
|
try {
|
|
5938
5926
|
this.onAudioStart?.();
|
|
5939
|
-
} catch (
|
|
5940
|
-
console.error(
|
|
5927
|
+
} catch (u) {
|
|
5928
|
+
console.error(u);
|
|
5941
5929
|
}
|
|
5942
5930
|
if (l.data.type === "playback-ended" && (this._streamPause(), this.onAudioEnd))
|
|
5943
5931
|
try {
|
|
@@ -5957,9 +5945,9 @@ class Be {
|
|
|
5957
5945
|
} catch {
|
|
5958
5946
|
}
|
|
5959
5947
|
if (this.resetLips(), this.lookAtCamera(500), t.mood && this.setMood(t.mood), this.onSubtitles = i || null, this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
|
|
5960
|
-
const l = this.audioCtx.resume(),
|
|
5948
|
+
const l = this.audioCtx.resume(), u = new Promise((r, h) => setTimeout(() => h("p2"), 1e3));
|
|
5961
5949
|
try {
|
|
5962
|
-
await Promise.race([l,
|
|
5950
|
+
await Promise.race([l, u]);
|
|
5963
5951
|
} catch {
|
|
5964
5952
|
console.warn("Can't play audio. Web Audio API suspended. This is often due to calling some speak method before the first user action, which is typically prevented by the browser.");
|
|
5965
5953
|
return;
|
|
@@ -6056,13 +6044,13 @@ class Be {
|
|
|
6056
6044
|
subtitles: [" " + i]
|
|
6057
6045
|
}
|
|
6058
6046
|
}), this.streamLipsyncType == "words")) {
|
|
6059
|
-
const l = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang,
|
|
6047
|
+
const l = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang, u = this.lipsyncPreProcessText(i, l), r = this.lipsyncWordsToVisemes(u, l);
|
|
6060
6048
|
if (r && r.visemes && r.visemes.length) {
|
|
6061
|
-
const
|
|
6049
|
+
const h = r.times[r.visemes.length - 1] + r.durations[r.visemes.length - 1], a = Math.min(o, Math.max(0, o - r.visemes.length * 150));
|
|
6062
6050
|
let c = 0.6 + this.convertRange(a, [0, o], [0, 0.4]);
|
|
6063
|
-
if (o = Math.min(o, r.visemes.length * 200),
|
|
6051
|
+
if (o = Math.min(o, r.visemes.length * 200), h > 0)
|
|
6064
6052
|
for (let d = 0; d < r.visemes.length; d++) {
|
|
6065
|
-
const g = e + s + r.times[d] /
|
|
6053
|
+
const g = e + s + r.times[d] / h * o, x = r.durations[d] / h * o;
|
|
6066
6054
|
this.animQueue.push({
|
|
6067
6055
|
template: { name: "viseme" },
|
|
6068
6056
|
ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
|
|
@@ -6174,9 +6162,9 @@ class Be {
|
|
|
6174
6162
|
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Re).divideScalar(2), Q.copy(this.armature.quaternion), Q.multiply(this.poseTarget.props["Hips.quaternion"]), Q.multiply(this.poseTarget.props["Spine.quaternion"]), Q.multiply(this.poseTarget.props["Spine1.quaternion"]), Q.multiply(this.poseTarget.props["Spine2.quaternion"]), Q.multiply(this.poseTarget.props["Neck.quaternion"]), Q.multiply(this.poseTarget.props["Head.quaternion"]);
|
|
6175
6163
|
const n = new f.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
|
|
6176
6164
|
V.set(s, i, 0, "YXZ");
|
|
6177
|
-
const l = new f.Quaternion().setFromEuler(V),
|
|
6178
|
-
V.setFromQuaternion(
|
|
6179
|
-
let r = V.x / (40 / 24) + 0.2,
|
|
6165
|
+
const l = new f.Quaternion().setFromEuler(V), u = new f.Quaternion().copy(l).multiply(Q.clone().invert());
|
|
6166
|
+
V.setFromQuaternion(u, "YXZ");
|
|
6167
|
+
let r = V.x / (40 / 24) + 0.2, h = V.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), c = Math.min(0.8, Math.max(-0.8, h)), d = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
|
|
6180
6168
|
if (t) {
|
|
6181
6169
|
let x = this.animQueue.findIndex((I) => I.template.name === "lookat");
|
|
6182
6170
|
x !== -1 && this.animQueue.splice(x, 1);
|
|
@@ -6210,9 +6198,9 @@ class Be {
|
|
|
6210
6198
|
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0);
|
|
6211
6199
|
const s = new f.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new f.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new f.Vector3().addVectors(s, o).divideScalar(2);
|
|
6212
6200
|
l.project(this.camera);
|
|
6213
|
-
let
|
|
6214
|
-
t === null && (t =
|
|
6215
|
-
let
|
|
6201
|
+
let u = (l.x + 1) / 2 * i.width + i.left, r = -(l.y - 1) / 2 * i.height + i.top;
|
|
6202
|
+
t === null && (t = u), e === null && (e = r), Q.copy(this.armature.quaternion), Q.multiply(this.poseTarget.props["Hips.quaternion"]), Q.multiply(this.poseTarget.props["Spine.quaternion"]), Q.multiply(this.poseTarget.props["Spine1.quaternion"]), Q.multiply(this.poseTarget.props["Spine2.quaternion"]), Q.multiply(this.poseTarget.props["Neck.quaternion"]), Q.multiply(this.poseTarget.props["Head.quaternion"]), V.setFromQuaternion(Q);
|
|
6203
|
+
let h = V.x / (40 / 24), a = V.y / (9 / 4), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - u, u), x = Math.max(window.innerHeight - r, r), b = this.convertRange(e, [r - x, r + x], [-0.3, 0.6]) - h + c, I = this.convertRange(t, [u - g, u + g], [-0.8, 0.8]) - a + d;
|
|
6216
6204
|
b = Math.min(0.6, Math.max(-0.3, b)), I = Math.min(0.8, Math.max(-0.8, I));
|
|
6217
6205
|
let B = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
|
|
6218
6206
|
if (n) {
|
|
@@ -6251,10 +6239,10 @@ class Be {
|
|
|
6251
6239
|
s.setFromCamera(i, this.camera);
|
|
6252
6240
|
const o = s.intersectObject(this.armature);
|
|
6253
6241
|
if (o.length > 0) {
|
|
6254
|
-
const l = o[0].point,
|
|
6255
|
-
this.objectLeftArm.getWorldPosition(
|
|
6256
|
-
const
|
|
6257
|
-
|
|
6242
|
+
const l = o[0].point, u = new f.Vector3(), r = new f.Vector3();
|
|
6243
|
+
this.objectLeftArm.getWorldPosition(u), this.objectRightArm.getWorldPosition(r);
|
|
6244
|
+
const h = u.distanceToSquared(l), a = r.distanceToSquared(l);
|
|
6245
|
+
h < a ? (this.ikSolve({
|
|
6258
6246
|
iterations: 20,
|
|
6259
6247
|
root: "LeftShoulder",
|
|
6260
6248
|
effector: "LeftHandMiddle1",
|
|
@@ -6275,8 +6263,8 @@ class Be {
|
|
|
6275
6263
|
}, l, !1, 1e3), this.setValue("handFistRight", 0));
|
|
6276
6264
|
} else
|
|
6277
6265
|
["LeftArm", "LeftForeArm", "LeftHand", "RightArm", "RightForeArm", "RightHand"].forEach((l) => {
|
|
6278
|
-
let
|
|
6279
|
-
this.poseTarget.props[
|
|
6266
|
+
let u = l + ".quaternion";
|
|
6267
|
+
this.poseTarget.props[u].copy(this.getPoseTemplateProp(u)), this.poseTarget.props[u].t = this.animClock, this.poseTarget.props[u].d = 1e3;
|
|
6280
6268
|
});
|
|
6281
6269
|
return o.length > 0;
|
|
6282
6270
|
}
|
|
@@ -6402,37 +6390,184 @@ class Be {
|
|
|
6402
6390
|
(e.isBone || e.type === "Bone") && t.add(e.name);
|
|
6403
6391
|
}), t;
|
|
6404
6392
|
}
|
|
6393
|
+
/**
|
|
6394
|
+
* Map bone names from different naming conventions to avatar bone names
|
|
6395
|
+
* @param {string} fbxBoneName - Bone name from FBX animation
|
|
6396
|
+
* @param {Set<string>} availableBones - Set of available bone names in avatar
|
|
6397
|
+
* @returns {string|null} Mapped bone name or null if no match found
|
|
6398
|
+
*/
|
|
6399
|
+
mapBoneName(t, e) {
|
|
6400
|
+
if (e.has(t))
|
|
6401
|
+
return t;
|
|
6402
|
+
let n = t;
|
|
6403
|
+
if (n.startsWith("CC_Base_") && (n = n.replace("CC_Base_", "")), n = n.replace(/^mixamorig/i, ""), e.has(n))
|
|
6404
|
+
return n;
|
|
6405
|
+
if (n.match(/^Spine\d+$/)) {
|
|
6406
|
+
const a = n.match(/\d+/)?.[0];
|
|
6407
|
+
if (a) {
|
|
6408
|
+
const c = `Spine${parseInt(a)}`;
|
|
6409
|
+
if (e.has(c))
|
|
6410
|
+
return c;
|
|
6411
|
+
if (a === "01" && e.has("Spine1"))
|
|
6412
|
+
return "Spine1";
|
|
6413
|
+
if (parseInt(a) >= 2 && e.has("Spine2"))
|
|
6414
|
+
return "Spine2";
|
|
6415
|
+
}
|
|
6416
|
+
}
|
|
6417
|
+
if (n.includes("Twist"))
|
|
6418
|
+
return null;
|
|
6419
|
+
const i = {
|
|
6420
|
+
// Spine mapping
|
|
6421
|
+
Spine01: "Spine1",
|
|
6422
|
+
Spine02: "Spine2",
|
|
6423
|
+
Spine03: "Spine2",
|
|
6424
|
+
// Left arm mapping
|
|
6425
|
+
L_Upperarm: "LeftArm",
|
|
6426
|
+
L_Forearm: "LeftForeArm",
|
|
6427
|
+
L_Hand: "LeftHand",
|
|
6428
|
+
L_Shoulder: "LeftShoulder",
|
|
6429
|
+
L_Index1: "LeftHandIndex1",
|
|
6430
|
+
L_Index2: "LeftHandIndex2",
|
|
6431
|
+
L_Index3: "LeftHandIndex3",
|
|
6432
|
+
L_Middle1: "LeftHandMiddle1",
|
|
6433
|
+
L_Middle2: "LeftHandMiddle2",
|
|
6434
|
+
L_Middle3: "LeftHandMiddle3",
|
|
6435
|
+
L_Ring1: "LeftHandRing1",
|
|
6436
|
+
L_Ring2: "LeftHandRing2",
|
|
6437
|
+
L_Ring3: "LeftHandRing3",
|
|
6438
|
+
L_Pinky1: "LeftHandPinky1",
|
|
6439
|
+
L_Pinky2: "LeftHandPinky2",
|
|
6440
|
+
L_Pinky3: "LeftHandPinky3",
|
|
6441
|
+
L_Thumb1: "LeftHandThumb1",
|
|
6442
|
+
L_Thumb2: "LeftHandThumb2",
|
|
6443
|
+
L_Thumb3: "LeftHandThumb3",
|
|
6444
|
+
// Right arm mapping
|
|
6445
|
+
R_Upperarm: "RightArm",
|
|
6446
|
+
R_Forearm: "RightForeArm",
|
|
6447
|
+
R_Hand: "RightHand",
|
|
6448
|
+
R_Shoulder: "RightShoulder",
|
|
6449
|
+
R_Index1: "RightHandIndex1",
|
|
6450
|
+
R_Index2: "RightHandIndex2",
|
|
6451
|
+
R_Index3: "RightHandIndex3",
|
|
6452
|
+
R_Middle1: "RightHandMiddle1",
|
|
6453
|
+
R_Middle2: "RightHandMiddle2",
|
|
6454
|
+
R_Middle3: "RightHandMiddle3",
|
|
6455
|
+
R_Ring1: "RightHandRing1",
|
|
6456
|
+
R_Ring2: "RightHandRing2",
|
|
6457
|
+
R_Ring3: "RightHandRing3",
|
|
6458
|
+
R_Pinky1: "RightHandPinky1",
|
|
6459
|
+
R_Pinky2: "RightHandPinky2",
|
|
6460
|
+
R_Pinky3: "RightHandPinky3",
|
|
6461
|
+
R_Thumb1: "RightHandThumb1",
|
|
6462
|
+
R_Thumb2: "RightHandThumb2",
|
|
6463
|
+
R_Thumb3: "RightHandThumb3",
|
|
6464
|
+
// Leg mapping
|
|
6465
|
+
L_Thigh: "LeftUpLeg",
|
|
6466
|
+
L_Calf: "LeftLeg",
|
|
6467
|
+
L_Foot: "LeftFoot",
|
|
6468
|
+
R_Thigh: "RightUpLeg",
|
|
6469
|
+
R_Calf: "RightLeg",
|
|
6470
|
+
R_Foot: "RightFoot"
|
|
6471
|
+
};
|
|
6472
|
+
if (i[n]) {
|
|
6473
|
+
const a = i[n];
|
|
6474
|
+
if (e.has(a))
|
|
6475
|
+
return a;
|
|
6476
|
+
}
|
|
6477
|
+
const s = n.toLowerCase(), o = s.match(/^[rl]_index(\d+)$/);
|
|
6478
|
+
if (o) {
|
|
6479
|
+
const a = o[1], d = `${s.startsWith("r") ? "Right" : "Left"}HandIndex${a}`;
|
|
6480
|
+
if (e.has(d))
|
|
6481
|
+
return d;
|
|
6482
|
+
}
|
|
6483
|
+
const l = s.match(/^[rl]_pinky(\d+)$/);
|
|
6484
|
+
if (l) {
|
|
6485
|
+
const a = l[1], d = `${s.startsWith("r") ? "Right" : "Left"}HandPinky${a}`;
|
|
6486
|
+
if (e.has(d))
|
|
6487
|
+
return d;
|
|
6488
|
+
}
|
|
6489
|
+
const u = s.match(/^[rl]_ring(\d+)$/);
|
|
6490
|
+
if (u) {
|
|
6491
|
+
const a = u[1], d = `${s.startsWith("r") ? "Right" : "Left"}HandRing${a}`;
|
|
6492
|
+
if (e.has(d))
|
|
6493
|
+
return d;
|
|
6494
|
+
}
|
|
6495
|
+
const r = s.match(/^[rl]_middle(\d+)$/);
|
|
6496
|
+
if (r) {
|
|
6497
|
+
const a = r[1], d = `${s.startsWith("r") ? "Right" : "Left"}HandMiddle${a}`;
|
|
6498
|
+
if (e.has(d))
|
|
6499
|
+
return d;
|
|
6500
|
+
}
|
|
6501
|
+
const h = s.match(/^[rl]_thumb(\d+)$/);
|
|
6502
|
+
if (h) {
|
|
6503
|
+
const a = h[1], d = `${s.startsWith("r") ? "Right" : "Left"}HandThumb${a}`;
|
|
6504
|
+
if (e.has(d))
|
|
6505
|
+
return d;
|
|
6506
|
+
}
|
|
6507
|
+
if (s.match(/^[rl]_upperarm/)) {
|
|
6508
|
+
const c = `${s.startsWith("r") ? "Right" : "Left"}Arm`;
|
|
6509
|
+
if (e.has(c))
|
|
6510
|
+
return c;
|
|
6511
|
+
}
|
|
6512
|
+
if (s.match(/^[rl]_forearm/)) {
|
|
6513
|
+
const c = `${s.startsWith("r") ? "Right" : "Left"}ForeArm`;
|
|
6514
|
+
if (e.has(c))
|
|
6515
|
+
return c;
|
|
6516
|
+
}
|
|
6517
|
+
if (s.match(/^[rl]_hand$/)) {
|
|
6518
|
+
const c = `${s.startsWith("r") ? "Right" : "Left"}Hand`;
|
|
6519
|
+
if (e.has(c))
|
|
6520
|
+
return c;
|
|
6521
|
+
}
|
|
6522
|
+
for (const a of e)
|
|
6523
|
+
if (a.toLowerCase() === s)
|
|
6524
|
+
return a;
|
|
6525
|
+
return null;
|
|
6526
|
+
}
|
|
6405
6527
|
/**
|
|
6406
6528
|
* Filter animation tracks to only include bones that exist in the avatar
|
|
6529
|
+
* Maps bone names from different naming conventions to avatar bone names
|
|
6407
6530
|
* @param {THREE.AnimationClip} clip - Animation clip to filter
|
|
6408
6531
|
* @param {Set<string>} availableBones - Set of available bone names
|
|
6409
|
-
* @returns {THREE.AnimationClip} Filtered animation clip
|
|
6532
|
+
* @returns {THREE.AnimationClip} Filtered animation clip with mapped bone names
|
|
6410
6533
|
*/
|
|
6411
6534
|
filterAnimationTracks(t, e) {
|
|
6412
|
-
const n = [], i = /* @__PURE__ */ new Set();
|
|
6413
|
-
return t.tracks.forEach((
|
|
6414
|
-
const l =
|
|
6415
|
-
|
|
6416
|
-
|
|
6535
|
+
const n = [], i = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Map();
|
|
6536
|
+
return t.tracks.forEach((o) => {
|
|
6537
|
+
const l = o.name.split("."), u = l[0], r = l[1], h = this.mapBoneName(u, e);
|
|
6538
|
+
if (h) {
|
|
6539
|
+
const a = `${h}.${r}`, c = o.clone();
|
|
6540
|
+
c.name = a, n.push(c), u !== h && s.set(u, h);
|
|
6541
|
+
} else
|
|
6542
|
+
i.add(u);
|
|
6543
|
+
}), s.size > 0 && console.info(
|
|
6544
|
+
`FBX animation "${t.name}": Mapped ${s.size} bone(s) to avatar skeleton:`,
|
|
6545
|
+
Array.from(s.entries()).slice(0, 5).map(([o, l]) => `${o} → ${l}`).join(", "),
|
|
6546
|
+
s.size > 5 ? "..." : ""
|
|
6547
|
+
), i.size > 0 && console.warn(
|
|
6548
|
+
`FBX animation "${t.name}" contains tracks for ${i.size} bone(s) that couldn't be mapped:`,
|
|
6549
|
+
Array.from(i).slice(0, 10).join(", "),
|
|
6550
|
+
i.size > 10 ? "..." : ""
|
|
6551
|
+
), n.length > 0 ? console.info(`Filtered ${t.tracks.length} tracks down to ${n.length} valid tracks (${s.size} mapped)`) : console.error(`No valid tracks found for animation "${t.name}". All bones are missing or couldn't be mapped.`), n.length === 0 ? null : new f.AnimationClip(t.name, t.duration, n);
|
|
6417
6552
|
}
|
|
6418
6553
|
async playAnimation(t, e = null, n = 10, i = 0, s = 0.01, o = !1) {
|
|
6419
6554
|
if (!this.armature) return;
|
|
6420
6555
|
this.positionWasLocked = !o, o ? console.log("Position locking disabled for FBX animation:", t) : (this.lockAvatarPosition(), console.log("Position locked immediately before FBX animation:", t));
|
|
6421
|
-
let l = this.animClips.find((
|
|
6556
|
+
let l = this.animClips.find((u) => u.url === t + "-" + i);
|
|
6422
6557
|
if (l) {
|
|
6423
|
-
let
|
|
6424
|
-
|
|
6558
|
+
let u = this.animQueue.find((a) => a.template.name === "pose");
|
|
6559
|
+
u && (u.ts[0] = 1 / 0), Object.entries(l.pose.props).forEach((a) => {
|
|
6425
6560
|
this.poseBase.props[a[0]] = a[1].clone(), this.poseTarget.props[a[0]] = a[1].clone(), this.poseTarget.props[a[0]].t = 0, this.poseTarget.props[a[0]].d = 1e3;
|
|
6426
6561
|
}), this.mixer ? console.log("Using existing mixer for FBX animation, preserving morph targets") : (this.mixer = new f.AnimationMixer(this.armature), console.log("Created new mixer for FBX animation")), this.mixer.addEventListener("finished", this.stopAnimation.bind(this), { once: !0 });
|
|
6427
|
-
const r = Math.ceil(n / l.clip.duration),
|
|
6428
|
-
|
|
6562
|
+
const r = Math.ceil(n / l.clip.duration), h = this.mixer.clipAction(l.clip);
|
|
6563
|
+
h.setLoop(f.LoopRepeat, r), h.clampWhenFinished = !0, this.currentFBXAction = h;
|
|
6429
6564
|
try {
|
|
6430
|
-
|
|
6565
|
+
h.fadeIn(0.5).play(), console.log("FBX animation started successfully:", t);
|
|
6431
6566
|
} catch (a) {
|
|
6432
6567
|
console.warn("FBX animation failed to start:", a), this.stopAnimation();
|
|
6433
6568
|
return;
|
|
6434
6569
|
}
|
|
6435
|
-
if (
|
|
6570
|
+
if (h.getClip().tracks.length === 0) {
|
|
6436
6571
|
console.warn("FBX animation has no valid tracks, stopping"), this.stopAnimation();
|
|
6437
6572
|
return;
|
|
6438
6573
|
}
|
|
@@ -6451,10 +6586,10 @@ class Be {
|
|
|
6451
6586
|
} catch (c) {
|
|
6452
6587
|
console.warn(`Could not verify file existence for ${t}, attempting to load anyway:`, c);
|
|
6453
6588
|
}
|
|
6454
|
-
const
|
|
6589
|
+
const h = new De();
|
|
6455
6590
|
let a;
|
|
6456
6591
|
try {
|
|
6457
|
-
a = await
|
|
6592
|
+
a = await h.loadAsync(t, e);
|
|
6458
6593
|
} catch (c) {
|
|
6459
6594
|
console.error(`Failed to load FBX animation from ${t}:`, c), console.error("Error details:", {
|
|
6460
6595
|
message: c.message,
|
|
@@ -6526,25 +6661,25 @@ class Be {
|
|
|
6526
6661
|
if (!this.armature) return;
|
|
6527
6662
|
let o = this.poseTemplates[t];
|
|
6528
6663
|
if (!o) {
|
|
6529
|
-
const l = this.animPoses.find((
|
|
6664
|
+
const l = this.animPoses.find((u) => u.url === t + "-" + i);
|
|
6530
6665
|
l && (o = l.pose);
|
|
6531
6666
|
}
|
|
6532
6667
|
if (o) {
|
|
6533
6668
|
this.poseName = t, this.mixer = null;
|
|
6534
|
-
let l = this.animQueue.find((
|
|
6669
|
+
let l = this.animQueue.find((u) => u.template.name === "pose");
|
|
6535
6670
|
l && (l.ts[0] = this.animClock + n * 1e3 + 2e3), this.setPoseFromTemplate(o);
|
|
6536
6671
|
} else {
|
|
6537
|
-
let
|
|
6538
|
-
if (
|
|
6539
|
-
let r =
|
|
6540
|
-
const
|
|
6672
|
+
let u = await new De().loadAsync(t, e);
|
|
6673
|
+
if (u && u.animations && u.animations[i]) {
|
|
6674
|
+
let r = u.animations[i];
|
|
6675
|
+
const h = {};
|
|
6541
6676
|
r.tracks.forEach((c) => {
|
|
6542
6677
|
c.name = c.name.replaceAll("mixamorig", "");
|
|
6543
6678
|
const d = c.name.split(".");
|
|
6544
|
-
d[1] === "position" ?
|
|
6679
|
+
d[1] === "position" ? h[c.name] = new f.Vector3(c.values[0] * s, c.values[1] * s, c.values[2] * s) : d[1] === "quaternion" ? h[c.name] = new f.Quaternion(c.values[0], c.values[1], c.values[2], c.values[3]) : d[1] === "rotation" && (h[d[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(c.values[0], c.values[1], c.values[2], "XYZ")).normalize());
|
|
6545
6680
|
});
|
|
6546
|
-
const a = { props:
|
|
6547
|
-
|
|
6681
|
+
const a = { props: h };
|
|
6682
|
+
h["Hips.position"] && (h["Hips.position"].y < 0.5 ? a.lying = !0 : a.standing = !0), this.animPoses.push({
|
|
6548
6683
|
url: t + "-" + i,
|
|
6549
6684
|
pose: a
|
|
6550
6685
|
}), this.playPose(t, e, n, i, s);
|
|
@@ -6573,10 +6708,10 @@ class Be {
|
|
|
6573
6708
|
let s = this.gestureTemplates[t];
|
|
6574
6709
|
if (s) {
|
|
6575
6710
|
this.gestureTimeout && (clearTimeout(this.gestureTimeout), this.gestureTimeout = null);
|
|
6576
|
-
let l = this.animQueue.findIndex((
|
|
6577
|
-
l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((
|
|
6578
|
-
for (let [
|
|
6579
|
-
r.t = this.animClock, r.d = i, this.poseTarget.props.hasOwnProperty(
|
|
6711
|
+
let l = this.animQueue.findIndex((u) => u.template.name === "talkinghands");
|
|
6712
|
+
l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((u) => 0)), this.gesture = this.propsToThreeObjects(s), n && (this.gesture = this.mirrorPose(this.gesture)), t === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new f.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new f.Quaternion(0, 1, 0, 0), -0.25));
|
|
6713
|
+
for (let [u, r] of Object.entries(this.gesture))
|
|
6714
|
+
r.t = this.animClock, r.d = i, this.poseTarget.props.hasOwnProperty(u) && (this.poseTarget.props[u].copy(r), this.poseTarget.props[u].t = this.animClock, this.poseTarget.props[u].d = i);
|
|
6580
6715
|
e && Number.isFinite(e) && (this.gestureTimeout = setTimeout(this.stopGesture.bind(this, i), 1e3 * e));
|
|
6581
6716
|
}
|
|
6582
6717
|
let o = this.animEmojis[t];
|
|
@@ -6584,15 +6719,15 @@ class Be {
|
|
|
6584
6719
|
this.lookAtCamera(500);
|
|
6585
6720
|
const l = this.animFactory(o);
|
|
6586
6721
|
if (l.gesture = !0, e && Number.isFinite(e)) {
|
|
6587
|
-
const
|
|
6588
|
-
if (e * 1e3 -
|
|
6722
|
+
const u = l.ts[0], h = l.ts[l.ts.length - 1] - u;
|
|
6723
|
+
if (e * 1e3 - h > 0) {
|
|
6589
6724
|
const c = [];
|
|
6590
6725
|
for (let x = 1; x < l.ts.length; x++) c.push(l.ts[x] - l.ts[x - 1]);
|
|
6591
|
-
const d = o.template?.rescale || c.map((x) => x /
|
|
6592
|
-
l.ts = l.ts.map((x, b, I) => b === 0 ?
|
|
6726
|
+
const d = o.template?.rescale || c.map((x) => x / h), g = e * 1e3 - h;
|
|
6727
|
+
l.ts = l.ts.map((x, b, I) => b === 0 ? u : I[b - 1] + c[b - 1] + d[b - 1] * g);
|
|
6593
6728
|
} else {
|
|
6594
|
-
const c = e * 1e3 /
|
|
6595
|
-
l.ts = l.ts.map((d) =>
|
|
6729
|
+
const c = e * 1e3 / h;
|
|
6730
|
+
l.ts = l.ts.map((d) => u + c * (d - u));
|
|
6596
6731
|
}
|
|
6597
6732
|
}
|
|
6598
6733
|
this.animQueue.push(l);
|
|
@@ -6622,7 +6757,7 @@ class Be {
|
|
|
6622
6757
|
* @param {numeric} [d=null] If set, apply in d milliseconds
|
|
6623
6758
|
*/
|
|
6624
6759
|
ikSolve(t, e = null, n = !1, i = null) {
|
|
6625
|
-
const s = new f.Vector3(), o = new f.Vector3(), l = new f.Vector3(),
|
|
6760
|
+
const s = new f.Vector3(), o = new f.Vector3(), l = new f.Vector3(), u = new f.Vector3(), r = new f.Quaternion(), h = new f.Vector3(), a = new f.Vector3(), c = new f.Vector3(), d = this.ikMesh.getObjectByName(t.root);
|
|
6626
6761
|
d.position.setFromMatrixPosition(this.armature.getObjectByName(t.root).matrixWorld), d.quaternion.setFromRotationMatrix(this.armature.getObjectByName(t.root).matrixWorld), e && n && e.applyQuaternion(this.armature.quaternion).add(d.position);
|
|
6627
6762
|
const g = this.ikMesh.getObjectByName(t.effector), x = t.links;
|
|
6628
6763
|
x.forEach((I) => {
|
|
@@ -6634,7 +6769,7 @@ class Be {
|
|
|
6634
6769
|
let B = !1;
|
|
6635
6770
|
for (let p = 0, M = x.length; p < M; p++) {
|
|
6636
6771
|
const z = x[p].bone;
|
|
6637
|
-
z.matrixWorld.decompose(
|
|
6772
|
+
z.matrixWorld.decompose(u, r, h), r.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, u), l.applyQuaternion(r), l.normalize(), s.subVectors(e, u), s.applyQuaternion(r), s.normalize();
|
|
6638
6773
|
let y = s.dot(l);
|
|
6639
6774
|
y > 1 ? y = 1 : y < -1 && (y = -1), y = Math.acos(y), !(y < 1e-5) && (x[p].minAngle !== void 0 && y < x[p].minAngle && (y = x[p].minAngle), x[p].maxAngle !== void 0 && y > x[p].maxAngle && (y = x[p].maxAngle), a.crossVectors(l, s), a.normalize(), Q.setFromAxisAngle(a, y), z.quaternion.multiply(Q), z.rotation.setFromVector3(c.setFromEuler(z.rotation).clamp(new f.Vector3(
|
|
6640
6775
|
x[p].minx !== void 0 ? x[p].minx : -1 / 0,
|
|
@@ -6708,7 +6843,7 @@ function Fe() {
|
|
|
6708
6843
|
voices: Ie.voices
|
|
6709
6844
|
};
|
|
6710
6845
|
}
|
|
6711
|
-
function
|
|
6846
|
+
function kt() {
|
|
6712
6847
|
const G = Fe(), t = [];
|
|
6713
6848
|
return Object.entries(G.voices).forEach(([e, n]) => {
|
|
6714
6849
|
t.push({
|
|
@@ -6726,9 +6861,9 @@ const Ve = Me(({
|
|
|
6726
6861
|
ttsVoice: s = null,
|
|
6727
6862
|
ttsApiKey: o = null,
|
|
6728
6863
|
bodyMovement: l = "idle",
|
|
6729
|
-
movementIntensity:
|
|
6864
|
+
movementIntensity: u = 0.5,
|
|
6730
6865
|
showFullAvatar: r = !0,
|
|
6731
|
-
cameraView:
|
|
6866
|
+
cameraView: h = "upper",
|
|
6732
6867
|
onReady: a = () => {
|
|
6733
6868
|
},
|
|
6734
6869
|
onLoading: c = () => {
|
|
@@ -6739,32 +6874,32 @@ const Ve = Me(({
|
|
|
6739
6874
|
style: x = {},
|
|
6740
6875
|
animations: b = {}
|
|
6741
6876
|
}, I) => {
|
|
6742
|
-
const B =
|
|
6877
|
+
const B = D(null), p = D(null), M = D(r), z = D(null), y = D(null), E = D(!1), P = D({ remainingText: null, originalText: null, options: null }), W = D([]), oe = D(0), [S, Z] = ce(!0), [_, X] = ce(null), [$, se] = ce(!1), [ae, pe] = ce(!1);
|
|
6743
6878
|
de(() => {
|
|
6744
6879
|
E.current = ae;
|
|
6745
6880
|
}, [ae]), de(() => {
|
|
6746
6881
|
M.current = r;
|
|
6747
6882
|
}, [r]);
|
|
6748
6883
|
const ee = Fe(), le = i || ee.service;
|
|
6749
|
-
let
|
|
6750
|
-
le === "browser" ?
|
|
6884
|
+
let O;
|
|
6885
|
+
le === "browser" ? O = {
|
|
6751
6886
|
service: "browser",
|
|
6752
6887
|
endpoint: "",
|
|
6753
6888
|
apiKey: null,
|
|
6754
6889
|
defaultVoice: "Google US English"
|
|
6755
|
-
} : le === "elevenlabs" ?
|
|
6890
|
+
} : le === "elevenlabs" ? O = {
|
|
6756
6891
|
service: "elevenlabs",
|
|
6757
6892
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
6758
6893
|
apiKey: o || ee.apiKey,
|
|
6759
6894
|
defaultVoice: s || ee.defaultVoice || Ie.defaultVoice,
|
|
6760
6895
|
voices: ee.voices || Ie.voices
|
|
6761
|
-
} : le === "deepgram" ?
|
|
6896
|
+
} : le === "deepgram" ? O = {
|
|
6762
6897
|
service: "deepgram",
|
|
6763
6898
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
6764
6899
|
apiKey: o || ee.apiKey,
|
|
6765
6900
|
defaultVoice: s || ee.defaultVoice || Te.defaultVoice,
|
|
6766
6901
|
voices: ee.voices || Te.voices
|
|
6767
|
-
} :
|
|
6902
|
+
} : O = {
|
|
6768
6903
|
...ee,
|
|
6769
6904
|
// Override API key if provided via props
|
|
6770
6905
|
apiKey: o !== null ? o : ee.apiKey
|
|
@@ -6774,18 +6909,18 @@ const Ve = Me(({
|
|
|
6774
6909
|
body: t,
|
|
6775
6910
|
avatarMood: e,
|
|
6776
6911
|
ttsLang: le === "browser" ? "en-US" : n,
|
|
6777
|
-
ttsVoice: s ||
|
|
6912
|
+
ttsVoice: s || O.defaultVoice,
|
|
6778
6913
|
lipsyncLang: "en",
|
|
6779
6914
|
showFullAvatar: r,
|
|
6780
6915
|
bodyMovement: l,
|
|
6781
|
-
movementIntensity:
|
|
6916
|
+
movementIntensity: u
|
|
6782
6917
|
}, R = {
|
|
6783
|
-
ttsEndpoint:
|
|
6784
|
-
ttsApikey:
|
|
6918
|
+
ttsEndpoint: O.endpoint,
|
|
6919
|
+
ttsApikey: O.apiKey,
|
|
6785
6920
|
ttsService: le,
|
|
6786
6921
|
lipsyncModules: ["en"],
|
|
6787
|
-
cameraView:
|
|
6788
|
-
},
|
|
6922
|
+
cameraView: h
|
|
6923
|
+
}, k = T(async () => {
|
|
6789
6924
|
if (!(!B.current || p.current))
|
|
6790
6925
|
try {
|
|
6791
6926
|
if (Z(!0), X(null), p.current = new Be(B.current, R), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), b && Object.keys(b).length > 0 && (p.current.customAnimations = b), await p.current.showAvatar(v, (N) => {
|
|
@@ -6814,10 +6949,10 @@ const Ve = Me(({
|
|
|
6814
6949
|
} catch (L) {
|
|
6815
6950
|
console.error("Error initializing TalkingHead:", L), X(L.message || "Failed to initialize avatar"), Z(!1), d(L);
|
|
6816
6951
|
}
|
|
6817
|
-
}, [G, t, e, n, i, s, o, r, l,
|
|
6818
|
-
de(() => (
|
|
6952
|
+
}, [G, t, e, n, i, s, o, r, l, u, h]);
|
|
6953
|
+
de(() => (k(), () => {
|
|
6819
6954
|
p.current && (p.current.stop(), p.current.dispose(), p.current = null);
|
|
6820
|
-
}), [
|
|
6955
|
+
}), [k]), de(() => {
|
|
6821
6956
|
if (!B.current || !p.current) return;
|
|
6822
6957
|
const L = new ResizeObserver((N) => {
|
|
6823
6958
|
for (const J of N)
|
|
@@ -6850,14 +6985,14 @@ const Ve = Me(({
|
|
|
6850
6985
|
};
|
|
6851
6986
|
if (F.onSpeechEnd && p.current) {
|
|
6852
6987
|
const Y = p.current;
|
|
6853
|
-
let
|
|
6988
|
+
let ue = null, Se = 0;
|
|
6854
6989
|
const Ae = 1200;
|
|
6855
6990
|
let be = !1;
|
|
6856
|
-
|
|
6857
|
-
if (
|
|
6991
|
+
ue = setInterval(() => {
|
|
6992
|
+
if (Se++, E.current)
|
|
6858
6993
|
return;
|
|
6859
|
-
if (
|
|
6860
|
-
if (
|
|
6994
|
+
if (Se > Ae) {
|
|
6995
|
+
if (ue && (clearInterval(ue), ue = null, y.current = null), !be && !E.current) {
|
|
6861
6996
|
be = !0;
|
|
6862
6997
|
try {
|
|
6863
6998
|
F.onSpeechEnd();
|
|
@@ -6867,10 +7002,10 @@ const Ve = Me(({
|
|
|
6867
7002
|
}
|
|
6868
7003
|
return;
|
|
6869
7004
|
}
|
|
6870
|
-
const ye = !Y.speechQueue || Y.speechQueue.length === 0,
|
|
6871
|
-
Y && Y.isSpeaking === !1 && ye &&
|
|
7005
|
+
const ye = !Y.speechQueue || Y.speechQueue.length === 0, ke = !Y.audioPlaylist || Y.audioPlaylist.length === 0;
|
|
7006
|
+
Y && Y.isSpeaking === !1 && ye && ke && Y.isAudioPlaying === !1 && !be && !E.current && setTimeout(() => {
|
|
6872
7007
|
if (Y && !E.current && Y.isSpeaking === !1 && (!Y.speechQueue || Y.speechQueue.length === 0) && (!Y.audioPlaylist || Y.audioPlaylist.length === 0) && Y.isAudioPlaying === !1 && !be && !E.current) {
|
|
6873
|
-
be = !0,
|
|
7008
|
+
be = !0, ue && (clearInterval(ue), ue = null, y.current = null);
|
|
6874
7009
|
try {
|
|
6875
7010
|
F.onSpeechEnd();
|
|
6876
7011
|
} catch (Ze) {
|
|
@@ -6878,7 +7013,7 @@ const Ve = Me(({
|
|
|
6878
7013
|
}
|
|
6879
7014
|
}
|
|
6880
7015
|
}, 100);
|
|
6881
|
-
}, 100), y.current =
|
|
7016
|
+
}, 100), y.current = ue;
|
|
6882
7017
|
}
|
|
6883
7018
|
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge)) : setTimeout(async () => {
|
|
6884
7019
|
await H(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge));
|
|
@@ -6886,7 +7021,7 @@ const Ve = Me(({
|
|
|
6886
7021
|
} catch (N) {
|
|
6887
7022
|
console.error("Error speaking text:", N), X(N.message || "Failed to speak text");
|
|
6888
7023
|
}
|
|
6889
|
-
}, [$, H, v.lipsyncLang]),
|
|
7024
|
+
}, [$, H, v.lipsyncLang]), K = T(() => {
|
|
6890
7025
|
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), z.current = null, pe(!1));
|
|
6891
7026
|
}, []), j = T(() => {
|
|
6892
7027
|
if (p.current && p.current.pauseSpeaking) {
|
|
@@ -6895,9 +7030,9 @@ const Ve = Me(({
|
|
|
6895
7030
|
y.current && (clearInterval(y.current), y.current = null);
|
|
6896
7031
|
let N = "";
|
|
6897
7032
|
if (z.current && W.current.length > 0) {
|
|
6898
|
-
const J = W.current.length, ge = L.speechQueue ? L.speechQueue.filter((Ae) => Ae && Ae.text && Array.isArray(Ae.text) && Ae.text.length > 0).length : 0, Y = L.audioPlaylist && L.audioPlaylist.length > 0,
|
|
6899
|
-
if (
|
|
6900
|
-
const be = L.speechQueue.filter((ye) => ye && ye.text && Array.isArray(ye.text) && ye.text.length > 0).map((ye) => ye.text.map((
|
|
7033
|
+
const J = W.current.length, ge = L.speechQueue ? L.speechQueue.filter((Ae) => Ae && Ae.text && Array.isArray(Ae.text) && Ae.text.length > 0).length : 0, Y = L.audioPlaylist && L.audioPlaylist.length > 0, ue = ge + (Y ? 1 : 0), Se = J - ue;
|
|
7034
|
+
if (ue > 0 && Se < J && (N = W.current.slice(Se).join(". ").trim(), !N && ge > 0 && L.speechQueue)) {
|
|
7035
|
+
const be = L.speechQueue.filter((ye) => ye && ye.text && Array.isArray(ye.text) && ye.text.length > 0).map((ye) => ye.text.map((ke) => ke.word || "").filter((ke) => ke.length > 0).join(" ")).filter((ye) => ye.length > 0).join(" ");
|
|
6901
7036
|
be && be.trim() && (N = be.trim());
|
|
6902
7037
|
}
|
|
6903
7038
|
}
|
|
@@ -6977,7 +7112,7 @@ const Ve = Me(({
|
|
|
6977
7112
|
}, []);
|
|
6978
7113
|
return Ee(I, () => ({
|
|
6979
7114
|
speakText: U,
|
|
6980
|
-
stopSpeaking:
|
|
7115
|
+
stopSpeaking: K,
|
|
6981
7116
|
pauseSpeaking: j,
|
|
6982
7117
|
resumeSpeaking: q,
|
|
6983
7118
|
resumeAudioContext: H,
|
|
@@ -7068,7 +7203,7 @@ const Ve = Me(({
|
|
|
7068
7203
|
}
|
|
7069
7204
|
}
|
|
7070
7205
|
),
|
|
7071
|
-
|
|
7206
|
+
S && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
|
|
7072
7207
|
position: "absolute",
|
|
7073
7208
|
top: "50%",
|
|
7074
7209
|
left: "50%",
|
|
@@ -7077,7 +7212,7 @@ const Ve = Me(({
|
|
|
7077
7212
|
fontSize: "18px",
|
|
7078
7213
|
zIndex: 10
|
|
7079
7214
|
}, children: "Loading avatar..." }),
|
|
7080
|
-
|
|
7215
|
+
_ && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
|
|
7081
7216
|
position: "absolute",
|
|
7082
7217
|
top: "50%",
|
|
7083
7218
|
left: "50%",
|
|
@@ -7088,7 +7223,7 @@ const Ve = Me(({
|
|
|
7088
7223
|
zIndex: 10,
|
|
7089
7224
|
padding: "20px",
|
|
7090
7225
|
borderRadius: "8px"
|
|
7091
|
-
}, children:
|
|
7226
|
+
}, children: _ })
|
|
7092
7227
|
]
|
|
7093
7228
|
}
|
|
7094
7229
|
);
|
|
@@ -7106,7 +7241,7 @@ const pt = Me(({
|
|
|
7106
7241
|
style: s = {},
|
|
7107
7242
|
avatarConfig: o = {}
|
|
7108
7243
|
}, l) => {
|
|
7109
|
-
const
|
|
7244
|
+
const u = D(null), r = D(null), [h, a] = ce(!0), [c, d] = ce(null), [g, x] = ce(!1), b = Fe(), I = o.ttsService || b.service, B = I === "browser" ? {
|
|
7110
7245
|
endpoint: "",
|
|
7111
7246
|
apiKey: null,
|
|
7112
7247
|
defaultVoice: "Google US English"
|
|
@@ -7137,29 +7272,29 @@ const pt = Me(({
|
|
|
7137
7272
|
lipsyncModules: ["en"],
|
|
7138
7273
|
cameraView: "upper"
|
|
7139
7274
|
}, z = T(async () => {
|
|
7140
|
-
if (!(!
|
|
7275
|
+
if (!(!u.current || r.current))
|
|
7141
7276
|
try {
|
|
7142
|
-
if (a(!0), d(null), r.current = new Be(
|
|
7143
|
-
if (
|
|
7144
|
-
const X = Math.min(100, Math.round(
|
|
7277
|
+
if (a(!0), d(null), r.current = new Be(u.current, M), await r.current.showAvatar(p, (_) => {
|
|
7278
|
+
if (_.lengthComputable) {
|
|
7279
|
+
const X = Math.min(100, Math.round(_.loaded / _.total * 100));
|
|
7145
7280
|
t(X);
|
|
7146
7281
|
}
|
|
7147
7282
|
}), r.current.morphs && r.current.morphs.length > 0) {
|
|
7148
|
-
const
|
|
7149
|
-
console.log("Available morph targets:", Object.keys(
|
|
7150
|
-
const X = Object.keys(
|
|
7283
|
+
const _ = r.current.morphs[0].morphTargetDictionary;
|
|
7284
|
+
console.log("Available morph targets:", Object.keys(_));
|
|
7285
|
+
const X = Object.keys(_).filter(($) => $.startsWith("viseme_"));
|
|
7151
7286
|
console.log("Viseme morph targets found:", X), X.length === 0 && (console.warn("No viseme morph targets found! Lip-sync will not work properly."), console.log("Expected viseme targets: viseme_aa, viseme_E, viseme_I, viseme_O, viseme_U, viseme_PP, viseme_SS, viseme_TH, viseme_DD, viseme_FF, viseme_kk, viseme_nn, viseme_RR, viseme_CH, viseme_sil"));
|
|
7152
7287
|
}
|
|
7153
|
-
if (await new Promise((
|
|
7288
|
+
if (await new Promise((_) => {
|
|
7154
7289
|
const X = () => {
|
|
7155
|
-
r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)),
|
|
7290
|
+
r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), _()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(X, 100));
|
|
7156
7291
|
};
|
|
7157
7292
|
X();
|
|
7158
7293
|
}), r.current && r.current.setShowFullAvatar)
|
|
7159
7294
|
try {
|
|
7160
7295
|
r.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
|
|
7161
|
-
} catch (
|
|
7162
|
-
console.warn("Error setting full body mode on initialization:",
|
|
7296
|
+
} catch (_) {
|
|
7297
|
+
console.warn("Error setting full body mode on initialization:", _);
|
|
7163
7298
|
}
|
|
7164
7299
|
a(!1), x(!0), n(r.current);
|
|
7165
7300
|
const Z = () => {
|
|
@@ -7168,18 +7303,18 @@ const pt = Me(({
|
|
|
7168
7303
|
return document.addEventListener("visibilitychange", Z), () => {
|
|
7169
7304
|
document.removeEventListener("visibilitychange", Z);
|
|
7170
7305
|
};
|
|
7171
|
-
} catch (
|
|
7172
|
-
console.error("Error initializing TalkingHead:",
|
|
7306
|
+
} catch (S) {
|
|
7307
|
+
console.error("Error initializing TalkingHead:", S), d(S.message || "Failed to initialize avatar"), a(!1), e(S);
|
|
7173
7308
|
}
|
|
7174
7309
|
}, []);
|
|
7175
7310
|
de(() => (z(), () => {
|
|
7176
7311
|
r.current && (r.current.stop(), r.current.dispose(), r.current = null);
|
|
7177
7312
|
}), [z]);
|
|
7178
|
-
const y = T((
|
|
7313
|
+
const y = T((S) => {
|
|
7179
7314
|
if (r.current && g)
|
|
7180
7315
|
try {
|
|
7181
|
-
console.log("Speaking text:",
|
|
7182
|
-
r.current && r.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(
|
|
7316
|
+
console.log("Speaking text:", S), console.log("Avatar config:", p), console.log("TalkingHead instance:", r.current), r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(S)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
|
|
7317
|
+
r.current && r.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(S)) : console.error("Lip-sync still not ready after waiting");
|
|
7183
7318
|
}, 500));
|
|
7184
7319
|
} catch (Z) {
|
|
7185
7320
|
console.error("Error speaking text:", Z), d(Z.message || "Failed to speak text");
|
|
@@ -7188,11 +7323,11 @@ const pt = Me(({
|
|
|
7188
7323
|
console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!r.current);
|
|
7189
7324
|
}, [g, p]), E = T(() => {
|
|
7190
7325
|
r.current && (r.current.stopSpeaking(), r.current.setSlowdownRate && (r.current.setSlowdownRate(1), console.log("Reset timing to normal")));
|
|
7191
|
-
}, []), P = T((
|
|
7192
|
-
r.current && r.current.setMood(
|
|
7193
|
-
}, []), W = T((
|
|
7194
|
-
r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(
|
|
7195
|
-
}, []), oe = T((
|
|
7326
|
+
}, []), P = T((S) => {
|
|
7327
|
+
r.current && r.current.setMood(S);
|
|
7328
|
+
}, []), W = T((S) => {
|
|
7329
|
+
r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(S), console.log("Timing adjustment set to:", S));
|
|
7330
|
+
}, []), oe = T((S, Z = !1) => {
|
|
7196
7331
|
if (r.current && r.current.playAnimation) {
|
|
7197
7332
|
if (r.current.setShowFullAvatar)
|
|
7198
7333
|
try {
|
|
@@ -7200,11 +7335,11 @@ const pt = Me(({
|
|
|
7200
7335
|
} catch (X) {
|
|
7201
7336
|
console.warn("Error setting full body mode:", X);
|
|
7202
7337
|
}
|
|
7203
|
-
if (
|
|
7338
|
+
if (S.includes("."))
|
|
7204
7339
|
try {
|
|
7205
|
-
r.current.playAnimation(
|
|
7340
|
+
r.current.playAnimation(S, null, 10, 0, 0.01, Z), console.log("Playing animation:", S);
|
|
7206
7341
|
} catch (X) {
|
|
7207
|
-
console.log(`Failed to play ${
|
|
7342
|
+
console.log(`Failed to play ${S}:`, X);
|
|
7208
7343
|
try {
|
|
7209
7344
|
r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
7210
7345
|
} catch ($) {
|
|
@@ -7216,13 +7351,13 @@ const pt = Me(({
|
|
|
7216
7351
|
let $ = !1;
|
|
7217
7352
|
for (const se of X)
|
|
7218
7353
|
try {
|
|
7219
|
-
r.current.playAnimation(
|
|
7354
|
+
r.current.playAnimation(S + se, null, 10, 0, 0.01, Z), console.log("Playing animation:", S + se), $ = !0;
|
|
7220
7355
|
break;
|
|
7221
7356
|
} catch {
|
|
7222
|
-
console.log(`Failed to play ${
|
|
7357
|
+
console.log(`Failed to play ${S}${se}, trying next format...`);
|
|
7223
7358
|
}
|
|
7224
7359
|
if (!$) {
|
|
7225
|
-
console.warn("Animation system not available or animation not found:",
|
|
7360
|
+
console.warn("Animation system not available or animation not found:", S);
|
|
7226
7361
|
try {
|
|
7227
7362
|
r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
7228
7363
|
} catch (se) {
|
|
@@ -7231,7 +7366,7 @@ const pt = Me(({
|
|
|
7231
7366
|
}
|
|
7232
7367
|
}
|
|
7233
7368
|
} else
|
|
7234
|
-
console.warn("Animation system not available or animation not found:",
|
|
7369
|
+
console.warn("Animation system not available or animation not found:", S);
|
|
7235
7370
|
}, []);
|
|
7236
7371
|
return Ee(l, () => ({
|
|
7237
7372
|
speakText: y,
|
|
@@ -7241,27 +7376,27 @@ const pt = Me(({
|
|
|
7241
7376
|
playAnimation: oe,
|
|
7242
7377
|
isReady: g,
|
|
7243
7378
|
talkingHead: r.current,
|
|
7244
|
-
setBodyMovement: (
|
|
7379
|
+
setBodyMovement: (S) => {
|
|
7245
7380
|
if (r.current && r.current.setShowFullAvatar && r.current.setBodyMovement)
|
|
7246
7381
|
try {
|
|
7247
|
-
r.current.setShowFullAvatar(!0), r.current.setBodyMovement(
|
|
7382
|
+
r.current.setShowFullAvatar(!0), r.current.setBodyMovement(S), console.log("Body movement set with full body mode:", S);
|
|
7248
7383
|
} catch (Z) {
|
|
7249
7384
|
console.warn("Error setting body movement:", Z);
|
|
7250
7385
|
}
|
|
7251
7386
|
},
|
|
7252
|
-
setMovementIntensity: (
|
|
7387
|
+
setMovementIntensity: (S) => r.current?.setMovementIntensity(S),
|
|
7253
7388
|
playRandomDance: () => {
|
|
7254
7389
|
if (r.current && r.current.setShowFullAvatar && r.current.playRandomDance)
|
|
7255
7390
|
try {
|
|
7256
7391
|
r.current.setShowFullAvatar(!0), r.current.playRandomDance(), console.log("Random dance played with full body mode");
|
|
7257
|
-
} catch (
|
|
7258
|
-
console.warn("Error playing random dance:",
|
|
7392
|
+
} catch (S) {
|
|
7393
|
+
console.warn("Error playing random dance:", S);
|
|
7259
7394
|
}
|
|
7260
7395
|
},
|
|
7261
|
-
playReaction: (
|
|
7396
|
+
playReaction: (S) => {
|
|
7262
7397
|
if (r.current && r.current.setShowFullAvatar && r.current.playReaction)
|
|
7263
7398
|
try {
|
|
7264
|
-
r.current.setShowFullAvatar(!0), r.current.playReaction(
|
|
7399
|
+
r.current.setShowFullAvatar(!0), r.current.playReaction(S), console.log("Reaction played with full body mode:", S);
|
|
7265
7400
|
} catch (Z) {
|
|
7266
7401
|
console.warn("Error playing reaction:", Z);
|
|
7267
7402
|
}
|
|
@@ -7270,14 +7405,14 @@ const pt = Me(({
|
|
|
7270
7405
|
if (r.current && r.current.setShowFullAvatar && r.current.playCelebration)
|
|
7271
7406
|
try {
|
|
7272
7407
|
r.current.setShowFullAvatar(!0), r.current.playCelebration(), console.log("Celebration played with full body mode");
|
|
7273
|
-
} catch (
|
|
7274
|
-
console.warn("Error playing celebration:",
|
|
7408
|
+
} catch (S) {
|
|
7409
|
+
console.warn("Error playing celebration:", S);
|
|
7275
7410
|
}
|
|
7276
7411
|
},
|
|
7277
|
-
setShowFullAvatar: (
|
|
7412
|
+
setShowFullAvatar: (S) => {
|
|
7278
7413
|
if (r.current && r.current.setShowFullAvatar)
|
|
7279
7414
|
try {
|
|
7280
|
-
r.current.setShowFullAvatar(
|
|
7415
|
+
r.current.setShowFullAvatar(S), console.log("Show full avatar set to:", S);
|
|
7281
7416
|
} catch (Z) {
|
|
7282
7417
|
console.warn("Error setting showFullAvatar:", Z);
|
|
7283
7418
|
}
|
|
@@ -7286,23 +7421,23 @@ const pt = Me(({
|
|
|
7286
7421
|
if (r.current && r.current.lockAvatarPosition)
|
|
7287
7422
|
try {
|
|
7288
7423
|
r.current.lockAvatarPosition();
|
|
7289
|
-
} catch (
|
|
7290
|
-
console.warn("Error locking avatar position:",
|
|
7424
|
+
} catch (S) {
|
|
7425
|
+
console.warn("Error locking avatar position:", S);
|
|
7291
7426
|
}
|
|
7292
7427
|
},
|
|
7293
7428
|
unlockAvatarPosition: () => {
|
|
7294
7429
|
if (r.current && r.current.unlockAvatarPosition)
|
|
7295
7430
|
try {
|
|
7296
7431
|
r.current.unlockAvatarPosition();
|
|
7297
|
-
} catch (
|
|
7298
|
-
console.warn("Error unlocking avatar position:",
|
|
7432
|
+
} catch (S) {
|
|
7433
|
+
console.warn("Error unlocking avatar position:", S);
|
|
7299
7434
|
}
|
|
7300
7435
|
}
|
|
7301
7436
|
})), /* @__PURE__ */ Pe("div", { className: `talking-head-container ${i}`, style: s, children: [
|
|
7302
7437
|
/* @__PURE__ */ me(
|
|
7303
7438
|
"div",
|
|
7304
7439
|
{
|
|
7305
|
-
ref:
|
|
7440
|
+
ref: u,
|
|
7306
7441
|
className: "talking-head-viewer",
|
|
7307
7442
|
style: {
|
|
7308
7443
|
width: "100%",
|
|
@@ -7311,7 +7446,7 @@ const pt = Me(({
|
|
|
7311
7446
|
}
|
|
7312
7447
|
}
|
|
7313
7448
|
),
|
|
7314
|
-
|
|
7449
|
+
h && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
|
|
7315
7450
|
position: "absolute",
|
|
7316
7451
|
top: "50%",
|
|
7317
7452
|
left: "50%",
|
|
@@ -7344,9 +7479,9 @@ const gt = Me(({
|
|
|
7344
7479
|
ttsService: s = null,
|
|
7345
7480
|
ttsVoice: o = null,
|
|
7346
7481
|
ttsApiKey: l = null,
|
|
7347
|
-
bodyMovement:
|
|
7482
|
+
bodyMovement: u = "idle",
|
|
7348
7483
|
movementIntensity: r = 0.5,
|
|
7349
|
-
showFullAvatar:
|
|
7484
|
+
showFullAvatar: h = !1,
|
|
7350
7485
|
cameraView: a = "upper",
|
|
7351
7486
|
onReady: c = () => {
|
|
7352
7487
|
},
|
|
@@ -7361,13 +7496,13 @@ const gt = Me(({
|
|
|
7361
7496
|
animations: B = {},
|
|
7362
7497
|
autoSpeak: p = !1
|
|
7363
7498
|
}, M) => {
|
|
7364
|
-
const z =
|
|
7499
|
+
const z = D(null), y = D(null), E = D(h), P = D(null), W = D(null), oe = D(!1), S = D({ remainingText: null, originalText: null, options: null }), Z = D([]), [_, X] = ce(!0), [$, se] = ce(null), [ae, pe] = ce(!1), [ee, le] = ce(!1);
|
|
7365
7500
|
de(() => {
|
|
7366
7501
|
oe.current = ee;
|
|
7367
7502
|
}, [ee]), de(() => {
|
|
7368
|
-
E.current =
|
|
7369
|
-
}, [
|
|
7370
|
-
const
|
|
7503
|
+
E.current = h;
|
|
7504
|
+
}, [h]);
|
|
7505
|
+
const O = Fe(), v = s || O.service;
|
|
7371
7506
|
let R;
|
|
7372
7507
|
v === "browser" ? R = {
|
|
7373
7508
|
service: "browser",
|
|
@@ -7377,28 +7512,28 @@ const gt = Me(({
|
|
|
7377
7512
|
} : v === "elevenlabs" ? R = {
|
|
7378
7513
|
service: "elevenlabs",
|
|
7379
7514
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
7380
|
-
apiKey: l ||
|
|
7381
|
-
defaultVoice: o ||
|
|
7382
|
-
voices:
|
|
7515
|
+
apiKey: l || O.apiKey,
|
|
7516
|
+
defaultVoice: o || O.defaultVoice || Ie.defaultVoice,
|
|
7517
|
+
voices: O.voices || Ie.voices
|
|
7383
7518
|
} : v === "deepgram" ? R = {
|
|
7384
7519
|
service: "deepgram",
|
|
7385
7520
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
7386
|
-
apiKey: l ||
|
|
7387
|
-
defaultVoice: o ||
|
|
7388
|
-
voices:
|
|
7521
|
+
apiKey: l || O.apiKey,
|
|
7522
|
+
defaultVoice: o || O.defaultVoice || Te.defaultVoice,
|
|
7523
|
+
voices: O.voices || Te.voices
|
|
7389
7524
|
} : R = {
|
|
7390
|
-
...
|
|
7391
|
-
apiKey: l !== null ? l :
|
|
7525
|
+
...O,
|
|
7526
|
+
apiKey: l !== null ? l : O.apiKey
|
|
7392
7527
|
};
|
|
7393
|
-
const
|
|
7528
|
+
const k = {
|
|
7394
7529
|
url: t,
|
|
7395
7530
|
body: e,
|
|
7396
7531
|
avatarMood: n,
|
|
7397
7532
|
ttsLang: v === "browser" ? "en-US" : i,
|
|
7398
7533
|
ttsVoice: o || R.defaultVoice,
|
|
7399
7534
|
lipsyncLang: "en",
|
|
7400
|
-
showFullAvatar:
|
|
7401
|
-
bodyMovement:
|
|
7535
|
+
showFullAvatar: h,
|
|
7536
|
+
bodyMovement: u,
|
|
7402
7537
|
movementIntensity: r
|
|
7403
7538
|
}, H = {
|
|
7404
7539
|
ttsEndpoint: R.endpoint,
|
|
@@ -7410,10 +7545,10 @@ const gt = Me(({
|
|
|
7410
7545
|
if (!(!z.current || y.current))
|
|
7411
7546
|
try {
|
|
7412
7547
|
X(!0), se(null), y.current = new Be(z.current, H), console.log("Avatar config being passed:", {
|
|
7413
|
-
url:
|
|
7414
|
-
body:
|
|
7415
|
-
avatarMood:
|
|
7416
|
-
}), await y.current.showAvatar(
|
|
7548
|
+
url: k.url,
|
|
7549
|
+
body: k.body,
|
|
7550
|
+
avatarMood: k.avatarMood
|
|
7551
|
+
}), await y.current.showAvatar(k, (te) => {
|
|
7417
7552
|
if (te.lengthComputable) {
|
|
7418
7553
|
const L = Math.min(100, Math.round(te.loaded / te.total * 100));
|
|
7419
7554
|
d(L);
|
|
@@ -7432,7 +7567,7 @@ const gt = Me(({
|
|
|
7432
7567
|
de(() => (U(), () => {
|
|
7433
7568
|
y.current && (y.current.stop(), y.current.dispose(), y.current = null);
|
|
7434
7569
|
}), [U]);
|
|
7435
|
-
const
|
|
7570
|
+
const K = T(async () => {
|
|
7436
7571
|
if (y.current)
|
|
7437
7572
|
try {
|
|
7438
7573
|
const C = y.current.audioCtx || y.current.audioContext;
|
|
@@ -7449,7 +7584,7 @@ const gt = Me(({
|
|
|
7449
7584
|
console.warn("No text provided to speak");
|
|
7450
7585
|
return;
|
|
7451
7586
|
}
|
|
7452
|
-
await
|
|
7587
|
+
await K(), S.current = { remainingText: null, originalText: null, options: null }, Z.current = [], P.current = { text: C, options: te }, W.current && (clearInterval(W.current), W.current = null), le(!1), oe.current = !1;
|
|
7453
7588
|
const L = C.split(/[.!?]+/).filter((N) => N.trim().length > 0);
|
|
7454
7589
|
Z.current = L;
|
|
7455
7590
|
const F = {
|
|
@@ -7463,7 +7598,7 @@ const gt = Me(({
|
|
|
7463
7598
|
} catch (N) {
|
|
7464
7599
|
console.error("Error speaking text:", N), se(N.message || "Failed to speak text");
|
|
7465
7600
|
}
|
|
7466
|
-
}, [ae, x,
|
|
7601
|
+
}, [ae, x, K]);
|
|
7467
7602
|
de(() => {
|
|
7468
7603
|
ae && G && p && y.current && j(G);
|
|
7469
7604
|
}, [ae, G, p, j]);
|
|
@@ -7474,7 +7609,7 @@ const gt = Me(({
|
|
|
7474
7609
|
if (C || te.length > 0 || L.length > 0) {
|
|
7475
7610
|
W.current && (clearInterval(W.current), W.current = null);
|
|
7476
7611
|
let F = "";
|
|
7477
|
-
L.length > 0 && (F = L.map((N) => N.text && Array.isArray(N.text) ? N.text.map((J) => J.word).join(" ") : N.text || "").join(" ")),
|
|
7612
|
+
L.length > 0 && (F = L.map((N) => N.text && Array.isArray(N.text) ? N.text.map((J) => J.word).join(" ") : N.text || "").join(" ")), S.current = {
|
|
7478
7613
|
remainingText: F || null,
|
|
7479
7614
|
originalText: P.current?.text || null,
|
|
7480
7615
|
options: P.current?.options || null
|
|
@@ -7486,13 +7621,13 @@ const gt = Me(({
|
|
|
7486
7621
|
}, []), Le = T(async () => {
|
|
7487
7622
|
if (!(!y.current || !ee))
|
|
7488
7623
|
try {
|
|
7489
|
-
await
|
|
7490
|
-
const C =
|
|
7624
|
+
await K(), le(!1), oe.current = !1;
|
|
7625
|
+
const C = S.current?.remainingText, te = S.current?.originalText || P.current?.text, L = S.current?.options || P.current?.options || {}, F = C || te;
|
|
7491
7626
|
F && j(F, L);
|
|
7492
7627
|
} catch (C) {
|
|
7493
7628
|
console.warn("Error resuming speech:", C), le(!1), oe.current = !1;
|
|
7494
7629
|
}
|
|
7495
|
-
}, [ee, j,
|
|
7630
|
+
}, [ee, j, K]), we = T(() => {
|
|
7496
7631
|
y.current && (y.current.stopSpeaking(), W.current && (clearInterval(W.current), W.current = null), le(!1), oe.current = !1);
|
|
7497
7632
|
}, []);
|
|
7498
7633
|
return Ee(M, () => ({
|
|
@@ -7500,7 +7635,7 @@ const gt = Me(({
|
|
|
7500
7635
|
pauseSpeaking: q,
|
|
7501
7636
|
resumeSpeaking: Le,
|
|
7502
7637
|
stopSpeaking: we,
|
|
7503
|
-
resumeAudioContext:
|
|
7638
|
+
resumeAudioContext: K,
|
|
7504
7639
|
isPaused: () => ee,
|
|
7505
7640
|
setMood: (C) => y.current?.setMood(C),
|
|
7506
7641
|
setBodyMovement: (C) => {
|
|
@@ -7529,7 +7664,7 @@ const gt = Me(({
|
|
|
7529
7664
|
}
|
|
7530
7665
|
}
|
|
7531
7666
|
),
|
|
7532
|
-
|
|
7667
|
+
_ && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
|
|
7533
7668
|
position: "absolute",
|
|
7534
7669
|
top: "50%",
|
|
7535
7670
|
left: "50%",
|
|
@@ -7567,9 +7702,9 @@ const yt = Me(({
|
|
|
7567
7702
|
},
|
|
7568
7703
|
onCustomAction: l = () => {
|
|
7569
7704
|
},
|
|
7570
|
-
autoStart:
|
|
7705
|
+
autoStart: u = !1
|
|
7571
7706
|
}, r) => {
|
|
7572
|
-
const
|
|
7707
|
+
const h = D(null), a = D({
|
|
7573
7708
|
currentModuleIndex: 0,
|
|
7574
7709
|
currentLessonIndex: 0,
|
|
7575
7710
|
currentQuestionIndex: 0,
|
|
@@ -7579,18 +7714,18 @@ const yt = Me(({
|
|
|
7579
7714
|
curriculumCompleted: !1,
|
|
7580
7715
|
score: 0,
|
|
7581
7716
|
totalQuestions: 0
|
|
7582
|
-
}), c =
|
|
7717
|
+
}), c = D({
|
|
7583
7718
|
onLessonStart: n,
|
|
7584
7719
|
onLessonComplete: i,
|
|
7585
7720
|
onQuestionAnswer: s,
|
|
7586
7721
|
onCurriculumComplete: o,
|
|
7587
7722
|
onCustomAction: l
|
|
7588
|
-
}), d =
|
|
7723
|
+
}), d = D(null), g = D(null), x = D(null), b = D(null), I = D(null), B = D(null), p = D(null), M = D(G?.curriculum || {
|
|
7589
7724
|
title: "Default Curriculum",
|
|
7590
7725
|
description: "No curriculum data provided",
|
|
7591
7726
|
language: "en",
|
|
7592
7727
|
modules: []
|
|
7593
|
-
}), z =
|
|
7728
|
+
}), z = D({
|
|
7594
7729
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7595
7730
|
avatarBody: t.avatarBody || "F",
|
|
7596
7731
|
mood: t.mood || "happy",
|
|
@@ -7650,15 +7785,15 @@ const yt = Me(({
|
|
|
7650
7785
|
score: a.current.score,
|
|
7651
7786
|
totalQuestions: a.current.totalQuestions,
|
|
7652
7787
|
percentage: v
|
|
7653
|
-
}),
|
|
7654
|
-
if (
|
|
7788
|
+
}), h.current) {
|
|
7789
|
+
if (h.current.setMood("happy"), e.lessonComplete)
|
|
7655
7790
|
try {
|
|
7656
|
-
|
|
7791
|
+
h.current.playAnimation(e.lessonComplete, !0);
|
|
7657
7792
|
} catch {
|
|
7658
|
-
|
|
7793
|
+
h.current.playCelebration();
|
|
7659
7794
|
}
|
|
7660
|
-
const
|
|
7661
|
-
|
|
7795
|
+
const k = M.current || { modules: [] }, H = k.modules[a.current.currentModuleIndex], U = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, K = a.current.currentModuleIndex < (k.modules?.length || 0) - 1, j = U || K, q = z.current || { lipsyncLang: "en" };
|
|
7796
|
+
h.current.speakText(R, {
|
|
7662
7797
|
lipsyncLang: q.lipsyncLang,
|
|
7663
7798
|
onSpeechEnd: () => {
|
|
7664
7799
|
c.current.onCustomAction({
|
|
@@ -7678,18 +7813,18 @@ const yt = Me(({
|
|
|
7678
7813
|
const v = M.current || { modules: [] };
|
|
7679
7814
|
if (c.current.onCurriculumComplete({
|
|
7680
7815
|
modules: v.modules.length,
|
|
7681
|
-
totalLessons: v.modules.reduce((R,
|
|
7682
|
-
}),
|
|
7683
|
-
if (
|
|
7816
|
+
totalLessons: v.modules.reduce((R, k) => R + k.lessons.length, 0)
|
|
7817
|
+
}), h.current) {
|
|
7818
|
+
if (h.current.setMood("celebrating"), e.curriculumComplete)
|
|
7684
7819
|
try {
|
|
7685
|
-
|
|
7820
|
+
h.current.playAnimation(e.curriculumComplete, !0);
|
|
7686
7821
|
} catch {
|
|
7687
|
-
|
|
7822
|
+
h.current.playCelebration();
|
|
7688
7823
|
}
|
|
7689
7824
|
const R = z.current || { lipsyncLang: "en" };
|
|
7690
|
-
|
|
7825
|
+
h.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: R.lipsyncLang });
|
|
7691
7826
|
}
|
|
7692
|
-
}, [e.curriculumComplete]),
|
|
7827
|
+
}, [e.curriculumComplete]), S = T(() => {
|
|
7693
7828
|
const v = y();
|
|
7694
7829
|
a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = v?.questions?.length || 0, a.current.score = 0;
|
|
7695
7830
|
const R = E();
|
|
@@ -7702,25 +7837,25 @@ const yt = Me(({
|
|
|
7702
7837
|
question: R,
|
|
7703
7838
|
score: a.current.score
|
|
7704
7839
|
});
|
|
7705
|
-
const
|
|
7706
|
-
if (!
|
|
7707
|
-
if (
|
|
7840
|
+
const k = () => {
|
|
7841
|
+
if (!h.current || !R) return;
|
|
7842
|
+
if (h.current.setMood("happy"), e.questionStart)
|
|
7708
7843
|
try {
|
|
7709
|
-
|
|
7844
|
+
h.current.playAnimation(e.questionStart, !0);
|
|
7710
7845
|
} catch (U) {
|
|
7711
7846
|
console.warn("Failed to play questionStart animation:", U);
|
|
7712
7847
|
}
|
|
7713
7848
|
const H = z.current || { lipsyncLang: "en" };
|
|
7714
|
-
R.type === "code_test" ?
|
|
7849
|
+
R.type === "code_test" ? h.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : R.type === "multiple_choice" ? h.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : R.type === "true_false" ? h.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : h.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: H.lipsyncLang });
|
|
7715
7850
|
};
|
|
7716
|
-
if (
|
|
7717
|
-
|
|
7718
|
-
else if (
|
|
7851
|
+
if (h.current && h.current.isReady && R)
|
|
7852
|
+
k();
|
|
7853
|
+
else if (h.current && h.current.isReady) {
|
|
7719
7854
|
const H = z.current || { lipsyncLang: "en" };
|
|
7720
|
-
|
|
7855
|
+
h.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: H.lipsyncLang });
|
|
7721
7856
|
} else {
|
|
7722
7857
|
const H = setInterval(() => {
|
|
7723
|
-
|
|
7858
|
+
h.current && h.current.isReady && (clearInterval(H), R && k());
|
|
7724
7859
|
}, 100);
|
|
7725
7860
|
setTimeout(() => {
|
|
7726
7861
|
clearInterval(H);
|
|
@@ -7729,7 +7864,7 @@ const yt = Me(({
|
|
|
7729
7864
|
}, [e.questionStart, y, E]), Z = T(() => {
|
|
7730
7865
|
const v = y();
|
|
7731
7866
|
if (a.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
|
|
7732
|
-
|
|
7867
|
+
h.current && h.current.stopSpeaking && h.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
|
|
7733
7868
|
const R = E();
|
|
7734
7869
|
R && c.current.onCustomAction({
|
|
7735
7870
|
type: "nextQuestion",
|
|
@@ -7740,42 +7875,42 @@ const yt = Me(({
|
|
|
7740
7875
|
question: R,
|
|
7741
7876
|
score: a.current.score
|
|
7742
7877
|
});
|
|
7743
|
-
const
|
|
7744
|
-
if (!
|
|
7745
|
-
if (
|
|
7878
|
+
const k = () => {
|
|
7879
|
+
if (!h.current || !R) return;
|
|
7880
|
+
if (h.current.setMood("happy"), h.current.setBodyMovement("idle"), e.nextQuestion)
|
|
7746
7881
|
try {
|
|
7747
|
-
|
|
7882
|
+
h.current.playAnimation(e.nextQuestion, !0);
|
|
7748
7883
|
} catch (q) {
|
|
7749
7884
|
console.warn("Failed to play nextQuestion animation:", q);
|
|
7750
7885
|
}
|
|
7751
|
-
const H = z.current || { lipsyncLang: "en" },
|
|
7886
|
+
const H = z.current || { lipsyncLang: "en" }, K = y()?.questions?.length || 0, j = a.current.currentQuestionIndex >= K - 1;
|
|
7752
7887
|
if (R.type === "code_test") {
|
|
7753
7888
|
const q = j ? `Great! Here's your final coding challenge: ${R.question}` : `Great! Now let's move on to your next coding challenge: ${R.question}`;
|
|
7754
|
-
|
|
7889
|
+
h.current.speakText(q, {
|
|
7755
7890
|
lipsyncLang: H.lipsyncLang
|
|
7756
7891
|
});
|
|
7757
7892
|
} else if (R.type === "multiple_choice") {
|
|
7758
7893
|
const q = j ? `Alright! Here's your final question: ${R.question}` : `Alright! Here's your next question: ${R.question}`;
|
|
7759
|
-
|
|
7894
|
+
h.current.speakText(q, {
|
|
7760
7895
|
lipsyncLang: H.lipsyncLang
|
|
7761
7896
|
});
|
|
7762
7897
|
} else if (R.type === "true_false") {
|
|
7763
7898
|
const q = j ? `Now let's try this final one: ${R.question}` : `Now let's try this one: ${R.question}`;
|
|
7764
|
-
|
|
7899
|
+
h.current.speakText(q, {
|
|
7765
7900
|
lipsyncLang: H.lipsyncLang
|
|
7766
7901
|
});
|
|
7767
7902
|
} else {
|
|
7768
7903
|
const q = j ? `Here's your final question: ${R.question}` : `Here's the next question: ${R.question}`;
|
|
7769
|
-
|
|
7904
|
+
h.current.speakText(q, {
|
|
7770
7905
|
lipsyncLang: H.lipsyncLang
|
|
7771
7906
|
});
|
|
7772
7907
|
}
|
|
7773
7908
|
};
|
|
7774
|
-
if (
|
|
7775
|
-
|
|
7909
|
+
if (h.current && h.current.isReady && R)
|
|
7910
|
+
k();
|
|
7776
7911
|
else if (R) {
|
|
7777
7912
|
const H = setInterval(() => {
|
|
7778
|
-
|
|
7913
|
+
h.current && h.current.isReady && (clearInterval(H), k());
|
|
7779
7914
|
}, 100);
|
|
7780
7915
|
setTimeout(() => {
|
|
7781
7916
|
clearInterval(H);
|
|
@@ -7789,11 +7924,11 @@ const yt = Me(({
|
|
|
7789
7924
|
totalQuestions: a.current.totalQuestions,
|
|
7790
7925
|
score: a.current.score
|
|
7791
7926
|
});
|
|
7792
|
-
}, [e.nextQuestion, y, E]),
|
|
7927
|
+
}, [e.nextQuestion, y, E]), _ = T(() => {
|
|
7793
7928
|
const v = M.current || { modules: [] }, R = v.modules[a.current.currentModuleIndex];
|
|
7794
7929
|
if (a.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
|
|
7795
7930
|
a.current.currentLessonIndex += 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0;
|
|
7796
|
-
const H = v.modules[a.current.currentModuleIndex], U = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1,
|
|
7931
|
+
const H = v.modules[a.current.currentModuleIndex], U = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, K = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, j = U || K;
|
|
7797
7932
|
c.current.onCustomAction({
|
|
7798
7933
|
type: "lessonStart",
|
|
7799
7934
|
moduleIndex: a.current.currentModuleIndex,
|
|
@@ -7803,10 +7938,10 @@ const yt = Me(({
|
|
|
7803
7938
|
moduleIndex: a.current.currentModuleIndex,
|
|
7804
7939
|
lessonIndex: a.current.currentLessonIndex,
|
|
7805
7940
|
lesson: y()
|
|
7806
|
-
}),
|
|
7941
|
+
}), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
|
|
7807
7942
|
} else if (a.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
|
|
7808
7943
|
a.current.currentModuleIndex += 1, a.current.currentLessonIndex = 0, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0;
|
|
7809
|
-
const U = v.modules[a.current.currentModuleIndex],
|
|
7944
|
+
const U = v.modules[a.current.currentModuleIndex], K = a.current.currentLessonIndex < (U?.lessons?.length || 0) - 1, j = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, q = K || j;
|
|
7810
7945
|
c.current.onCustomAction({
|
|
7811
7946
|
type: "lessonStart",
|
|
7812
7947
|
moduleIndex: a.current.currentModuleIndex,
|
|
@@ -7816,27 +7951,27 @@ const yt = Me(({
|
|
|
7816
7951
|
moduleIndex: a.current.currentModuleIndex,
|
|
7817
7952
|
lessonIndex: a.current.currentLessonIndex,
|
|
7818
7953
|
lesson: y()
|
|
7819
|
-
}),
|
|
7954
|
+
}), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
|
|
7820
7955
|
} else
|
|
7821
7956
|
I.current && I.current();
|
|
7822
7957
|
}, []), X = T(() => {
|
|
7823
7958
|
const v = y();
|
|
7824
7959
|
let R = null;
|
|
7825
7960
|
if (v?.avatar_script && v?.body) {
|
|
7826
|
-
const
|
|
7827
|
-
R = `${
|
|
7961
|
+
const k = v.avatar_script.trim(), H = v.body.trim(), U = k.match(/[.!?]$/) ? " " : ". ";
|
|
7962
|
+
R = `${k}${U}${H}`;
|
|
7828
7963
|
} else
|
|
7829
7964
|
R = v?.avatar_script || v?.body || null;
|
|
7830
|
-
if (
|
|
7831
|
-
a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0,
|
|
7832
|
-
let
|
|
7965
|
+
if (h.current && h.current.isReady && R) {
|
|
7966
|
+
a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0, h.current.setMood("happy");
|
|
7967
|
+
let k = !1;
|
|
7833
7968
|
if (e.teaching)
|
|
7834
7969
|
try {
|
|
7835
|
-
|
|
7970
|
+
h.current.playAnimation(e.teaching, !0), k = !0;
|
|
7836
7971
|
} catch (U) {
|
|
7837
7972
|
console.warn("Failed to play teaching animation:", U);
|
|
7838
7973
|
}
|
|
7839
|
-
|
|
7974
|
+
k || h.current.setBodyMovement("gesturing");
|
|
7840
7975
|
const H = z.current || { lipsyncLang: "en" };
|
|
7841
7976
|
c.current.onLessonStart({
|
|
7842
7977
|
moduleIndex: a.current.currentModuleIndex,
|
|
@@ -7847,7 +7982,7 @@ const yt = Me(({
|
|
|
7847
7982
|
moduleIndex: a.current.currentModuleIndex,
|
|
7848
7983
|
lessonIndex: a.current.currentLessonIndex,
|
|
7849
7984
|
lesson: v
|
|
7850
|
-
}),
|
|
7985
|
+
}), h.current.speakText(R, {
|
|
7851
7986
|
lipsyncLang: H.lipsyncLang,
|
|
7852
7987
|
onSpeechEnd: () => {
|
|
7853
7988
|
a.current.isTeaching = !1, c.current.onCustomAction({
|
|
@@ -7867,29 +8002,29 @@ const yt = Me(({
|
|
|
7867
8002
|
});
|
|
7868
8003
|
}
|
|
7869
8004
|
}, [e.teaching, y]), $ = T((v) => {
|
|
7870
|
-
const R = E(),
|
|
7871
|
-
if (
|
|
8005
|
+
const R = E(), k = P(v, R);
|
|
8006
|
+
if (k && (a.current.score += 1), c.current.onQuestionAnswer({
|
|
7872
8007
|
moduleIndex: a.current.currentModuleIndex,
|
|
7873
8008
|
lessonIndex: a.current.currentLessonIndex,
|
|
7874
8009
|
questionIndex: a.current.currentQuestionIndex,
|
|
7875
8010
|
answer: v,
|
|
7876
|
-
isCorrect:
|
|
8011
|
+
isCorrect: k,
|
|
7877
8012
|
question: R
|
|
7878
|
-
}),
|
|
7879
|
-
if (
|
|
7880
|
-
if (
|
|
8013
|
+
}), h.current)
|
|
8014
|
+
if (k) {
|
|
8015
|
+
if (h.current.setMood("happy"), e.correct)
|
|
7881
8016
|
try {
|
|
7882
|
-
|
|
8017
|
+
h.current.playReaction("happy");
|
|
7883
8018
|
} catch {
|
|
7884
|
-
|
|
8019
|
+
h.current.setBodyMovement("happy");
|
|
7885
8020
|
}
|
|
7886
|
-
|
|
8021
|
+
h.current.setBodyMovement("gesturing");
|
|
7887
8022
|
const U = y()?.questions?.length || 0;
|
|
7888
8023
|
a.current.currentQuestionIndex >= U - 1;
|
|
7889
|
-
const
|
|
7890
|
-
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", U, "hasNextQuestion:",
|
|
8024
|
+
const K = a.current.currentQuestionIndex < U - 1;
|
|
8025
|
+
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", U, "hasNextQuestion:", K);
|
|
7891
8026
|
const j = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, q = z.current || { lipsyncLang: "en" };
|
|
7892
|
-
|
|
8027
|
+
h.current.speakText(j, {
|
|
7893
8028
|
lipsyncLang: q.lipsyncLang,
|
|
7894
8029
|
onSpeechEnd: () => {
|
|
7895
8030
|
c.current.onCustomAction({
|
|
@@ -7898,24 +8033,24 @@ const yt = Me(({
|
|
|
7898
8033
|
lessonIndex: a.current.currentLessonIndex,
|
|
7899
8034
|
questionIndex: a.current.currentQuestionIndex,
|
|
7900
8035
|
isCorrect: !0,
|
|
7901
|
-
hasNextQuestion:
|
|
8036
|
+
hasNextQuestion: K,
|
|
7902
8037
|
score: a.current.score,
|
|
7903
8038
|
totalQuestions: a.current.totalQuestions
|
|
7904
8039
|
});
|
|
7905
8040
|
}
|
|
7906
8041
|
});
|
|
7907
8042
|
} else {
|
|
7908
|
-
if (
|
|
8043
|
+
if (h.current.setMood("sad"), e.incorrect)
|
|
7909
8044
|
try {
|
|
7910
|
-
|
|
8045
|
+
h.current.playAnimation(e.incorrect, !0);
|
|
7911
8046
|
} catch {
|
|
7912
|
-
|
|
8047
|
+
h.current.setBodyMovement("idle");
|
|
7913
8048
|
}
|
|
7914
|
-
|
|
7915
|
-
const U = y()?.questions?.length || 0,
|
|
8049
|
+
h.current.setBodyMovement("gesturing");
|
|
8050
|
+
const U = y()?.questions?.length || 0, K = a.current.currentQuestionIndex >= U - 1, j = a.current.currentQuestionIndex < U - 1;
|
|
7916
8051
|
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", U, "hasNextQuestion:", j);
|
|
7917
|
-
const q = R.type === "code_test" ? `Your code didn't pass all the tests. ${R.explanation || "Try again!"}` : `Not quite right, but don't worry! ${R.explanation || ""}${
|
|
7918
|
-
|
|
8052
|
+
const q = R.type === "code_test" ? `Your code didn't pass all the tests. ${R.explanation || "Try again!"}` : `Not quite right, but don't worry! ${R.explanation || ""}${K ? "" : " Let's move on to the next question."}`, Le = z.current || { lipsyncLang: "en" };
|
|
8053
|
+
h.current.speakText(q, {
|
|
7919
8054
|
lipsyncLang: Le.lipsyncLang,
|
|
7920
8055
|
onSpeechEnd: () => {
|
|
7921
8056
|
c.current.onCustomAction({
|
|
@@ -7938,7 +8073,7 @@ const yt = Me(({
|
|
|
7938
8073
|
moduleIndex: a.current.currentModuleIndex,
|
|
7939
8074
|
lessonIndex: a.current.currentLessonIndex,
|
|
7940
8075
|
questionIndex: a.current.currentQuestionIndex,
|
|
7941
|
-
isCorrect:
|
|
8076
|
+
isCorrect: k,
|
|
7942
8077
|
hasNextQuestion: a.current.currentQuestionIndex < U - 1,
|
|
7943
8078
|
score: a.current.score,
|
|
7944
8079
|
totalQuestions: a.current.totalQuestions,
|
|
@@ -7955,7 +8090,7 @@ const yt = Me(({
|
|
|
7955
8090
|
console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
|
|
7956
8091
|
return;
|
|
7957
8092
|
}
|
|
7958
|
-
const
|
|
8093
|
+
const k = {
|
|
7959
8094
|
passed: v.passed === !0,
|
|
7960
8095
|
results: v.results || [],
|
|
7961
8096
|
output: v.output || "",
|
|
@@ -7970,9 +8105,9 @@ const yt = Me(({
|
|
|
7970
8105
|
moduleIndex: a.current.currentModuleIndex,
|
|
7971
8106
|
lessonIndex: a.current.currentLessonIndex,
|
|
7972
8107
|
questionIndex: a.current.currentQuestionIndex,
|
|
7973
|
-
testResult:
|
|
8108
|
+
testResult: k,
|
|
7974
8109
|
question: R
|
|
7975
|
-
}), p.current && p.current(
|
|
8110
|
+
}), p.current && p.current(k);
|
|
7976
8111
|
}, [E, P]), ae = T(() => {
|
|
7977
8112
|
if (a.current.currentQuestionIndex > 0) {
|
|
7978
8113
|
a.current.currentQuestionIndex -= 1;
|
|
@@ -7987,23 +8122,23 @@ const yt = Me(({
|
|
|
7987
8122
|
score: a.current.score
|
|
7988
8123
|
});
|
|
7989
8124
|
const R = () => {
|
|
7990
|
-
if (!
|
|
7991
|
-
|
|
7992
|
-
const
|
|
7993
|
-
v.type === "code_test" ?
|
|
7994
|
-
lipsyncLang:
|
|
7995
|
-
}) :
|
|
7996
|
-
lipsyncLang:
|
|
8125
|
+
if (!h.current || !v) return;
|
|
8126
|
+
h.current.setMood("happy"), h.current.setBodyMovement("idle");
|
|
8127
|
+
const k = z.current || { lipsyncLang: "en" };
|
|
8128
|
+
v.type === "code_test" ? h.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
|
|
8129
|
+
lipsyncLang: k.lipsyncLang
|
|
8130
|
+
}) : h.current.speakText(`Going back to: ${v.question}`, {
|
|
8131
|
+
lipsyncLang: k.lipsyncLang
|
|
7997
8132
|
});
|
|
7998
8133
|
};
|
|
7999
|
-
if (
|
|
8134
|
+
if (h.current && h.current.isReady && v)
|
|
8000
8135
|
R();
|
|
8001
8136
|
else if (v) {
|
|
8002
|
-
const
|
|
8003
|
-
|
|
8137
|
+
const k = setInterval(() => {
|
|
8138
|
+
h.current && h.current.isReady && (clearInterval(k), R());
|
|
8004
8139
|
}, 100);
|
|
8005
8140
|
setTimeout(() => {
|
|
8006
|
-
clearInterval(
|
|
8141
|
+
clearInterval(k);
|
|
8007
8142
|
}, 5e3);
|
|
8008
8143
|
}
|
|
8009
8144
|
}
|
|
@@ -8018,7 +8153,7 @@ const yt = Me(({
|
|
|
8018
8153
|
moduleIndex: a.current.currentModuleIndex,
|
|
8019
8154
|
lessonIndex: a.current.currentLessonIndex,
|
|
8020
8155
|
lesson: y()
|
|
8021
|
-
}),
|
|
8156
|
+
}), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
|
|
8022
8157
|
else if (a.current.currentModuleIndex > 0) {
|
|
8023
8158
|
const H = v.modules[a.current.currentModuleIndex - 1];
|
|
8024
8159
|
a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (H?.lessons?.length || 1) - 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, c.current.onCustomAction({
|
|
@@ -8029,28 +8164,28 @@ const yt = Me(({
|
|
|
8029
8164
|
moduleIndex: a.current.currentModuleIndex,
|
|
8030
8165
|
lessonIndex: a.current.currentLessonIndex,
|
|
8031
8166
|
lesson: y()
|
|
8032
|
-
}),
|
|
8167
|
+
}), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
|
|
8033
8168
|
}
|
|
8034
8169
|
}, [y]), ee = T(() => {
|
|
8035
8170
|
a.current.currentModuleIndex = 0, a.current.currentLessonIndex = 0, a.current.currentQuestionIndex = 0, a.current.isTeaching = !1, a.current.isQuestionMode = !1, a.current.lessonCompleted = !1, a.current.curriculumCompleted = !1, a.current.score = 0, a.current.totalQuestions = 0;
|
|
8036
8171
|
}, []), le = T((v) => {
|
|
8037
8172
|
console.log("Avatar is ready!", v);
|
|
8038
|
-
const R = y(),
|
|
8039
|
-
|
|
8173
|
+
const R = y(), k = R?.avatar_script || R?.body;
|
|
8174
|
+
u && k && setTimeout(() => {
|
|
8040
8175
|
d.current && d.current();
|
|
8041
8176
|
}, 10);
|
|
8042
|
-
}, [
|
|
8177
|
+
}, [u, y]);
|
|
8043
8178
|
Xe(() => {
|
|
8044
|
-
d.current = X, g.current =
|
|
8179
|
+
d.current = X, g.current = _, x.current = W, b.current = Z, I.current = oe, B.current = S, p.current = $;
|
|
8045
8180
|
}), Ee(r, () => ({
|
|
8046
8181
|
// Curriculum control methods
|
|
8047
8182
|
startTeaching: X,
|
|
8048
|
-
startQuestions:
|
|
8183
|
+
startQuestions: S,
|
|
8049
8184
|
handleAnswerSelect: $,
|
|
8050
8185
|
handleCodeTestResult: se,
|
|
8051
8186
|
nextQuestion: Z,
|
|
8052
8187
|
previousQuestion: ae,
|
|
8053
|
-
nextLesson:
|
|
8188
|
+
nextLesson: _,
|
|
8054
8189
|
previousLesson: pe,
|
|
8055
8190
|
completeLesson: W,
|
|
8056
8191
|
completeCurriculum: oe,
|
|
@@ -8059,43 +8194,43 @@ const yt = Me(({
|
|
|
8059
8194
|
getCurrentQuestion: () => E(),
|
|
8060
8195
|
getCurrentLesson: () => y(),
|
|
8061
8196
|
// Direct access to avatar ref (always returns current value)
|
|
8062
|
-
getAvatarRef: () =>
|
|
8197
|
+
getAvatarRef: () => h.current,
|
|
8063
8198
|
// Convenience methods that delegate to avatar (always check current ref)
|
|
8064
8199
|
speakText: async (v, R = {}) => {
|
|
8065
|
-
await
|
|
8066
|
-
const
|
|
8067
|
-
|
|
8200
|
+
await h.current?.resumeAudioContext?.();
|
|
8201
|
+
const k = z.current || { lipsyncLang: "en" };
|
|
8202
|
+
h.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang || k.lipsyncLang });
|
|
8068
8203
|
},
|
|
8069
8204
|
resumeAudioContext: async () => {
|
|
8070
|
-
if (
|
|
8071
|
-
return await
|
|
8072
|
-
const v =
|
|
8205
|
+
if (h.current?.resumeAudioContext)
|
|
8206
|
+
return await h.current.resumeAudioContext();
|
|
8207
|
+
const v = h.current?.talkingHead;
|
|
8073
8208
|
if (v?.audioCtx) {
|
|
8074
8209
|
const R = v.audioCtx;
|
|
8075
8210
|
if (R.state === "suspended" || R.state === "interrupted")
|
|
8076
8211
|
try {
|
|
8077
8212
|
await R.resume(), console.log("Audio context resumed via talkingHead");
|
|
8078
|
-
} catch (
|
|
8079
|
-
console.warn("Failed to resume audio context:",
|
|
8213
|
+
} catch (k) {
|
|
8214
|
+
console.warn("Failed to resume audio context:", k);
|
|
8080
8215
|
}
|
|
8081
8216
|
} else
|
|
8082
8217
|
console.warn("Audio context not available yet");
|
|
8083
8218
|
},
|
|
8084
|
-
stopSpeaking: () =>
|
|
8085
|
-
pauseSpeaking: () =>
|
|
8086
|
-
resumeSpeaking: async () => await
|
|
8087
|
-
isPaused: () =>
|
|
8088
|
-
setMood: (v) =>
|
|
8089
|
-
playAnimation: (v, R) =>
|
|
8090
|
-
setBodyMovement: (v) =>
|
|
8091
|
-
setMovementIntensity: (v) =>
|
|
8092
|
-
playRandomDance: () =>
|
|
8093
|
-
playReaction: (v) =>
|
|
8094
|
-
playCelebration: () =>
|
|
8095
|
-
setShowFullAvatar: (v) =>
|
|
8096
|
-
setTimingAdjustment: (v) =>
|
|
8097
|
-
lockAvatarPosition: () =>
|
|
8098
|
-
unlockAvatarPosition: () =>
|
|
8219
|
+
stopSpeaking: () => h.current?.stopSpeaking(),
|
|
8220
|
+
pauseSpeaking: () => h.current?.pauseSpeaking(),
|
|
8221
|
+
resumeSpeaking: async () => await h.current?.resumeSpeaking(),
|
|
8222
|
+
isPaused: () => h.current && typeof h.current.isPaused < "u" ? h.current.isPaused : !1,
|
|
8223
|
+
setMood: (v) => h.current?.setMood(v),
|
|
8224
|
+
playAnimation: (v, R) => h.current?.playAnimation(v, R),
|
|
8225
|
+
setBodyMovement: (v) => h.current?.setBodyMovement(v),
|
|
8226
|
+
setMovementIntensity: (v) => h.current?.setMovementIntensity(v),
|
|
8227
|
+
playRandomDance: () => h.current?.playRandomDance(),
|
|
8228
|
+
playReaction: (v) => h.current?.playReaction(v),
|
|
8229
|
+
playCelebration: () => h.current?.playCelebration(),
|
|
8230
|
+
setShowFullAvatar: (v) => h.current?.setShowFullAvatar(v),
|
|
8231
|
+
setTimingAdjustment: (v) => h.current?.setTimingAdjustment(v),
|
|
8232
|
+
lockAvatarPosition: () => h.current?.lockAvatarPosition(),
|
|
8233
|
+
unlockAvatarPosition: () => h.current?.unlockAvatarPosition(),
|
|
8099
8234
|
// Custom action trigger
|
|
8100
8235
|
triggerCustomAction: (v, R) => {
|
|
8101
8236
|
c.current.onCustomAction({
|
|
@@ -8105,11 +8240,11 @@ const yt = Me(({
|
|
|
8105
8240
|
});
|
|
8106
8241
|
},
|
|
8107
8242
|
// Responsive resize handler
|
|
8108
|
-
handleResize: () =>
|
|
8243
|
+
handleResize: () => h.current?.handleResize(),
|
|
8109
8244
|
// Avatar readiness check (always returns current value)
|
|
8110
|
-
isAvatarReady: () =>
|
|
8111
|
-
}), [X,
|
|
8112
|
-
const
|
|
8245
|
+
isAvatarReady: () => h.current?.isReady || !1
|
|
8246
|
+
}), [X, S, $, se, Z, _, W, oe, ee, E, y]);
|
|
8247
|
+
const O = z.current || {
|
|
8113
8248
|
avatarUrl: "/avatars/brunette.glb",
|
|
8114
8249
|
avatarBody: "F",
|
|
8115
8250
|
mood: "happy",
|
|
@@ -8125,19 +8260,19 @@ const yt = Me(({
|
|
|
8125
8260
|
return /* @__PURE__ */ me("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ me(
|
|
8126
8261
|
Ve,
|
|
8127
8262
|
{
|
|
8128
|
-
ref:
|
|
8129
|
-
avatarUrl:
|
|
8130
|
-
avatarBody:
|
|
8131
|
-
mood:
|
|
8132
|
-
ttsLang:
|
|
8133
|
-
ttsService:
|
|
8134
|
-
ttsVoice:
|
|
8135
|
-
ttsApiKey:
|
|
8136
|
-
bodyMovement:
|
|
8137
|
-
movementIntensity:
|
|
8138
|
-
showFullAvatar:
|
|
8263
|
+
ref: h,
|
|
8264
|
+
avatarUrl: O.avatarUrl,
|
|
8265
|
+
avatarBody: O.avatarBody,
|
|
8266
|
+
mood: O.mood,
|
|
8267
|
+
ttsLang: O.ttsLang,
|
|
8268
|
+
ttsService: O.ttsService,
|
|
8269
|
+
ttsVoice: O.ttsVoice,
|
|
8270
|
+
ttsApiKey: O.ttsApiKey,
|
|
8271
|
+
bodyMovement: O.bodyMovement,
|
|
8272
|
+
movementIntensity: O.movementIntensity,
|
|
8273
|
+
showFullAvatar: O.showFullAvatar,
|
|
8139
8274
|
cameraView: "upper",
|
|
8140
|
-
animations:
|
|
8275
|
+
animations: O.animations,
|
|
8141
8276
|
onReady: le,
|
|
8142
8277
|
onLoading: () => {
|
|
8143
8278
|
},
|
|
@@ -8260,6 +8395,6 @@ export {
|
|
|
8260
8395
|
Ge as animations,
|
|
8261
8396
|
Fe as getActiveTTSConfig,
|
|
8262
8397
|
wt as getAnimation,
|
|
8263
|
-
|
|
8398
|
+
kt as getVoiceOptions,
|
|
8264
8399
|
zt as hasAnimation
|
|
8265
8400
|
};
|