@sage-rsc/talking-head-react 1.1.3 → 1.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/index.cjs +9 -2
- package/dist/index.js +718 -624
- package/package.json +1 -1
- package/src/lib/talkinghead.mjs +224 -16
package/dist/index.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { jsxs as Pe, jsx as me } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef as Me, useRef as
|
|
2
|
+
import { forwardRef as Me, useRef as O, useState as ce, useEffect as de, useCallback as F, useImperativeHandle as Ee, useLayoutEffect as Xe } from "react";
|
|
3
3
|
import * as f from "three";
|
|
4
4
|
import { OrbitControls as Ye } from "three/addons/controls/OrbitControls.js";
|
|
5
5
|
import { GLTFLoader as je } from "three/addons/loaders/GLTFLoader.js";
|
|
6
6
|
import { DRACOLoader as Qe } from "three/addons/loaders/DRACOLoader.js";
|
|
7
|
-
import { FBXLoader as
|
|
8
|
-
import { RoomEnvironment as
|
|
9
|
-
import
|
|
10
|
-
let
|
|
11
|
-
const A = [0, 0, 0, 0],
|
|
7
|
+
import { FBXLoader as Be } from "three/addons/loaders/FBXLoader.js";
|
|
8
|
+
import { RoomEnvironment as _e } from "three/addons/environments/RoomEnvironment.js";
|
|
9
|
+
import qe from "three/addons/libs/stats.module.js";
|
|
10
|
+
let p, re, he;
|
|
11
|
+
const A = [0, 0, 0, 0], z = new f.Vector3(), ze = new f.Vector3(), ie = new f.Vector3(), Ce = new f.Vector3();
|
|
12
12
|
new f.Plane();
|
|
13
13
|
new f.Ray();
|
|
14
14
|
new f.Euler();
|
|
15
|
-
const
|
|
15
|
+
const oe = 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), Ke = new f.Vector3(1, 0, 0),
|
|
17
|
+
const He = new f.Vector3(0, 0, 1), Ke = new f.Vector3(1, 0, 0), $e = new f.Vector3(0, 1, 0), Je = new f.Vector3(0, 0, 1);
|
|
18
18
|
class et {
|
|
19
19
|
constructor(t = null) {
|
|
20
20
|
this.opt = Object.assign({
|
|
@@ -264,7 +264,7 @@ class et {
|
|
|
264
264
|
"pivot",
|
|
265
265
|
"helper"
|
|
266
266
|
].forEach((n) => {
|
|
267
|
-
|
|
267
|
+
p = this.getValue(t.name, n), p && (e[n] = p);
|
|
268
268
|
}), e;
|
|
269
269
|
});
|
|
270
270
|
}
|
|
@@ -279,7 +279,7 @@ class et {
|
|
|
279
279
|
this.armature.traverse((o) => {
|
|
280
280
|
e.has(o) || (e.set(o, t), t++);
|
|
281
281
|
}), this.data.sort((o, l) => e.get(o.bone) - e.get(l.bone)), this.data.forEach((o) => {
|
|
282
|
-
|
|
282
|
+
p = this.dict[o.boneParent.name], p && (p.children || (p.children = []), p.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
285
|
i(o).forEach((u) => {
|
|
@@ -321,7 +321,7 @@ class et {
|
|
|
321
321
|
/// Bone's parent object
|
|
322
322
|
vBasis: r.position.clone(),
|
|
323
323
|
// Original local position
|
|
324
|
-
vWorld: r.parent.getWorldPosition(
|
|
324
|
+
vWorld: r.parent.getWorldPosition(z).clone(),
|
|
325
325
|
// World position, parent
|
|
326
326
|
qBasis: r.parent.quaternion.clone(),
|
|
327
327
|
// Original quaternion, parent
|
|
@@ -338,7 +338,7 @@ class et {
|
|
|
338
338
|
ea: [0, 0, 0, 0]
|
|
339
339
|
// External acceleration [m/s^2]
|
|
340
340
|
};
|
|
341
|
-
h.boneParent.matrixWorld.decompose(
|
|
341
|
+
h.boneParent.matrixWorld.decompose(z, oe, ie), z.copy(He).applyQuaternion(oe).setY(0).normalize(), oe.premultiply(Oe.setFromUnitVectors(He, z).invert()).normalize(), h.qWorldInverseYaw = oe.clone().normalize(), this.data.push(h), this.dict[u] = h;
|
|
342
342
|
try {
|
|
343
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) {
|
|
@@ -356,22 +356,22 @@ class et {
|
|
|
356
356
|
for (this.timerMs += t, t > 1e3 && (this.timerMs = 0), t /= 1e3, e = 0, i = this.objectsUpdate.length; e < i; e++)
|
|
357
357
|
o = this.objectsUpdate[e], o.updateMatrix(), o.parent === null ? o.matrixWorld.copy(o.matrix) : o.matrixWorld.multiplyMatrices(o.parent.matrixWorld, o.matrix), o.matrixWorldNeedsUpdate = !1;
|
|
358
358
|
for (e = 0, i = this.data.length; e < i; e++) {
|
|
359
|
-
if (o = this.data[e],
|
|
359
|
+
if (o = this.data[e], z.copy(o.vWorld), fe.copy(o.boneParent.matrixWorld), xe.copy(fe).invert(), o.vWorld.setFromMatrixPosition(fe), z.applyMatrix4(xe), z.length() > 0.5 && (console.info("Info: Unrealistic jump of " + z.length().toFixed(2) + " meters."), z.setLength(0.5)), z.applyQuaternion(o.bone.quaternion), A[0] = z.x, A[1] = z.y, A[2] = -z.z, A[3] = z.length() / 3, o.children)
|
|
360
360
|
for (n = 0, s = o.children.length; n < s; n++)
|
|
361
|
-
|
|
362
|
-
if (
|
|
361
|
+
p = o.children[n], A[0] -= p.v[0] * t / 3, A[1] -= p.v[1] * t / 3, A[2] += p.v[2] * t / 3, A[3] -= p.v[3] * t / 3;
|
|
362
|
+
if (p = this.opt.sensitivityFactor, A[0] *= o.ext * p, A[1] *= o.ext * p, A[2] *= o.ext * p, A[3] *= o.ext * p, o.isX && (p = A[0] / t, o.ea[0] = (p - o.ev[0]) / t, o.ev[0] = p, o.a[0] = -o.k[0] * o.p[0] - o.c[0] * o.v[0] - o.ea[0], o.p[0] += o.v[0] * t + o.a[0] * t * t / 2 + A[0], p = o.v[0] + o.a[0] * t / 2, p = -o.k[0] * o.p[0] - o.c[0] * p - o.ea[0], o.v[0] = o.v[0] + (p + o.a[0]) * t / 2), o.isY && (p = A[1] / t, o.ea[1] = (p - o.ev[1]) / t, o.ev[1] = p, o.a[1] = -o.k[1] * o.p[1] - o.c[1] * o.v[1] - o.ea[1], o.p[1] += o.v[1] * t + o.a[1] * t * t / 2 + A[1], p = o.v[1] + o.a[1] * t / 2, p = -o.k[1] * o.p[1] - o.c[1] * p - o.ea[1], o.v[1] = o.v[1] + (p + o.a[1]) * t / 2), o.isZ && (p = A[2] / t, o.ea[2] = (p - o.ev[2]) / t, o.ev[2] = p, o.a[2] = -o.k[2] * o.p[2] - o.c[2] * o.v[2] - o.ea[2], o.p[2] += o.v[2] * t + o.a[2] * t * t / 2 + A[2], p = o.v[2] + o.a[2] * t / 2, p = -o.k[2] * o.p[2] - o.c[2] * p - o.ea[2], o.v[2] = o.v[2] + (p + o.a[2]) * t / 2), o.isT && (p = A[3] / t, o.ea[3] = (p - o.ev[3]) / t, o.ev[3] = p, o.a[3] = -o.k[3] * o.p[3] - o.c[3] * o.v[3] - o.ea[3], o.p[3] += o.v[3] * t + o.a[3] * t * t / 2 + A[3], p = o.v[3] + o.a[3] * t / 2, p = -o.k[3] * o.p[3] - o.c[3] * p - o.ea[3], o.v[3] = o.v[3] + (p + o.a[3]) * t / 2), this.timerMs < this.opt.warmupMs && (o.v[0] *= 1e-4, o.p[0] *= 1e-4, o.v[1] *= 1e-4, o.p[1] *= 1e-4, o.v[2] *= 1e-4, o.p[2] *= 1e-4, o.v[3] *= 1e-4, o.p[3] *= 1e-4), A[0] = o.p[0], A[1] = o.p[1], A[2] = o.p[2], A[3] = o.p[3], p = this.opt.movementFactor, A[0] *= p, A[1] *= p, A[2] *= p, A[3] *= p, o.dl && (p = o.dl, A[0] += p[0], A[1] += p[1], A[2] += p[2]), o.dw && (p = o.dw, z.set(
|
|
363
363
|
o.vBasis.x + A[0],
|
|
364
364
|
o.vBasis.y + A[1],
|
|
365
365
|
o.vBasis.z + A[2]
|
|
366
|
-
),
|
|
366
|
+
), z.applyMatrix4(fe), z.x += p[0], z.y += p[1], z.z += p[2], z.applyMatrix4(xe), A[0] += z.x - o.vBasis.x, A[1] += z.y - o.vBasis.y, A[2] += z.z - o.vBasis.z), o.limits && this.opt.isLimits && (p = o.limits, p[0] && (p[0][0] !== null && A[0] < p[0][0] && (A[0] = p[0][0]), p[0][1] !== null && A[0] > p[0][1] && (A[0] = p[0][1])), p[1] && (p[1][0] !== null && A[1] < p[1][0] && (A[1] = p[1][0]), p[1][1] !== null && A[1] > p[1][1] && (A[1] = p[1][1])), p[2] && (p[2][0] !== null && A[2] < p[2][0] && (A[2] = p[2][0]), p[2][1] !== null && A[2] > p[2][1] && (A[2] = p[2][1])), p[3] && (p[3][0] !== null && A[3] < p[3][0] && (A[3] = p[3][0]), p[3][1] !== null && A[3] > p[3][1] && (A[3] = p[3][1]))), o.isPoint)
|
|
367
367
|
o.bone.position.set(
|
|
368
368
|
o.vBasis.x + A[0],
|
|
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(
|
|
372
|
+
else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(z, oe, ie), z.copy(He).applyQuaternion(oe).setY(0).normalize(), oe.premultiply(Oe.setFromUnitVectors(He, z).invert()).normalize(), o.boneParent.quaternion.multiply(oe.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (p = Math.atan(A[0] / o.l), oe.setFromAxisAngle(Je, -p), o.boneParent.quaternion.multiply(oe)), o.isY && (p = o.l / 3, p = p * Math.tanh(A[1] / p), o.bone.position.setLength(o.l + p)), o.isX && (p = Math.atan(A[2] / o.l), oe.setFromAxisAngle(Ke, -p), o.boneParent.quaternion.multiply(oe)), o.isT && (p = 1.5 * Math.tanh(A[3] * 1.5), oe.setFromAxisAngle($e, -p), o.boneParent.quaternion.multiply(oe)), o.boneParent.updateWorldMatrix(!1, !0), o.excludes && this.opt.isExcludes)
|
|
373
373
|
for (n = 0, s = o.excludes.length; n < s; n++)
|
|
374
|
-
|
|
374
|
+
p = o.excludes[n], ie.set(0, 0, 0), p.deltaLocal && (ie.x += p.deltaLocal[0], ie.y += p.deltaLocal[1], ie.z += p.deltaLocal[2]), ie.applyMatrix4(p.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ie.applyMatrix4(xe), z.copy(o.bone.position), !(z.distanceToSquared(ie) >= p.radiusSq) && (he = z.length(), re = ie.length(), !(re > p.radius + he) && (re < Math.abs(p.radius - he) || (re = (re * re + he * he - p.radiusSq) / (2 * re), ie.normalize(), Ce.copy(ie).multiplyScalar(re), re = Math.sqrt(he * he - re * re), z.subVectors(z, Ce).projectOnPlane(ie).normalize().multiplyScalar(re), ze.subVectors(o.vBasis, Ce).projectOnPlane(ie).normalize(), he = ze.dot(z), he < 0 && (he = Math.sqrt(re * re - he * he), ze.multiplyScalar(he), z.add(ze)), z.add(Ce).normalize(), ie.copy(o.bone.position).normalize(), oe.setFromUnitVectors(ie, z), o.boneParent.quaternion.premultiply(oe), o.boneParent.updateWorldMatrix(!1, !0))));
|
|
375
375
|
}
|
|
376
376
|
this.helpers.isActive && this.updateHelpers();
|
|
377
377
|
}
|
|
@@ -382,18 +382,18 @@ class et {
|
|
|
382
382
|
* @param {boolean} [keepSetting=false] If true, keep the previos all setting
|
|
383
383
|
*/
|
|
384
384
|
showHelpers(t) {
|
|
385
|
-
if (this.hideHelpers(), this.helpers.isShowAll = t === void 0 ? this.helpers.isShowAll : t === !0,
|
|
386
|
-
(this.helpers.isShowAll || e.helper === !0) && (
|
|
385
|
+
if (this.hideHelpers(), this.helpers.isShowAll = t === void 0 ? this.helpers.isShowAll : t === !0, p = this.helpers, this.data.forEach((e) => {
|
|
386
|
+
(this.helpers.isShowAll || e.helper === !0) && (p.points.bones.push(e.bone), p.points.pivots.push(e.pivot), e.type !== 0 && p.lines.bones.push(e.bone), e.excludes && e.excludes.forEach((n) => {
|
|
387
387
|
let i = !1;
|
|
388
|
-
for (let s = 0; s <
|
|
389
|
-
if (
|
|
388
|
+
for (let s = 0; s < p.excludes.bones.length; s++)
|
|
389
|
+
if (p.excludes.bones[s] === n.bone && p.excludes.radii[s] === n.radius && !(p.excludes.deltaLocals[s] === null && n.deltaLocal !== null) && !(p.excludes.deltaLocals[s] !== null && n.deltaLocal === null) && !(p.excludes.deltaLocals[s] !== null && p.excludes.deltaLocals[s].some((o, l) => o !== n.deltaLocal[l]))) {
|
|
390
390
|
i = !0;
|
|
391
391
|
break;
|
|
392
392
|
}
|
|
393
|
-
i || (
|
|
393
|
+
i || (p.excludes.bones.push(n.bone), p.excludes.radii.push(n.radius), p.excludes.deltaLocals.push(n.deltaLocal ? [...n.deltaLocal] : null), p.excludes.objects.push(null));
|
|
394
394
|
}));
|
|
395
|
-
}),
|
|
396
|
-
const i = new f.SphereGeometry(
|
|
395
|
+
}), p = this.helpers.excludes, this.opt.isExcludes && p.bones.length && p.bones.forEach((e, n) => {
|
|
396
|
+
const i = new f.SphereGeometry(p.radii[n], 6, 6), s = new f.MeshBasicMaterial({
|
|
397
397
|
depthTest: !1,
|
|
398
398
|
depthWrite: !1,
|
|
399
399
|
toneMapped: !1,
|
|
@@ -401,16 +401,16 @@ class et {
|
|
|
401
401
|
wireframe: !0,
|
|
402
402
|
color: this.opt.helperExcludesColor
|
|
403
403
|
});
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
404
|
+
p.objects[n] = new f.Mesh(i, s), p.objects[n].renderOrder = 997, e.add(p.objects[n]), p.deltaLocals[n] && p.objects[n].position.set(
|
|
405
|
+
p.deltaLocals[n][0],
|
|
406
|
+
p.deltaLocals[n][1],
|
|
407
|
+
p.deltaLocals[n][2]
|
|
408
408
|
);
|
|
409
|
-
}),
|
|
409
|
+
}), p = this.helpers.points, p.bones.length) {
|
|
410
410
|
this.helpers.isActive = !0;
|
|
411
|
-
const e = new f.BufferGeometry(), n =
|
|
411
|
+
const e = new f.BufferGeometry(), n = p.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 =
|
|
413
|
+
const i = new f.Color(this.opt.helperBoneColor1), s = new f.Color(this.opt.helperBoneColor2), o = p.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,
|
|
@@ -420,12 +420,12 @@ class et {
|
|
|
420
420
|
size: 0.2,
|
|
421
421
|
vertexColors: !0
|
|
422
422
|
});
|
|
423
|
-
|
|
423
|
+
p.object = new f.Points(e, l), p.object.renderOrder = 998, p.object.matrix = this.armature.matrixWorld, p.object.matrixAutoUpdate = !1, this.scene.add(p.object);
|
|
424
424
|
}
|
|
425
|
-
if (
|
|
426
|
-
const e = new f.BufferGeometry(), n =
|
|
425
|
+
if (p = this.helpers.lines, p.bones.length) {
|
|
426
|
+
const e = new f.BufferGeometry(), n = p.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 =
|
|
428
|
+
const i = new f.Color(this.opt.helperLinkColor1), s = new f.Color(this.opt.helperLinkColor2), o = p.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,
|
|
@@ -434,26 +434,26 @@ class et {
|
|
|
434
434
|
toneMapped: !1,
|
|
435
435
|
transparent: !0
|
|
436
436
|
});
|
|
437
|
-
|
|
437
|
+
p.object = new f.LineSegments(e, l), p.object.renderOrder = 999, p.object.matrix = this.armature.matrixWorld, p.object.matrixAutoUpdate = !1, this.scene.add(p.object);
|
|
438
438
|
}
|
|
439
439
|
}
|
|
440
440
|
/**
|
|
441
441
|
* Update the positions of dynamic bone helpers.
|
|
442
442
|
*/
|
|
443
443
|
updateHelpers() {
|
|
444
|
-
if (
|
|
444
|
+
if (p = this.helpers.points, p.bones.length) {
|
|
445
445
|
xe.copy(this.armature.matrixWorld).invert();
|
|
446
|
-
const t =
|
|
447
|
-
for (let e = 0, n =
|
|
448
|
-
fe.multiplyMatrices(xe,
|
|
449
|
-
t.needsUpdate = !0,
|
|
446
|
+
const t = p.object.geometry.getAttribute("position");
|
|
447
|
+
for (let e = 0, n = p.bones.length; e < n; e++)
|
|
448
|
+
fe.multiplyMatrices(xe, p.bones[e].matrixWorld), z.setFromMatrixPosition(fe), t.setXYZ(e, z.x, z.y, z.z);
|
|
449
|
+
t.needsUpdate = !0, p.object.updateMatrixWorld();
|
|
450
450
|
}
|
|
451
|
-
if (
|
|
451
|
+
if (p = this.helpers.lines, p.bones.length) {
|
|
452
452
|
xe.copy(this.armature.matrixWorld).invert();
|
|
453
|
-
const t =
|
|
454
|
-
for (let e = 0, n = 0, i =
|
|
455
|
-
fe.multiplyMatrices(xe,
|
|
456
|
-
t.needsUpdate = !0,
|
|
453
|
+
const t = p.object.geometry.getAttribute("position");
|
|
454
|
+
for (let e = 0, n = 0, i = p.bones.length; e < i; e++, n += 2)
|
|
455
|
+
fe.multiplyMatrices(xe, p.bones[e].matrixWorld), z.setFromMatrixPosition(fe), t.setXYZ(n, z.x, z.y, z.z), fe.multiplyMatrices(xe, p.bones[e].parent.matrixWorld), z.setFromMatrixPosition(fe), t.setXYZ(n + 1, z.x, z.y, z.z);
|
|
456
|
+
t.needsUpdate = !0, p.object.updateMatrixWorld();
|
|
457
457
|
}
|
|
458
458
|
}
|
|
459
459
|
/**
|
|
@@ -462,9 +462,9 @@ class et {
|
|
|
462
462
|
hideHelpers() {
|
|
463
463
|
[this.helpers.points, this.helpers.lines].forEach((t) => {
|
|
464
464
|
t.bones = [], t.object && (this.scene.remove(t.object), t.object.geometry.dispose(), t.object.material.dispose(), t.object = null);
|
|
465
|
-
}),
|
|
466
|
-
t && (
|
|
467
|
-
}),
|
|
465
|
+
}), p = this.helpers.excludes, p.objects.forEach((t, e) => {
|
|
466
|
+
t && (p.bones[e].remove(t), t.geometry.dispose(), t.material.dispose());
|
|
467
|
+
}), p.bones = [], p.deltaLocals = [], p.radii = [], p.objects = [], this.helpers.isActive = !1;
|
|
468
468
|
}
|
|
469
469
|
/**
|
|
470
470
|
* Start dynamic bones.
|
|
@@ -2629,7 +2629,7 @@ const ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
|
2629
2629
|
fr: rt,
|
|
2630
2630
|
fi: ht,
|
|
2631
2631
|
lt: ct
|
|
2632
|
-
},
|
|
2632
|
+
}, _ = new f.Quaternion(), V = new f.Euler(), Re = new f.Vector3(), ve = new f.Vector3(), We = new f.Box3();
|
|
2633
2633
|
new f.Matrix4();
|
|
2634
2634
|
new f.Matrix4();
|
|
2635
2635
|
new f.Vector3();
|
|
@@ -2637,7 +2637,7 @@ new f.Vector3(0, 0, 1);
|
|
|
2637
2637
|
const mt = new f.Vector3(1, 0, 0);
|
|
2638
2638
|
new f.Vector3(0, 1, 0);
|
|
2639
2639
|
new f.Vector3(0, 0, 1);
|
|
2640
|
-
class
|
|
2640
|
+
class Ne {
|
|
2641
2641
|
/**
|
|
2642
2642
|
* Avatar.
|
|
2643
2643
|
* @typedef {Object} Avatar
|
|
@@ -2763,7 +2763,7 @@ class De {
|
|
|
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 qe(), 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: {
|
|
@@ -4086,7 +4086,7 @@ class De {
|
|
|
4086
4086
|
this.opt.lightSpotDispersion
|
|
4087
4087
|
), this.setLighting(this.opt);
|
|
4088
4088
|
const l = new f.PMREMGenerator(this.renderer);
|
|
4089
|
-
l.compileEquirectangularShader(), this.scene.environment = l.fromScene(new
|
|
4089
|
+
l.compileEquirectangularShader(), this.scene.environment = l.fromScene(new _e()).texture, this.resizeobserver = new ResizeObserver(this.onResize.bind(this)), this.resizeobserver.observe(this.nodeAvatar), this.controls = new Ye(this.camera, this.renderer.domElement), this.controls.enableZoom = this.opt.cameraZoomEnable, this.controls.enableRotate = this.opt.cameraRotateEnable, this.controls.enablePan = this.opt.cameraPanEnable, this.controls.minDistance = 2, this.controls.maxDistance = 2e3, this.controls.autoRotateSpeed = 0, this.controls.autoRotate = !1, this.controls.update(), this.cameraClock = null;
|
|
4090
4090
|
}
|
|
4091
4091
|
this.ikMesh = new f.SkinnedMesh();
|
|
4092
4092
|
const s = {
|
|
@@ -4400,7 +4400,7 @@ class De {
|
|
|
4400
4400
|
if (e.x === 0 && e.y === 0 && e.z === 0) continue;
|
|
4401
4401
|
V.set(e.x, e.y, e.z);
|
|
4402
4402
|
const n = this.poseAvatar.props[t];
|
|
4403
|
-
n.isQuaternion ? (
|
|
4403
|
+
n.isQuaternion ? (_.setFromEuler(V), n.multiply(_)) : n.isVector3 && n.add(V);
|
|
4404
4404
|
}
|
|
4405
4405
|
}
|
|
4406
4406
|
/**
|
|
@@ -5193,7 +5193,7 @@ class De {
|
|
|
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) && 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 && (
|
|
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 && (_.setFromAxisAngle(mt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(_)), We.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(Re), Re.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(ve), ve.sub(this.armature.position), this.objectHips.position.y -= We.min.y / 2, this.objectHips.position.x -= (Re.x + ve.x) / 4, this.objectHips.position.z -= (Re.z + ve.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) {
|
|
@@ -5264,10 +5264,10 @@ class De {
|
|
|
5264
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 I = b === x.length - 1,
|
|
5268
|
-
let
|
|
5269
|
-
const
|
|
5270
|
-
if (
|
|
5267
|
+
const I = b === x.length - 1, H = x[b].match(l);
|
|
5268
|
+
let m = x[b].match(s);
|
|
5269
|
+
const T = x[b].match(u), k = x[b].match(o);
|
|
5270
|
+
if (m && !I && !T && x[b + 1].match(s) && (m = !1), n && (h += x[b]), H && (!i || i.every((y) => b < y[0] || b > y[1])) && (a += x[b]), (k || m || 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({
|
|
@@ -5280,12 +5280,12 @@ class De {
|
|
|
5280
5280
|
}), h = ""), a.length)) {
|
|
5281
5281
|
const y = this.lipsyncWordsToVisemes(a, r);
|
|
5282
5282
|
if (y && y.visemes && y.visemes.length) {
|
|
5283
|
-
const
|
|
5283
|
+
const M = y.times[y.visemes.length - 1] + y.durations[y.visemes.length - 1];
|
|
5284
5284
|
for (let P = 0; P < y.visemes.length; P++)
|
|
5285
5285
|
g.push({
|
|
5286
5286
|
mark: c,
|
|
5287
5287
|
template: { name: "viseme" },
|
|
5288
|
-
ts: [(y.times[P] - 0.6) /
|
|
5288
|
+
ts: [(y.times[P] - 0.6) / M, (y.times[P] + 0.5) / M, (y.times[P] + y.durations[P] + 0.5) / M],
|
|
5289
5289
|
vs: {
|
|
5290
5290
|
["viseme_" + y.visemes[P]]: [null, y.visemes[P] === "PP" || y.visemes[P] === "FF" ? 0.9 : 0.6, 0]
|
|
5291
5291
|
}
|
|
@@ -5293,14 +5293,14 @@ class De {
|
|
|
5293
5293
|
}
|
|
5294
5294
|
a = "", c++;
|
|
5295
5295
|
}
|
|
5296
|
-
if (
|
|
5296
|
+
if (m || I) {
|
|
5297
5297
|
if (d.length || I && g.length) {
|
|
5298
5298
|
const y = {
|
|
5299
5299
|
anim: g
|
|
5300
5300
|
};
|
|
5301
5301
|
n && (y.onSubtitles = n), d.length && !e.avatarMute && (y.text = d, e.avatarMood && (y.mood = e.avatarMood), e.ttsLang && (y.lang = e.ttsLang), e.ttsVoice && (y.voice = e.ttsVoice), e.ttsRate && (y.rate = e.ttsRate), e.ttsVoice && (y.pitch = e.ttsPitch), e.ttsVolume && (y.volume = e.ttsVolume)), this.speechQueue.push(y), d = [], a = "", c = 0, g = [];
|
|
5302
5302
|
}
|
|
5303
|
-
if (
|
|
5303
|
+
if (T) {
|
|
5304
5304
|
let y = this.animEmojis[x[b]];
|
|
5305
5305
|
y && y.link && (y = this.animEmojis[y.link]), y && this.speechQueue.push({ emoji: y });
|
|
5306
5306
|
}
|
|
@@ -5398,10 +5398,10 @@ class De {
|
|
|
5398
5398
|
let x = 0.6 + this.convertRange(g, [0, h], [0, 0.4]);
|
|
5399
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 I = r + c.times[b] / d * h,
|
|
5401
|
+
const I = r + c.times[b] / d * h, H = c.durations[b] / d * h;
|
|
5402
5402
|
o.push({
|
|
5403
5403
|
template: { name: "viseme" },
|
|
5404
|
-
ts: [I - Math.min(60, 2 *
|
|
5404
|
+
ts: [I - Math.min(60, 2 * H / 3), I + Math.min(25, H / 2), I + H + Math.min(60, H / 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
|
}
|
|
@@ -5479,12 +5479,12 @@ class De {
|
|
|
5479
5479
|
*/
|
|
5480
5480
|
async synthesizeWithBrowserTTS(t) {
|
|
5481
5481
|
return new Promise((e, n) => {
|
|
5482
|
-
const i = t.text.map((
|
|
5482
|
+
const i = t.text.map((m) => m.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
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
5484
|
const h = speechSynthesis.getVoices(), a = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
|
|
5485
5485
|
if (a && h.length > 0) {
|
|
5486
|
-
const
|
|
5487
|
-
|
|
5486
|
+
const m = h.find((T) => T.name.includes(a) || T.lang === o);
|
|
5487
|
+
m && (s.voice = m);
|
|
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);
|
|
5490
5490
|
console.log("Browser TTS Lip-sync Debug:", {
|
|
@@ -5497,23 +5497,23 @@ class De {
|
|
|
5497
5497
|
});
|
|
5498
5498
|
const I = [];
|
|
5499
5499
|
if (b && b.visemes && b.visemes.length > 0) {
|
|
5500
|
-
const
|
|
5501
|
-
for (let
|
|
5502
|
-
const
|
|
5500
|
+
const m = b.times[b.visemes.length - 1] + b.durations[b.visemes.length - 1];
|
|
5501
|
+
for (let T = 0; T < b.visemes.length; T++) {
|
|
5502
|
+
const k = b.visemes[T], y = b.times[T] / m, M = b.durations[T] / m, P = y * c, D = M * c;
|
|
5503
5503
|
I.push({
|
|
5504
5504
|
template: { name: "viseme" },
|
|
5505
|
-
ts: [P - Math.min(60, 2 *
|
|
5505
|
+
ts: [P - Math.min(60, 2 * D / 3), P + Math.min(25, D / 2), P + D + Math.min(60, D / 2)],
|
|
5506
5506
|
vs: {
|
|
5507
|
-
["viseme_" +
|
|
5507
|
+
["viseme_" + k]: [null, k === "PP" || k === "FF" ? 0.9 : 0.6, 0]
|
|
5508
5508
|
}
|
|
5509
5509
|
});
|
|
5510
5510
|
}
|
|
5511
5511
|
}
|
|
5512
|
-
const
|
|
5513
|
-
this.audioPlaylist.push({ anim:
|
|
5512
|
+
const H = [...t.anim, ...I];
|
|
5513
|
+
this.audioPlaylist.push({ anim: H, audio: d }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
|
|
5514
5514
|
e();
|
|
5515
|
-
}, s.onerror = (
|
|
5516
|
-
console.error("Speech synthesis error:",
|
|
5515
|
+
}, s.onerror = (m) => {
|
|
5516
|
+
console.error("Speech synthesis error:", m.error), n(m.error);
|
|
5517
5517
|
}, speechSynthesis.speak(s);
|
|
5518
5518
|
});
|
|
5519
5519
|
}
|
|
@@ -6146,7 +6146,7 @@ class De {
|
|
|
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),
|
|
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), Re.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), ve.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(Re, ve).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,10 +6159,10 @@ class De {
|
|
|
6159
6159
|
this.lookAt(null, null, t);
|
|
6160
6160
|
return;
|
|
6161
6161
|
}
|
|
6162
|
-
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0),
|
|
6163
|
-
const n = new f.Vector3().subVectors(e,
|
|
6162
|
+
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), Re.setFromMatrixPosition(this.objectLeftEye.matrixWorld), ve.setFromMatrixPosition(this.objectRightEye.matrixWorld), Re.add(ve).divideScalar(2), _.copy(this.armature.quaternion), _.multiply(this.poseTarget.props["Hips.quaternion"]), _.multiply(this.poseTarget.props["Spine.quaternion"]), _.multiply(this.poseTarget.props["Spine1.quaternion"]), _.multiply(this.poseTarget.props["Spine2.quaternion"]), _.multiply(this.poseTarget.props["Neck.quaternion"]), _.multiply(this.poseTarget.props["Head.quaternion"]);
|
|
6163
|
+
const n = new f.Vector3().subVectors(e, Re).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), u = new f.Quaternion().copy(l).multiply(
|
|
6165
|
+
const l = new f.Quaternion().setFromEuler(V), u = new f.Quaternion().copy(l).multiply(_.clone().invert());
|
|
6166
6166
|
V.setFromQuaternion(u, "YXZ");
|
|
6167
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) {
|
|
@@ -6199,21 +6199,21 @@ class De {
|
|
|
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
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),
|
|
6202
|
+
t === null && (t = u), e === null && (e = r), _.copy(this.armature.quaternion), _.multiply(this.poseTarget.props["Hips.quaternion"]), _.multiply(this.poseTarget.props["Spine.quaternion"]), _.multiply(this.poseTarget.props["Spine1.quaternion"]), _.multiply(this.poseTarget.props["Spine2.quaternion"]), _.multiply(this.poseTarget.props["Neck.quaternion"]), _.multiply(this.poseTarget.props["Head.quaternion"]), V.setFromQuaternion(_);
|
|
6203
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
6204
|
b = Math.min(0.6, Math.max(-0.3, b)), I = Math.min(0.8, Math.max(-0.8, I));
|
|
6205
|
-
let
|
|
6205
|
+
let H = (Math.random() - 0.5) / 4, m = (Math.random() - 0.5) / 4;
|
|
6206
6206
|
if (n) {
|
|
6207
|
-
let
|
|
6208
|
-
|
|
6209
|
-
const
|
|
6207
|
+
let T = this.animQueue.findIndex((y) => y.template.name === "lookat");
|
|
6208
|
+
T !== -1 && this.animQueue.splice(T, 1);
|
|
6209
|
+
const k = {
|
|
6210
6210
|
name: "lookat",
|
|
6211
6211
|
dt: [750, n],
|
|
6212
6212
|
vs: {
|
|
6213
|
-
bodyRotateX: [b +
|
|
6214
|
-
bodyRotateY: [I +
|
|
6215
|
-
eyesRotateX: [-3 *
|
|
6216
|
-
eyesRotateY: [-5 *
|
|
6213
|
+
bodyRotateX: [b + H],
|
|
6214
|
+
bodyRotateY: [I + m],
|
|
6215
|
+
eyesRotateX: [-3 * H + 0.1],
|
|
6216
|
+
eyesRotateY: [-5 * m],
|
|
6217
6217
|
browInnerUp: [[0, 0.7]],
|
|
6218
6218
|
mouthLeft: [[0, 0.7]],
|
|
6219
6219
|
mouthRight: [[0, 0.7]],
|
|
@@ -6221,7 +6221,7 @@ class De {
|
|
|
6221
6221
|
headMove: [0]
|
|
6222
6222
|
}
|
|
6223
6223
|
};
|
|
6224
|
-
this.animQueue.push(this.animFactory(
|
|
6224
|
+
this.animQueue.push(this.animFactory(k));
|
|
6225
6225
|
}
|
|
6226
6226
|
}
|
|
6227
6227
|
/**
|
|
@@ -6421,17 +6421,31 @@ class De {
|
|
|
6421
6421
|
Spine01: "Spine1",
|
|
6422
6422
|
Spine02: "Spine2",
|
|
6423
6423
|
Spine03: "Spine2",
|
|
6424
|
+
Spine1: "Spine1",
|
|
6425
|
+
Spine2: "Spine2",
|
|
6426
|
+
Spine: "Spine1",
|
|
6427
|
+
// Head and neck
|
|
6428
|
+
Head: "Head",
|
|
6429
|
+
Neck: "Neck",
|
|
6430
|
+
Neck1: "Neck",
|
|
6431
|
+
Neck2: "Neck",
|
|
6424
6432
|
// Left arm mapping
|
|
6425
6433
|
L_Upperarm: "LeftArm",
|
|
6426
6434
|
L_Forearm: "LeftForeArm",
|
|
6427
6435
|
L_Hand: "LeftHand",
|
|
6428
6436
|
L_Shoulder: "LeftShoulder",
|
|
6437
|
+
L_Clavicle: "LeftShoulder",
|
|
6438
|
+
L_UpperArm: "LeftArm",
|
|
6439
|
+
L_ForeArm: "LeftForeArm",
|
|
6429
6440
|
L_Index1: "LeftHandIndex1",
|
|
6430
6441
|
L_Index2: "LeftHandIndex2",
|
|
6431
6442
|
L_Index3: "LeftHandIndex3",
|
|
6432
6443
|
L_Middle1: "LeftHandMiddle1",
|
|
6433
6444
|
L_Middle2: "LeftHandMiddle2",
|
|
6434
6445
|
L_Middle3: "LeftHandMiddle3",
|
|
6446
|
+
L_Mid1: "LeftHandMiddle1",
|
|
6447
|
+
L_Mid2: "LeftHandMiddle2",
|
|
6448
|
+
L_Mid3: "LeftHandMiddle3",
|
|
6435
6449
|
L_Ring1: "LeftHandRing1",
|
|
6436
6450
|
L_Ring2: "LeftHandRing2",
|
|
6437
6451
|
L_Ring3: "LeftHandRing3",
|
|
@@ -6446,12 +6460,18 @@ class De {
|
|
|
6446
6460
|
R_Forearm: "RightForeArm",
|
|
6447
6461
|
R_Hand: "RightHand",
|
|
6448
6462
|
R_Shoulder: "RightShoulder",
|
|
6463
|
+
R_Clavicle: "RightShoulder",
|
|
6464
|
+
R_UpperArm: "RightArm",
|
|
6465
|
+
R_ForeArm: "RightForeArm",
|
|
6449
6466
|
R_Index1: "RightHandIndex1",
|
|
6450
6467
|
R_Index2: "RightHandIndex2",
|
|
6451
6468
|
R_Index3: "RightHandIndex3",
|
|
6452
6469
|
R_Middle1: "RightHandMiddle1",
|
|
6453
6470
|
R_Middle2: "RightHandMiddle2",
|
|
6454
6471
|
R_Middle3: "RightHandMiddle3",
|
|
6472
|
+
R_Mid1: "RightHandMiddle1",
|
|
6473
|
+
R_Mid2: "RightHandMiddle2",
|
|
6474
|
+
R_Mid3: "RightHandMiddle3",
|
|
6455
6475
|
R_Ring1: "RightHandRing1",
|
|
6456
6476
|
R_Ring2: "RightHandRing2",
|
|
6457
6477
|
R_Ring3: "RightHandRing3",
|
|
@@ -6465,9 +6485,17 @@ class De {
|
|
|
6465
6485
|
L_Thigh: "LeftUpLeg",
|
|
6466
6486
|
L_Calf: "LeftLeg",
|
|
6467
6487
|
L_Foot: "LeftFoot",
|
|
6488
|
+
L_UpLeg: "LeftUpLeg",
|
|
6489
|
+
L_Leg: "LeftLeg",
|
|
6468
6490
|
R_Thigh: "RightUpLeg",
|
|
6469
6491
|
R_Calf: "RightLeg",
|
|
6470
|
-
R_Foot: "RightFoot"
|
|
6492
|
+
R_Foot: "RightFoot",
|
|
6493
|
+
R_UpLeg: "RightUpLeg",
|
|
6494
|
+
R_Leg: "RightLeg",
|
|
6495
|
+
// Root/Hips
|
|
6496
|
+
Hips: "Hips",
|
|
6497
|
+
Root: "Hips",
|
|
6498
|
+
Pelvis: "Hips"
|
|
6471
6499
|
};
|
|
6472
6500
|
if (i[n]) {
|
|
6473
6501
|
const a = i[n];
|
|
@@ -6494,7 +6522,7 @@ class De {
|
|
|
6494
6522
|
if (e.has(d))
|
|
6495
6523
|
return d;
|
|
6496
6524
|
}
|
|
6497
|
-
const r = s.match(/^[rl]
|
|
6525
|
+
const r = s.match(/^[rl]_(?:middle|mid)(\d+)$/);
|
|
6498
6526
|
if (r) {
|
|
6499
6527
|
const a = r[1], d = `${s.startsWith("r") ? "Right" : "Left"}HandMiddle${a}`;
|
|
6500
6528
|
if (e.has(d))
|
|
@@ -6511,7 +6539,7 @@ class De {
|
|
|
6511
6539
|
if (e.has(c))
|
|
6512
6540
|
return c;
|
|
6513
6541
|
}
|
|
6514
|
-
if (s.includes("upperarmtwist") || s.includes("forearmtwist"))
|
|
6542
|
+
if (s.includes("upperarmtwist") || s.includes("forearmtwist") || s.includes("ribstwist") || s.includes("breast") || s.includes("twist"))
|
|
6515
6543
|
return null;
|
|
6516
6544
|
if (s.match(/^[rl]_forearm/)) {
|
|
6517
6545
|
const c = `${s.startsWith("r") ? "Right" : "Left"}ForeArm`;
|
|
@@ -6523,9 +6551,37 @@ class De {
|
|
|
6523
6551
|
if (e.has(c))
|
|
6524
6552
|
return c;
|
|
6525
6553
|
}
|
|
6554
|
+
if (s.match(/^[rl]_clavicle/)) {
|
|
6555
|
+
const c = `${s.startsWith("r") ? "Right" : "Left"}Shoulder`;
|
|
6556
|
+
if (e.has(c))
|
|
6557
|
+
return c;
|
|
6558
|
+
}
|
|
6559
|
+
if (s.match(/^[rl]_shoulder/)) {
|
|
6560
|
+
const c = `${s.startsWith("r") ? "Right" : "Left"}Shoulder`;
|
|
6561
|
+
if (e.has(c))
|
|
6562
|
+
return c;
|
|
6563
|
+
}
|
|
6564
|
+
if (s.match(/^spine0?(\d+)$/)) {
|
|
6565
|
+
const a = s.match(/^spine0?(\d+)$/)[1];
|
|
6566
|
+
if (a === "1") {
|
|
6567
|
+
if (e.has("Spine1")) return "Spine1";
|
|
6568
|
+
} else if ((a === "2" || a === "3") && e.has("Spine2"))
|
|
6569
|
+
return "Spine2";
|
|
6570
|
+
}
|
|
6571
|
+
if (s.match(/^neck\d*$/) && e.has("Neck"))
|
|
6572
|
+
return "Neck";
|
|
6573
|
+
if (s === "head" && e.has("Head"))
|
|
6574
|
+
return "Head";
|
|
6575
|
+
if (s.match(/^(hips|pelvis|root)$/) && e.has("Hips"))
|
|
6576
|
+
return "Hips";
|
|
6526
6577
|
for (const a of e)
|
|
6527
6578
|
if (a.toLowerCase() === s)
|
|
6528
6579
|
return a;
|
|
6580
|
+
for (const a of e) {
|
|
6581
|
+
const c = a.toLowerCase();
|
|
6582
|
+
if ((c.includes(s) || s.includes(c)) && (c === s || c.replace(/[^a-z0-9]/g, "") === s.replace(/[^a-z0-9]/g, "")))
|
|
6583
|
+
return a;
|
|
6584
|
+
}
|
|
6529
6585
|
return null;
|
|
6530
6586
|
}
|
|
6531
6587
|
/**
|
|
@@ -6536,27 +6592,65 @@ class De {
|
|
|
6536
6592
|
* @returns {THREE.AnimationClip} Filtered animation clip with mapped bone names
|
|
6537
6593
|
*/
|
|
6538
6594
|
filterAnimationTracks(t, e) {
|
|
6539
|
-
const n = [], i = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Map();
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
6595
|
+
const n = [], i = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Set();
|
|
6596
|
+
this._loggedAvailableBones || (console.log("Available avatar bones:", Array.from(e).sort().join(", ")), this._loggedAvailableBones = !0), t.tracks.forEach((u) => {
|
|
6597
|
+
const h = u.name.split(".")[0];
|
|
6598
|
+
o.add(h);
|
|
6599
|
+
}), console.log(`
|
|
6600
|
+
=== FBX Animation "${t.name}" Bone Analysis ===`), console.log("FBX bone names in animation:", Array.from(o).sort().join(", ")), console.log(`Total FBX bones: ${o.size}, Avatar bones: ${e.size}
|
|
6601
|
+
`), t.tracks.forEach((u) => {
|
|
6602
|
+
const r = u.name.split("."), h = r[0], a = r[1], c = this.mapBoneName(h, e);
|
|
6603
|
+
if (c) {
|
|
6604
|
+
const d = `${c}.${a}`, g = u.clone();
|
|
6605
|
+
g.name = d;
|
|
6606
|
+
const x = c.includes("Arm") || c.includes("Hand") || c.includes("Shoulder"), b = c.includes("ForeArm");
|
|
6607
|
+
if (x && (a === "quaternion" || a === "rotation")) {
|
|
6608
|
+
if (a === "quaternion" && g.values && g.values.length >= 4) {
|
|
6609
|
+
const I = g.times.length;
|
|
6610
|
+
for (let H = 0; H < I; H++) {
|
|
6611
|
+
const m = H * 4;
|
|
6612
|
+
if (m + 3 < g.values.length) {
|
|
6613
|
+
let T = g.values[m], k = g.values[m + 1], y = g.values[m + 2], M = g.values[m + 3];
|
|
6614
|
+
if (b || c.includes("Hand")) {
|
|
6615
|
+
const P = Math.PI, D = Math.cos(P / 2), J = Math.sin(P / 2), S = D * M - J * T, G = D * T + J * M, Q = D * k - J * y, Z = D * y + J * k;
|
|
6616
|
+
T = G, k = Q, y = Z, M = S;
|
|
6617
|
+
}
|
|
6618
|
+
g.values[m] = T, g.values[m + 1] = k, g.values[m + 2] = y, g.values[m + 3] = M;
|
|
6619
|
+
}
|
|
6620
|
+
}
|
|
6621
|
+
} else if (a === "rotation" && g.values && g.values.length >= 3) {
|
|
6622
|
+
const I = g.times.length;
|
|
6623
|
+
for (let H = 0; H < I; H++) {
|
|
6624
|
+
const m = H * 3;
|
|
6625
|
+
m + 2 < g.values.length && (b || c.includes("Hand")) && (g.values[m + 1] += Math.PI);
|
|
6626
|
+
}
|
|
6627
|
+
}
|
|
6628
|
+
}
|
|
6629
|
+
n.push(g), h !== c && s.set(h, c);
|
|
6549
6630
|
} else
|
|
6550
|
-
i.add(
|
|
6551
|
-
}),
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
`
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
|
|
6631
|
+
i.add(h);
|
|
6632
|
+
}), console.log(`
|
|
6633
|
+
=== Mapping Results for "${t.name}" ===`), s.size > 0 && (console.info(`✓ Successfully mapped ${s.size} bone(s):`), Array.from(s.entries()).forEach(([u, r]) => {
|
|
6634
|
+
console.log(` ${u} → ${r}`);
|
|
6635
|
+
})), i.size > 0 && (console.warn(`
|
|
6636
|
+
✗ Could not map ${i.size} bone(s):`), Array.from(i).sort().forEach((u) => {
|
|
6637
|
+
console.log(` - ${u}`);
|
|
6638
|
+
const r = u.replace(/^(CC_Base_|mixamorig)/i, "").replace(/^[RL]_/, (a) => a.toLowerCase()), h = [];
|
|
6639
|
+
for (const a of e) {
|
|
6640
|
+
const c = a.toLowerCase(), d = r.toLowerCase();
|
|
6641
|
+
(c.includes(d) || d.includes(c)) && h.push(a);
|
|
6642
|
+
}
|
|
6643
|
+
h.length > 0 && console.log(` → Possible matches: ${h.slice(0, 3).join(", ")}`);
|
|
6644
|
+
}));
|
|
6645
|
+
const l = /* @__PURE__ */ new Set();
|
|
6646
|
+
return o.forEach((u) => {
|
|
6647
|
+
e.has(u) && !s.has(u) && l.add(u);
|
|
6648
|
+
}), l.size > 0 && (console.info(`
|
|
6649
|
+
✓ Direct matches (no mapping needed): ${l.size} bone(s)`), Array.from(l).sort().slice(0, 10).forEach((u) => {
|
|
6650
|
+
console.log(` - ${u}`);
|
|
6651
|
+
}), l.size > 10 && console.log(` ... and ${l.size - 10} more`)), console.log(`
|
|
6652
|
+
=== Summary ===`), console.log(`Total FBX tracks: ${t.tracks.length}`), console.log(`Valid tracks: ${n.length}`), console.log(`Mapped bones: ${s.size}`), console.log(`Direct matches: ${l.size}`), console.log(`Missing bones: ${i.size}`), console.log(`========================================
|
|
6653
|
+
`), n.length === 0 && 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);
|
|
6560
6654
|
}
|
|
6561
6655
|
async playAnimation(t, e = null, n = 10, i = 0, s = 0.01, o = !1) {
|
|
6562
6656
|
if (!this.armature) return;
|
|
@@ -6594,7 +6688,7 @@ class De {
|
|
|
6594
6688
|
} catch (c) {
|
|
6595
6689
|
console.warn(`Could not verify file existence for ${t}, attempting to load anyway:`, c);
|
|
6596
6690
|
}
|
|
6597
|
-
const h = new
|
|
6691
|
+
const h = new Be();
|
|
6598
6692
|
let a;
|
|
6599
6693
|
try {
|
|
6600
6694
|
a = await h.loadAsync(t, e);
|
|
@@ -6628,12 +6722,12 @@ class De {
|
|
|
6628
6722
|
const x = {};
|
|
6629
6723
|
c.tracks.forEach((I) => {
|
|
6630
6724
|
I.name = I.name.replaceAll("mixamorig", "");
|
|
6631
|
-
const
|
|
6632
|
-
if (
|
|
6633
|
-
for (let
|
|
6634
|
-
I.values[
|
|
6725
|
+
const H = I.name.split(".");
|
|
6726
|
+
if (H[1] === "position") {
|
|
6727
|
+
for (let m = 0; m < I.values.length; m++)
|
|
6728
|
+
I.values[m] = I.values[m] * s;
|
|
6635
6729
|
x[I.name] = new f.Vector3(I.values[0], I.values[1], I.values[2]);
|
|
6636
|
-
} else
|
|
6730
|
+
} else H[1] === "quaternion" ? x[I.name] = new f.Quaternion(I.values[0], I.values[1], I.values[2], I.values[3]) : H[1] === "rotation" && (x[H[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(I.values[0], I.values[1], I.values[2], "XYZ")).normalize());
|
|
6637
6731
|
});
|
|
6638
6732
|
const b = { props: x };
|
|
6639
6733
|
x["Hips.position"] && (x["Hips.position"].y < 0.5 ? b.lying = !0 : b.standing = !0), this.animClips.push({
|
|
@@ -6677,7 +6771,7 @@ class De {
|
|
|
6677
6771
|
let l = this.animQueue.find((u) => u.template.name === "pose");
|
|
6678
6772
|
l && (l.ts[0] = this.animClock + n * 1e3 + 2e3), this.setPoseFromTemplate(o);
|
|
6679
6773
|
} else {
|
|
6680
|
-
let u = await new
|
|
6774
|
+
let u = await new Be().loadAsync(t, e);
|
|
6681
6775
|
if (u && u.animations && u.animations[i]) {
|
|
6682
6776
|
let r = u.animations[i];
|
|
6683
6777
|
const h = {};
|
|
@@ -6774,22 +6868,22 @@ class De {
|
|
|
6774
6868
|
const b = t.iterations || 10;
|
|
6775
6869
|
if (e)
|
|
6776
6870
|
for (let I = 0; I < b; I++) {
|
|
6777
|
-
let
|
|
6778
|
-
for (let
|
|
6779
|
-
const
|
|
6780
|
-
|
|
6871
|
+
let H = !1;
|
|
6872
|
+
for (let m = 0, T = x.length; m < T; m++) {
|
|
6873
|
+
const k = x[m].bone;
|
|
6874
|
+
k.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();
|
|
6781
6875
|
let y = s.dot(l);
|
|
6782
|
-
y > 1 ? y = 1 : y < -1 && (y = -1), y = Math.acos(y), !(y < 1e-5) && (x[
|
|
6783
|
-
x[
|
|
6784
|
-
x[
|
|
6785
|
-
x[
|
|
6876
|
+
y > 1 ? y = 1 : y < -1 && (y = -1), y = Math.acos(y), !(y < 1e-5) && (x[m].minAngle !== void 0 && y < x[m].minAngle && (y = x[m].minAngle), x[m].maxAngle !== void 0 && y > x[m].maxAngle && (y = x[m].maxAngle), a.crossVectors(l, s), a.normalize(), _.setFromAxisAngle(a, y), k.quaternion.multiply(_), k.rotation.setFromVector3(c.setFromEuler(k.rotation).clamp(new f.Vector3(
|
|
6877
|
+
x[m].minx !== void 0 ? x[m].minx : -1 / 0,
|
|
6878
|
+
x[m].miny !== void 0 ? x[m].miny : -1 / 0,
|
|
6879
|
+
x[m].minz !== void 0 ? x[m].minz : -1 / 0
|
|
6786
6880
|
), new f.Vector3(
|
|
6787
|
-
x[
|
|
6788
|
-
x[
|
|
6789
|
-
x[
|
|
6790
|
-
))),
|
|
6881
|
+
x[m].maxx !== void 0 ? x[m].maxx : 1 / 0,
|
|
6882
|
+
x[m].maxy !== void 0 ? x[m].maxy : 1 / 0,
|
|
6883
|
+
x[m].maxz !== void 0 ? x[m].maxz : 1 / 0
|
|
6884
|
+
))), k.updateMatrixWorld(!0), H = !0);
|
|
6791
6885
|
}
|
|
6792
|
-
if (!
|
|
6886
|
+
if (!H) break;
|
|
6793
6887
|
}
|
|
6794
6888
|
i && x.forEach((I) => {
|
|
6795
6889
|
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;
|
|
@@ -6852,16 +6946,16 @@ function Fe() {
|
|
|
6852
6946
|
};
|
|
6853
6947
|
}
|
|
6854
6948
|
function kt() {
|
|
6855
|
-
const
|
|
6856
|
-
return Object.entries(
|
|
6949
|
+
const X = Fe(), t = [];
|
|
6950
|
+
return Object.entries(X.voices).forEach(([e, n]) => {
|
|
6857
6951
|
t.push({
|
|
6858
6952
|
value: n,
|
|
6859
|
-
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${
|
|
6953
|
+
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${X.service})`
|
|
6860
6954
|
});
|
|
6861
6955
|
}), t;
|
|
6862
6956
|
}
|
|
6863
6957
|
const Ve = Me(({
|
|
6864
|
-
avatarUrl:
|
|
6958
|
+
avatarUrl: X = "/avatars/brunette.glb",
|
|
6865
6959
|
avatarBody: t = "F",
|
|
6866
6960
|
mood: e = "neutral",
|
|
6867
6961
|
ttsLang: n = "en",
|
|
@@ -6882,140 +6976,140 @@ const Ve = Me(({
|
|
|
6882
6976
|
style: x = {},
|
|
6883
6977
|
animations: b = {}
|
|
6884
6978
|
}, I) => {
|
|
6885
|
-
const
|
|
6979
|
+
const H = O(null), m = O(null), T = O(r), k = O(null), y = O(null), M = O(!1), P = O({ remainingText: null, originalText: null, options: null }), D = O([]), J = O(0), [S, G] = ce(!0), [Q, Z] = ce(null), [ee, se] = ce(!1), [ae, pe] = ce(!1);
|
|
6886
6980
|
de(() => {
|
|
6887
|
-
|
|
6981
|
+
M.current = ae;
|
|
6888
6982
|
}, [ae]), de(() => {
|
|
6889
|
-
|
|
6983
|
+
T.current = r;
|
|
6890
6984
|
}, [r]);
|
|
6891
|
-
const
|
|
6892
|
-
let
|
|
6893
|
-
le === "browser" ?
|
|
6985
|
+
const te = Fe(), le = i || te.service;
|
|
6986
|
+
let U;
|
|
6987
|
+
le === "browser" ? U = {
|
|
6894
6988
|
service: "browser",
|
|
6895
6989
|
endpoint: "",
|
|
6896
6990
|
apiKey: null,
|
|
6897
6991
|
defaultVoice: "Google US English"
|
|
6898
|
-
} : le === "elevenlabs" ?
|
|
6992
|
+
} : le === "elevenlabs" ? U = {
|
|
6899
6993
|
service: "elevenlabs",
|
|
6900
6994
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
6901
|
-
apiKey: o ||
|
|
6902
|
-
defaultVoice: s ||
|
|
6903
|
-
voices:
|
|
6904
|
-
} : le === "deepgram" ?
|
|
6995
|
+
apiKey: o || te.apiKey,
|
|
6996
|
+
defaultVoice: s || te.defaultVoice || Ie.defaultVoice,
|
|
6997
|
+
voices: te.voices || Ie.voices
|
|
6998
|
+
} : le === "deepgram" ? U = {
|
|
6905
6999
|
service: "deepgram",
|
|
6906
7000
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
6907
|
-
apiKey: o ||
|
|
6908
|
-
defaultVoice: s ||
|
|
6909
|
-
voices:
|
|
6910
|
-
} :
|
|
6911
|
-
...
|
|
7001
|
+
apiKey: o || te.apiKey,
|
|
7002
|
+
defaultVoice: s || te.defaultVoice || Te.defaultVoice,
|
|
7003
|
+
voices: te.voices || Te.voices
|
|
7004
|
+
} : U = {
|
|
7005
|
+
...te,
|
|
6912
7006
|
// Override API key if provided via props
|
|
6913
|
-
apiKey: o !== null ? o :
|
|
7007
|
+
apiKey: o !== null ? o : te.apiKey
|
|
6914
7008
|
};
|
|
6915
|
-
const
|
|
6916
|
-
url:
|
|
7009
|
+
const R = {
|
|
7010
|
+
url: X,
|
|
6917
7011
|
body: t,
|
|
6918
7012
|
avatarMood: e,
|
|
6919
7013
|
ttsLang: le === "browser" ? "en-US" : n,
|
|
6920
|
-
ttsVoice: s ||
|
|
7014
|
+
ttsVoice: s || U.defaultVoice,
|
|
6921
7015
|
lipsyncLang: "en",
|
|
6922
7016
|
showFullAvatar: r,
|
|
6923
7017
|
bodyMovement: l,
|
|
6924
7018
|
movementIntensity: u
|
|
6925
|
-
},
|
|
6926
|
-
ttsEndpoint:
|
|
6927
|
-
ttsApikey:
|
|
7019
|
+
}, v = {
|
|
7020
|
+
ttsEndpoint: U.endpoint,
|
|
7021
|
+
ttsApikey: U.apiKey,
|
|
6928
7022
|
ttsService: le,
|
|
6929
7023
|
lipsyncModules: ["en"],
|
|
6930
7024
|
cameraView: h
|
|
6931
|
-
},
|
|
6932
|
-
if (!(!
|
|
7025
|
+
}, w = F(async () => {
|
|
7026
|
+
if (!(!H.current || m.current))
|
|
6933
7027
|
try {
|
|
6934
|
-
if (
|
|
7028
|
+
if (G(!0), Z(null), m.current = new Ne(H.current, v), m.current.controls && (m.current.controls.enableRotate = !1, m.current.controls.enableZoom = !1, m.current.controls.enablePan = !1, m.current.controls.enableDamping = !1), b && Object.keys(b).length > 0 && (m.current.customAnimations = b), await m.current.showAvatar(R, (B) => {
|
|
6935
7029
|
if (B.lengthComputable) {
|
|
6936
|
-
const
|
|
6937
|
-
c(
|
|
7030
|
+
const $ = Math.min(100, Math.round(B.loaded / B.total * 100));
|
|
7031
|
+
c($);
|
|
6938
7032
|
}
|
|
6939
7033
|
}), await new Promise((B) => {
|
|
6940
|
-
const
|
|
6941
|
-
|
|
7034
|
+
const $ = () => {
|
|
7035
|
+
m.current.lipsync && Object.keys(m.current.lipsync).length > 0 ? B() : setTimeout($, 100);
|
|
6942
7036
|
};
|
|
6943
|
-
|
|
6944
|
-
}),
|
|
7037
|
+
$();
|
|
7038
|
+
}), m.current && m.current.setShowFullAvatar)
|
|
6945
7039
|
try {
|
|
6946
|
-
|
|
7040
|
+
m.current.setShowFullAvatar(r);
|
|
6947
7041
|
} catch (B) {
|
|
6948
7042
|
console.warn("Error setting full body mode on initialization:", B);
|
|
6949
7043
|
}
|
|
6950
|
-
|
|
6951
|
-
const
|
|
6952
|
-
document.visibilityState === "visible" ?
|
|
7044
|
+
m.current && m.current.controls && (m.current.controls.enableRotate = !1, m.current.controls.enableZoom = !1, m.current.controls.enablePan = !1, m.current.controls.enableDamping = !1, m.current.controls.update()), G(!1), se(!0), a(m.current);
|
|
7045
|
+
const N = () => {
|
|
7046
|
+
document.visibilityState === "visible" ? m.current?.start() : m.current?.stop();
|
|
6953
7047
|
};
|
|
6954
|
-
return document.addEventListener("visibilitychange",
|
|
6955
|
-
document.removeEventListener("visibilitychange",
|
|
7048
|
+
return document.addEventListener("visibilitychange", N), () => {
|
|
7049
|
+
document.removeEventListener("visibilitychange", N);
|
|
6956
7050
|
};
|
|
6957
7051
|
} catch (L) {
|
|
6958
|
-
console.error("Error initializing TalkingHead:", L),
|
|
7052
|
+
console.error("Error initializing TalkingHead:", L), Z(L.message || "Failed to initialize avatar"), G(!1), d(L);
|
|
6959
7053
|
}
|
|
6960
|
-
}, [
|
|
6961
|
-
de(() => (
|
|
6962
|
-
|
|
6963
|
-
}), [
|
|
6964
|
-
if (!
|
|
7054
|
+
}, [X, t, e, n, i, s, o, r, l, u, h]);
|
|
7055
|
+
de(() => (w(), () => {
|
|
7056
|
+
m.current && (m.current.stop(), m.current.dispose(), m.current = null);
|
|
7057
|
+
}), [w]), de(() => {
|
|
7058
|
+
if (!H.current || !m.current) return;
|
|
6965
7059
|
const L = new ResizeObserver((B) => {
|
|
6966
|
-
for (const
|
|
6967
|
-
|
|
7060
|
+
for (const $ of B)
|
|
7061
|
+
m.current && m.current.onResize && m.current.onResize();
|
|
6968
7062
|
});
|
|
6969
|
-
L.observe(
|
|
6970
|
-
const
|
|
6971
|
-
|
|
7063
|
+
L.observe(H.current);
|
|
7064
|
+
const N = () => {
|
|
7065
|
+
m.current && m.current.onResize && m.current.onResize();
|
|
6972
7066
|
};
|
|
6973
|
-
return window.addEventListener("resize",
|
|
6974
|
-
L.disconnect(), window.removeEventListener("resize",
|
|
7067
|
+
return window.addEventListener("resize", N), () => {
|
|
7068
|
+
L.disconnect(), window.removeEventListener("resize", N);
|
|
6975
7069
|
};
|
|
6976
|
-
}, [
|
|
6977
|
-
const
|
|
6978
|
-
if (
|
|
7070
|
+
}, [ee]);
|
|
7071
|
+
const E = F(async () => {
|
|
7072
|
+
if (m.current && m.current.audioCtx)
|
|
6979
7073
|
try {
|
|
6980
|
-
(
|
|
7074
|
+
(m.current.audioCtx.state === "suspended" || m.current.audioCtx.state === "interrupted") && (await m.current.audioCtx.resume(), console.log("Audio context resumed"));
|
|
6981
7075
|
} catch (L) {
|
|
6982
7076
|
console.warn("Failed to resume audio context:", L);
|
|
6983
7077
|
}
|
|
6984
|
-
}, []),
|
|
6985
|
-
if (
|
|
7078
|
+
}, []), W = F(async (L, N = {}) => {
|
|
7079
|
+
if (m.current && ee)
|
|
6986
7080
|
try {
|
|
6987
|
-
y.current && (clearInterval(y.current), y.current = null),
|
|
6988
|
-
const B = /[!\.\?\n\p{Extended_Pictographic}]/ug,
|
|
6989
|
-
|
|
7081
|
+
y.current && (clearInterval(y.current), y.current = null), k.current = { text: L, options: N }, P.current = { remainingText: null, originalText: null, options: null };
|
|
7082
|
+
const B = /[!\.\?\n\p{Extended_Pictographic}]/ug, $ = L.split(B).map((Y) => Y.trim()).filter((Y) => Y.length > 0);
|
|
7083
|
+
D.current = $, J.current = 0, pe(!1), M.current = !1, await E();
|
|
6990
7084
|
const ge = {
|
|
6991
|
-
...
|
|
6992
|
-
lipsyncLang:
|
|
7085
|
+
...N,
|
|
7086
|
+
lipsyncLang: N.lipsyncLang || R.lipsyncLang || "en"
|
|
6993
7087
|
};
|
|
6994
|
-
if (
|
|
6995
|
-
const Y =
|
|
7088
|
+
if (N.onSpeechEnd && m.current) {
|
|
7089
|
+
const Y = m.current;
|
|
6996
7090
|
let ue = null, Se = 0;
|
|
6997
7091
|
const Ae = 1200;
|
|
6998
7092
|
let be = !1;
|
|
6999
7093
|
ue = setInterval(() => {
|
|
7000
|
-
if (Se++,
|
|
7094
|
+
if (Se++, M.current)
|
|
7001
7095
|
return;
|
|
7002
7096
|
if (Se > Ae) {
|
|
7003
|
-
if (ue && (clearInterval(ue), ue = null, y.current = null), !be && !
|
|
7097
|
+
if (ue && (clearInterval(ue), ue = null, y.current = null), !be && !M.current) {
|
|
7004
7098
|
be = !0;
|
|
7005
7099
|
try {
|
|
7006
|
-
|
|
7007
|
-
} catch (
|
|
7008
|
-
console.error("Error in onSpeechEnd callback (timeout):",
|
|
7100
|
+
N.onSpeechEnd();
|
|
7101
|
+
} catch (De) {
|
|
7102
|
+
console.error("Error in onSpeechEnd callback (timeout):", De);
|
|
7009
7103
|
}
|
|
7010
7104
|
}
|
|
7011
7105
|
return;
|
|
7012
7106
|
}
|
|
7013
7107
|
const ye = !Y.speechQueue || Y.speechQueue.length === 0, ke = !Y.audioPlaylist || Y.audioPlaylist.length === 0;
|
|
7014
|
-
Y && Y.isSpeaking === !1 && ye && ke && Y.isAudioPlaying === !1 && !be && !
|
|
7015
|
-
if (Y && !
|
|
7108
|
+
Y && Y.isSpeaking === !1 && ye && ke && Y.isAudioPlaying === !1 && !be && !M.current && setTimeout(() => {
|
|
7109
|
+
if (Y && !M.current && Y.isSpeaking === !1 && (!Y.speechQueue || Y.speechQueue.length === 0) && (!Y.audioPlaylist || Y.audioPlaylist.length === 0) && Y.isAudioPlaying === !1 && !be && !M.current) {
|
|
7016
7110
|
be = !0, ue && (clearInterval(ue), ue = null, y.current = null);
|
|
7017
7111
|
try {
|
|
7018
|
-
|
|
7112
|
+
N.onSpeechEnd();
|
|
7019
7113
|
} catch (Ze) {
|
|
7020
7114
|
console.error("Error in onSpeechEnd callback:", Ze);
|
|
7021
7115
|
}
|
|
@@ -7023,167 +7117,167 @@ const Ve = Me(({
|
|
|
7023
7117
|
}, 100);
|
|
7024
7118
|
}, 100), y.current = ue;
|
|
7025
7119
|
}
|
|
7026
|
-
|
|
7027
|
-
await
|
|
7120
|
+
m.current.lipsync && Object.keys(m.current.lipsync).length > 0 ? (m.current.setSlowdownRate && m.current.setSlowdownRate(1.05), m.current.speakText(L, ge)) : setTimeout(async () => {
|
|
7121
|
+
await E(), m.current && m.current.lipsync && (m.current.setSlowdownRate && m.current.setSlowdownRate(1.05), m.current.speakText(L, ge));
|
|
7028
7122
|
}, 100);
|
|
7029
7123
|
} catch (B) {
|
|
7030
|
-
console.error("Error speaking text:", B),
|
|
7124
|
+
console.error("Error speaking text:", B), Z(B.message || "Failed to speak text");
|
|
7031
7125
|
}
|
|
7032
|
-
}, [
|
|
7033
|
-
|
|
7034
|
-
}, []), j =
|
|
7035
|
-
if (
|
|
7036
|
-
const L =
|
|
7126
|
+
}, [ee, E, R.lipsyncLang]), K = F(() => {
|
|
7127
|
+
m.current && (m.current.stopSpeaking(), m.current.setSlowdownRate && m.current.setSlowdownRate(1), k.current = null, pe(!1));
|
|
7128
|
+
}, []), j = F(() => {
|
|
7129
|
+
if (m.current && m.current.pauseSpeaking) {
|
|
7130
|
+
const L = m.current;
|
|
7037
7131
|
if (L.isSpeaking || L.audioPlaylist && L.audioPlaylist.length > 0 || L.speechQueue && L.speechQueue.length > 0) {
|
|
7038
7132
|
y.current && (clearInterval(y.current), y.current = null);
|
|
7039
7133
|
let B = "";
|
|
7040
|
-
if (
|
|
7041
|
-
const
|
|
7042
|
-
if (ue > 0 && Se <
|
|
7134
|
+
if (k.current && D.current.length > 0) {
|
|
7135
|
+
const $ = D.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 = $ - ue;
|
|
7136
|
+
if (ue > 0 && Se < $ && (B = D.current.slice(Se).join(". ").trim(), !B && ge > 0 && L.speechQueue)) {
|
|
7043
7137
|
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(" ");
|
|
7044
7138
|
be && be.trim() && (B = be.trim());
|
|
7045
7139
|
}
|
|
7046
7140
|
}
|
|
7047
|
-
|
|
7141
|
+
k.current && (P.current = {
|
|
7048
7142
|
remainingText: B || null,
|
|
7049
|
-
originalText:
|
|
7050
|
-
options:
|
|
7051
|
-
}), L.speechQueue && (L.speechQueue.length = 0),
|
|
7143
|
+
originalText: k.current.text,
|
|
7144
|
+
options: k.current.options
|
|
7145
|
+
}), L.speechQueue && (L.speechQueue.length = 0), m.current.pauseSpeaking(), M.current = !0, pe(!0);
|
|
7052
7146
|
}
|
|
7053
7147
|
}
|
|
7054
|
-
}, []), q =
|
|
7055
|
-
if (!
|
|
7148
|
+
}, []), q = F(async () => {
|
|
7149
|
+
if (!m.current || !ae)
|
|
7056
7150
|
return;
|
|
7057
|
-
let L = "",
|
|
7151
|
+
let L = "", N = {};
|
|
7058
7152
|
if (P.current && P.current.remainingText)
|
|
7059
|
-
L = P.current.remainingText,
|
|
7060
|
-
else if (
|
|
7061
|
-
L =
|
|
7153
|
+
L = P.current.remainingText, N = P.current.options || {}, P.current = { remainingText: null, originalText: null, options: null };
|
|
7154
|
+
else if (k.current && k.current.text)
|
|
7155
|
+
L = k.current.text, N = k.current.options || {};
|
|
7062
7156
|
else {
|
|
7063
|
-
console.warn("Resume called but no paused speech found"), pe(!1),
|
|
7157
|
+
console.warn("Resume called but no paused speech found"), pe(!1), M.current = !1;
|
|
7064
7158
|
return;
|
|
7065
7159
|
}
|
|
7066
|
-
pe(!1),
|
|
7160
|
+
pe(!1), M.current = !1, await E();
|
|
7067
7161
|
const B = {
|
|
7068
|
-
...
|
|
7069
|
-
lipsyncLang:
|
|
7162
|
+
...N,
|
|
7163
|
+
lipsyncLang: N.lipsyncLang || R.lipsyncLang || "en"
|
|
7070
7164
|
};
|
|
7071
7165
|
try {
|
|
7072
|
-
await
|
|
7073
|
-
} catch (
|
|
7074
|
-
console.error("Error resuming speech:",
|
|
7166
|
+
await W(L, B);
|
|
7167
|
+
} catch ($) {
|
|
7168
|
+
console.error("Error resuming speech:", $), pe(!1), M.current = !1;
|
|
7075
7169
|
}
|
|
7076
|
-
}, [
|
|
7077
|
-
|
|
7078
|
-
}, []), we =
|
|
7079
|
-
|
|
7080
|
-
}, []), C =
|
|
7081
|
-
if (
|
|
7082
|
-
if (b && b[L] && (L = b[L]),
|
|
7170
|
+
}, [E, ae, W, R]), Le = F((L) => {
|
|
7171
|
+
m.current && m.current.setMood(L);
|
|
7172
|
+
}, []), we = F((L) => {
|
|
7173
|
+
m.current && m.current.setSlowdownRate && m.current.setSlowdownRate(L);
|
|
7174
|
+
}, []), C = F((L, N = !1) => {
|
|
7175
|
+
if (m.current && m.current.playAnimation) {
|
|
7176
|
+
if (b && b[L] && (L = b[L]), m.current.setShowFullAvatar)
|
|
7083
7177
|
try {
|
|
7084
|
-
|
|
7085
|
-
} catch (
|
|
7086
|
-
console.warn("Error setting full body mode:",
|
|
7178
|
+
m.current.setShowFullAvatar(T.current);
|
|
7179
|
+
} catch ($) {
|
|
7180
|
+
console.warn("Error setting full body mode:", $);
|
|
7087
7181
|
}
|
|
7088
7182
|
if (L.includes("."))
|
|
7089
7183
|
try {
|
|
7090
|
-
|
|
7091
|
-
} catch (
|
|
7092
|
-
console.warn(`Failed to play ${L}:`,
|
|
7184
|
+
m.current.playAnimation(L, null, 10, 0, 0.01, N);
|
|
7185
|
+
} catch ($) {
|
|
7186
|
+
console.warn(`Failed to play ${L}:`, $);
|
|
7093
7187
|
try {
|
|
7094
|
-
|
|
7188
|
+
m.current.setBodyMovement("idle");
|
|
7095
7189
|
} catch (ge) {
|
|
7096
7190
|
console.warn("Fallback animation also failed:", ge);
|
|
7097
7191
|
}
|
|
7098
7192
|
}
|
|
7099
7193
|
else {
|
|
7100
|
-
const
|
|
7194
|
+
const $ = [".fbx", ".glb", ".gltf"];
|
|
7101
7195
|
let ge = !1;
|
|
7102
|
-
for (const Y of
|
|
7196
|
+
for (const Y of $)
|
|
7103
7197
|
try {
|
|
7104
|
-
|
|
7198
|
+
m.current.playAnimation(L + Y, null, 10, 0, 0.01, N), ge = !0;
|
|
7105
7199
|
break;
|
|
7106
7200
|
} catch {
|
|
7107
7201
|
}
|
|
7108
7202
|
if (!ge) {
|
|
7109
7203
|
console.warn("Animation not found:", L);
|
|
7110
7204
|
try {
|
|
7111
|
-
|
|
7205
|
+
m.current.setBodyMovement("idle");
|
|
7112
7206
|
} catch (Y) {
|
|
7113
7207
|
console.warn("Fallback animation also failed:", Y);
|
|
7114
7208
|
}
|
|
7115
7209
|
}
|
|
7116
7210
|
}
|
|
7117
7211
|
}
|
|
7118
|
-
}, [b]),
|
|
7119
|
-
|
|
7212
|
+
}, [b]), ne = F(() => {
|
|
7213
|
+
m.current && m.current.onResize && m.current.onResize();
|
|
7120
7214
|
}, []);
|
|
7121
7215
|
return Ee(I, () => ({
|
|
7122
|
-
speakText:
|
|
7216
|
+
speakText: W,
|
|
7123
7217
|
stopSpeaking: K,
|
|
7124
7218
|
pauseSpeaking: j,
|
|
7125
7219
|
resumeSpeaking: q,
|
|
7126
|
-
resumeAudioContext:
|
|
7220
|
+
resumeAudioContext: E,
|
|
7127
7221
|
setMood: Le,
|
|
7128
7222
|
setTimingAdjustment: we,
|
|
7129
7223
|
playAnimation: C,
|
|
7130
|
-
isReady:
|
|
7224
|
+
isReady: ee,
|
|
7131
7225
|
isPaused: ae,
|
|
7132
|
-
talkingHead:
|
|
7133
|
-
handleResize:
|
|
7226
|
+
talkingHead: m.current,
|
|
7227
|
+
handleResize: ne,
|
|
7134
7228
|
setBodyMovement: (L) => {
|
|
7135
|
-
if (
|
|
7229
|
+
if (m.current && m.current.setShowFullAvatar && m.current.setBodyMovement)
|
|
7136
7230
|
try {
|
|
7137
|
-
|
|
7138
|
-
} catch (
|
|
7139
|
-
console.warn("Error setting body movement:",
|
|
7231
|
+
m.current.setShowFullAvatar(T.current), m.current.setBodyMovement(L);
|
|
7232
|
+
} catch (N) {
|
|
7233
|
+
console.warn("Error setting body movement:", N);
|
|
7140
7234
|
}
|
|
7141
7235
|
},
|
|
7142
|
-
setMovementIntensity: (L) =>
|
|
7236
|
+
setMovementIntensity: (L) => m.current?.setMovementIntensity(L),
|
|
7143
7237
|
playRandomDance: () => {
|
|
7144
|
-
if (
|
|
7238
|
+
if (m.current && m.current.setShowFullAvatar && m.current.playRandomDance)
|
|
7145
7239
|
try {
|
|
7146
|
-
|
|
7240
|
+
m.current.setShowFullAvatar(T.current), m.current.playRandomDance();
|
|
7147
7241
|
} catch (L) {
|
|
7148
7242
|
console.warn("Error playing random dance:", L);
|
|
7149
7243
|
}
|
|
7150
7244
|
},
|
|
7151
7245
|
playReaction: (L) => {
|
|
7152
|
-
if (
|
|
7246
|
+
if (m.current && m.current.setShowFullAvatar && m.current.playReaction)
|
|
7153
7247
|
try {
|
|
7154
|
-
|
|
7155
|
-
} catch (
|
|
7156
|
-
console.warn("Error playing reaction:",
|
|
7248
|
+
m.current.setShowFullAvatar(T.current), m.current.playReaction(L);
|
|
7249
|
+
} catch (N) {
|
|
7250
|
+
console.warn("Error playing reaction:", N);
|
|
7157
7251
|
}
|
|
7158
7252
|
},
|
|
7159
7253
|
playCelebration: () => {
|
|
7160
|
-
if (
|
|
7254
|
+
if (m.current && m.current.setShowFullAvatar && m.current.playCelebration)
|
|
7161
7255
|
try {
|
|
7162
|
-
|
|
7256
|
+
m.current.setShowFullAvatar(T.current), m.current.playCelebration();
|
|
7163
7257
|
} catch (L) {
|
|
7164
7258
|
console.warn("Error playing celebration:", L);
|
|
7165
7259
|
}
|
|
7166
7260
|
},
|
|
7167
7261
|
setShowFullAvatar: (L) => {
|
|
7168
|
-
if (
|
|
7262
|
+
if (m.current && m.current.setShowFullAvatar)
|
|
7169
7263
|
try {
|
|
7170
|
-
|
|
7171
|
-
} catch (
|
|
7172
|
-
console.warn("Error setting showFullAvatar:",
|
|
7264
|
+
T.current = L, m.current.setShowFullAvatar(L);
|
|
7265
|
+
} catch (N) {
|
|
7266
|
+
console.warn("Error setting showFullAvatar:", N);
|
|
7173
7267
|
}
|
|
7174
7268
|
},
|
|
7175
7269
|
lockAvatarPosition: () => {
|
|
7176
|
-
if (
|
|
7270
|
+
if (m.current && m.current.lockAvatarPosition)
|
|
7177
7271
|
try {
|
|
7178
|
-
|
|
7272
|
+
m.current.lockAvatarPosition();
|
|
7179
7273
|
} catch (L) {
|
|
7180
7274
|
console.warn("Error locking avatar position:", L);
|
|
7181
7275
|
}
|
|
7182
7276
|
},
|
|
7183
7277
|
unlockAvatarPosition: () => {
|
|
7184
|
-
if (
|
|
7278
|
+
if (m.current && m.current.unlockAvatarPosition)
|
|
7185
7279
|
try {
|
|
7186
|
-
|
|
7280
|
+
m.current.unlockAvatarPosition();
|
|
7187
7281
|
} catch (L) {
|
|
7188
7282
|
console.warn("Error unlocking avatar position:", L);
|
|
7189
7283
|
}
|
|
@@ -7202,7 +7296,7 @@ const Ve = Me(({
|
|
|
7202
7296
|
/* @__PURE__ */ me(
|
|
7203
7297
|
"div",
|
|
7204
7298
|
{
|
|
7205
|
-
ref:
|
|
7299
|
+
ref: H,
|
|
7206
7300
|
className: "talking-head-viewer",
|
|
7207
7301
|
style: {
|
|
7208
7302
|
width: "100%",
|
|
@@ -7220,7 +7314,7 @@ const Ve = Me(({
|
|
|
7220
7314
|
fontSize: "18px",
|
|
7221
7315
|
zIndex: 10
|
|
7222
7316
|
}, children: "Loading avatar..." }),
|
|
7223
|
-
|
|
7317
|
+
Q && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
|
|
7224
7318
|
position: "absolute",
|
|
7225
7319
|
top: "50%",
|
|
7226
7320
|
left: "50%",
|
|
@@ -7231,14 +7325,14 @@ const Ve = Me(({
|
|
|
7231
7325
|
zIndex: 10,
|
|
7232
7326
|
padding: "20px",
|
|
7233
7327
|
borderRadius: "8px"
|
|
7234
|
-
}, children:
|
|
7328
|
+
}, children: Q })
|
|
7235
7329
|
]
|
|
7236
7330
|
}
|
|
7237
7331
|
);
|
|
7238
7332
|
});
|
|
7239
7333
|
Ve.displayName = "TalkingHeadAvatar";
|
|
7240
7334
|
const pt = Me(({
|
|
7241
|
-
text:
|
|
7335
|
+
text: X = "Hello! I'm a talking avatar. How are you today?",
|
|
7242
7336
|
onLoading: t = () => {
|
|
7243
7337
|
},
|
|
7244
7338
|
onError: e = () => {
|
|
@@ -7249,7 +7343,7 @@ const pt = Me(({
|
|
|
7249
7343
|
style: s = {},
|
|
7250
7344
|
avatarConfig: o = {}
|
|
7251
7345
|
}, l) => {
|
|
7252
|
-
const u =
|
|
7346
|
+
const u = O(null), r = O(null), [h, a] = ce(!0), [c, d] = ce(null), [g, x] = ce(!1), b = Fe(), I = o.ttsService || b.service, H = I === "browser" ? {
|
|
7253
7347
|
endpoint: "",
|
|
7254
7348
|
apiKey: null,
|
|
7255
7349
|
defaultVoice: "Google US English"
|
|
@@ -7259,13 +7353,13 @@ const pt = Me(({
|
|
|
7259
7353
|
apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey : b.apiKey,
|
|
7260
7354
|
// Override endpoint for ElevenLabs if service is explicitly set
|
|
7261
7355
|
endpoint: I === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : b.endpoint
|
|
7262
|
-
},
|
|
7356
|
+
}, m = {
|
|
7263
7357
|
url: "/avatars/brunette.glb",
|
|
7264
7358
|
// Use brunette avatar (working glTF file)
|
|
7265
7359
|
body: "F",
|
|
7266
7360
|
avatarMood: "neutral",
|
|
7267
7361
|
ttsLang: I === "browser" ? "en-US" : "en",
|
|
7268
|
-
ttsVoice: o.ttsVoice ||
|
|
7362
|
+
ttsVoice: o.ttsVoice || H.defaultVoice,
|
|
7269
7363
|
lipsyncLang: "en",
|
|
7270
7364
|
// English lip-sync
|
|
7271
7365
|
showFullAvatar: !0,
|
|
@@ -7273,98 +7367,98 @@ const pt = Me(({
|
|
|
7273
7367
|
bodyMovement: "idle",
|
|
7274
7368
|
movementIntensity: 0.5,
|
|
7275
7369
|
...o
|
|
7276
|
-
},
|
|
7277
|
-
ttsEndpoint:
|
|
7278
|
-
ttsApikey:
|
|
7370
|
+
}, T = {
|
|
7371
|
+
ttsEndpoint: H.endpoint,
|
|
7372
|
+
ttsApikey: H.apiKey,
|
|
7279
7373
|
ttsService: I,
|
|
7280
7374
|
lipsyncModules: ["en"],
|
|
7281
7375
|
cameraView: "upper"
|
|
7282
|
-
},
|
|
7376
|
+
}, k = F(async () => {
|
|
7283
7377
|
if (!(!u.current || r.current))
|
|
7284
7378
|
try {
|
|
7285
|
-
if (a(!0), d(null), r.current = new
|
|
7286
|
-
if (
|
|
7287
|
-
const
|
|
7288
|
-
t(
|
|
7379
|
+
if (a(!0), d(null), r.current = new Ne(u.current, T), await r.current.showAvatar(m, (Q) => {
|
|
7380
|
+
if (Q.lengthComputable) {
|
|
7381
|
+
const Z = Math.min(100, Math.round(Q.loaded / Q.total * 100));
|
|
7382
|
+
t(Z);
|
|
7289
7383
|
}
|
|
7290
7384
|
}), r.current.morphs && r.current.morphs.length > 0) {
|
|
7291
|
-
const
|
|
7292
|
-
console.log("Available morph targets:", Object.keys(
|
|
7293
|
-
const
|
|
7294
|
-
console.log("Viseme morph targets found:",
|
|
7385
|
+
const Q = r.current.morphs[0].morphTargetDictionary;
|
|
7386
|
+
console.log("Available morph targets:", Object.keys(Q));
|
|
7387
|
+
const Z = Object.keys(Q).filter((ee) => ee.startsWith("viseme_"));
|
|
7388
|
+
console.log("Viseme morph targets found:", Z), Z.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"));
|
|
7295
7389
|
}
|
|
7296
|
-
if (await new Promise((
|
|
7297
|
-
const
|
|
7298
|
-
r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)),
|
|
7390
|
+
if (await new Promise((Q) => {
|
|
7391
|
+
const Z = () => {
|
|
7392
|
+
r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), Q()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(Z, 100));
|
|
7299
7393
|
};
|
|
7300
|
-
|
|
7394
|
+
Z();
|
|
7301
7395
|
}), r.current && r.current.setShowFullAvatar)
|
|
7302
7396
|
try {
|
|
7303
7397
|
r.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
|
|
7304
|
-
} catch (
|
|
7305
|
-
console.warn("Error setting full body mode on initialization:",
|
|
7398
|
+
} catch (Q) {
|
|
7399
|
+
console.warn("Error setting full body mode on initialization:", Q);
|
|
7306
7400
|
}
|
|
7307
7401
|
a(!1), x(!0), n(r.current);
|
|
7308
|
-
const
|
|
7402
|
+
const G = () => {
|
|
7309
7403
|
document.visibilityState === "visible" ? r.current?.start() : r.current?.stop();
|
|
7310
7404
|
};
|
|
7311
|
-
return document.addEventListener("visibilitychange",
|
|
7312
|
-
document.removeEventListener("visibilitychange",
|
|
7405
|
+
return document.addEventListener("visibilitychange", G), () => {
|
|
7406
|
+
document.removeEventListener("visibilitychange", G);
|
|
7313
7407
|
};
|
|
7314
7408
|
} catch (S) {
|
|
7315
7409
|
console.error("Error initializing TalkingHead:", S), d(S.message || "Failed to initialize avatar"), a(!1), e(S);
|
|
7316
7410
|
}
|
|
7317
7411
|
}, []);
|
|
7318
|
-
de(() => (
|
|
7412
|
+
de(() => (k(), () => {
|
|
7319
7413
|
r.current && (r.current.stop(), r.current.dispose(), r.current = null);
|
|
7320
|
-
}), [
|
|
7321
|
-
const y =
|
|
7414
|
+
}), [k]);
|
|
7415
|
+
const y = F((S) => {
|
|
7322
7416
|
if (r.current && g)
|
|
7323
7417
|
try {
|
|
7324
|
-
console.log("Speaking text:", S), console.log("Avatar config:",
|
|
7418
|
+
console.log("Speaking text:", S), console.log("Avatar config:", m), console.log("TalkingHead instance:", r.current), r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(S)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
|
|
7325
7419
|
r.current && r.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(S)) : console.error("Lip-sync still not ready after waiting");
|
|
7326
7420
|
}, 500));
|
|
7327
|
-
} catch (
|
|
7328
|
-
console.error("Error speaking text:",
|
|
7421
|
+
} catch (G) {
|
|
7422
|
+
console.error("Error speaking text:", G), d(G.message || "Failed to speak text");
|
|
7329
7423
|
}
|
|
7330
7424
|
else
|
|
7331
7425
|
console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!r.current);
|
|
7332
|
-
}, [g,
|
|
7426
|
+
}, [g, m]), M = F(() => {
|
|
7333
7427
|
r.current && (r.current.stopSpeaking(), r.current.setSlowdownRate && (r.current.setSlowdownRate(1), console.log("Reset timing to normal")));
|
|
7334
|
-
}, []), P =
|
|
7428
|
+
}, []), P = F((S) => {
|
|
7335
7429
|
r.current && r.current.setMood(S);
|
|
7336
|
-
}, []),
|
|
7430
|
+
}, []), D = F((S) => {
|
|
7337
7431
|
r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(S), console.log("Timing adjustment set to:", S));
|
|
7338
|
-
}, []),
|
|
7432
|
+
}, []), J = F((S, G = !1) => {
|
|
7339
7433
|
if (r.current && r.current.playAnimation) {
|
|
7340
7434
|
if (r.current.setShowFullAvatar)
|
|
7341
7435
|
try {
|
|
7342
7436
|
r.current.setShowFullAvatar(!0);
|
|
7343
|
-
} catch (
|
|
7344
|
-
console.warn("Error setting full body mode:",
|
|
7437
|
+
} catch (Z) {
|
|
7438
|
+
console.warn("Error setting full body mode:", Z);
|
|
7345
7439
|
}
|
|
7346
7440
|
if (S.includes("."))
|
|
7347
7441
|
try {
|
|
7348
|
-
r.current.playAnimation(S, null, 10, 0, 0.01,
|
|
7349
|
-
} catch (
|
|
7350
|
-
console.log(`Failed to play ${S}:`,
|
|
7442
|
+
r.current.playAnimation(S, null, 10, 0, 0.01, G), console.log("Playing animation:", S);
|
|
7443
|
+
} catch (Z) {
|
|
7444
|
+
console.log(`Failed to play ${S}:`, Z);
|
|
7351
7445
|
try {
|
|
7352
7446
|
r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
7353
|
-
} catch (
|
|
7354
|
-
console.warn("Fallback animation also failed:",
|
|
7447
|
+
} catch (ee) {
|
|
7448
|
+
console.warn("Fallback animation also failed:", ee);
|
|
7355
7449
|
}
|
|
7356
7450
|
}
|
|
7357
7451
|
else {
|
|
7358
|
-
const
|
|
7359
|
-
let
|
|
7360
|
-
for (const se of
|
|
7452
|
+
const Z = [".fbx", ".glb", ".gltf"];
|
|
7453
|
+
let ee = !1;
|
|
7454
|
+
for (const se of Z)
|
|
7361
7455
|
try {
|
|
7362
|
-
r.current.playAnimation(S + se, null, 10, 0, 0.01,
|
|
7456
|
+
r.current.playAnimation(S + se, null, 10, 0, 0.01, G), console.log("Playing animation:", S + se), ee = !0;
|
|
7363
7457
|
break;
|
|
7364
7458
|
} catch {
|
|
7365
7459
|
console.log(`Failed to play ${S}${se}, trying next format...`);
|
|
7366
7460
|
}
|
|
7367
|
-
if (
|
|
7461
|
+
if (!ee) {
|
|
7368
7462
|
console.warn("Animation system not available or animation not found:", S);
|
|
7369
7463
|
try {
|
|
7370
7464
|
r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
@@ -7378,18 +7472,18 @@ const pt = Me(({
|
|
|
7378
7472
|
}, []);
|
|
7379
7473
|
return Ee(l, () => ({
|
|
7380
7474
|
speakText: y,
|
|
7381
|
-
stopSpeaking:
|
|
7475
|
+
stopSpeaking: M,
|
|
7382
7476
|
setMood: P,
|
|
7383
|
-
setTimingAdjustment:
|
|
7384
|
-
playAnimation:
|
|
7477
|
+
setTimingAdjustment: D,
|
|
7478
|
+
playAnimation: J,
|
|
7385
7479
|
isReady: g,
|
|
7386
7480
|
talkingHead: r.current,
|
|
7387
7481
|
setBodyMovement: (S) => {
|
|
7388
7482
|
if (r.current && r.current.setShowFullAvatar && r.current.setBodyMovement)
|
|
7389
7483
|
try {
|
|
7390
7484
|
r.current.setShowFullAvatar(!0), r.current.setBodyMovement(S), console.log("Body movement set with full body mode:", S);
|
|
7391
|
-
} catch (
|
|
7392
|
-
console.warn("Error setting body movement:",
|
|
7485
|
+
} catch (G) {
|
|
7486
|
+
console.warn("Error setting body movement:", G);
|
|
7393
7487
|
}
|
|
7394
7488
|
},
|
|
7395
7489
|
setMovementIntensity: (S) => r.current?.setMovementIntensity(S),
|
|
@@ -7405,8 +7499,8 @@ const pt = Me(({
|
|
|
7405
7499
|
if (r.current && r.current.setShowFullAvatar && r.current.playReaction)
|
|
7406
7500
|
try {
|
|
7407
7501
|
r.current.setShowFullAvatar(!0), r.current.playReaction(S), console.log("Reaction played with full body mode:", S);
|
|
7408
|
-
} catch (
|
|
7409
|
-
console.warn("Error playing reaction:",
|
|
7502
|
+
} catch (G) {
|
|
7503
|
+
console.warn("Error playing reaction:", G);
|
|
7410
7504
|
}
|
|
7411
7505
|
},
|
|
7412
7506
|
playCelebration: () => {
|
|
@@ -7421,8 +7515,8 @@ const pt = Me(({
|
|
|
7421
7515
|
if (r.current && r.current.setShowFullAvatar)
|
|
7422
7516
|
try {
|
|
7423
7517
|
r.current.setShowFullAvatar(S), console.log("Show full avatar set to:", S);
|
|
7424
|
-
} catch (
|
|
7425
|
-
console.warn("Error setting showFullAvatar:",
|
|
7518
|
+
} catch (G) {
|
|
7519
|
+
console.warn("Error setting showFullAvatar:", G);
|
|
7426
7520
|
}
|
|
7427
7521
|
},
|
|
7428
7522
|
lockAvatarPosition: () => {
|
|
@@ -7479,7 +7573,7 @@ const pt = Me(({
|
|
|
7479
7573
|
});
|
|
7480
7574
|
pt.displayName = "TalkingHeadComponent";
|
|
7481
7575
|
const gt = Me(({
|
|
7482
|
-
text:
|
|
7576
|
+
text: X = null,
|
|
7483
7577
|
avatarUrl: t = "/avatars/brunette.glb",
|
|
7484
7578
|
avatarBody: e = "F",
|
|
7485
7579
|
mood: n = "neutral",
|
|
@@ -7501,67 +7595,67 @@ const gt = Me(({
|
|
|
7501
7595
|
},
|
|
7502
7596
|
className: b = "",
|
|
7503
7597
|
style: I = {},
|
|
7504
|
-
animations:
|
|
7505
|
-
autoSpeak:
|
|
7506
|
-
},
|
|
7507
|
-
const
|
|
7598
|
+
animations: H = {},
|
|
7599
|
+
autoSpeak: m = !1
|
|
7600
|
+
}, T) => {
|
|
7601
|
+
const k = O(null), y = O(null), M = O(h), P = O(null), D = O(null), J = O(!1), S = O({ remainingText: null, originalText: null, options: null }), G = O([]), [Q, Z] = ce(!0), [ee, se] = ce(null), [ae, pe] = ce(!1), [te, le] = ce(!1);
|
|
7508
7602
|
de(() => {
|
|
7509
|
-
|
|
7510
|
-
}, [
|
|
7511
|
-
|
|
7603
|
+
J.current = te;
|
|
7604
|
+
}, [te]), de(() => {
|
|
7605
|
+
M.current = h;
|
|
7512
7606
|
}, [h]);
|
|
7513
|
-
const
|
|
7514
|
-
let
|
|
7515
|
-
|
|
7607
|
+
const U = Fe(), R = s || U.service;
|
|
7608
|
+
let v;
|
|
7609
|
+
R === "browser" ? v = {
|
|
7516
7610
|
service: "browser",
|
|
7517
7611
|
endpoint: "",
|
|
7518
7612
|
apiKey: null,
|
|
7519
7613
|
defaultVoice: "Google US English"
|
|
7520
|
-
} :
|
|
7614
|
+
} : R === "elevenlabs" ? v = {
|
|
7521
7615
|
service: "elevenlabs",
|
|
7522
7616
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
7523
|
-
apiKey: l ||
|
|
7524
|
-
defaultVoice: o ||
|
|
7525
|
-
voices:
|
|
7526
|
-
} :
|
|
7617
|
+
apiKey: l || U.apiKey,
|
|
7618
|
+
defaultVoice: o || U.defaultVoice || Ie.defaultVoice,
|
|
7619
|
+
voices: U.voices || Ie.voices
|
|
7620
|
+
} : R === "deepgram" ? v = {
|
|
7527
7621
|
service: "deepgram",
|
|
7528
7622
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
7529
|
-
apiKey: l ||
|
|
7530
|
-
defaultVoice: o ||
|
|
7531
|
-
voices:
|
|
7532
|
-
} :
|
|
7533
|
-
...
|
|
7534
|
-
apiKey: l !== null ? l :
|
|
7623
|
+
apiKey: l || U.apiKey,
|
|
7624
|
+
defaultVoice: o || U.defaultVoice || Te.defaultVoice,
|
|
7625
|
+
voices: U.voices || Te.voices
|
|
7626
|
+
} : v = {
|
|
7627
|
+
...U,
|
|
7628
|
+
apiKey: l !== null ? l : U.apiKey
|
|
7535
7629
|
};
|
|
7536
|
-
const
|
|
7630
|
+
const w = {
|
|
7537
7631
|
url: t,
|
|
7538
7632
|
body: e,
|
|
7539
7633
|
avatarMood: n,
|
|
7540
|
-
ttsLang:
|
|
7541
|
-
ttsVoice: o ||
|
|
7634
|
+
ttsLang: R === "browser" ? "en-US" : i,
|
|
7635
|
+
ttsVoice: o || v.defaultVoice,
|
|
7542
7636
|
lipsyncLang: "en",
|
|
7543
7637
|
showFullAvatar: h,
|
|
7544
7638
|
bodyMovement: u,
|
|
7545
7639
|
movementIntensity: r
|
|
7546
|
-
},
|
|
7547
|
-
ttsEndpoint:
|
|
7548
|
-
ttsApikey:
|
|
7549
|
-
ttsService:
|
|
7640
|
+
}, E = {
|
|
7641
|
+
ttsEndpoint: v.endpoint,
|
|
7642
|
+
ttsApikey: v.apiKey,
|
|
7643
|
+
ttsService: R,
|
|
7550
7644
|
lipsyncModules: ["en"],
|
|
7551
7645
|
cameraView: a
|
|
7552
|
-
},
|
|
7553
|
-
if (!(!
|
|
7646
|
+
}, W = F(async () => {
|
|
7647
|
+
if (!(!k.current || y.current))
|
|
7554
7648
|
try {
|
|
7555
|
-
|
|
7556
|
-
url:
|
|
7557
|
-
body:
|
|
7558
|
-
avatarMood:
|
|
7559
|
-
}), await y.current.showAvatar(
|
|
7560
|
-
if (
|
|
7561
|
-
const L = Math.min(100, Math.round(
|
|
7649
|
+
Z(!0), se(null), y.current = new Ne(k.current, E), console.log("Avatar config being passed:", {
|
|
7650
|
+
url: w.url,
|
|
7651
|
+
body: w.body,
|
|
7652
|
+
avatarMood: w.avatarMood
|
|
7653
|
+
}), await y.current.showAvatar(w, (ne) => {
|
|
7654
|
+
if (ne.lengthComputable) {
|
|
7655
|
+
const L = Math.min(100, Math.round(ne.loaded / ne.total * 100));
|
|
7562
7656
|
d(L);
|
|
7563
7657
|
}
|
|
7564
|
-
}), y.current?.avatar && console.log("Avatar body after initialization:", y.current.avatar.body),
|
|
7658
|
+
}), y.current?.avatar && console.log("Avatar body after initialization:", y.current.avatar.body), Z(!1), pe(!0), c(y.current);
|
|
7565
7659
|
const C = () => {
|
|
7566
7660
|
document.visibilityState === "visible" ? y.current?.start() : y.current?.stop();
|
|
7567
7661
|
};
|
|
@@ -7569,13 +7663,13 @@ const gt = Me(({
|
|
|
7569
7663
|
document.removeEventListener("visibilitychange", C);
|
|
7570
7664
|
};
|
|
7571
7665
|
} catch (C) {
|
|
7572
|
-
console.error("Error initializing TalkingHead:", C), se(C.message || "Failed to initialize avatar"),
|
|
7666
|
+
console.error("Error initializing TalkingHead:", C), se(C.message || "Failed to initialize avatar"), Z(!1), g(C);
|
|
7573
7667
|
}
|
|
7574
7668
|
}, []);
|
|
7575
|
-
de(() => (
|
|
7669
|
+
de(() => (W(), () => {
|
|
7576
7670
|
y.current && (y.current.stop(), y.current.dispose(), y.current = null);
|
|
7577
|
-
}), [
|
|
7578
|
-
const K =
|
|
7671
|
+
}), [W]);
|
|
7672
|
+
const K = F(async () => {
|
|
7579
7673
|
if (y.current)
|
|
7580
7674
|
try {
|
|
7581
7675
|
const C = y.current.audioCtx || y.current.audioContext;
|
|
@@ -7583,7 +7677,7 @@ const gt = Me(({
|
|
|
7583
7677
|
} catch (C) {
|
|
7584
7678
|
console.warn("Failed to resume audio context:", C);
|
|
7585
7679
|
}
|
|
7586
|
-
}, []), j =
|
|
7680
|
+
}, []), j = F(async (C, ne = {}) => {
|
|
7587
7681
|
if (!y.current || !ae) {
|
|
7588
7682
|
console.warn("Avatar not ready for speaking");
|
|
7589
7683
|
return;
|
|
@@ -7592,70 +7686,70 @@ const gt = Me(({
|
|
|
7592
7686
|
console.warn("No text provided to speak");
|
|
7593
7687
|
return;
|
|
7594
7688
|
}
|
|
7595
|
-
await K(), S.current = { remainingText: null, originalText: null, options: null },
|
|
7689
|
+
await K(), S.current = { remainingText: null, originalText: null, options: null }, G.current = [], P.current = { text: C, options: ne }, D.current && (clearInterval(D.current), D.current = null), le(!1), J.current = !1;
|
|
7596
7690
|
const L = C.split(/[.!?]+/).filter((B) => B.trim().length > 0);
|
|
7597
|
-
|
|
7598
|
-
const
|
|
7599
|
-
lipsyncLang:
|
|
7691
|
+
G.current = L;
|
|
7692
|
+
const N = {
|
|
7693
|
+
lipsyncLang: ne.lipsyncLang || "en",
|
|
7600
7694
|
onSpeechEnd: () => {
|
|
7601
|
-
|
|
7695
|
+
D.current && (clearInterval(D.current), D.current = null), ne.onSpeechEnd && ne.onSpeechEnd(), x();
|
|
7602
7696
|
}
|
|
7603
7697
|
};
|
|
7604
7698
|
try {
|
|
7605
|
-
y.current.speakText(C,
|
|
7699
|
+
y.current.speakText(C, N);
|
|
7606
7700
|
} catch (B) {
|
|
7607
7701
|
console.error("Error speaking text:", B), se(B.message || "Failed to speak text");
|
|
7608
7702
|
}
|
|
7609
7703
|
}, [ae, x, K]);
|
|
7610
7704
|
de(() => {
|
|
7611
|
-
ae &&
|
|
7612
|
-
}, [ae,
|
|
7613
|
-
const q =
|
|
7705
|
+
ae && X && m && y.current && j(X);
|
|
7706
|
+
}, [ae, X, m, j]);
|
|
7707
|
+
const q = F(() => {
|
|
7614
7708
|
if (y.current)
|
|
7615
7709
|
try {
|
|
7616
|
-
const C = y.current.isSpeaking || !1,
|
|
7617
|
-
if (C ||
|
|
7618
|
-
|
|
7619
|
-
let
|
|
7620
|
-
L.length > 0 && (
|
|
7621
|
-
remainingText:
|
|
7710
|
+
const C = y.current.isSpeaking || !1, ne = y.current.audioPlaylist || [], L = y.current.speechQueue || [];
|
|
7711
|
+
if (C || ne.length > 0 || L.length > 0) {
|
|
7712
|
+
D.current && (clearInterval(D.current), D.current = null);
|
|
7713
|
+
let N = "";
|
|
7714
|
+
L.length > 0 && (N = L.map((B) => B.text && Array.isArray(B.text) ? B.text.map(($) => $.word).join(" ") : B.text || "").join(" ")), S.current = {
|
|
7715
|
+
remainingText: N || null,
|
|
7622
7716
|
originalText: P.current?.text || null,
|
|
7623
7717
|
options: P.current?.options || null
|
|
7624
|
-
}, y.current.speechQueue.length = 0, y.current.pauseSpeaking(), le(!0),
|
|
7718
|
+
}, y.current.speechQueue.length = 0, y.current.pauseSpeaking(), le(!0), J.current = !0;
|
|
7625
7719
|
}
|
|
7626
7720
|
} catch (C) {
|
|
7627
7721
|
console.warn("Error pausing speech:", C);
|
|
7628
7722
|
}
|
|
7629
|
-
}, []), Le =
|
|
7630
|
-
if (!(!y.current || !
|
|
7723
|
+
}, []), Le = F(async () => {
|
|
7724
|
+
if (!(!y.current || !te))
|
|
7631
7725
|
try {
|
|
7632
|
-
await K(), le(!1),
|
|
7633
|
-
const C = S.current?.remainingText,
|
|
7634
|
-
|
|
7726
|
+
await K(), le(!1), J.current = !1;
|
|
7727
|
+
const C = S.current?.remainingText, ne = S.current?.originalText || P.current?.text, L = S.current?.options || P.current?.options || {}, N = C || ne;
|
|
7728
|
+
N && j(N, L);
|
|
7635
7729
|
} catch (C) {
|
|
7636
|
-
console.warn("Error resuming speech:", C), le(!1),
|
|
7730
|
+
console.warn("Error resuming speech:", C), le(!1), J.current = !1;
|
|
7637
7731
|
}
|
|
7638
|
-
}, [
|
|
7639
|
-
y.current && (y.current.stopSpeaking(),
|
|
7732
|
+
}, [te, j, K]), we = F(() => {
|
|
7733
|
+
y.current && (y.current.stopSpeaking(), D.current && (clearInterval(D.current), D.current = null), le(!1), J.current = !1);
|
|
7640
7734
|
}, []);
|
|
7641
|
-
return Ee(
|
|
7735
|
+
return Ee(T, () => ({
|
|
7642
7736
|
speakText: j,
|
|
7643
7737
|
pauseSpeaking: q,
|
|
7644
7738
|
resumeSpeaking: Le,
|
|
7645
7739
|
stopSpeaking: we,
|
|
7646
7740
|
resumeAudioContext: K,
|
|
7647
|
-
isPaused: () =>
|
|
7741
|
+
isPaused: () => te,
|
|
7648
7742
|
setMood: (C) => y.current?.setMood(C),
|
|
7649
7743
|
setBodyMovement: (C) => {
|
|
7650
7744
|
y.current && y.current.setBodyMovement(C);
|
|
7651
7745
|
},
|
|
7652
|
-
playAnimation: (C,
|
|
7653
|
-
y.current && y.current.playAnimation && y.current.playAnimation(C, null, 10, 0, 0.01,
|
|
7746
|
+
playAnimation: (C, ne = !1) => {
|
|
7747
|
+
y.current && y.current.playAnimation && y.current.playAnimation(C, null, 10, 0, 0.01, ne);
|
|
7654
7748
|
},
|
|
7655
7749
|
playReaction: (C) => y.current?.playReaction(C),
|
|
7656
7750
|
playCelebration: () => y.current?.playCelebration(),
|
|
7657
7751
|
setShowFullAvatar: (C) => {
|
|
7658
|
-
y.current && (
|
|
7752
|
+
y.current && (M.current = C, y.current.setShowFullAvatar(C));
|
|
7659
7753
|
},
|
|
7660
7754
|
isReady: ae,
|
|
7661
7755
|
talkingHead: y.current
|
|
@@ -7663,7 +7757,7 @@ const gt = Me(({
|
|
|
7663
7757
|
/* @__PURE__ */ me(
|
|
7664
7758
|
"div",
|
|
7665
7759
|
{
|
|
7666
|
-
ref:
|
|
7760
|
+
ref: k,
|
|
7667
7761
|
className: "talking-head-viewer",
|
|
7668
7762
|
style: {
|
|
7669
7763
|
width: "100%",
|
|
@@ -7672,7 +7766,7 @@ const gt = Me(({
|
|
|
7672
7766
|
}
|
|
7673
7767
|
}
|
|
7674
7768
|
),
|
|
7675
|
-
|
|
7769
|
+
Q && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
|
|
7676
7770
|
position: "absolute",
|
|
7677
7771
|
top: "50%",
|
|
7678
7772
|
left: "50%",
|
|
@@ -7681,7 +7775,7 @@ const gt = Me(({
|
|
|
7681
7775
|
fontSize: "18px",
|
|
7682
7776
|
zIndex: 10
|
|
7683
7777
|
}, children: "Loading avatar..." }),
|
|
7684
|
-
|
|
7778
|
+
ee && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
|
|
7685
7779
|
position: "absolute",
|
|
7686
7780
|
top: "50%",
|
|
7687
7781
|
left: "50%",
|
|
@@ -7692,12 +7786,12 @@ const gt = Me(({
|
|
|
7692
7786
|
zIndex: 10,
|
|
7693
7787
|
padding: "20px",
|
|
7694
7788
|
borderRadius: "8px"
|
|
7695
|
-
}, children:
|
|
7789
|
+
}, children: ee })
|
|
7696
7790
|
] });
|
|
7697
7791
|
});
|
|
7698
7792
|
gt.displayName = "SimpleTalkingAvatar";
|
|
7699
7793
|
const yt = Me(({
|
|
7700
|
-
curriculumData:
|
|
7794
|
+
curriculumData: X = null,
|
|
7701
7795
|
avatarConfig: t = {},
|
|
7702
7796
|
animations: e = {},
|
|
7703
7797
|
onLessonStart: n = () => {
|
|
@@ -7712,7 +7806,7 @@ const yt = Me(({
|
|
|
7712
7806
|
},
|
|
7713
7807
|
autoStart: u = !1
|
|
7714
7808
|
}, r) => {
|
|
7715
|
-
const h =
|
|
7809
|
+
const h = O(null), a = O({
|
|
7716
7810
|
currentModuleIndex: 0,
|
|
7717
7811
|
currentLessonIndex: 0,
|
|
7718
7812
|
currentQuestionIndex: 0,
|
|
@@ -7722,18 +7816,18 @@ const yt = Me(({
|
|
|
7722
7816
|
curriculumCompleted: !1,
|
|
7723
7817
|
score: 0,
|
|
7724
7818
|
totalQuestions: 0
|
|
7725
|
-
}), c =
|
|
7819
|
+
}), c = O({
|
|
7726
7820
|
onLessonStart: n,
|
|
7727
7821
|
onLessonComplete: i,
|
|
7728
7822
|
onQuestionAnswer: s,
|
|
7729
7823
|
onCurriculumComplete: o,
|
|
7730
7824
|
onCustomAction: l
|
|
7731
|
-
}), d =
|
|
7825
|
+
}), d = O(null), g = O(null), x = O(null), b = O(null), I = O(null), H = O(null), m = O(null), T = O(X?.curriculum || {
|
|
7732
7826
|
title: "Default Curriculum",
|
|
7733
7827
|
description: "No curriculum data provided",
|
|
7734
7828
|
language: "en",
|
|
7735
7829
|
modules: []
|
|
7736
|
-
}),
|
|
7830
|
+
}), k = O({
|
|
7737
7831
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7738
7832
|
avatarBody: t.avatarBody || "F",
|
|
7739
7833
|
mood: t.mood || "happy",
|
|
@@ -7756,12 +7850,12 @@ const yt = Me(({
|
|
|
7756
7850
|
onCustomAction: l
|
|
7757
7851
|
};
|
|
7758
7852
|
}, [n, i, s, o, l]), de(() => {
|
|
7759
|
-
|
|
7853
|
+
T.current = X?.curriculum || {
|
|
7760
7854
|
title: "Default Curriculum",
|
|
7761
7855
|
description: "No curriculum data provided",
|
|
7762
7856
|
language: "en",
|
|
7763
7857
|
modules: []
|
|
7764
|
-
},
|
|
7858
|
+
}, k.current = {
|
|
7765
7859
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7766
7860
|
avatarBody: t.avatarBody || "F",
|
|
7767
7861
|
mood: t.mood || "happy",
|
|
@@ -7775,24 +7869,24 @@ const yt = Me(({
|
|
|
7775
7869
|
animations: e,
|
|
7776
7870
|
lipsyncLang: "en"
|
|
7777
7871
|
};
|
|
7778
|
-
}, [
|
|
7779
|
-
const y =
|
|
7872
|
+
}, [X, t, e]);
|
|
7873
|
+
const y = F(() => (T.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), M = F(() => y()?.questions[a.current.currentQuestionIndex], [y]), P = F((R, v) => v.type === "multiple_choice" || v.type === "true_false" ? R === v.answer : v.type === "code_test" && typeof R == "object" && R !== null ? R.passed === !0 : !1, []), D = F(() => {
|
|
7780
7874
|
a.current.lessonCompleted = !0, a.current.isQuestionMode = !1;
|
|
7781
|
-
const
|
|
7782
|
-
let
|
|
7783
|
-
if (a.current.totalQuestions > 0 ?
|
|
7875
|
+
const R = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
|
|
7876
|
+
let v = "Congratulations! You've completed this lesson";
|
|
7877
|
+
if (a.current.totalQuestions > 0 ? v += ` You got ${a.current.score} correct out of ${a.current.totalQuestions} question${a.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${R} percent. ` : v += "! ", R >= 80 ? v += "Excellent work! You have a great understanding of this topic." : R >= 60 ? v += "Good job! You understand most of the concepts." : v += "Keep practicing! You're making progress.", c.current.onLessonComplete({
|
|
7784
7878
|
moduleIndex: a.current.currentModuleIndex,
|
|
7785
7879
|
lessonIndex: a.current.currentLessonIndex,
|
|
7786
7880
|
score: a.current.score,
|
|
7787
7881
|
totalQuestions: a.current.totalQuestions,
|
|
7788
|
-
percentage:
|
|
7882
|
+
percentage: R
|
|
7789
7883
|
}), c.current.onCustomAction({
|
|
7790
7884
|
type: "lessonComplete",
|
|
7791
7885
|
moduleIndex: a.current.currentModuleIndex,
|
|
7792
7886
|
lessonIndex: a.current.currentLessonIndex,
|
|
7793
7887
|
score: a.current.score,
|
|
7794
7888
|
totalQuestions: a.current.totalQuestions,
|
|
7795
|
-
percentage:
|
|
7889
|
+
percentage: R
|
|
7796
7890
|
}), h.current) {
|
|
7797
7891
|
if (h.current.setMood("happy"), e.lessonComplete)
|
|
7798
7892
|
try {
|
|
@@ -7800,8 +7894,8 @@ const yt = Me(({
|
|
|
7800
7894
|
} catch {
|
|
7801
7895
|
h.current.playCelebration();
|
|
7802
7896
|
}
|
|
7803
|
-
const
|
|
7804
|
-
h.current.speakText(
|
|
7897
|
+
const w = T.current || { modules: [] }, E = w.modules[a.current.currentModuleIndex], W = a.current.currentLessonIndex < (E?.lessons?.length || 0) - 1, K = a.current.currentModuleIndex < (w.modules?.length || 0) - 1, j = W || K, q = k.current || { lipsyncLang: "en" };
|
|
7898
|
+
h.current.speakText(v, {
|
|
7805
7899
|
lipsyncLang: q.lipsyncLang,
|
|
7806
7900
|
onSpeechEnd: () => {
|
|
7807
7901
|
c.current.onCustomAction({
|
|
@@ -7810,18 +7904,18 @@ const yt = Me(({
|
|
|
7810
7904
|
lessonIndex: a.current.currentLessonIndex,
|
|
7811
7905
|
score: a.current.score,
|
|
7812
7906
|
totalQuestions: a.current.totalQuestions,
|
|
7813
|
-
percentage:
|
|
7907
|
+
percentage: R,
|
|
7814
7908
|
hasNextLesson: j
|
|
7815
7909
|
});
|
|
7816
7910
|
}
|
|
7817
7911
|
});
|
|
7818
7912
|
}
|
|
7819
|
-
}, [e.lessonComplete]),
|
|
7913
|
+
}, [e.lessonComplete]), J = F(() => {
|
|
7820
7914
|
a.current.curriculumCompleted = !0;
|
|
7821
|
-
const
|
|
7915
|
+
const R = T.current || { modules: [] };
|
|
7822
7916
|
if (c.current.onCurriculumComplete({
|
|
7823
|
-
modules:
|
|
7824
|
-
totalLessons:
|
|
7917
|
+
modules: R.modules.length,
|
|
7918
|
+
totalLessons: R.modules.reduce((v, w) => v + w.lessons.length, 0)
|
|
7825
7919
|
}), h.current) {
|
|
7826
7920
|
if (h.current.setMood("celebrating"), e.curriculumComplete)
|
|
7827
7921
|
try {
|
|
@@ -7829,99 +7923,99 @@ const yt = Me(({
|
|
|
7829
7923
|
} catch {
|
|
7830
7924
|
h.current.playCelebration();
|
|
7831
7925
|
}
|
|
7832
|
-
const
|
|
7833
|
-
h.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang:
|
|
7926
|
+
const v = k.current || { lipsyncLang: "en" };
|
|
7927
|
+
h.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: v.lipsyncLang });
|
|
7834
7928
|
}
|
|
7835
|
-
}, [e.curriculumComplete]), S =
|
|
7836
|
-
const
|
|
7837
|
-
a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions =
|
|
7838
|
-
const
|
|
7839
|
-
|
|
7929
|
+
}, [e.curriculumComplete]), S = F(() => {
|
|
7930
|
+
const R = y();
|
|
7931
|
+
a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = R?.questions?.length || 0, a.current.score = 0;
|
|
7932
|
+
const v = M();
|
|
7933
|
+
v && c.current.onCustomAction({
|
|
7840
7934
|
type: "questionStart",
|
|
7841
7935
|
moduleIndex: a.current.currentModuleIndex,
|
|
7842
7936
|
lessonIndex: a.current.currentLessonIndex,
|
|
7843
7937
|
questionIndex: a.current.currentQuestionIndex,
|
|
7844
7938
|
totalQuestions: a.current.totalQuestions,
|
|
7845
|
-
question:
|
|
7939
|
+
question: v,
|
|
7846
7940
|
score: a.current.score
|
|
7847
7941
|
});
|
|
7848
|
-
const
|
|
7849
|
-
if (!h.current || !
|
|
7942
|
+
const w = () => {
|
|
7943
|
+
if (!h.current || !v) return;
|
|
7850
7944
|
if (h.current.setMood("happy"), e.questionStart)
|
|
7851
7945
|
try {
|
|
7852
7946
|
h.current.playAnimation(e.questionStart, !0);
|
|
7853
|
-
} catch (
|
|
7854
|
-
console.warn("Failed to play questionStart animation:",
|
|
7947
|
+
} catch (W) {
|
|
7948
|
+
console.warn("Failed to play questionStart animation:", W);
|
|
7855
7949
|
}
|
|
7856
|
-
const
|
|
7857
|
-
|
|
7950
|
+
const E = k.current || { lipsyncLang: "en" };
|
|
7951
|
+
v.type === "code_test" ? h.current.speakText(`Let's test your coding skills! Here's your first challenge: ${v.question}`, { lipsyncLang: E.lipsyncLang }) : v.type === "multiple_choice" ? h.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: E.lipsyncLang }) : v.type === "true_false" ? h.current.speakText(`Let's start with some true or false questions. First question: ${v.question}`, { lipsyncLang: E.lipsyncLang }) : h.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: E.lipsyncLang });
|
|
7858
7952
|
};
|
|
7859
|
-
if (h.current && h.current.isReady &&
|
|
7860
|
-
|
|
7953
|
+
if (h.current && h.current.isReady && v)
|
|
7954
|
+
w();
|
|
7861
7955
|
else if (h.current && h.current.isReady) {
|
|
7862
|
-
const
|
|
7863
|
-
h.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang:
|
|
7956
|
+
const E = k.current || { lipsyncLang: "en" };
|
|
7957
|
+
h.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: E.lipsyncLang });
|
|
7864
7958
|
} else {
|
|
7865
|
-
const
|
|
7866
|
-
h.current && h.current.isReady && (clearInterval(
|
|
7959
|
+
const E = setInterval(() => {
|
|
7960
|
+
h.current && h.current.isReady && (clearInterval(E), v && w());
|
|
7867
7961
|
}, 100);
|
|
7868
7962
|
setTimeout(() => {
|
|
7869
|
-
clearInterval(
|
|
7963
|
+
clearInterval(E);
|
|
7870
7964
|
}, 5e3);
|
|
7871
7965
|
}
|
|
7872
|
-
}, [e.questionStart, y,
|
|
7873
|
-
const
|
|
7874
|
-
if (a.current.currentQuestionIndex < (
|
|
7966
|
+
}, [e.questionStart, y, M]), G = F(() => {
|
|
7967
|
+
const R = y();
|
|
7968
|
+
if (a.current.currentQuestionIndex < (R?.questions?.length || 0) - 1) {
|
|
7875
7969
|
h.current && h.current.stopSpeaking && h.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
|
|
7876
|
-
const
|
|
7877
|
-
|
|
7970
|
+
const v = M();
|
|
7971
|
+
v && c.current.onCustomAction({
|
|
7878
7972
|
type: "nextQuestion",
|
|
7879
7973
|
moduleIndex: a.current.currentModuleIndex,
|
|
7880
7974
|
lessonIndex: a.current.currentLessonIndex,
|
|
7881
7975
|
questionIndex: a.current.currentQuestionIndex,
|
|
7882
7976
|
totalQuestions: a.current.totalQuestions,
|
|
7883
|
-
question:
|
|
7977
|
+
question: v,
|
|
7884
7978
|
score: a.current.score
|
|
7885
7979
|
});
|
|
7886
|
-
const
|
|
7887
|
-
if (!h.current || !
|
|
7980
|
+
const w = () => {
|
|
7981
|
+
if (!h.current || !v) return;
|
|
7888
7982
|
if (h.current.setMood("happy"), h.current.setBodyMovement("idle"), e.nextQuestion)
|
|
7889
7983
|
try {
|
|
7890
7984
|
h.current.playAnimation(e.nextQuestion, !0);
|
|
7891
7985
|
} catch (q) {
|
|
7892
7986
|
console.warn("Failed to play nextQuestion animation:", q);
|
|
7893
7987
|
}
|
|
7894
|
-
const
|
|
7895
|
-
if (
|
|
7896
|
-
const q = j ? `Great! Here's your final coding challenge: ${
|
|
7988
|
+
const E = k.current || { lipsyncLang: "en" }, K = y()?.questions?.length || 0, j = a.current.currentQuestionIndex >= K - 1;
|
|
7989
|
+
if (v.type === "code_test") {
|
|
7990
|
+
const q = j ? `Great! Here's your final coding challenge: ${v.question}` : `Great! Now let's move on to your next coding challenge: ${v.question}`;
|
|
7897
7991
|
h.current.speakText(q, {
|
|
7898
|
-
lipsyncLang:
|
|
7992
|
+
lipsyncLang: E.lipsyncLang
|
|
7899
7993
|
});
|
|
7900
|
-
} else if (
|
|
7901
|
-
const q = j ? `Alright! Here's your final question: ${
|
|
7994
|
+
} else if (v.type === "multiple_choice") {
|
|
7995
|
+
const q = j ? `Alright! Here's your final question: ${v.question}` : `Alright! Here's your next question: ${v.question}`;
|
|
7902
7996
|
h.current.speakText(q, {
|
|
7903
|
-
lipsyncLang:
|
|
7997
|
+
lipsyncLang: E.lipsyncLang
|
|
7904
7998
|
});
|
|
7905
|
-
} else if (
|
|
7906
|
-
const q = j ? `Now let's try this final one: ${
|
|
7999
|
+
} else if (v.type === "true_false") {
|
|
8000
|
+
const q = j ? `Now let's try this final one: ${v.question}` : `Now let's try this one: ${v.question}`;
|
|
7907
8001
|
h.current.speakText(q, {
|
|
7908
|
-
lipsyncLang:
|
|
8002
|
+
lipsyncLang: E.lipsyncLang
|
|
7909
8003
|
});
|
|
7910
8004
|
} else {
|
|
7911
|
-
const q = j ? `Here's your final question: ${
|
|
8005
|
+
const q = j ? `Here's your final question: ${v.question}` : `Here's the next question: ${v.question}`;
|
|
7912
8006
|
h.current.speakText(q, {
|
|
7913
|
-
lipsyncLang:
|
|
8007
|
+
lipsyncLang: E.lipsyncLang
|
|
7914
8008
|
});
|
|
7915
8009
|
}
|
|
7916
8010
|
};
|
|
7917
|
-
if (h.current && h.current.isReady &&
|
|
7918
|
-
|
|
7919
|
-
else if (
|
|
7920
|
-
const
|
|
7921
|
-
h.current && h.current.isReady && (clearInterval(
|
|
8011
|
+
if (h.current && h.current.isReady && v)
|
|
8012
|
+
w();
|
|
8013
|
+
else if (v) {
|
|
8014
|
+
const E = setInterval(() => {
|
|
8015
|
+
h.current && h.current.isReady && (clearInterval(E), w());
|
|
7922
8016
|
}, 100);
|
|
7923
8017
|
setTimeout(() => {
|
|
7924
|
-
clearInterval(
|
|
8018
|
+
clearInterval(E);
|
|
7925
8019
|
}, 5e3);
|
|
7926
8020
|
}
|
|
7927
8021
|
} else
|
|
@@ -7932,11 +8026,11 @@ const yt = Me(({
|
|
|
7932
8026
|
totalQuestions: a.current.totalQuestions,
|
|
7933
8027
|
score: a.current.score
|
|
7934
8028
|
});
|
|
7935
|
-
}, [e.nextQuestion, y,
|
|
7936
|
-
const
|
|
7937
|
-
if (a.current.currentLessonIndex < (
|
|
8029
|
+
}, [e.nextQuestion, y, M]), Q = F(() => {
|
|
8030
|
+
const R = T.current || { modules: [] }, v = R.modules[a.current.currentModuleIndex];
|
|
8031
|
+
if (a.current.currentLessonIndex < (v?.lessons?.length || 0) - 1) {
|
|
7938
8032
|
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;
|
|
7939
|
-
const
|
|
8033
|
+
const E = R.modules[a.current.currentModuleIndex], W = a.current.currentLessonIndex < (E?.lessons?.length || 0) - 1, K = a.current.currentModuleIndex < (R.modules?.length || 0) - 1, j = W || K;
|
|
7940
8034
|
c.current.onCustomAction({
|
|
7941
8035
|
type: "lessonStart",
|
|
7942
8036
|
moduleIndex: a.current.currentModuleIndex,
|
|
@@ -7947,9 +8041,9 @@ const yt = Me(({
|
|
|
7947
8041
|
lessonIndex: a.current.currentLessonIndex,
|
|
7948
8042
|
lesson: y()
|
|
7949
8043
|
}), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
|
|
7950
|
-
} else if (a.current.currentModuleIndex < (
|
|
8044
|
+
} else if (a.current.currentModuleIndex < (R.modules?.length || 0) - 1) {
|
|
7951
8045
|
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;
|
|
7952
|
-
const
|
|
8046
|
+
const W = R.modules[a.current.currentModuleIndex], K = a.current.currentLessonIndex < (W?.lessons?.length || 0) - 1, j = a.current.currentModuleIndex < (R.modules?.length || 0) - 1, q = K || j;
|
|
7953
8047
|
c.current.onCustomAction({
|
|
7954
8048
|
type: "lessonStart",
|
|
7955
8049
|
moduleIndex: a.current.currentModuleIndex,
|
|
@@ -7962,64 +8056,64 @@ const yt = Me(({
|
|
|
7962
8056
|
}), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
|
|
7963
8057
|
} else
|
|
7964
8058
|
I.current && I.current();
|
|
7965
|
-
}, []),
|
|
7966
|
-
const
|
|
7967
|
-
let
|
|
7968
|
-
if (
|
|
7969
|
-
const
|
|
7970
|
-
|
|
8059
|
+
}, []), Z = F(() => {
|
|
8060
|
+
const R = y();
|
|
8061
|
+
let v = null;
|
|
8062
|
+
if (R?.avatar_script && R?.body) {
|
|
8063
|
+
const w = R.avatar_script.trim(), E = R.body.trim(), W = w.match(/[.!?]$/) ? " " : ". ";
|
|
8064
|
+
v = `${w}${W}${E}`;
|
|
7971
8065
|
} else
|
|
7972
|
-
|
|
7973
|
-
if (h.current && h.current.isReady &&
|
|
8066
|
+
v = R?.avatar_script || R?.body || null;
|
|
8067
|
+
if (h.current && h.current.isReady && v) {
|
|
7974
8068
|
a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0, h.current.setMood("happy");
|
|
7975
|
-
let
|
|
8069
|
+
let w = !1;
|
|
7976
8070
|
if (e.teaching)
|
|
7977
8071
|
try {
|
|
7978
|
-
h.current.playAnimation(e.teaching, !0),
|
|
7979
|
-
} catch (
|
|
7980
|
-
console.warn("Failed to play teaching animation:",
|
|
8072
|
+
h.current.playAnimation(e.teaching, !0), w = !0;
|
|
8073
|
+
} catch (W) {
|
|
8074
|
+
console.warn("Failed to play teaching animation:", W);
|
|
7981
8075
|
}
|
|
7982
|
-
|
|
7983
|
-
const
|
|
8076
|
+
w || h.current.setBodyMovement("gesturing");
|
|
8077
|
+
const E = k.current || { lipsyncLang: "en" };
|
|
7984
8078
|
c.current.onLessonStart({
|
|
7985
8079
|
moduleIndex: a.current.currentModuleIndex,
|
|
7986
8080
|
lessonIndex: a.current.currentLessonIndex,
|
|
7987
|
-
lesson:
|
|
8081
|
+
lesson: R
|
|
7988
8082
|
}), c.current.onCustomAction({
|
|
7989
8083
|
type: "teachingStart",
|
|
7990
8084
|
moduleIndex: a.current.currentModuleIndex,
|
|
7991
8085
|
lessonIndex: a.current.currentLessonIndex,
|
|
7992
|
-
lesson:
|
|
7993
|
-
}), h.current.speakText(
|
|
7994
|
-
lipsyncLang:
|
|
8086
|
+
lesson: R
|
|
8087
|
+
}), h.current.speakText(v, {
|
|
8088
|
+
lipsyncLang: E.lipsyncLang,
|
|
7995
8089
|
onSpeechEnd: () => {
|
|
7996
8090
|
a.current.isTeaching = !1, c.current.onCustomAction({
|
|
7997
8091
|
type: "teachingComplete",
|
|
7998
8092
|
moduleIndex: a.current.currentModuleIndex,
|
|
7999
8093
|
lessonIndex: a.current.currentLessonIndex,
|
|
8000
|
-
lesson:
|
|
8001
|
-
hasQuestions:
|
|
8002
|
-
}),
|
|
8094
|
+
lesson: R,
|
|
8095
|
+
hasQuestions: R.questions && R.questions.length > 0
|
|
8096
|
+
}), R?.code_example && c.current.onCustomAction({
|
|
8003
8097
|
type: "codeExampleReady",
|
|
8004
8098
|
moduleIndex: a.current.currentModuleIndex,
|
|
8005
8099
|
lessonIndex: a.current.currentLessonIndex,
|
|
8006
|
-
lesson:
|
|
8007
|
-
codeExample:
|
|
8100
|
+
lesson: R,
|
|
8101
|
+
codeExample: R.code_example
|
|
8008
8102
|
});
|
|
8009
8103
|
}
|
|
8010
8104
|
});
|
|
8011
8105
|
}
|
|
8012
|
-
}, [e.teaching, y]),
|
|
8013
|
-
const
|
|
8014
|
-
if (
|
|
8106
|
+
}, [e.teaching, y]), ee = F((R) => {
|
|
8107
|
+
const v = M(), w = P(R, v);
|
|
8108
|
+
if (w && (a.current.score += 1), c.current.onQuestionAnswer({
|
|
8015
8109
|
moduleIndex: a.current.currentModuleIndex,
|
|
8016
8110
|
lessonIndex: a.current.currentLessonIndex,
|
|
8017
8111
|
questionIndex: a.current.currentQuestionIndex,
|
|
8018
|
-
answer:
|
|
8019
|
-
isCorrect:
|
|
8020
|
-
question:
|
|
8112
|
+
answer: R,
|
|
8113
|
+
isCorrect: w,
|
|
8114
|
+
question: v
|
|
8021
8115
|
}), h.current)
|
|
8022
|
-
if (
|
|
8116
|
+
if (w) {
|
|
8023
8117
|
if (h.current.setMood("happy"), e.correct)
|
|
8024
8118
|
try {
|
|
8025
8119
|
h.current.playReaction("happy");
|
|
@@ -8027,11 +8121,11 @@ const yt = Me(({
|
|
|
8027
8121
|
h.current.setBodyMovement("happy");
|
|
8028
8122
|
}
|
|
8029
8123
|
h.current.setBodyMovement("gesturing");
|
|
8030
|
-
const
|
|
8031
|
-
a.current.currentQuestionIndex >=
|
|
8032
|
-
const K = a.current.currentQuestionIndex <
|
|
8033
|
-
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:",
|
|
8034
|
-
const j =
|
|
8124
|
+
const W = y()?.questions?.length || 0;
|
|
8125
|
+
a.current.currentQuestionIndex >= W - 1;
|
|
8126
|
+
const K = a.current.currentQuestionIndex < W - 1;
|
|
8127
|
+
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", W, "hasNextQuestion:", K);
|
|
8128
|
+
const j = v.type === "code_test" ? `Great job! Your code passed all the tests! ${v.explanation || ""}` : `Excellent! That's correct! ${v.explanation || ""}`, q = k.current || { lipsyncLang: "en" };
|
|
8035
8129
|
h.current.speakText(j, {
|
|
8036
8130
|
lipsyncLang: q.lipsyncLang,
|
|
8037
8131
|
onSpeechEnd: () => {
|
|
@@ -8055,9 +8149,9 @@ const yt = Me(({
|
|
|
8055
8149
|
h.current.setBodyMovement("idle");
|
|
8056
8150
|
}
|
|
8057
8151
|
h.current.setBodyMovement("gesturing");
|
|
8058
|
-
const
|
|
8059
|
-
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:",
|
|
8060
|
-
const q =
|
|
8152
|
+
const W = y()?.questions?.length || 0, K = a.current.currentQuestionIndex >= W - 1, j = a.current.currentQuestionIndex < W - 1;
|
|
8153
|
+
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", W, "hasNextQuestion:", j);
|
|
8154
|
+
const q = v.type === "code_test" ? `Your code didn't pass all the tests. ${v.explanation || "Try again!"}` : `Not quite right, but don't worry! ${v.explanation || ""}${K ? "" : " Let's move on to the next question."}`, Le = k.current || { lipsyncLang: "en" };
|
|
8061
8155
|
h.current.speakText(q, {
|
|
8062
8156
|
lipsyncLang: Le.lipsyncLang,
|
|
8063
8157
|
onSpeechEnd: () => {
|
|
@@ -8075,84 +8169,84 @@ const yt = Me(({
|
|
|
8075
8169
|
});
|
|
8076
8170
|
}
|
|
8077
8171
|
else {
|
|
8078
|
-
const
|
|
8172
|
+
const W = y()?.questions?.length || 0;
|
|
8079
8173
|
c.current.onCustomAction({
|
|
8080
8174
|
type: "answerFeedbackComplete",
|
|
8081
8175
|
moduleIndex: a.current.currentModuleIndex,
|
|
8082
8176
|
lessonIndex: a.current.currentLessonIndex,
|
|
8083
8177
|
questionIndex: a.current.currentQuestionIndex,
|
|
8084
|
-
isCorrect:
|
|
8085
|
-
hasNextQuestion: a.current.currentQuestionIndex <
|
|
8178
|
+
isCorrect: w,
|
|
8179
|
+
hasNextQuestion: a.current.currentQuestionIndex < W - 1,
|
|
8086
8180
|
score: a.current.score,
|
|
8087
8181
|
totalQuestions: a.current.totalQuestions,
|
|
8088
8182
|
avatarNotReady: !0
|
|
8089
8183
|
});
|
|
8090
8184
|
}
|
|
8091
|
-
}, [e.correct, e.incorrect,
|
|
8092
|
-
const
|
|
8093
|
-
if (!
|
|
8185
|
+
}, [e.correct, e.incorrect, M, y, P]), se = F((R) => {
|
|
8186
|
+
const v = M();
|
|
8187
|
+
if (!R || typeof R != "object") {
|
|
8094
8188
|
console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
|
|
8095
8189
|
return;
|
|
8096
8190
|
}
|
|
8097
|
-
if (
|
|
8191
|
+
if (v?.type !== "code_test") {
|
|
8098
8192
|
console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
|
|
8099
8193
|
return;
|
|
8100
8194
|
}
|
|
8101
|
-
const
|
|
8102
|
-
passed:
|
|
8103
|
-
results:
|
|
8104
|
-
output:
|
|
8105
|
-
error:
|
|
8106
|
-
executionTime:
|
|
8107
|
-
testCount:
|
|
8108
|
-
passedCount:
|
|
8109
|
-
failedCount:
|
|
8195
|
+
const w = {
|
|
8196
|
+
passed: R.passed === !0,
|
|
8197
|
+
results: R.results || [],
|
|
8198
|
+
output: R.output || "",
|
|
8199
|
+
error: R.error || null,
|
|
8200
|
+
executionTime: R.executionTime || null,
|
|
8201
|
+
testCount: R.testCount || 0,
|
|
8202
|
+
passedCount: R.passedCount || 0,
|
|
8203
|
+
failedCount: R.failedCount || 0
|
|
8110
8204
|
};
|
|
8111
8205
|
c.current.onCustomAction({
|
|
8112
8206
|
type: "codeTestSubmitted",
|
|
8113
8207
|
moduleIndex: a.current.currentModuleIndex,
|
|
8114
8208
|
lessonIndex: a.current.currentLessonIndex,
|
|
8115
8209
|
questionIndex: a.current.currentQuestionIndex,
|
|
8116
|
-
testResult:
|
|
8117
|
-
question:
|
|
8118
|
-
}),
|
|
8119
|
-
}, [
|
|
8210
|
+
testResult: w,
|
|
8211
|
+
question: v
|
|
8212
|
+
}), m.current && m.current(w);
|
|
8213
|
+
}, [M, P]), ae = F(() => {
|
|
8120
8214
|
if (a.current.currentQuestionIndex > 0) {
|
|
8121
8215
|
a.current.currentQuestionIndex -= 1;
|
|
8122
|
-
const
|
|
8123
|
-
|
|
8216
|
+
const R = M();
|
|
8217
|
+
R && c.current.onCustomAction({
|
|
8124
8218
|
type: "questionStart",
|
|
8125
8219
|
moduleIndex: a.current.currentModuleIndex,
|
|
8126
8220
|
lessonIndex: a.current.currentLessonIndex,
|
|
8127
8221
|
questionIndex: a.current.currentQuestionIndex,
|
|
8128
8222
|
totalQuestions: a.current.totalQuestions,
|
|
8129
|
-
question:
|
|
8223
|
+
question: R,
|
|
8130
8224
|
score: a.current.score
|
|
8131
8225
|
});
|
|
8132
|
-
const
|
|
8133
|
-
if (!h.current || !
|
|
8226
|
+
const v = () => {
|
|
8227
|
+
if (!h.current || !R) return;
|
|
8134
8228
|
h.current.setMood("happy"), h.current.setBodyMovement("idle");
|
|
8135
|
-
const
|
|
8136
|
-
|
|
8137
|
-
lipsyncLang:
|
|
8138
|
-
}) : h.current.speakText(`Going back to: ${
|
|
8139
|
-
lipsyncLang:
|
|
8229
|
+
const w = k.current || { lipsyncLang: "en" };
|
|
8230
|
+
R.type === "code_test" ? h.current.speakText(`Let's go back to this coding challenge: ${R.question}`, {
|
|
8231
|
+
lipsyncLang: w.lipsyncLang
|
|
8232
|
+
}) : h.current.speakText(`Going back to: ${R.question}`, {
|
|
8233
|
+
lipsyncLang: w.lipsyncLang
|
|
8140
8234
|
});
|
|
8141
8235
|
};
|
|
8142
|
-
if (h.current && h.current.isReady &&
|
|
8143
|
-
|
|
8144
|
-
else if (
|
|
8145
|
-
const
|
|
8146
|
-
h.current && h.current.isReady && (clearInterval(
|
|
8236
|
+
if (h.current && h.current.isReady && R)
|
|
8237
|
+
v();
|
|
8238
|
+
else if (R) {
|
|
8239
|
+
const w = setInterval(() => {
|
|
8240
|
+
h.current && h.current.isReady && (clearInterval(w), v());
|
|
8147
8241
|
}, 100);
|
|
8148
8242
|
setTimeout(() => {
|
|
8149
|
-
clearInterval(
|
|
8243
|
+
clearInterval(w);
|
|
8150
8244
|
}, 5e3);
|
|
8151
8245
|
}
|
|
8152
8246
|
}
|
|
8153
|
-
}, [
|
|
8154
|
-
const
|
|
8155
|
-
if (
|
|
8247
|
+
}, [M]), pe = F(() => {
|
|
8248
|
+
const R = T.current || { modules: [] };
|
|
8249
|
+
if (R.modules[a.current.currentModuleIndex], a.current.currentLessonIndex > 0)
|
|
8156
8250
|
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, c.current.onCustomAction({
|
|
8157
8251
|
type: "lessonStart",
|
|
8158
8252
|
moduleIndex: a.current.currentModuleIndex,
|
|
@@ -8163,8 +8257,8 @@ const yt = Me(({
|
|
|
8163
8257
|
lesson: y()
|
|
8164
8258
|
}), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
|
|
8165
8259
|
else if (a.current.currentModuleIndex > 0) {
|
|
8166
|
-
const
|
|
8167
|
-
a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (
|
|
8260
|
+
const E = R.modules[a.current.currentModuleIndex - 1];
|
|
8261
|
+
a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (E?.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({
|
|
8168
8262
|
type: "lessonStart",
|
|
8169
8263
|
moduleIndex: a.current.currentModuleIndex,
|
|
8170
8264
|
lessonIndex: a.current.currentLessonIndex
|
|
@@ -8174,52 +8268,52 @@ const yt = Me(({
|
|
|
8174
8268
|
lesson: y()
|
|
8175
8269
|
}), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
|
|
8176
8270
|
}
|
|
8177
|
-
}, [y]),
|
|
8271
|
+
}, [y]), te = F(() => {
|
|
8178
8272
|
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;
|
|
8179
|
-
}, []), le =
|
|
8180
|
-
console.log("Avatar is ready!",
|
|
8181
|
-
const
|
|
8182
|
-
u &&
|
|
8273
|
+
}, []), le = F((R) => {
|
|
8274
|
+
console.log("Avatar is ready!", R);
|
|
8275
|
+
const v = y(), w = v?.avatar_script || v?.body;
|
|
8276
|
+
u && w && setTimeout(() => {
|
|
8183
8277
|
d.current && d.current();
|
|
8184
8278
|
}, 10);
|
|
8185
8279
|
}, [u, y]);
|
|
8186
8280
|
Xe(() => {
|
|
8187
|
-
d.current =
|
|
8281
|
+
d.current = Z, g.current = Q, x.current = D, b.current = G, I.current = J, H.current = S, m.current = ee;
|
|
8188
8282
|
}), Ee(r, () => ({
|
|
8189
8283
|
// Curriculum control methods
|
|
8190
|
-
startTeaching:
|
|
8284
|
+
startTeaching: Z,
|
|
8191
8285
|
startQuestions: S,
|
|
8192
|
-
handleAnswerSelect:
|
|
8286
|
+
handleAnswerSelect: ee,
|
|
8193
8287
|
handleCodeTestResult: se,
|
|
8194
|
-
nextQuestion:
|
|
8288
|
+
nextQuestion: G,
|
|
8195
8289
|
previousQuestion: ae,
|
|
8196
|
-
nextLesson:
|
|
8290
|
+
nextLesson: Q,
|
|
8197
8291
|
previousLesson: pe,
|
|
8198
|
-
completeLesson:
|
|
8199
|
-
completeCurriculum:
|
|
8200
|
-
resetCurriculum:
|
|
8292
|
+
completeLesson: D,
|
|
8293
|
+
completeCurriculum: J,
|
|
8294
|
+
resetCurriculum: te,
|
|
8201
8295
|
getState: () => ({ ...a.current }),
|
|
8202
|
-
getCurrentQuestion: () =>
|
|
8296
|
+
getCurrentQuestion: () => M(),
|
|
8203
8297
|
getCurrentLesson: () => y(),
|
|
8204
8298
|
// Direct access to avatar ref (always returns current value)
|
|
8205
8299
|
getAvatarRef: () => h.current,
|
|
8206
8300
|
// Convenience methods that delegate to avatar (always check current ref)
|
|
8207
|
-
speakText: async (
|
|
8301
|
+
speakText: async (R, v = {}) => {
|
|
8208
8302
|
await h.current?.resumeAudioContext?.();
|
|
8209
|
-
const
|
|
8210
|
-
h.current?.speakText(
|
|
8303
|
+
const w = k.current || { lipsyncLang: "en" };
|
|
8304
|
+
h.current?.speakText(R, { ...v, lipsyncLang: v.lipsyncLang || w.lipsyncLang });
|
|
8211
8305
|
},
|
|
8212
8306
|
resumeAudioContext: async () => {
|
|
8213
8307
|
if (h.current?.resumeAudioContext)
|
|
8214
8308
|
return await h.current.resumeAudioContext();
|
|
8215
|
-
const
|
|
8216
|
-
if (
|
|
8217
|
-
const
|
|
8218
|
-
if (
|
|
8309
|
+
const R = h.current?.talkingHead;
|
|
8310
|
+
if (R?.audioCtx) {
|
|
8311
|
+
const v = R.audioCtx;
|
|
8312
|
+
if (v.state === "suspended" || v.state === "interrupted")
|
|
8219
8313
|
try {
|
|
8220
|
-
await
|
|
8221
|
-
} catch (
|
|
8222
|
-
console.warn("Failed to resume audio context:",
|
|
8314
|
+
await v.resume(), console.log("Audio context resumed via talkingHead");
|
|
8315
|
+
} catch (w) {
|
|
8316
|
+
console.warn("Failed to resume audio context:", w);
|
|
8223
8317
|
}
|
|
8224
8318
|
} else
|
|
8225
8319
|
console.warn("Audio context not available yet");
|
|
@@ -8228,22 +8322,22 @@ const yt = Me(({
|
|
|
8228
8322
|
pauseSpeaking: () => h.current?.pauseSpeaking(),
|
|
8229
8323
|
resumeSpeaking: async () => await h.current?.resumeSpeaking(),
|
|
8230
8324
|
isPaused: () => h.current && typeof h.current.isPaused < "u" ? h.current.isPaused : !1,
|
|
8231
|
-
setMood: (
|
|
8232
|
-
playAnimation: (
|
|
8233
|
-
setBodyMovement: (
|
|
8234
|
-
setMovementIntensity: (
|
|
8325
|
+
setMood: (R) => h.current?.setMood(R),
|
|
8326
|
+
playAnimation: (R, v) => h.current?.playAnimation(R, v),
|
|
8327
|
+
setBodyMovement: (R) => h.current?.setBodyMovement(R),
|
|
8328
|
+
setMovementIntensity: (R) => h.current?.setMovementIntensity(R),
|
|
8235
8329
|
playRandomDance: () => h.current?.playRandomDance(),
|
|
8236
|
-
playReaction: (
|
|
8330
|
+
playReaction: (R) => h.current?.playReaction(R),
|
|
8237
8331
|
playCelebration: () => h.current?.playCelebration(),
|
|
8238
|
-
setShowFullAvatar: (
|
|
8239
|
-
setTimingAdjustment: (
|
|
8332
|
+
setShowFullAvatar: (R) => h.current?.setShowFullAvatar(R),
|
|
8333
|
+
setTimingAdjustment: (R) => h.current?.setTimingAdjustment(R),
|
|
8240
8334
|
lockAvatarPosition: () => h.current?.lockAvatarPosition(),
|
|
8241
8335
|
unlockAvatarPosition: () => h.current?.unlockAvatarPosition(),
|
|
8242
8336
|
// Custom action trigger
|
|
8243
|
-
triggerCustomAction: (
|
|
8337
|
+
triggerCustomAction: (R, v) => {
|
|
8244
8338
|
c.current.onCustomAction({
|
|
8245
|
-
type:
|
|
8246
|
-
...
|
|
8339
|
+
type: R,
|
|
8340
|
+
...v,
|
|
8247
8341
|
state: { ...a.current }
|
|
8248
8342
|
});
|
|
8249
8343
|
},
|
|
@@ -8251,8 +8345,8 @@ const yt = Me(({
|
|
|
8251
8345
|
handleResize: () => h.current?.handleResize(),
|
|
8252
8346
|
// Avatar readiness check (always returns current value)
|
|
8253
8347
|
isAvatarReady: () => h.current?.isReady || !1
|
|
8254
|
-
}), [
|
|
8255
|
-
const
|
|
8348
|
+
}), [Z, S, ee, se, G, Q, D, J, te, M, y]);
|
|
8349
|
+
const U = k.current || {
|
|
8256
8350
|
avatarUrl: "/avatars/brunette.glb",
|
|
8257
8351
|
avatarBody: "F",
|
|
8258
8352
|
mood: "happy",
|
|
@@ -8269,23 +8363,23 @@ const yt = Me(({
|
|
|
8269
8363
|
Ve,
|
|
8270
8364
|
{
|
|
8271
8365
|
ref: h,
|
|
8272
|
-
avatarUrl:
|
|
8273
|
-
avatarBody:
|
|
8274
|
-
mood:
|
|
8275
|
-
ttsLang:
|
|
8276
|
-
ttsService:
|
|
8277
|
-
ttsVoice:
|
|
8278
|
-
ttsApiKey:
|
|
8279
|
-
bodyMovement:
|
|
8280
|
-
movementIntensity:
|
|
8281
|
-
showFullAvatar:
|
|
8366
|
+
avatarUrl: U.avatarUrl,
|
|
8367
|
+
avatarBody: U.avatarBody,
|
|
8368
|
+
mood: U.mood,
|
|
8369
|
+
ttsLang: U.ttsLang,
|
|
8370
|
+
ttsService: U.ttsService,
|
|
8371
|
+
ttsVoice: U.ttsVoice,
|
|
8372
|
+
ttsApiKey: U.ttsApiKey,
|
|
8373
|
+
bodyMovement: U.bodyMovement,
|
|
8374
|
+
movementIntensity: U.movementIntensity,
|
|
8375
|
+
showFullAvatar: U.showFullAvatar,
|
|
8282
8376
|
cameraView: "upper",
|
|
8283
|
-
animations:
|
|
8377
|
+
animations: U.animations,
|
|
8284
8378
|
onReady: le,
|
|
8285
8379
|
onLoading: () => {
|
|
8286
8380
|
},
|
|
8287
|
-
onError: (
|
|
8288
|
-
console.error("Avatar error:",
|
|
8381
|
+
onError: (R) => {
|
|
8382
|
+
console.error("Avatar error:", R);
|
|
8289
8383
|
}
|
|
8290
8384
|
}
|
|
8291
8385
|
) });
|
|
@@ -8394,7 +8488,7 @@ const Ge = {
|
|
|
8394
8488
|
duration: 5e3,
|
|
8395
8489
|
description: "Excited, energetic movement"
|
|
8396
8490
|
}
|
|
8397
|
-
}, wt = (
|
|
8491
|
+
}, wt = (X) => Ge[X] || null, zt = (X) => Ge.hasOwnProperty(X);
|
|
8398
8492
|
export {
|
|
8399
8493
|
yt as CurriculumLearning,
|
|
8400
8494
|
gt as SimpleTalkingAvatar,
|