@sage-rsc/talking-head-react 1.1.1 → 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 +655 -508
- package/package.json +1 -1
- package/src/lib/talkinghead.mjs +251 -10
package/dist/index.js
CHANGED
|
@@ -6,15 +6,15 @@ import { GLTFLoader as je } from "three/addons/loaders/GLTFLoader.js";
|
|
|
6
6
|
import { DRACOLoader as Qe } from "three/addons/loaders/DRACOLoader.js";
|
|
7
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
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(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(
|
|
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,14 +2622,14 @@ 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
|
-
}, Q = new f.Quaternion(), V = new f.Euler(), ve = new f.Vector3(),
|
|
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();
|
|
2634
2634
|
new f.Matrix4();
|
|
2635
2635
|
new f.Vector3();
|
|
@@ -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) *
|
|
4232
|
-
l.setXYZ(g, x, b,
|
|
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
|
+
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
|
});
|
|
@@ -4985,11 +4985,11 @@ class Be {
|
|
|
4985
4985
|
else if (l.hasOwnProperty("alt")) {
|
|
4986
4986
|
let r = l.alt[0];
|
|
4987
4987
|
if (l.alt.length > 1) {
|
|
4988
|
-
const
|
|
4988
|
+
const h = Math.random();
|
|
4989
4989
|
let a = 0;
|
|
4990
4990
|
for (let c = 0; c < l.alt.length; c++) {
|
|
4991
4991
|
let d = this.valueFn(l.alt[c].p);
|
|
4992
|
-
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) {
|
|
4993
4993
|
r = l.alt[c];
|
|
4994
4994
|
break;
|
|
4995
4995
|
}
|
|
@@ -4999,19 +4999,19 @@ class Be {
|
|
|
4999
4999
|
continue;
|
|
5000
5000
|
} else
|
|
5001
5001
|
break;
|
|
5002
|
-
let
|
|
5003
|
-
if (Array.isArray(
|
|
5004
|
-
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) => {
|
|
5005
5005
|
let a = this.valueFn(r);
|
|
5006
|
-
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;
|
|
5007
5007
|
});
|
|
5008
5008
|
else {
|
|
5009
|
-
let r = Object.values(l.vs).reduce((
|
|
5009
|
+
let r = Object.values(l.vs).reduce((h, a) => a.length > h ? a.length : h, 0);
|
|
5010
5010
|
o.ts = Array(r + 1).fill(0);
|
|
5011
5011
|
}
|
|
5012
|
-
s ? o.ts = o.ts.map((r) =>
|
|
5013
|
-
for (let [r,
|
|
5014
|
-
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));
|
|
5015
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];
|
|
5016
5016
|
}
|
|
5017
5017
|
for (let r of Object.keys(o.vs))
|
|
@@ -5093,8 +5093,8 @@ class Be {
|
|
|
5093
5093
|
if (this.isSpeaking)
|
|
5094
5094
|
for (l = 0, this.audioAnalyzerNode.getByteFrequencyData(this.volumeFrequencyData), n = 2, s = 10; n < s; n++)
|
|
5095
5095
|
this.volumeFrequencyData[n] > l && (l = this.volumeFrequencyData[n]);
|
|
5096
|
-
let
|
|
5097
|
-
const
|
|
5096
|
+
let u = null, r = null;
|
|
5097
|
+
const h = [];
|
|
5098
5098
|
for (n = 0, s = this.animQueue.length; n < s; n++) {
|
|
5099
5099
|
const a = this.animQueue[n];
|
|
5100
5100
|
if (!(!a || !a.ts || !a.ts.length || this.animClock < a.ts[0])) {
|
|
@@ -5121,12 +5121,12 @@ class Be {
|
|
|
5121
5121
|
g.newvalue *= 1 + l / 255 - 0.5;
|
|
5122
5122
|
}
|
|
5123
5123
|
g.needsUpdate = !0;
|
|
5124
|
-
} 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);
|
|
5125
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;
|
|
5126
5126
|
}
|
|
5127
5127
|
}
|
|
5128
|
-
for (let a = 0, c =
|
|
5129
|
-
switch (i =
|
|
5128
|
+
for (let a = 0, c = h.length; a < c; a++)
|
|
5129
|
+
switch (i = h[a].val, h[a].mt) {
|
|
5130
5130
|
case "speak":
|
|
5131
5131
|
this.speakText(i);
|
|
5132
5132
|
break;
|
|
@@ -5172,7 +5172,7 @@ class Be {
|
|
|
5172
5172
|
}, i.x ? new f.Vector3(i.x, i.y, i.z) : null, !0, i.d);
|
|
5173
5173
|
break;
|
|
5174
5174
|
}
|
|
5175
|
-
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({
|
|
5176
5176
|
name: "headmove",
|
|
5177
5177
|
dt: [[1e3, 2e3], [1e3, 2e3, 1, 2], [1e3, 2e3], [1e3, 2e3, 1, 2]],
|
|
5178
5178
|
vs: {
|
|
@@ -5193,7 +5193,7 @@ class Be {
|
|
|
5193
5193
|
eyeLookOutRight: [null, 0],
|
|
5194
5194
|
eyeContact: [0]
|
|
5195
5195
|
}
|
|
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) &&
|
|
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)
|
|
5197
5197
|
this.stats && this.stats.end();
|
|
5198
5198
|
else {
|
|
5199
5199
|
if (this.cameraClock !== null && this.cameraClock < 1e3) {
|
|
@@ -5260,24 +5260,24 @@ class Be {
|
|
|
5260
5260
|
*/
|
|
5261
5261
|
speakText(t, e = null, n = null, i = null) {
|
|
5262
5262
|
e = e || {};
|
|
5263
|
-
const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, l = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug,
|
|
5264
|
-
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 = [];
|
|
5265
5265
|
const x = Array.from(this.segmenter.segment(t), (b) => b.segment);
|
|
5266
5266
|
for (let b = 0; b < x.length; b++) {
|
|
5267
|
-
const
|
|
5267
|
+
const I = b === x.length - 1, B = x[b].match(l);
|
|
5268
5268
|
let p = x[b].match(s);
|
|
5269
|
-
const M = x[b].match(
|
|
5270
|
-
if (p && !
|
|
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({
|
|
5271
5271
|
mark: c,
|
|
5272
5272
|
word: a
|
|
5273
|
-
})),
|
|
5273
|
+
})), h.length && (g.push({
|
|
5274
5274
|
mark: c,
|
|
5275
5275
|
template: { name: "subtitles" },
|
|
5276
5276
|
ts: [0],
|
|
5277
5277
|
vs: {
|
|
5278
|
-
subtitles: [
|
|
5278
|
+
subtitles: [h]
|
|
5279
5279
|
}
|
|
5280
|
-
}),
|
|
5280
|
+
}), h = ""), a.length)) {
|
|
5281
5281
|
const y = this.lipsyncWordsToVisemes(a, r);
|
|
5282
5282
|
if (y && y.visemes && y.visemes.length) {
|
|
5283
5283
|
const E = y.times[y.visemes.length - 1] + y.durations[y.visemes.length - 1];
|
|
@@ -5293,8 +5293,8 @@ class Be {
|
|
|
5293
5293
|
}
|
|
5294
5294
|
a = "", c++;
|
|
5295
5295
|
}
|
|
5296
|
-
if (p ||
|
|
5297
|
-
if (d.length ||
|
|
5296
|
+
if (p || I) {
|
|
5297
|
+
if (d.length || I && g.length) {
|
|
5298
5298
|
const y = {
|
|
5299
5299
|
anim: g
|
|
5300
5300
|
};
|
|
@@ -5383,25 +5383,25 @@ class Be {
|
|
|
5383
5383
|
if (t.words) {
|
|
5384
5384
|
let o = [];
|
|
5385
5385
|
for (let l = 0; l < t.words.length; l++) {
|
|
5386
|
-
const
|
|
5387
|
-
let
|
|
5388
|
-
if (
|
|
5386
|
+
const u = t.words[l], r = t.wtimes[l];
|
|
5387
|
+
let h = t.wdurations[l];
|
|
5388
|
+
if (u.length && (n && o.push({
|
|
5389
5389
|
template: { name: "subtitles" },
|
|
5390
5390
|
ts: [r],
|
|
5391
5391
|
vs: {
|
|
5392
|
-
subtitles: [" " +
|
|
5392
|
+
subtitles: [" " + u]
|
|
5393
5393
|
}
|
|
5394
5394
|
}), !t.visemes)) {
|
|
5395
|
-
const a = this.lipsyncPreProcessText(
|
|
5395
|
+
const a = this.lipsyncPreProcessText(u, i), c = this.lipsyncWordsToVisemes(a, i);
|
|
5396
5396
|
if (c && c.visemes && c.visemes.length) {
|
|
5397
|
-
const d = c.times[c.visemes.length - 1] + c.durations[c.visemes.length - 1], g = Math.min(
|
|
5398
|
-
let x = 0.6 + this.convertRange(g, [0,
|
|
5399
|
-
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)
|
|
5400
5400
|
for (let b = 0; b < c.visemes.length; b++) {
|
|
5401
|
-
const
|
|
5401
|
+
const I = r + c.times[b] / d * h, B = c.durations[b] / d * h;
|
|
5402
5402
|
o.push({
|
|
5403
5403
|
template: { name: "viseme" },
|
|
5404
|
-
ts: [
|
|
5404
|
+
ts: [I - Math.min(60, 2 * B / 3), I + Math.min(25, B / 2), I + B + Math.min(60, B / 2)],
|
|
5405
5405
|
vs: {
|
|
5406
5406
|
["viseme_" + c.visemes[b]]: [null, c.visemes[b] === "PP" || c.visemes[b] === "FF" ? 0.9 : x, 0]
|
|
5407
5407
|
}
|
|
@@ -5412,22 +5412,22 @@ class Be {
|
|
|
5412
5412
|
}
|
|
5413
5413
|
if (t.visemes)
|
|
5414
5414
|
for (let l = 0; l < t.visemes.length; l++) {
|
|
5415
|
-
const
|
|
5415
|
+
const u = t.visemes[l], r = t.vtimes[l], h = t.vdurations[l];
|
|
5416
5416
|
o.push({
|
|
5417
5417
|
template: { name: "viseme" },
|
|
5418
|
-
ts: [r - 2 *
|
|
5418
|
+
ts: [r - 2 * h / 3, r + h / 2, r + h + h / 2],
|
|
5419
5419
|
vs: {
|
|
5420
|
-
["viseme_" +
|
|
5420
|
+
["viseme_" + u]: [null, u === "PP" || u === "FF" ? 0.9 : 0.6, 0]
|
|
5421
5421
|
}
|
|
5422
5422
|
});
|
|
5423
5423
|
}
|
|
5424
5424
|
if (t.markers)
|
|
5425
5425
|
for (let l = 0; l < t.markers.length; l++) {
|
|
5426
|
-
const
|
|
5426
|
+
const u = t.markers[l], r = t.mtimes[l];
|
|
5427
5427
|
o.push({
|
|
5428
5428
|
template: { name: "markers" },
|
|
5429
5429
|
ts: [r],
|
|
5430
|
-
vs: { function: [
|
|
5430
|
+
vs: { function: [u] }
|
|
5431
5431
|
});
|
|
5432
5432
|
}
|
|
5433
5433
|
o.length && (s.anim = o);
|
|
@@ -5447,7 +5447,7 @@ class Be {
|
|
|
5447
5447
|
if (this.isAudioPlaying = !0, this.audioPlaylist.length) {
|
|
5448
5448
|
const e = this.audioPlaylist.shift();
|
|
5449
5449
|
if (this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
|
|
5450
|
-
const s = this.audioCtx.resume(), o = new Promise((l,
|
|
5450
|
+
const s = this.audioCtx.resume(), o = new Promise((l, u) => setTimeout(() => u("p2"), 1e3));
|
|
5451
5451
|
try {
|
|
5452
5452
|
await Promise.race([s, o]);
|
|
5453
5453
|
} catch {
|
|
@@ -5479,11 +5479,11 @@ class Be {
|
|
|
5479
5479
|
*/
|
|
5480
5480
|
async synthesizeWithBrowserTTS(t) {
|
|
5481
5481
|
return new Promise((e, n) => {
|
|
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,
|
|
5483
|
-
s.lang = o, s.rate = Math.max(0.1, Math.min(10, l)), s.pitch = Math.max(0, Math.min(2,
|
|
5484
|
-
const
|
|
5485
|
-
if (a &&
|
|
5486
|
-
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);
|
|
5487
5487
|
p && (s.voice = p);
|
|
5488
5488
|
}
|
|
5489
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);
|
|
@@ -5495,12 +5495,12 @@ class Be {
|
|
|
5495
5495
|
hasVisemes: b && b.visemes && b.visemes.length > 0,
|
|
5496
5496
|
estimatedDuration: c
|
|
5497
5497
|
});
|
|
5498
|
-
const
|
|
5498
|
+
const I = [];
|
|
5499
5499
|
if (b && b.visemes && b.visemes.length > 0) {
|
|
5500
5500
|
const p = b.times[b.visemes.length - 1] + b.durations[b.visemes.length - 1];
|
|
5501
5501
|
for (let M = 0; M < b.visemes.length; M++) {
|
|
5502
5502
|
const z = b.visemes[M], y = b.times[M] / p, E = b.durations[M] / p, P = y * c, W = E * c;
|
|
5503
|
-
|
|
5503
|
+
I.push({
|
|
5504
5504
|
template: { name: "viseme" },
|
|
5505
5505
|
ts: [P - Math.min(60, 2 * W / 3), P + Math.min(25, W / 2), P + W + Math.min(60, W / 2)],
|
|
5506
5506
|
vs: {
|
|
@@ -5509,7 +5509,7 @@ class Be {
|
|
|
5509
5509
|
});
|
|
5510
5510
|
}
|
|
5511
5511
|
}
|
|
5512
|
-
const B = [...t.anim, ...
|
|
5512
|
+
const B = [...t.anim, ...I];
|
|
5513
5513
|
this.audioPlaylist.push({ anim: B, audio: d }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
|
|
5514
5514
|
e();
|
|
5515
5515
|
}, s.onerror = (p) => {
|
|
@@ -5544,15 +5544,15 @@ class Be {
|
|
|
5544
5544
|
throw new Error(`ElevenLabs TTS error: ${s.status} ${s.statusText}`);
|
|
5545
5545
|
const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
|
|
5546
5546
|
console.log("Using text-based lip-sync for debugging...");
|
|
5547
|
-
const
|
|
5547
|
+
const u = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
|
|
5548
5548
|
let r;
|
|
5549
5549
|
try {
|
|
5550
5550
|
console.log("Lip-sync modules available:", {
|
|
5551
5551
|
hasLipsync: !!this.lipsync,
|
|
5552
5552
|
lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
|
|
5553
|
-
lipsyncLang:
|
|
5553
|
+
lipsyncLang: u
|
|
5554
5554
|
});
|
|
5555
|
-
const c = this.lipsyncPreProcessText(e,
|
|
5555
|
+
const c = this.lipsyncPreProcessText(e, u), d = this.lipsyncWordsToVisemes(c, u);
|
|
5556
5556
|
if (console.log("Lip-sync data:", {
|
|
5557
5557
|
processedText: c,
|
|
5558
5558
|
lipsyncData: d,
|
|
@@ -5577,8 +5577,8 @@ class Be {
|
|
|
5577
5577
|
const d = e.toLowerCase().split(/\s+/), g = [];
|
|
5578
5578
|
for (const x of d)
|
|
5579
5579
|
for (const b of x) {
|
|
5580
|
-
let
|
|
5581
|
-
"aeiou".includes(b) ?
|
|
5580
|
+
let I = "aa";
|
|
5581
|
+
"aeiou".includes(b) ? I = "aa" : "bp".includes(b) ? I = "PP" : "fv".includes(b) ? I = "FF" : "st".includes(b) ? I = "SS" : "dln".includes(b) ? I = "DD" : "kg".includes(b) ? I = "kk" : "rw".includes(b) && (I = "RR"), g.push(I);
|
|
5582
5582
|
}
|
|
5583
5583
|
r = {
|
|
5584
5584
|
visemes: g.map((x, b) => ({
|
|
@@ -5605,12 +5605,12 @@ class Be {
|
|
|
5605
5605
|
visemes: r.visemes ? r.visemes.slice(0, 3) : []
|
|
5606
5606
|
// Show first 3 visemes for debugging
|
|
5607
5607
|
});
|
|
5608
|
-
const
|
|
5608
|
+
const h = [];
|
|
5609
5609
|
if (r.visemes && r.visemes.length > 0) {
|
|
5610
5610
|
console.log("ElevenLabs: Generating lip-sync animation from", r.visemes.length, "visemes");
|
|
5611
5611
|
for (let c = 0; c < r.visemes.length; c++) {
|
|
5612
5612
|
const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, b = d.intensity;
|
|
5613
|
-
|
|
5613
|
+
h.push({
|
|
5614
5614
|
template: { name: "viseme" },
|
|
5615
5615
|
ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
|
|
5616
5616
|
vs: {
|
|
@@ -5618,11 +5618,11 @@ class Be {
|
|
|
5618
5618
|
}
|
|
5619
5619
|
});
|
|
5620
5620
|
}
|
|
5621
|
-
console.log("ElevenLabs: Generated",
|
|
5621
|
+
console.log("ElevenLabs: Generated", h.length, "lip-sync animation frames");
|
|
5622
5622
|
} else
|
|
5623
5623
|
console.warn("ElevenLabs: No visemes available for lip-sync animation");
|
|
5624
|
-
const a = [...t.anim, ...
|
|
5625
|
-
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();
|
|
5626
5626
|
}
|
|
5627
5627
|
/**
|
|
5628
5628
|
* Synthesize speech using Deepgram Aura-2 TTS
|
|
@@ -5642,15 +5642,15 @@ class Be {
|
|
|
5642
5642
|
throw new Error(`Deepgram TTS error: ${s.status} ${s.statusText}`);
|
|
5643
5643
|
const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
|
|
5644
5644
|
console.log("Using text-based lip-sync for Deepgram...");
|
|
5645
|
-
const
|
|
5645
|
+
const u = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
|
|
5646
5646
|
let r;
|
|
5647
5647
|
try {
|
|
5648
5648
|
console.log("Lip-sync modules available:", {
|
|
5649
5649
|
hasLipsync: !!this.lipsync,
|
|
5650
5650
|
lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
|
|
5651
|
-
lipsyncLang:
|
|
5651
|
+
lipsyncLang: u
|
|
5652
5652
|
});
|
|
5653
|
-
const c = this.lipsyncPreProcessText(e,
|
|
5653
|
+
const c = this.lipsyncPreProcessText(e, u), d = this.lipsyncWordsToVisemes(c, u);
|
|
5654
5654
|
if (console.log("Lip-sync data:", {
|
|
5655
5655
|
processedText: c,
|
|
5656
5656
|
lipsyncData: d,
|
|
@@ -5675,8 +5675,8 @@ class Be {
|
|
|
5675
5675
|
const d = e.toLowerCase().split(/\s+/), g = [];
|
|
5676
5676
|
for (const x of d)
|
|
5677
5677
|
for (const b of x) {
|
|
5678
|
-
let
|
|
5679
|
-
"aeiou".includes(b) ?
|
|
5678
|
+
let I = "aa";
|
|
5679
|
+
"aeiou".includes(b) ? I = "aa" : "bp".includes(b) ? I = "PP" : "fv".includes(b) ? I = "FF" : "st".includes(b) ? I = "SS" : "dln".includes(b) ? I = "DD" : "kg".includes(b) ? I = "kk" : "rw".includes(b) && (I = "RR"), g.push(I);
|
|
5680
5680
|
}
|
|
5681
5681
|
r = {
|
|
5682
5682
|
visemes: g.map((x, b) => ({
|
|
@@ -5703,12 +5703,12 @@ class Be {
|
|
|
5703
5703
|
visemes: r.visemes ? r.visemes.slice(0, 3) : []
|
|
5704
5704
|
// Show first 3 visemes for debugging
|
|
5705
5705
|
});
|
|
5706
|
-
const
|
|
5706
|
+
const h = [];
|
|
5707
5707
|
if (r.visemes && r.visemes.length > 0) {
|
|
5708
5708
|
console.log("Deepgram: Generating lip-sync animation from", r.visemes.length, "visemes");
|
|
5709
5709
|
for (let c = 0; c < r.visemes.length; c++) {
|
|
5710
5710
|
const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, b = d.intensity;
|
|
5711
|
-
|
|
5711
|
+
h.push({
|
|
5712
5712
|
template: { name: "viseme" },
|
|
5713
5713
|
ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
|
|
5714
5714
|
vs: {
|
|
@@ -5716,11 +5716,11 @@ class Be {
|
|
|
5716
5716
|
}
|
|
5717
5717
|
});
|
|
5718
5718
|
}
|
|
5719
|
-
console.log("Deepgram: Generated",
|
|
5719
|
+
console.log("Deepgram: Generated", h.length, "lip-sync animation frames");
|
|
5720
5720
|
} else
|
|
5721
5721
|
console.warn("Deepgram: No visemes available for lip-sync animation");
|
|
5722
|
-
const a = [...t.anim, ...
|
|
5723
|
-
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();
|
|
5724
5724
|
}
|
|
5725
5725
|
/**
|
|
5726
5726
|
* Synthesize speech using Azure TTS
|
|
@@ -5746,20 +5746,20 @@ class Be {
|
|
|
5746
5746
|
throw new Error(`Azure TTS error: ${s.status} ${s.statusText}`);
|
|
5747
5747
|
const o = await s.arrayBuffer(), l = await this.audioCtx.decodeAudioData(o);
|
|
5748
5748
|
console.log("Analyzing audio for precise lip-sync...");
|
|
5749
|
-
const
|
|
5749
|
+
const u = await this.audioAnalyzer.analyzeAudio(l, e);
|
|
5750
5750
|
console.log("Azure TTS Audio Analysis:", {
|
|
5751
5751
|
text: e,
|
|
5752
5752
|
audioDuration: l.duration,
|
|
5753
|
-
visemeCount:
|
|
5754
|
-
wordCount:
|
|
5753
|
+
visemeCount: u.visemes.length,
|
|
5754
|
+
wordCount: u.words.length,
|
|
5755
5755
|
features: {
|
|
5756
|
-
onsets:
|
|
5757
|
-
boundaries:
|
|
5756
|
+
onsets: u.features.onsets.length,
|
|
5757
|
+
boundaries: u.features.phonemeBoundaries.length
|
|
5758
5758
|
}
|
|
5759
5759
|
});
|
|
5760
5760
|
const r = [];
|
|
5761
|
-
for (let a = 0; a <
|
|
5762
|
-
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;
|
|
5763
5763
|
r.push({
|
|
5764
5764
|
template: { name: "viseme" },
|
|
5765
5765
|
ts: [d - Math.min(60, 2 * g / 3), d + Math.min(25, g / 2), d + g + Math.min(60, g / 2)],
|
|
@@ -5768,8 +5768,8 @@ class Be {
|
|
|
5768
5768
|
}
|
|
5769
5769
|
});
|
|
5770
5770
|
}
|
|
5771
|
-
const
|
|
5772
|
-
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();
|
|
5773
5773
|
}
|
|
5774
5774
|
/**
|
|
5775
5775
|
* Synthesize speech using external TTS service (Google Cloud, etc.)
|
|
@@ -5808,24 +5808,24 @@ class Be {
|
|
|
5808
5808
|
if (i.status === 200 && s && s.audioContent) {
|
|
5809
5809
|
const o = this.b64ToArrayBuffer(s.audioContent), l = await this.audioCtx.decodeAudioData(o);
|
|
5810
5810
|
this.speakWithHands();
|
|
5811
|
-
const
|
|
5811
|
+
const u = [0];
|
|
5812
5812
|
let r = 0;
|
|
5813
5813
|
t.text.forEach((c, d) => {
|
|
5814
5814
|
if (d > 0) {
|
|
5815
|
-
let g =
|
|
5816
|
-
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);
|
|
5817
5817
|
}
|
|
5818
5818
|
});
|
|
5819
|
-
const
|
|
5820
|
-
|
|
5819
|
+
const h = [{ mark: 0, time: 0 }];
|
|
5820
|
+
u.forEach((c, d) => {
|
|
5821
5821
|
if (d > 0) {
|
|
5822
|
-
let g = c -
|
|
5823
|
-
|
|
5822
|
+
let g = c - u[d - 1];
|
|
5823
|
+
h[d - 1].duration = g, h.push({ mark: d, time: c });
|
|
5824
5824
|
}
|
|
5825
5825
|
});
|
|
5826
5826
|
let a = 1e3 * l.duration;
|
|
5827
|
-
a > this.opt.ttsTrimEnd && (a = a - this.opt.ttsTrimEnd),
|
|
5828
|
-
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];
|
|
5829
5829
|
if (d)
|
|
5830
5830
|
for (let g = 0; g < c.ts.length; g++)
|
|
5831
5831
|
c.ts[g] = d.time + c.ts[g] * d.duration + this.opt.ttsTrimStart;
|
|
@@ -5908,10 +5908,10 @@ class Be {
|
|
|
5908
5908
|
}
|
|
5909
5909
|
if (!this.workletLoaded)
|
|
5910
5910
|
try {
|
|
5911
|
-
const l = this.audioCtx.audioWorklet.addModule(dt.href),
|
|
5912
|
-
(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)
|
|
5913
5913
|
);
|
|
5914
|
-
await Promise.race([l,
|
|
5914
|
+
await Promise.race([l, u]), this.workletLoaded = !0;
|
|
5915
5915
|
} catch (l) {
|
|
5916
5916
|
throw console.error("Failed to load audio worklet:", l), new Error("Failed to initialize streaming speech");
|
|
5917
5917
|
}
|
|
@@ -5924,8 +5924,8 @@ class Be {
|
|
|
5924
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))
|
|
5925
5925
|
try {
|
|
5926
5926
|
this.onAudioStart?.();
|
|
5927
|
-
} catch (
|
|
5928
|
-
console.error(
|
|
5927
|
+
} catch (u) {
|
|
5928
|
+
console.error(u);
|
|
5929
5929
|
}
|
|
5930
5930
|
if (l.data.type === "playback-ended" && (this._streamPause(), this.onAudioEnd))
|
|
5931
5931
|
try {
|
|
@@ -5945,9 +5945,9 @@ class Be {
|
|
|
5945
5945
|
} catch {
|
|
5946
5946
|
}
|
|
5947
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") {
|
|
5948
|
-
const l = this.audioCtx.resume(),
|
|
5948
|
+
const l = this.audioCtx.resume(), u = new Promise((r, h) => setTimeout(() => h("p2"), 1e3));
|
|
5949
5949
|
try {
|
|
5950
|
-
await Promise.race([l,
|
|
5950
|
+
await Promise.race([l, u]);
|
|
5951
5951
|
} catch {
|
|
5952
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.");
|
|
5953
5953
|
return;
|
|
@@ -6044,13 +6044,13 @@ class Be {
|
|
|
6044
6044
|
subtitles: [" " + i]
|
|
6045
6045
|
}
|
|
6046
6046
|
}), this.streamLipsyncType == "words")) {
|
|
6047
|
-
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);
|
|
6048
6048
|
if (r && r.visemes && r.visemes.length) {
|
|
6049
|
-
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));
|
|
6050
6050
|
let c = 0.6 + this.convertRange(a, [0, o], [0, 0.4]);
|
|
6051
|
-
if (o = Math.min(o, r.visemes.length * 200),
|
|
6051
|
+
if (o = Math.min(o, r.visemes.length * 200), h > 0)
|
|
6052
6052
|
for (let d = 0; d < r.visemes.length; d++) {
|
|
6053
|
-
const g = e + s + r.times[d] /
|
|
6053
|
+
const g = e + s + r.times[d] / h * o, x = r.durations[d] / h * o;
|
|
6054
6054
|
this.animQueue.push({
|
|
6055
6055
|
template: { name: "viseme" },
|
|
6056
6056
|
ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
|
|
@@ -6146,7 +6146,7 @@ class Be {
|
|
|
6146
6146
|
*/
|
|
6147
6147
|
lookAtCamera(t) {
|
|
6148
6148
|
let e;
|
|
6149
|
-
if (this.speakTo && (e = new f.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld),
|
|
6149
|
+
if (this.speakTo && (e = new f.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(ve, Re).divideScalar(2)) : this.speakTo.isObject3D ? this.speakTo.getWorldPosition(e) : this.speakTo.isVector3 ? e.set(this.speakTo) : this.speakTo.x && this.speakTo.y && this.speakTo.z && e.set(this.speakTo.x, this.speakTo.y, this.speakTo.z)), !e) {
|
|
6150
6150
|
if (this.avatar.hasOwnProperty("avatarIgnoreCamera")) {
|
|
6151
6151
|
if (this.avatar.avatarIgnoreCamera) {
|
|
6152
6152
|
this.lookAhead(t);
|
|
@@ -6159,14 +6159,14 @@ class Be {
|
|
|
6159
6159
|
this.lookAt(null, null, t);
|
|
6160
6160
|
return;
|
|
6161
6161
|
}
|
|
6162
|
-
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld),
|
|
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"]);
|
|
6163
6163
|
const n = new f.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
|
|
6164
6164
|
V.set(s, i, 0, "YXZ");
|
|
6165
|
-
const l = new f.Quaternion().setFromEuler(V),
|
|
6166
|
-
V.setFromQuaternion(
|
|
6167
|
-
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;
|
|
6168
6168
|
if (t) {
|
|
6169
|
-
let x = this.animQueue.findIndex((
|
|
6169
|
+
let x = this.animQueue.findIndex((I) => I.template.name === "lookat");
|
|
6170
6170
|
x !== -1 && this.animQueue.splice(x, 1);
|
|
6171
6171
|
const b = {
|
|
6172
6172
|
name: "lookat",
|
|
@@ -6198,10 +6198,10 @@ class Be {
|
|
|
6198
6198
|
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0);
|
|
6199
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);
|
|
6200
6200
|
l.project(this.camera);
|
|
6201
|
-
let
|
|
6202
|
-
t === null && (t =
|
|
6203
|
-
let
|
|
6204
|
-
b = Math.min(0.6, Math.max(-0.3, b)),
|
|
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;
|
|
6204
|
+
b = Math.min(0.6, Math.max(-0.3, b)), I = Math.min(0.8, Math.max(-0.8, I));
|
|
6205
6205
|
let B = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
|
|
6206
6206
|
if (n) {
|
|
6207
6207
|
let M = this.animQueue.findIndex((y) => y.template.name === "lookat");
|
|
@@ -6211,7 +6211,7 @@ class Be {
|
|
|
6211
6211
|
dt: [750, n],
|
|
6212
6212
|
vs: {
|
|
6213
6213
|
bodyRotateX: [b + B],
|
|
6214
|
-
bodyRotateY: [
|
|
6214
|
+
bodyRotateY: [I + p],
|
|
6215
6215
|
eyesRotateX: [-3 * B + 0.1],
|
|
6216
6216
|
eyesRotateY: [-5 * p],
|
|
6217
6217
|
browInnerUp: [[0, 0.7]],
|
|
@@ -6239,10 +6239,10 @@ class Be {
|
|
|
6239
6239
|
s.setFromCamera(i, this.camera);
|
|
6240
6240
|
const o = s.intersectObject(this.armature);
|
|
6241
6241
|
if (o.length > 0) {
|
|
6242
|
-
const l = o[0].point,
|
|
6243
|
-
this.objectLeftArm.getWorldPosition(
|
|
6244
|
-
const
|
|
6245
|
-
|
|
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({
|
|
6246
6246
|
iterations: 20,
|
|
6247
6247
|
root: "LeftShoulder",
|
|
6248
6248
|
effector: "LeftHandMiddle1",
|
|
@@ -6263,8 +6263,8 @@ class Be {
|
|
|
6263
6263
|
}, l, !1, 1e3), this.setValue("handFistRight", 0));
|
|
6264
6264
|
} else
|
|
6265
6265
|
["LeftArm", "LeftForeArm", "LeftHand", "RightArm", "RightForeArm", "RightHand"].forEach((l) => {
|
|
6266
|
-
let
|
|
6267
|
-
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;
|
|
6268
6268
|
});
|
|
6269
6269
|
return o.length > 0;
|
|
6270
6270
|
}
|
|
@@ -6390,37 +6390,184 @@ class Be {
|
|
|
6390
6390
|
(e.isBone || e.type === "Bone") && t.add(e.name);
|
|
6391
6391
|
}), t;
|
|
6392
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
|
+
}
|
|
6393
6527
|
/**
|
|
6394
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
|
|
6395
6530
|
* @param {THREE.AnimationClip} clip - Animation clip to filter
|
|
6396
6531
|
* @param {Set<string>} availableBones - Set of available bone names
|
|
6397
|
-
* @returns {THREE.AnimationClip} Filtered animation clip
|
|
6532
|
+
* @returns {THREE.AnimationClip} Filtered animation clip with mapped bone names
|
|
6398
6533
|
*/
|
|
6399
6534
|
filterAnimationTracks(t, e) {
|
|
6400
|
-
const n = [], i = /* @__PURE__ */ new Set();
|
|
6401
|
-
return t.tracks.forEach((
|
|
6402
|
-
const l =
|
|
6403
|
-
|
|
6404
|
-
|
|
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);
|
|
6405
6552
|
}
|
|
6406
6553
|
async playAnimation(t, e = null, n = 10, i = 0, s = 0.01, o = !1) {
|
|
6407
6554
|
if (!this.armature) return;
|
|
6408
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));
|
|
6409
|
-
let l = this.animClips.find((
|
|
6556
|
+
let l = this.animClips.find((u) => u.url === t + "-" + i);
|
|
6410
6557
|
if (l) {
|
|
6411
|
-
let
|
|
6412
|
-
|
|
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) => {
|
|
6413
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;
|
|
6414
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 });
|
|
6415
|
-
const r = Math.ceil(n / l.clip.duration),
|
|
6416
|
-
|
|
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;
|
|
6417
6564
|
try {
|
|
6418
|
-
|
|
6565
|
+
h.fadeIn(0.5).play(), console.log("FBX animation started successfully:", t);
|
|
6419
6566
|
} catch (a) {
|
|
6420
6567
|
console.warn("FBX animation failed to start:", a), this.stopAnimation();
|
|
6421
6568
|
return;
|
|
6422
6569
|
}
|
|
6423
|
-
if (
|
|
6570
|
+
if (h.getClip().tracks.length === 0) {
|
|
6424
6571
|
console.warn("FBX animation has no valid tracks, stopping"), this.stopAnimation();
|
|
6425
6572
|
return;
|
|
6426
6573
|
}
|
|
@@ -6439,10 +6586,10 @@ class Be {
|
|
|
6439
6586
|
} catch (c) {
|
|
6440
6587
|
console.warn(`Could not verify file existence for ${t}, attempting to load anyway:`, c);
|
|
6441
6588
|
}
|
|
6442
|
-
const
|
|
6589
|
+
const h = new De();
|
|
6443
6590
|
let a;
|
|
6444
6591
|
try {
|
|
6445
|
-
a = await
|
|
6592
|
+
a = await h.loadAsync(t, e);
|
|
6446
6593
|
} catch (c) {
|
|
6447
6594
|
console.error(`Failed to load FBX animation from ${t}:`, c), console.error("Error details:", {
|
|
6448
6595
|
message: c.message,
|
|
@@ -6471,14 +6618,14 @@ class Be {
|
|
|
6471
6618
|
}
|
|
6472
6619
|
c = g;
|
|
6473
6620
|
const x = {};
|
|
6474
|
-
c.tracks.forEach((
|
|
6475
|
-
|
|
6476
|
-
const B =
|
|
6621
|
+
c.tracks.forEach((I) => {
|
|
6622
|
+
I.name = I.name.replaceAll("mixamorig", "");
|
|
6623
|
+
const B = I.name.split(".");
|
|
6477
6624
|
if (B[1] === "position") {
|
|
6478
|
-
for (let p = 0; p <
|
|
6479
|
-
|
|
6480
|
-
x[
|
|
6481
|
-
} else B[1] === "quaternion" ? x[
|
|
6625
|
+
for (let p = 0; p < I.values.length; p++)
|
|
6626
|
+
I.values[p] = I.values[p] * s;
|
|
6627
|
+
x[I.name] = new f.Vector3(I.values[0], I.values[1], I.values[2]);
|
|
6628
|
+
} else B[1] === "quaternion" ? x[I.name] = new f.Quaternion(I.values[0], I.values[1], I.values[2], I.values[3]) : B[1] === "rotation" && (x[B[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(I.values[0], I.values[1], I.values[2], "XYZ")).normalize());
|
|
6482
6629
|
});
|
|
6483
6630
|
const b = { props: x };
|
|
6484
6631
|
x["Hips.position"] && (x["Hips.position"].y < 0.5 ? b.lying = !0 : b.standing = !0), this.animClips.push({
|
|
@@ -6514,25 +6661,25 @@ class Be {
|
|
|
6514
6661
|
if (!this.armature) return;
|
|
6515
6662
|
let o = this.poseTemplates[t];
|
|
6516
6663
|
if (!o) {
|
|
6517
|
-
const l = this.animPoses.find((
|
|
6664
|
+
const l = this.animPoses.find((u) => u.url === t + "-" + i);
|
|
6518
6665
|
l && (o = l.pose);
|
|
6519
6666
|
}
|
|
6520
6667
|
if (o) {
|
|
6521
6668
|
this.poseName = t, this.mixer = null;
|
|
6522
|
-
let l = this.animQueue.find((
|
|
6669
|
+
let l = this.animQueue.find((u) => u.template.name === "pose");
|
|
6523
6670
|
l && (l.ts[0] = this.animClock + n * 1e3 + 2e3), this.setPoseFromTemplate(o);
|
|
6524
6671
|
} else {
|
|
6525
|
-
let
|
|
6526
|
-
if (
|
|
6527
|
-
let r =
|
|
6528
|
-
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 = {};
|
|
6529
6676
|
r.tracks.forEach((c) => {
|
|
6530
6677
|
c.name = c.name.replaceAll("mixamorig", "");
|
|
6531
6678
|
const d = c.name.split(".");
|
|
6532
|
-
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());
|
|
6533
6680
|
});
|
|
6534
|
-
const a = { props:
|
|
6535
|
-
|
|
6681
|
+
const a = { props: h };
|
|
6682
|
+
h["Hips.position"] && (h["Hips.position"].y < 0.5 ? a.lying = !0 : a.standing = !0), this.animPoses.push({
|
|
6536
6683
|
url: t + "-" + i,
|
|
6537
6684
|
pose: a
|
|
6538
6685
|
}), this.playPose(t, e, n, i, s);
|
|
@@ -6561,10 +6708,10 @@ class Be {
|
|
|
6561
6708
|
let s = this.gestureTemplates[t];
|
|
6562
6709
|
if (s) {
|
|
6563
6710
|
this.gestureTimeout && (clearTimeout(this.gestureTimeout), this.gestureTimeout = null);
|
|
6564
|
-
let l = this.animQueue.findIndex((
|
|
6565
|
-
l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((
|
|
6566
|
-
for (let [
|
|
6567
|
-
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);
|
|
6568
6715
|
e && Number.isFinite(e) && (this.gestureTimeout = setTimeout(this.stopGesture.bind(this, i), 1e3 * e));
|
|
6569
6716
|
}
|
|
6570
6717
|
let o = this.animEmojis[t];
|
|
@@ -6572,15 +6719,15 @@ class Be {
|
|
|
6572
6719
|
this.lookAtCamera(500);
|
|
6573
6720
|
const l = this.animFactory(o);
|
|
6574
6721
|
if (l.gesture = !0, e && Number.isFinite(e)) {
|
|
6575
|
-
const
|
|
6576
|
-
if (e * 1e3 -
|
|
6722
|
+
const u = l.ts[0], h = l.ts[l.ts.length - 1] - u;
|
|
6723
|
+
if (e * 1e3 - h > 0) {
|
|
6577
6724
|
const c = [];
|
|
6578
6725
|
for (let x = 1; x < l.ts.length; x++) c.push(l.ts[x] - l.ts[x - 1]);
|
|
6579
|
-
const d = o.template?.rescale || c.map((x) => x /
|
|
6580
|
-
l.ts = l.ts.map((x, b,
|
|
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);
|
|
6581
6728
|
} else {
|
|
6582
|
-
const c = e * 1e3 /
|
|
6583
|
-
l.ts = l.ts.map((d) =>
|
|
6729
|
+
const c = e * 1e3 / h;
|
|
6730
|
+
l.ts = l.ts.map((d) => u + c * (d - u));
|
|
6584
6731
|
}
|
|
6585
6732
|
}
|
|
6586
6733
|
this.animQueue.push(l);
|
|
@@ -6610,19 +6757,19 @@ class Be {
|
|
|
6610
6757
|
* @param {numeric} [d=null] If set, apply in d milliseconds
|
|
6611
6758
|
*/
|
|
6612
6759
|
ikSolve(t, e = null, n = !1, i = null) {
|
|
6613
|
-
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);
|
|
6614
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);
|
|
6615
6762
|
const g = this.ikMesh.getObjectByName(t.effector), x = t.links;
|
|
6616
|
-
x.forEach((
|
|
6617
|
-
|
|
6763
|
+
x.forEach((I) => {
|
|
6764
|
+
I.bone = this.ikMesh.getObjectByName(I.link), I.bone.quaternion.copy(this.getPoseTemplateProp(I.link + ".quaternion"));
|
|
6618
6765
|
}), d.updateMatrixWorld(!0);
|
|
6619
6766
|
const b = t.iterations || 10;
|
|
6620
6767
|
if (e)
|
|
6621
|
-
for (let
|
|
6768
|
+
for (let I = 0; I < b; I++) {
|
|
6622
6769
|
let B = !1;
|
|
6623
6770
|
for (let p = 0, M = x.length; p < M; p++) {
|
|
6624
6771
|
const z = x[p].bone;
|
|
6625
|
-
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();
|
|
6626
6773
|
let y = s.dot(l);
|
|
6627
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(
|
|
6628
6775
|
x[p].minx !== void 0 ? x[p].minx : -1 / 0,
|
|
@@ -6636,8 +6783,8 @@ class Be {
|
|
|
6636
6783
|
}
|
|
6637
6784
|
if (!B) break;
|
|
6638
6785
|
}
|
|
6639
|
-
i && x.forEach((
|
|
6640
|
-
this.poseTarget.props[
|
|
6786
|
+
i && x.forEach((I) => {
|
|
6787
|
+
this.poseTarget.props[I.link + ".quaternion"].copy(I.bone.quaternion), this.poseTarget.props[I.link + ".quaternion"].t = this.animClock, this.poseTarget.props[I.link + ".quaternion"].d = i;
|
|
6641
6788
|
});
|
|
6642
6789
|
}
|
|
6643
6790
|
/**
|
|
@@ -6647,7 +6794,7 @@ class Be {
|
|
|
6647
6794
|
this.isRunning = !1, this.stop(), this.stopSpeaking(), this.streamStop(), this.isAvatarOnly ? this.armature && (this.armature.parent && this.armature.parent.remove(this.armature), this.clearThree(this.armature)) : (this.clearThree(this.scene), this.resizeobserver.disconnect(), this.renderer && (this.renderer.dispose(), this.renderer.domElement && this.renderer.domElement.parentNode && this.renderer.domElement.parentNode.removeChild(this.renderer.domElement), this.renderer = null)), this.clearThree(this.ikMesh), this.dynamicbones.dispose();
|
|
6648
6795
|
}
|
|
6649
6796
|
}
|
|
6650
|
-
const
|
|
6797
|
+
const Ie = {
|
|
6651
6798
|
apiKey: "sk_ace57ef3ef65a92b9d3bee2a00183b78ca790bc3e10964f2",
|
|
6652
6799
|
// Replace with your actual API key (should start with sk_)
|
|
6653
6800
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
@@ -6690,10 +6837,10 @@ const Re = {
|
|
|
6690
6837
|
function Fe() {
|
|
6691
6838
|
return {
|
|
6692
6839
|
service: "elevenlabs",
|
|
6693
|
-
endpoint:
|
|
6694
|
-
apiKey:
|
|
6695
|
-
defaultVoice:
|
|
6696
|
-
voices:
|
|
6840
|
+
endpoint: Ie.endpoint,
|
|
6841
|
+
apiKey: Ie.apiKey,
|
|
6842
|
+
defaultVoice: Ie.defaultVoice,
|
|
6843
|
+
voices: Ie.voices
|
|
6697
6844
|
};
|
|
6698
6845
|
}
|
|
6699
6846
|
function kt() {
|
|
@@ -6714,9 +6861,9 @@ const Ve = Me(({
|
|
|
6714
6861
|
ttsVoice: s = null,
|
|
6715
6862
|
ttsApiKey: o = null,
|
|
6716
6863
|
bodyMovement: l = "idle",
|
|
6717
|
-
movementIntensity:
|
|
6864
|
+
movementIntensity: u = 0.5,
|
|
6718
6865
|
showFullAvatar: r = !0,
|
|
6719
|
-
cameraView:
|
|
6866
|
+
cameraView: h = "upper",
|
|
6720
6867
|
onReady: a = () => {
|
|
6721
6868
|
},
|
|
6722
6869
|
onLoading: c = () => {
|
|
@@ -6726,8 +6873,8 @@ const Ve = Me(({
|
|
|
6726
6873
|
className: g = "",
|
|
6727
6874
|
style: x = {},
|
|
6728
6875
|
animations: b = {}
|
|
6729
|
-
},
|
|
6730
|
-
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), [
|
|
6876
|
+
}, I) => {
|
|
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);
|
|
6731
6878
|
de(() => {
|
|
6732
6879
|
E.current = ae;
|
|
6733
6880
|
}, [ae]), de(() => {
|
|
@@ -6744,8 +6891,8 @@ const Ve = Me(({
|
|
|
6744
6891
|
service: "elevenlabs",
|
|
6745
6892
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
6746
6893
|
apiKey: o || ee.apiKey,
|
|
6747
|
-
defaultVoice: s || ee.defaultVoice ||
|
|
6748
|
-
voices: ee.voices ||
|
|
6894
|
+
defaultVoice: s || ee.defaultVoice || Ie.defaultVoice,
|
|
6895
|
+
voices: ee.voices || Ie.voices
|
|
6749
6896
|
} : le === "deepgram" ? O = {
|
|
6750
6897
|
service: "deepgram",
|
|
6751
6898
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
@@ -6766,17 +6913,17 @@ const Ve = Me(({
|
|
|
6766
6913
|
lipsyncLang: "en",
|
|
6767
6914
|
showFullAvatar: r,
|
|
6768
6915
|
bodyMovement: l,
|
|
6769
|
-
movementIntensity:
|
|
6770
|
-
},
|
|
6916
|
+
movementIntensity: u
|
|
6917
|
+
}, R = {
|
|
6771
6918
|
ttsEndpoint: O.endpoint,
|
|
6772
6919
|
ttsApikey: O.apiKey,
|
|
6773
6920
|
ttsService: le,
|
|
6774
6921
|
lipsyncModules: ["en"],
|
|
6775
|
-
cameraView:
|
|
6922
|
+
cameraView: h
|
|
6776
6923
|
}, k = T(async () => {
|
|
6777
6924
|
if (!(!B.current || p.current))
|
|
6778
6925
|
try {
|
|
6779
|
-
if (Z(!0), X(null), p.current = new Be(B.current,
|
|
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) => {
|
|
6780
6927
|
if (N.lengthComputable) {
|
|
6781
6928
|
const J = Math.min(100, Math.round(N.loaded / N.total * 100));
|
|
6782
6929
|
c(J);
|
|
@@ -6802,7 +6949,7 @@ const Ve = Me(({
|
|
|
6802
6949
|
} catch (L) {
|
|
6803
6950
|
console.error("Error initializing TalkingHead:", L), X(L.message || "Failed to initialize avatar"), Z(!1), d(L);
|
|
6804
6951
|
}
|
|
6805
|
-
}, [G, t, e, n, i, s, o, r, l,
|
|
6952
|
+
}, [G, t, e, n, i, s, o, r, l, u, h]);
|
|
6806
6953
|
de(() => (k(), () => {
|
|
6807
6954
|
p.current && (p.current.stop(), p.current.dispose(), p.current = null);
|
|
6808
6955
|
}), [k]), de(() => {
|
|
@@ -6838,14 +6985,14 @@ const Ve = Me(({
|
|
|
6838
6985
|
};
|
|
6839
6986
|
if (F.onSpeechEnd && p.current) {
|
|
6840
6987
|
const Y = p.current;
|
|
6841
|
-
let
|
|
6988
|
+
let ue = null, Se = 0;
|
|
6842
6989
|
const Ae = 1200;
|
|
6843
6990
|
let be = !1;
|
|
6844
|
-
|
|
6991
|
+
ue = setInterval(() => {
|
|
6845
6992
|
if (Se++, E.current)
|
|
6846
6993
|
return;
|
|
6847
6994
|
if (Se > Ae) {
|
|
6848
|
-
if (
|
|
6995
|
+
if (ue && (clearInterval(ue), ue = null, y.current = null), !be && !E.current) {
|
|
6849
6996
|
be = !0;
|
|
6850
6997
|
try {
|
|
6851
6998
|
F.onSpeechEnd();
|
|
@@ -6858,7 +7005,7 @@ const Ve = Me(({
|
|
|
6858
7005
|
const ye = !Y.speechQueue || Y.speechQueue.length === 0, ke = !Y.audioPlaylist || Y.audioPlaylist.length === 0;
|
|
6859
7006
|
Y && Y.isSpeaking === !1 && ye && ke && Y.isAudioPlaying === !1 && !be && !E.current && setTimeout(() => {
|
|
6860
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) {
|
|
6861
|
-
be = !0,
|
|
7008
|
+
be = !0, ue && (clearInterval(ue), ue = null, y.current = null);
|
|
6862
7009
|
try {
|
|
6863
7010
|
F.onSpeechEnd();
|
|
6864
7011
|
} catch (Ze) {
|
|
@@ -6866,7 +7013,7 @@ const Ve = Me(({
|
|
|
6866
7013
|
}
|
|
6867
7014
|
}
|
|
6868
7015
|
}, 100);
|
|
6869
|
-
}, 100), y.current =
|
|
7016
|
+
}, 100), y.current = ue;
|
|
6870
7017
|
}
|
|
6871
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 () => {
|
|
6872
7019
|
await H(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge));
|
|
@@ -6874,7 +7021,7 @@ const Ve = Me(({
|
|
|
6874
7021
|
} catch (N) {
|
|
6875
7022
|
console.error("Error speaking text:", N), X(N.message || "Failed to speak text");
|
|
6876
7023
|
}
|
|
6877
|
-
}, [$, H, v.lipsyncLang]),
|
|
7024
|
+
}, [$, H, v.lipsyncLang]), K = T(() => {
|
|
6878
7025
|
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), z.current = null, pe(!1));
|
|
6879
7026
|
}, []), j = T(() => {
|
|
6880
7027
|
if (p.current && p.current.pauseSpeaking) {
|
|
@@ -6883,8 +7030,8 @@ const Ve = Me(({
|
|
|
6883
7030
|
y.current && (clearInterval(y.current), y.current = null);
|
|
6884
7031
|
let N = "";
|
|
6885
7032
|
if (z.current && W.current.length > 0) {
|
|
6886
|
-
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,
|
|
6887
|
-
if (
|
|
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)) {
|
|
6888
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(" ");
|
|
6889
7036
|
be && be.trim() && (N = be.trim());
|
|
6890
7037
|
}
|
|
@@ -6963,9 +7110,9 @@ const Ve = Me(({
|
|
|
6963
7110
|
}, [b]), te = T(() => {
|
|
6964
7111
|
p.current && p.current.onResize && p.current.onResize();
|
|
6965
7112
|
}, []);
|
|
6966
|
-
return Ee(
|
|
7113
|
+
return Ee(I, () => ({
|
|
6967
7114
|
speakText: U,
|
|
6968
|
-
stopSpeaking:
|
|
7115
|
+
stopSpeaking: K,
|
|
6969
7116
|
pauseSpeaking: j,
|
|
6970
7117
|
resumeSpeaking: q,
|
|
6971
7118
|
resumeAudioContext: H,
|
|
@@ -7065,7 +7212,7 @@ const Ve = Me(({
|
|
|
7065
7212
|
fontSize: "18px",
|
|
7066
7213
|
zIndex: 10
|
|
7067
7214
|
}, children: "Loading avatar..." }),
|
|
7068
|
-
|
|
7215
|
+
_ && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
|
|
7069
7216
|
position: "absolute",
|
|
7070
7217
|
top: "50%",
|
|
7071
7218
|
left: "50%",
|
|
@@ -7076,7 +7223,7 @@ const Ve = Me(({
|
|
|
7076
7223
|
zIndex: 10,
|
|
7077
7224
|
padding: "20px",
|
|
7078
7225
|
borderRadius: "8px"
|
|
7079
|
-
}, children:
|
|
7226
|
+
}, children: _ })
|
|
7080
7227
|
]
|
|
7081
7228
|
}
|
|
7082
7229
|
);
|
|
@@ -7094,7 +7241,7 @@ const pt = Me(({
|
|
|
7094
7241
|
style: s = {},
|
|
7095
7242
|
avatarConfig: o = {}
|
|
7096
7243
|
}, l) => {
|
|
7097
|
-
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" ? {
|
|
7098
7245
|
endpoint: "",
|
|
7099
7246
|
apiKey: null,
|
|
7100
7247
|
defaultVoice: "Google US English"
|
|
@@ -7103,13 +7250,13 @@ const pt = Me(({
|
|
|
7103
7250
|
// Override API key if provided via avatarConfig
|
|
7104
7251
|
apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey : b.apiKey,
|
|
7105
7252
|
// Override endpoint for ElevenLabs if service is explicitly set
|
|
7106
|
-
endpoint:
|
|
7253
|
+
endpoint: I === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : b.endpoint
|
|
7107
7254
|
}, p = {
|
|
7108
7255
|
url: "/avatars/brunette.glb",
|
|
7109
7256
|
// Use brunette avatar (working glTF file)
|
|
7110
7257
|
body: "F",
|
|
7111
7258
|
avatarMood: "neutral",
|
|
7112
|
-
ttsLang:
|
|
7259
|
+
ttsLang: I === "browser" ? "en-US" : "en",
|
|
7113
7260
|
ttsVoice: o.ttsVoice || B.defaultVoice,
|
|
7114
7261
|
lipsyncLang: "en",
|
|
7115
7262
|
// English lip-sync
|
|
@@ -7121,33 +7268,33 @@ const pt = Me(({
|
|
|
7121
7268
|
}, M = {
|
|
7122
7269
|
ttsEndpoint: B.endpoint,
|
|
7123
7270
|
ttsApikey: B.apiKey,
|
|
7124
|
-
ttsService:
|
|
7271
|
+
ttsService: I,
|
|
7125
7272
|
lipsyncModules: ["en"],
|
|
7126
7273
|
cameraView: "upper"
|
|
7127
7274
|
}, z = T(async () => {
|
|
7128
|
-
if (!(!
|
|
7275
|
+
if (!(!u.current || r.current))
|
|
7129
7276
|
try {
|
|
7130
|
-
if (a(!0), d(null), r.current = new Be(
|
|
7131
|
-
if (
|
|
7132
|
-
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));
|
|
7133
7280
|
t(X);
|
|
7134
7281
|
}
|
|
7135
7282
|
}), r.current.morphs && r.current.morphs.length > 0) {
|
|
7136
|
-
const
|
|
7137
|
-
console.log("Available morph targets:", Object.keys(
|
|
7138
|
-
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_"));
|
|
7139
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"));
|
|
7140
7287
|
}
|
|
7141
|
-
if (await new Promise((
|
|
7288
|
+
if (await new Promise((_) => {
|
|
7142
7289
|
const X = () => {
|
|
7143
|
-
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));
|
|
7144
7291
|
};
|
|
7145
7292
|
X();
|
|
7146
7293
|
}), r.current && r.current.setShowFullAvatar)
|
|
7147
7294
|
try {
|
|
7148
7295
|
r.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
|
|
7149
|
-
} catch (
|
|
7150
|
-
console.warn("Error setting full body mode on initialization:",
|
|
7296
|
+
} catch (_) {
|
|
7297
|
+
console.warn("Error setting full body mode on initialization:", _);
|
|
7151
7298
|
}
|
|
7152
7299
|
a(!1), x(!0), n(r.current);
|
|
7153
7300
|
const Z = () => {
|
|
@@ -7290,7 +7437,7 @@ const pt = Me(({
|
|
|
7290
7437
|
/* @__PURE__ */ me(
|
|
7291
7438
|
"div",
|
|
7292
7439
|
{
|
|
7293
|
-
ref:
|
|
7440
|
+
ref: u,
|
|
7294
7441
|
className: "talking-head-viewer",
|
|
7295
7442
|
style: {
|
|
7296
7443
|
width: "100%",
|
|
@@ -7299,7 +7446,7 @@ const pt = Me(({
|
|
|
7299
7446
|
}
|
|
7300
7447
|
}
|
|
7301
7448
|
),
|
|
7302
|
-
|
|
7449
|
+
h && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
|
|
7303
7450
|
position: "absolute",
|
|
7304
7451
|
top: "50%",
|
|
7305
7452
|
left: "50%",
|
|
@@ -7332,9 +7479,9 @@ const gt = Me(({
|
|
|
7332
7479
|
ttsService: s = null,
|
|
7333
7480
|
ttsVoice: o = null,
|
|
7334
7481
|
ttsApiKey: l = null,
|
|
7335
|
-
bodyMovement:
|
|
7482
|
+
bodyMovement: u = "idle",
|
|
7336
7483
|
movementIntensity: r = 0.5,
|
|
7337
|
-
showFullAvatar:
|
|
7484
|
+
showFullAvatar: h = !1,
|
|
7338
7485
|
cameraView: a = "upper",
|
|
7339
7486
|
onReady: c = () => {
|
|
7340
7487
|
},
|
|
@@ -7345,36 +7492,36 @@ const gt = Me(({
|
|
|
7345
7492
|
onSpeechEnd: x = () => {
|
|
7346
7493
|
},
|
|
7347
7494
|
className: b = "",
|
|
7348
|
-
style:
|
|
7495
|
+
style: I = {},
|
|
7349
7496
|
animations: B = {},
|
|
7350
7497
|
autoSpeak: p = !1
|
|
7351
7498
|
}, M) => {
|
|
7352
|
-
const z = D(null), y = D(null), E = D(
|
|
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);
|
|
7353
7500
|
de(() => {
|
|
7354
7501
|
oe.current = ee;
|
|
7355
7502
|
}, [ee]), de(() => {
|
|
7356
|
-
E.current =
|
|
7357
|
-
}, [
|
|
7503
|
+
E.current = h;
|
|
7504
|
+
}, [h]);
|
|
7358
7505
|
const O = Fe(), v = s || O.service;
|
|
7359
|
-
let
|
|
7360
|
-
v === "browser" ?
|
|
7506
|
+
let R;
|
|
7507
|
+
v === "browser" ? R = {
|
|
7361
7508
|
service: "browser",
|
|
7362
7509
|
endpoint: "",
|
|
7363
7510
|
apiKey: null,
|
|
7364
7511
|
defaultVoice: "Google US English"
|
|
7365
|
-
} : v === "elevenlabs" ?
|
|
7512
|
+
} : v === "elevenlabs" ? R = {
|
|
7366
7513
|
service: "elevenlabs",
|
|
7367
7514
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
7368
7515
|
apiKey: l || O.apiKey,
|
|
7369
|
-
defaultVoice: o || O.defaultVoice ||
|
|
7370
|
-
voices: O.voices ||
|
|
7371
|
-
} : v === "deepgram" ?
|
|
7516
|
+
defaultVoice: o || O.defaultVoice || Ie.defaultVoice,
|
|
7517
|
+
voices: O.voices || Ie.voices
|
|
7518
|
+
} : v === "deepgram" ? R = {
|
|
7372
7519
|
service: "deepgram",
|
|
7373
7520
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
7374
7521
|
apiKey: l || O.apiKey,
|
|
7375
7522
|
defaultVoice: o || O.defaultVoice || Te.defaultVoice,
|
|
7376
7523
|
voices: O.voices || Te.voices
|
|
7377
|
-
} :
|
|
7524
|
+
} : R = {
|
|
7378
7525
|
...O,
|
|
7379
7526
|
apiKey: l !== null ? l : O.apiKey
|
|
7380
7527
|
};
|
|
@@ -7383,14 +7530,14 @@ const gt = Me(({
|
|
|
7383
7530
|
body: e,
|
|
7384
7531
|
avatarMood: n,
|
|
7385
7532
|
ttsLang: v === "browser" ? "en-US" : i,
|
|
7386
|
-
ttsVoice: o ||
|
|
7533
|
+
ttsVoice: o || R.defaultVoice,
|
|
7387
7534
|
lipsyncLang: "en",
|
|
7388
|
-
showFullAvatar:
|
|
7389
|
-
bodyMovement:
|
|
7535
|
+
showFullAvatar: h,
|
|
7536
|
+
bodyMovement: u,
|
|
7390
7537
|
movementIntensity: r
|
|
7391
7538
|
}, H = {
|
|
7392
|
-
ttsEndpoint:
|
|
7393
|
-
ttsApikey:
|
|
7539
|
+
ttsEndpoint: R.endpoint,
|
|
7540
|
+
ttsApikey: R.apiKey,
|
|
7394
7541
|
ttsService: v,
|
|
7395
7542
|
lipsyncModules: ["en"],
|
|
7396
7543
|
cameraView: a
|
|
@@ -7420,7 +7567,7 @@ const gt = Me(({
|
|
|
7420
7567
|
de(() => (U(), () => {
|
|
7421
7568
|
y.current && (y.current.stop(), y.current.dispose(), y.current = null);
|
|
7422
7569
|
}), [U]);
|
|
7423
|
-
const
|
|
7570
|
+
const K = T(async () => {
|
|
7424
7571
|
if (y.current)
|
|
7425
7572
|
try {
|
|
7426
7573
|
const C = y.current.audioCtx || y.current.audioContext;
|
|
@@ -7437,7 +7584,7 @@ const gt = Me(({
|
|
|
7437
7584
|
console.warn("No text provided to speak");
|
|
7438
7585
|
return;
|
|
7439
7586
|
}
|
|
7440
|
-
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;
|
|
7441
7588
|
const L = C.split(/[.!?]+/).filter((N) => N.trim().length > 0);
|
|
7442
7589
|
Z.current = L;
|
|
7443
7590
|
const F = {
|
|
@@ -7451,7 +7598,7 @@ const gt = Me(({
|
|
|
7451
7598
|
} catch (N) {
|
|
7452
7599
|
console.error("Error speaking text:", N), se(N.message || "Failed to speak text");
|
|
7453
7600
|
}
|
|
7454
|
-
}, [ae, x,
|
|
7601
|
+
}, [ae, x, K]);
|
|
7455
7602
|
de(() => {
|
|
7456
7603
|
ae && G && p && y.current && j(G);
|
|
7457
7604
|
}, [ae, G, p, j]);
|
|
@@ -7474,13 +7621,13 @@ const gt = Me(({
|
|
|
7474
7621
|
}, []), Le = T(async () => {
|
|
7475
7622
|
if (!(!y.current || !ee))
|
|
7476
7623
|
try {
|
|
7477
|
-
await
|
|
7624
|
+
await K(), le(!1), oe.current = !1;
|
|
7478
7625
|
const C = S.current?.remainingText, te = S.current?.originalText || P.current?.text, L = S.current?.options || P.current?.options || {}, F = C || te;
|
|
7479
7626
|
F && j(F, L);
|
|
7480
7627
|
} catch (C) {
|
|
7481
7628
|
console.warn("Error resuming speech:", C), le(!1), oe.current = !1;
|
|
7482
7629
|
}
|
|
7483
|
-
}, [ee, j,
|
|
7630
|
+
}, [ee, j, K]), we = T(() => {
|
|
7484
7631
|
y.current && (y.current.stopSpeaking(), W.current && (clearInterval(W.current), W.current = null), le(!1), oe.current = !1);
|
|
7485
7632
|
}, []);
|
|
7486
7633
|
return Ee(M, () => ({
|
|
@@ -7488,7 +7635,7 @@ const gt = Me(({
|
|
|
7488
7635
|
pauseSpeaking: q,
|
|
7489
7636
|
resumeSpeaking: Le,
|
|
7490
7637
|
stopSpeaking: we,
|
|
7491
|
-
resumeAudioContext:
|
|
7638
|
+
resumeAudioContext: K,
|
|
7492
7639
|
isPaused: () => ee,
|
|
7493
7640
|
setMood: (C) => y.current?.setMood(C),
|
|
7494
7641
|
setBodyMovement: (C) => {
|
|
@@ -7504,7 +7651,7 @@ const gt = Me(({
|
|
|
7504
7651
|
},
|
|
7505
7652
|
isReady: ae,
|
|
7506
7653
|
talkingHead: y.current
|
|
7507
|
-
})), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${b}`, style:
|
|
7654
|
+
})), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${b}`, style: I, children: [
|
|
7508
7655
|
/* @__PURE__ */ me(
|
|
7509
7656
|
"div",
|
|
7510
7657
|
{
|
|
@@ -7517,7 +7664,7 @@ const gt = Me(({
|
|
|
7517
7664
|
}
|
|
7518
7665
|
}
|
|
7519
7666
|
),
|
|
7520
|
-
|
|
7667
|
+
_ && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
|
|
7521
7668
|
position: "absolute",
|
|
7522
7669
|
top: "50%",
|
|
7523
7670
|
left: "50%",
|
|
@@ -7555,9 +7702,9 @@ const yt = Me(({
|
|
|
7555
7702
|
},
|
|
7556
7703
|
onCustomAction: l = () => {
|
|
7557
7704
|
},
|
|
7558
|
-
autoStart:
|
|
7705
|
+
autoStart: u = !1
|
|
7559
7706
|
}, r) => {
|
|
7560
|
-
const
|
|
7707
|
+
const h = D(null), a = D({
|
|
7561
7708
|
currentModuleIndex: 0,
|
|
7562
7709
|
currentLessonIndex: 0,
|
|
7563
7710
|
currentQuestionIndex: 0,
|
|
@@ -7573,7 +7720,7 @@ const yt = Me(({
|
|
|
7573
7720
|
onQuestionAnswer: s,
|
|
7574
7721
|
onCurriculumComplete: o,
|
|
7575
7722
|
onCustomAction: l
|
|
7576
|
-
}), d = D(null), g = D(null), x = D(null), b = D(null),
|
|
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 || {
|
|
7577
7724
|
title: "Default Curriculum",
|
|
7578
7725
|
description: "No curriculum data provided",
|
|
7579
7726
|
language: "en",
|
|
@@ -7621,11 +7768,11 @@ const yt = Me(({
|
|
|
7621
7768
|
lipsyncLang: "en"
|
|
7622
7769
|
};
|
|
7623
7770
|
}, [G, t, e]);
|
|
7624
|
-
const y = T(() => (M.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), E = T(() => y()?.questions[a.current.currentQuestionIndex], [y]), P = T((v,
|
|
7771
|
+
const y = T(() => (M.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), E = T(() => y()?.questions[a.current.currentQuestionIndex], [y]), P = T((v, R) => R.type === "multiple_choice" || R.type === "true_false" ? v === R.answer : R.type === "code_test" && typeof v == "object" && v !== null ? v.passed === !0 : !1, []), W = T(() => {
|
|
7625
7772
|
a.current.lessonCompleted = !0, a.current.isQuestionMode = !1;
|
|
7626
7773
|
const v = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
|
|
7627
|
-
let
|
|
7628
|
-
if (a.current.totalQuestions > 0 ?
|
|
7774
|
+
let R = "Congratulations! You've completed this lesson";
|
|
7775
|
+
if (a.current.totalQuestions > 0 ? R += ` You got ${a.current.score} correct out of ${a.current.totalQuestions} question${a.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${v} percent. ` : R += "! ", v >= 80 ? R += "Excellent work! You have a great understanding of this topic." : v >= 60 ? R += "Good job! You understand most of the concepts." : R += "Keep practicing! You're making progress.", c.current.onLessonComplete({
|
|
7629
7776
|
moduleIndex: a.current.currentModuleIndex,
|
|
7630
7777
|
lessonIndex: a.current.currentLessonIndex,
|
|
7631
7778
|
score: a.current.score,
|
|
@@ -7638,15 +7785,15 @@ const yt = Me(({
|
|
|
7638
7785
|
score: a.current.score,
|
|
7639
7786
|
totalQuestions: a.current.totalQuestions,
|
|
7640
7787
|
percentage: v
|
|
7641
|
-
}),
|
|
7642
|
-
if (
|
|
7788
|
+
}), h.current) {
|
|
7789
|
+
if (h.current.setMood("happy"), e.lessonComplete)
|
|
7643
7790
|
try {
|
|
7644
|
-
|
|
7791
|
+
h.current.playAnimation(e.lessonComplete, !0);
|
|
7645
7792
|
} catch {
|
|
7646
|
-
|
|
7793
|
+
h.current.playCelebration();
|
|
7647
7794
|
}
|
|
7648
|
-
const k = M.current || { modules: [] }, H = k.modules[a.current.currentModuleIndex], U = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1,
|
|
7649
|
-
|
|
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, {
|
|
7650
7797
|
lipsyncLang: q.lipsyncLang,
|
|
7651
7798
|
onSpeechEnd: () => {
|
|
7652
7799
|
c.current.onCustomAction({
|
|
@@ -7666,49 +7813,49 @@ const yt = Me(({
|
|
|
7666
7813
|
const v = M.current || { modules: [] };
|
|
7667
7814
|
if (c.current.onCurriculumComplete({
|
|
7668
7815
|
modules: v.modules.length,
|
|
7669
|
-
totalLessons: v.modules.reduce((
|
|
7670
|
-
}),
|
|
7671
|
-
if (
|
|
7816
|
+
totalLessons: v.modules.reduce((R, k) => R + k.lessons.length, 0)
|
|
7817
|
+
}), h.current) {
|
|
7818
|
+
if (h.current.setMood("celebrating"), e.curriculumComplete)
|
|
7672
7819
|
try {
|
|
7673
|
-
|
|
7820
|
+
h.current.playAnimation(e.curriculumComplete, !0);
|
|
7674
7821
|
} catch {
|
|
7675
|
-
|
|
7822
|
+
h.current.playCelebration();
|
|
7676
7823
|
}
|
|
7677
|
-
const
|
|
7678
|
-
|
|
7824
|
+
const R = z.current || { lipsyncLang: "en" };
|
|
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 });
|
|
7679
7826
|
}
|
|
7680
7827
|
}, [e.curriculumComplete]), S = T(() => {
|
|
7681
7828
|
const v = y();
|
|
7682
7829
|
a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = v?.questions?.length || 0, a.current.score = 0;
|
|
7683
|
-
const
|
|
7684
|
-
|
|
7830
|
+
const R = E();
|
|
7831
|
+
R && c.current.onCustomAction({
|
|
7685
7832
|
type: "questionStart",
|
|
7686
7833
|
moduleIndex: a.current.currentModuleIndex,
|
|
7687
7834
|
lessonIndex: a.current.currentLessonIndex,
|
|
7688
7835
|
questionIndex: a.current.currentQuestionIndex,
|
|
7689
7836
|
totalQuestions: a.current.totalQuestions,
|
|
7690
|
-
question:
|
|
7837
|
+
question: R,
|
|
7691
7838
|
score: a.current.score
|
|
7692
7839
|
});
|
|
7693
7840
|
const k = () => {
|
|
7694
|
-
if (!
|
|
7695
|
-
if (
|
|
7841
|
+
if (!h.current || !R) return;
|
|
7842
|
+
if (h.current.setMood("happy"), e.questionStart)
|
|
7696
7843
|
try {
|
|
7697
|
-
|
|
7844
|
+
h.current.playAnimation(e.questionStart, !0);
|
|
7698
7845
|
} catch (U) {
|
|
7699
7846
|
console.warn("Failed to play questionStart animation:", U);
|
|
7700
7847
|
}
|
|
7701
7848
|
const H = z.current || { lipsyncLang: "en" };
|
|
7702
|
-
|
|
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 });
|
|
7703
7850
|
};
|
|
7704
|
-
if (
|
|
7851
|
+
if (h.current && h.current.isReady && R)
|
|
7705
7852
|
k();
|
|
7706
|
-
else if (
|
|
7853
|
+
else if (h.current && h.current.isReady) {
|
|
7707
7854
|
const H = z.current || { lipsyncLang: "en" };
|
|
7708
|
-
|
|
7855
|
+
h.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: H.lipsyncLang });
|
|
7709
7856
|
} else {
|
|
7710
7857
|
const H = setInterval(() => {
|
|
7711
|
-
|
|
7858
|
+
h.current && h.current.isReady && (clearInterval(H), R && k());
|
|
7712
7859
|
}, 100);
|
|
7713
7860
|
setTimeout(() => {
|
|
7714
7861
|
clearInterval(H);
|
|
@@ -7717,53 +7864,53 @@ const yt = Me(({
|
|
|
7717
7864
|
}, [e.questionStart, y, E]), Z = T(() => {
|
|
7718
7865
|
const v = y();
|
|
7719
7866
|
if (a.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
|
|
7720
|
-
|
|
7721
|
-
const
|
|
7722
|
-
|
|
7867
|
+
h.current && h.current.stopSpeaking && h.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
|
|
7868
|
+
const R = E();
|
|
7869
|
+
R && c.current.onCustomAction({
|
|
7723
7870
|
type: "nextQuestion",
|
|
7724
7871
|
moduleIndex: a.current.currentModuleIndex,
|
|
7725
7872
|
lessonIndex: a.current.currentLessonIndex,
|
|
7726
7873
|
questionIndex: a.current.currentQuestionIndex,
|
|
7727
7874
|
totalQuestions: a.current.totalQuestions,
|
|
7728
|
-
question:
|
|
7875
|
+
question: R,
|
|
7729
7876
|
score: a.current.score
|
|
7730
7877
|
});
|
|
7731
7878
|
const k = () => {
|
|
7732
|
-
if (!
|
|
7733
|
-
if (
|
|
7879
|
+
if (!h.current || !R) return;
|
|
7880
|
+
if (h.current.setMood("happy"), h.current.setBodyMovement("idle"), e.nextQuestion)
|
|
7734
7881
|
try {
|
|
7735
|
-
|
|
7882
|
+
h.current.playAnimation(e.nextQuestion, !0);
|
|
7736
7883
|
} catch (q) {
|
|
7737
7884
|
console.warn("Failed to play nextQuestion animation:", q);
|
|
7738
7885
|
}
|
|
7739
|
-
const H = z.current || { lipsyncLang: "en" },
|
|
7740
|
-
if (
|
|
7741
|
-
const q = j ? `Great! Here's your final coding challenge: ${
|
|
7742
|
-
|
|
7886
|
+
const H = z.current || { lipsyncLang: "en" }, K = y()?.questions?.length || 0, j = a.current.currentQuestionIndex >= K - 1;
|
|
7887
|
+
if (R.type === "code_test") {
|
|
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}`;
|
|
7889
|
+
h.current.speakText(q, {
|
|
7743
7890
|
lipsyncLang: H.lipsyncLang
|
|
7744
7891
|
});
|
|
7745
|
-
} else if (
|
|
7746
|
-
const q = j ? `Alright! Here's your final question: ${
|
|
7747
|
-
|
|
7892
|
+
} else if (R.type === "multiple_choice") {
|
|
7893
|
+
const q = j ? `Alright! Here's your final question: ${R.question}` : `Alright! Here's your next question: ${R.question}`;
|
|
7894
|
+
h.current.speakText(q, {
|
|
7748
7895
|
lipsyncLang: H.lipsyncLang
|
|
7749
7896
|
});
|
|
7750
|
-
} else if (
|
|
7751
|
-
const q = j ? `Now let's try this final one: ${
|
|
7752
|
-
|
|
7897
|
+
} else if (R.type === "true_false") {
|
|
7898
|
+
const q = j ? `Now let's try this final one: ${R.question}` : `Now let's try this one: ${R.question}`;
|
|
7899
|
+
h.current.speakText(q, {
|
|
7753
7900
|
lipsyncLang: H.lipsyncLang
|
|
7754
7901
|
});
|
|
7755
7902
|
} else {
|
|
7756
|
-
const q = j ? `Here's your final question: ${
|
|
7757
|
-
|
|
7903
|
+
const q = j ? `Here's your final question: ${R.question}` : `Here's the next question: ${R.question}`;
|
|
7904
|
+
h.current.speakText(q, {
|
|
7758
7905
|
lipsyncLang: H.lipsyncLang
|
|
7759
7906
|
});
|
|
7760
7907
|
}
|
|
7761
7908
|
};
|
|
7762
|
-
if (
|
|
7909
|
+
if (h.current && h.current.isReady && R)
|
|
7763
7910
|
k();
|
|
7764
|
-
else if (
|
|
7911
|
+
else if (R) {
|
|
7765
7912
|
const H = setInterval(() => {
|
|
7766
|
-
|
|
7913
|
+
h.current && h.current.isReady && (clearInterval(H), k());
|
|
7767
7914
|
}, 100);
|
|
7768
7915
|
setTimeout(() => {
|
|
7769
7916
|
clearInterval(H);
|
|
@@ -7777,11 +7924,11 @@ const yt = Me(({
|
|
|
7777
7924
|
totalQuestions: a.current.totalQuestions,
|
|
7778
7925
|
score: a.current.score
|
|
7779
7926
|
});
|
|
7780
|
-
}, [e.nextQuestion, y, E]),
|
|
7781
|
-
const v = M.current || { modules: [] },
|
|
7782
|
-
if (a.current.currentLessonIndex < (
|
|
7927
|
+
}, [e.nextQuestion, y, E]), _ = T(() => {
|
|
7928
|
+
const v = M.current || { modules: [] }, R = v.modules[a.current.currentModuleIndex];
|
|
7929
|
+
if (a.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
|
|
7783
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;
|
|
7784
|
-
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;
|
|
7785
7932
|
c.current.onCustomAction({
|
|
7786
7933
|
type: "lessonStart",
|
|
7787
7934
|
moduleIndex: a.current.currentModuleIndex,
|
|
@@ -7791,10 +7938,10 @@ const yt = Me(({
|
|
|
7791
7938
|
moduleIndex: a.current.currentModuleIndex,
|
|
7792
7939
|
lessonIndex: a.current.currentLessonIndex,
|
|
7793
7940
|
lesson: y()
|
|
7794
|
-
}),
|
|
7941
|
+
}), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
|
|
7795
7942
|
} else if (a.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
|
|
7796
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;
|
|
7797
|
-
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;
|
|
7798
7945
|
c.current.onCustomAction({
|
|
7799
7946
|
type: "lessonStart",
|
|
7800
7947
|
moduleIndex: a.current.currentModuleIndex,
|
|
@@ -7804,27 +7951,27 @@ const yt = Me(({
|
|
|
7804
7951
|
moduleIndex: a.current.currentModuleIndex,
|
|
7805
7952
|
lessonIndex: a.current.currentLessonIndex,
|
|
7806
7953
|
lesson: y()
|
|
7807
|
-
}),
|
|
7954
|
+
}), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
|
|
7808
7955
|
} else
|
|
7809
|
-
|
|
7956
|
+
I.current && I.current();
|
|
7810
7957
|
}, []), X = T(() => {
|
|
7811
7958
|
const v = y();
|
|
7812
|
-
let
|
|
7959
|
+
let R = null;
|
|
7813
7960
|
if (v?.avatar_script && v?.body) {
|
|
7814
7961
|
const k = v.avatar_script.trim(), H = v.body.trim(), U = k.match(/[.!?]$/) ? " " : ". ";
|
|
7815
|
-
|
|
7962
|
+
R = `${k}${U}${H}`;
|
|
7816
7963
|
} else
|
|
7817
|
-
|
|
7818
|
-
if (
|
|
7819
|
-
a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0,
|
|
7964
|
+
R = v?.avatar_script || v?.body || null;
|
|
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");
|
|
7820
7967
|
let k = !1;
|
|
7821
7968
|
if (e.teaching)
|
|
7822
7969
|
try {
|
|
7823
|
-
|
|
7970
|
+
h.current.playAnimation(e.teaching, !0), k = !0;
|
|
7824
7971
|
} catch (U) {
|
|
7825
7972
|
console.warn("Failed to play teaching animation:", U);
|
|
7826
7973
|
}
|
|
7827
|
-
k ||
|
|
7974
|
+
k || h.current.setBodyMovement("gesturing");
|
|
7828
7975
|
const H = z.current || { lipsyncLang: "en" };
|
|
7829
7976
|
c.current.onLessonStart({
|
|
7830
7977
|
moduleIndex: a.current.currentModuleIndex,
|
|
@@ -7835,7 +7982,7 @@ const yt = Me(({
|
|
|
7835
7982
|
moduleIndex: a.current.currentModuleIndex,
|
|
7836
7983
|
lessonIndex: a.current.currentLessonIndex,
|
|
7837
7984
|
lesson: v
|
|
7838
|
-
}),
|
|
7985
|
+
}), h.current.speakText(R, {
|
|
7839
7986
|
lipsyncLang: H.lipsyncLang,
|
|
7840
7987
|
onSpeechEnd: () => {
|
|
7841
7988
|
a.current.isTeaching = !1, c.current.onCustomAction({
|
|
@@ -7855,29 +8002,29 @@ const yt = Me(({
|
|
|
7855
8002
|
});
|
|
7856
8003
|
}
|
|
7857
8004
|
}, [e.teaching, y]), $ = T((v) => {
|
|
7858
|
-
const
|
|
8005
|
+
const R = E(), k = P(v, R);
|
|
7859
8006
|
if (k && (a.current.score += 1), c.current.onQuestionAnswer({
|
|
7860
8007
|
moduleIndex: a.current.currentModuleIndex,
|
|
7861
8008
|
lessonIndex: a.current.currentLessonIndex,
|
|
7862
8009
|
questionIndex: a.current.currentQuestionIndex,
|
|
7863
8010
|
answer: v,
|
|
7864
8011
|
isCorrect: k,
|
|
7865
|
-
question:
|
|
7866
|
-
}),
|
|
8012
|
+
question: R
|
|
8013
|
+
}), h.current)
|
|
7867
8014
|
if (k) {
|
|
7868
|
-
if (
|
|
8015
|
+
if (h.current.setMood("happy"), e.correct)
|
|
7869
8016
|
try {
|
|
7870
|
-
|
|
8017
|
+
h.current.playReaction("happy");
|
|
7871
8018
|
} catch {
|
|
7872
|
-
|
|
8019
|
+
h.current.setBodyMovement("happy");
|
|
7873
8020
|
}
|
|
7874
|
-
|
|
8021
|
+
h.current.setBodyMovement("gesturing");
|
|
7875
8022
|
const U = y()?.questions?.length || 0;
|
|
7876
8023
|
a.current.currentQuestionIndex >= U - 1;
|
|
7877
|
-
const
|
|
7878
|
-
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", U, "hasNextQuestion:",
|
|
7879
|
-
const j =
|
|
7880
|
-
|
|
8024
|
+
const K = a.current.currentQuestionIndex < U - 1;
|
|
8025
|
+
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", U, "hasNextQuestion:", K);
|
|
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" };
|
|
8027
|
+
h.current.speakText(j, {
|
|
7881
8028
|
lipsyncLang: q.lipsyncLang,
|
|
7882
8029
|
onSpeechEnd: () => {
|
|
7883
8030
|
c.current.onCustomAction({
|
|
@@ -7886,24 +8033,24 @@ const yt = Me(({
|
|
|
7886
8033
|
lessonIndex: a.current.currentLessonIndex,
|
|
7887
8034
|
questionIndex: a.current.currentQuestionIndex,
|
|
7888
8035
|
isCorrect: !0,
|
|
7889
|
-
hasNextQuestion:
|
|
8036
|
+
hasNextQuestion: K,
|
|
7890
8037
|
score: a.current.score,
|
|
7891
8038
|
totalQuestions: a.current.totalQuestions
|
|
7892
8039
|
});
|
|
7893
8040
|
}
|
|
7894
8041
|
});
|
|
7895
8042
|
} else {
|
|
7896
|
-
if (
|
|
8043
|
+
if (h.current.setMood("sad"), e.incorrect)
|
|
7897
8044
|
try {
|
|
7898
|
-
|
|
8045
|
+
h.current.playAnimation(e.incorrect, !0);
|
|
7899
8046
|
} catch {
|
|
7900
|
-
|
|
8047
|
+
h.current.setBodyMovement("idle");
|
|
7901
8048
|
}
|
|
7902
|
-
|
|
7903
|
-
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;
|
|
7904
8051
|
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", U, "hasNextQuestion:", j);
|
|
7905
|
-
const q =
|
|
7906
|
-
|
|
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, {
|
|
7907
8054
|
lipsyncLang: Le.lipsyncLang,
|
|
7908
8055
|
onSpeechEnd: () => {
|
|
7909
8056
|
c.current.onCustomAction({
|
|
@@ -7934,12 +8081,12 @@ const yt = Me(({
|
|
|
7934
8081
|
});
|
|
7935
8082
|
}
|
|
7936
8083
|
}, [e.correct, e.incorrect, E, y, P]), se = T((v) => {
|
|
7937
|
-
const
|
|
8084
|
+
const R = E();
|
|
7938
8085
|
if (!v || typeof v != "object") {
|
|
7939
8086
|
console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
|
|
7940
8087
|
return;
|
|
7941
8088
|
}
|
|
7942
|
-
if (
|
|
8089
|
+
if (R?.type !== "code_test") {
|
|
7943
8090
|
console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
|
|
7944
8091
|
return;
|
|
7945
8092
|
}
|
|
@@ -7959,7 +8106,7 @@ const yt = Me(({
|
|
|
7959
8106
|
lessonIndex: a.current.currentLessonIndex,
|
|
7960
8107
|
questionIndex: a.current.currentQuestionIndex,
|
|
7961
8108
|
testResult: k,
|
|
7962
|
-
question:
|
|
8109
|
+
question: R
|
|
7963
8110
|
}), p.current && p.current(k);
|
|
7964
8111
|
}, [E, P]), ae = T(() => {
|
|
7965
8112
|
if (a.current.currentQuestionIndex > 0) {
|
|
@@ -7974,21 +8121,21 @@ const yt = Me(({
|
|
|
7974
8121
|
question: v,
|
|
7975
8122
|
score: a.current.score
|
|
7976
8123
|
});
|
|
7977
|
-
const
|
|
7978
|
-
if (!
|
|
7979
|
-
|
|
8124
|
+
const R = () => {
|
|
8125
|
+
if (!h.current || !v) return;
|
|
8126
|
+
h.current.setMood("happy"), h.current.setBodyMovement("idle");
|
|
7980
8127
|
const k = z.current || { lipsyncLang: "en" };
|
|
7981
|
-
v.type === "code_test" ?
|
|
8128
|
+
v.type === "code_test" ? h.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
|
|
7982
8129
|
lipsyncLang: k.lipsyncLang
|
|
7983
|
-
}) :
|
|
8130
|
+
}) : h.current.speakText(`Going back to: ${v.question}`, {
|
|
7984
8131
|
lipsyncLang: k.lipsyncLang
|
|
7985
8132
|
});
|
|
7986
8133
|
};
|
|
7987
|
-
if (
|
|
7988
|
-
|
|
8134
|
+
if (h.current && h.current.isReady && v)
|
|
8135
|
+
R();
|
|
7989
8136
|
else if (v) {
|
|
7990
8137
|
const k = setInterval(() => {
|
|
7991
|
-
|
|
8138
|
+
h.current && h.current.isReady && (clearInterval(k), R());
|
|
7992
8139
|
}, 100);
|
|
7993
8140
|
setTimeout(() => {
|
|
7994
8141
|
clearInterval(k);
|
|
@@ -8006,7 +8153,7 @@ const yt = Me(({
|
|
|
8006
8153
|
moduleIndex: a.current.currentModuleIndex,
|
|
8007
8154
|
lessonIndex: a.current.currentLessonIndex,
|
|
8008
8155
|
lesson: y()
|
|
8009
|
-
}),
|
|
8156
|
+
}), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
|
|
8010
8157
|
else if (a.current.currentModuleIndex > 0) {
|
|
8011
8158
|
const H = v.modules[a.current.currentModuleIndex - 1];
|
|
8012
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({
|
|
@@ -8017,19 +8164,19 @@ const yt = Me(({
|
|
|
8017
8164
|
moduleIndex: a.current.currentModuleIndex,
|
|
8018
8165
|
lessonIndex: a.current.currentLessonIndex,
|
|
8019
8166
|
lesson: y()
|
|
8020
|
-
}),
|
|
8167
|
+
}), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
|
|
8021
8168
|
}
|
|
8022
8169
|
}, [y]), ee = T(() => {
|
|
8023
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;
|
|
8024
8171
|
}, []), le = T((v) => {
|
|
8025
8172
|
console.log("Avatar is ready!", v);
|
|
8026
|
-
const
|
|
8027
|
-
|
|
8173
|
+
const R = y(), k = R?.avatar_script || R?.body;
|
|
8174
|
+
u && k && setTimeout(() => {
|
|
8028
8175
|
d.current && d.current();
|
|
8029
8176
|
}, 10);
|
|
8030
|
-
}, [
|
|
8177
|
+
}, [u, y]);
|
|
8031
8178
|
Xe(() => {
|
|
8032
|
-
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 = $;
|
|
8033
8180
|
}), Ee(r, () => ({
|
|
8034
8181
|
// Curriculum control methods
|
|
8035
8182
|
startTeaching: X,
|
|
@@ -8038,7 +8185,7 @@ const yt = Me(({
|
|
|
8038
8185
|
handleCodeTestResult: se,
|
|
8039
8186
|
nextQuestion: Z,
|
|
8040
8187
|
previousQuestion: ae,
|
|
8041
|
-
nextLesson:
|
|
8188
|
+
nextLesson: _,
|
|
8042
8189
|
previousLesson: pe,
|
|
8043
8190
|
completeLesson: W,
|
|
8044
8191
|
completeCurriculum: oe,
|
|
@@ -8047,56 +8194,56 @@ const yt = Me(({
|
|
|
8047
8194
|
getCurrentQuestion: () => E(),
|
|
8048
8195
|
getCurrentLesson: () => y(),
|
|
8049
8196
|
// Direct access to avatar ref (always returns current value)
|
|
8050
|
-
getAvatarRef: () =>
|
|
8197
|
+
getAvatarRef: () => h.current,
|
|
8051
8198
|
// Convenience methods that delegate to avatar (always check current ref)
|
|
8052
|
-
speakText: async (v,
|
|
8053
|
-
await
|
|
8199
|
+
speakText: async (v, R = {}) => {
|
|
8200
|
+
await h.current?.resumeAudioContext?.();
|
|
8054
8201
|
const k = z.current || { lipsyncLang: "en" };
|
|
8055
|
-
|
|
8202
|
+
h.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang || k.lipsyncLang });
|
|
8056
8203
|
},
|
|
8057
8204
|
resumeAudioContext: async () => {
|
|
8058
|
-
if (
|
|
8059
|
-
return await
|
|
8060
|
-
const v =
|
|
8205
|
+
if (h.current?.resumeAudioContext)
|
|
8206
|
+
return await h.current.resumeAudioContext();
|
|
8207
|
+
const v = h.current?.talkingHead;
|
|
8061
8208
|
if (v?.audioCtx) {
|
|
8062
|
-
const
|
|
8063
|
-
if (
|
|
8209
|
+
const R = v.audioCtx;
|
|
8210
|
+
if (R.state === "suspended" || R.state === "interrupted")
|
|
8064
8211
|
try {
|
|
8065
|
-
await
|
|
8212
|
+
await R.resume(), console.log("Audio context resumed via talkingHead");
|
|
8066
8213
|
} catch (k) {
|
|
8067
8214
|
console.warn("Failed to resume audio context:", k);
|
|
8068
8215
|
}
|
|
8069
8216
|
} else
|
|
8070
8217
|
console.warn("Audio context not available yet");
|
|
8071
8218
|
},
|
|
8072
|
-
stopSpeaking: () =>
|
|
8073
|
-
pauseSpeaking: () =>
|
|
8074
|
-
resumeSpeaking: async () => await
|
|
8075
|
-
isPaused: () =>
|
|
8076
|
-
setMood: (v) =>
|
|
8077
|
-
playAnimation: (v,
|
|
8078
|
-
setBodyMovement: (v) =>
|
|
8079
|
-
setMovementIntensity: (v) =>
|
|
8080
|
-
playRandomDance: () =>
|
|
8081
|
-
playReaction: (v) =>
|
|
8082
|
-
playCelebration: () =>
|
|
8083
|
-
setShowFullAvatar: (v) =>
|
|
8084
|
-
setTimingAdjustment: (v) =>
|
|
8085
|
-
lockAvatarPosition: () =>
|
|
8086
|
-
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(),
|
|
8087
8234
|
// Custom action trigger
|
|
8088
|
-
triggerCustomAction: (v,
|
|
8235
|
+
triggerCustomAction: (v, R) => {
|
|
8089
8236
|
c.current.onCustomAction({
|
|
8090
8237
|
type: v,
|
|
8091
|
-
...
|
|
8238
|
+
...R,
|
|
8092
8239
|
state: { ...a.current }
|
|
8093
8240
|
});
|
|
8094
8241
|
},
|
|
8095
8242
|
// Responsive resize handler
|
|
8096
|
-
handleResize: () =>
|
|
8243
|
+
handleResize: () => h.current?.handleResize(),
|
|
8097
8244
|
// Avatar readiness check (always returns current value)
|
|
8098
|
-
isAvatarReady: () =>
|
|
8099
|
-
}), [X, S, $, se, Z,
|
|
8245
|
+
isAvatarReady: () => h.current?.isReady || !1
|
|
8246
|
+
}), [X, S, $, se, Z, _, W, oe, ee, E, y]);
|
|
8100
8247
|
const O = z.current || {
|
|
8101
8248
|
avatarUrl: "/avatars/brunette.glb",
|
|
8102
8249
|
avatarBody: "F",
|
|
@@ -8113,7 +8260,7 @@ const yt = Me(({
|
|
|
8113
8260
|
return /* @__PURE__ */ me("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ me(
|
|
8114
8261
|
Ve,
|
|
8115
8262
|
{
|
|
8116
|
-
ref:
|
|
8263
|
+
ref: h,
|
|
8117
8264
|
avatarUrl: O.avatarUrl,
|
|
8118
8265
|
avatarBody: O.avatarBody,
|
|
8119
8266
|
mood: O.mood,
|