@sage-rsc/talking-head-react 1.3.8 → 1.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4398,14 +4398,14 @@ class Be {
4398
4398
  * This is called from updatePoseBase for pose-based animations
4399
4399
  */
4400
4400
  applyShoulderAdjustment() {
4401
- const e = new y.Euler();
4401
+ const t = new y.Euler(), e = 1;
4402
4402
  if (this.poseAvatar.props["LeftShoulder.quaternion"]) {
4403
4403
  const n = this.poseAvatar.props["LeftShoulder.quaternion"];
4404
- e.setFromQuaternion(n, "XYZ"), e.x += -0.6, n.setFromEuler(e, "XYZ");
4404
+ t.setFromQuaternion(n, "XYZ"), t.x > e && (t.x = Math.max(e, t.x - 0.4)), n.setFromEuler(t, "XYZ");
4405
4405
  }
4406
4406
  if (this.poseAvatar.props["RightShoulder.quaternion"]) {
4407
4407
  const n = this.poseAvatar.props["RightShoulder.quaternion"];
4408
- e.setFromQuaternion(n, "XYZ"), e.x += -0.6, n.setFromEuler(e, "XYZ");
4408
+ t.setFromQuaternion(n, "XYZ"), t.x > e && (t.x = Math.max(e, t.x - 0.4)), n.setFromEuler(t, "XYZ");
4409
4409
  }
4410
4410
  }
4411
4411
  /**
@@ -4415,8 +4415,10 @@ class Be {
4415
4415
  */
4416
4416
  applyShoulderAdjustmentToBones() {
4417
4417
  if (!this.armature) return;
4418
- const t = -0.6, e = new y.Euler(), n = new y.Quaternion(), i = this.armature.getObjectByName("LeftShoulder"), s = this.armature.getObjectByName("RightShoulder");
4419
- i && i.quaternion && (e.setFromQuaternion(i.quaternion, "XYZ"), e.x += t, n.setFromEuler(e, "XYZ"), i.quaternion.copy(n), i.updateMatrixWorld(!0)), s && s.quaternion && (e.setFromQuaternion(s.quaternion, "XYZ"), e.x += t, n.setFromEuler(e, "XYZ"), s.quaternion.copy(n), s.updateMatrixWorld(!0));
4418
+ const t = this.armature.getObjectByName("LeftShoulder"), e = this.armature.getObjectByName("RightShoulder");
4419
+ if (!t || !e) return;
4420
+ const n = new y.Euler(), i = new y.Quaternion(), s = 1;
4421
+ t.quaternion && (n.setFromQuaternion(t.quaternion, "XYZ"), n.x > s && (n.x = Math.max(s, n.x - 0.4)), i.setFromEuler(n, "XYZ"), t.quaternion.copy(i), t.updateMatrixWorld(!0)), e.quaternion && (n.setFromQuaternion(e.quaternion, "XYZ"), n.x > s && (n.x = Math.max(s, n.x - 0.4)), i.setFromEuler(n, "XYZ"), e.quaternion.copy(i), e.updateMatrixWorld(!0));
4420
4422
  }
4421
4423
  /**
4422
4424
  * Update avatar pose deltas
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sage-rsc/talking-head-react",
3
- "version": "1.3.8",
3
+ "version": "1.3.9",
4
4
  "description": "A reusable React component for 3D talking avatars with lip-sync and text-to-speech",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -0,0 +1,51 @@
1
+ #!/bin/bash
2
+ # Script to help update TalkingHead while preserving customizations
3
+
4
+ set -e
5
+
6
+ echo "=== TalkingHead Update Helper ==="
7
+ echo ""
8
+ echo "This script helps identify customizations to preserve during update."
9
+ echo ""
10
+
11
+ # Colors for output
12
+ GREEN='\033[0;32m'
13
+ YELLOW='\033[1;33m'
14
+ NC='\033[0m' # No Color
15
+
16
+ echo -e "${GREEN}Step 1: Identifying custom methods...${NC}"
17
+ echo ""
18
+ echo "=== Position Locking Methods ==="
19
+ grep -n "lockAvatarPosition\|unlockAvatarPosition\|maintainLockedPosition" src/lib/talkinghead.mjs | head -20
20
+
21
+ echo ""
22
+ echo "=== Shoulder Adjustment Methods ==="
23
+ grep -n "applyShoulderAdjustment" src/lib/talkinghead.mjs | head -10
24
+
25
+ echo ""
26
+ echo "=== Position Locking Calls ==="
27
+ grep -n "lockAvatarPosition\|unlockAvatarPosition\|positionWasLocked\|lockedPosition" src/lib/talkinghead.mjs | head -20
28
+
29
+ echo ""
30
+ echo -e "${YELLOW}Step 2: Custom files to preserve (DO NOT REPLACE):${NC}"
31
+ echo "- src/components/TalkingHeadComponent.jsx"
32
+ echo "- src/components/TalkingHeadAvatar.jsx"
33
+ echo "- src/components/SimpleTalkingAvatar.jsx"
34
+ echo "- src/components/CurriculumLearning.jsx"
35
+ echo "- src/config/ttsConfig.js"
36
+ echo "- src/lib/enhancedFBXLoader.js"
37
+ echo "- src/lib/fbxAnimationLoader.js"
38
+ echo "- src/utils/animationLoader.js"
39
+ echo "- scripts/generate-animation-manifest.js"
40
+
41
+ echo ""
42
+ echo -e "${GREEN}Step 3: Next steps:${NC}"
43
+ echo "1. Download latest TalkingHead source"
44
+ echo "2. Compare talkinghead.mjs files"
45
+ echo "3. Merge changes while preserving custom methods above"
46
+ echo "4. Test thoroughly"
47
+ echo ""
48
+ echo "To compare files, use:"
49
+ echo " diff -u old-talkinghead.mjs src/lib/talkinghead.mjs > talkinghead.diff"
50
+ echo ""
51
+
@@ -1618,15 +1618,17 @@ class TalkingHead {
1618
1618
  * This is called from updatePoseBase for pose-based animations
1619
1619
  */
1620
1620
  applyShoulderAdjustment() {
1621
- // Shoulder adjustment: reduce X-axis rotation by ~0.6 radians (34 degrees) to lower shoulders to a relaxed position
1622
- const shoulderAdjustment = -0.6; // Negative to lower shoulders (increased for more relaxed look)
1623
1621
  const tempEuler = new THREE.Euler();
1622
+ const maxX = 1.0; // Maximum X rotation for relaxed shoulders
1624
1623
 
1625
1624
  // Adjust left shoulder
1626
1625
  if (this.poseAvatar.props['LeftShoulder.quaternion']) {
1627
1626
  const leftShoulder = this.poseAvatar.props['LeftShoulder.quaternion'];
1628
1627
  tempEuler.setFromQuaternion(leftShoulder, 'XYZ');
1629
- tempEuler.x += shoulderAdjustment; // Reduce X rotation to lower shoulder
1628
+ // Reduce X rotation if too high for relaxed shoulders
1629
+ if (tempEuler.x > maxX) {
1630
+ tempEuler.x = Math.max(maxX, tempEuler.x - 0.4);
1631
+ }
1630
1632
  leftShoulder.setFromEuler(tempEuler, 'XYZ');
1631
1633
  }
1632
1634
 
@@ -1634,7 +1636,10 @@ class TalkingHead {
1634
1636
  if (this.poseAvatar.props['RightShoulder.quaternion']) {
1635
1637
  const rightShoulder = this.poseAvatar.props['RightShoulder.quaternion'];
1636
1638
  tempEuler.setFromQuaternion(rightShoulder, 'XYZ');
1637
- tempEuler.x += shoulderAdjustment; // Reduce X rotation to lower shoulder
1639
+ // Reduce X rotation if too high for relaxed shoulders
1640
+ if (tempEuler.x > maxX) {
1641
+ tempEuler.x = Math.max(maxX, tempEuler.x - 0.4);
1642
+ }
1638
1643
  rightShoulder.setFromEuler(tempEuler, 'XYZ');
1639
1644
  }
1640
1645
  }
@@ -1647,28 +1652,41 @@ class TalkingHead {
1647
1652
  applyShoulderAdjustmentToBones() {
1648
1653
  if (!this.armature) return;
1649
1654
 
1650
- // Shoulder adjustment: reduce X-axis rotation by ~0.6 radians (34 degrees) to lower shoulders
1651
- const shoulderAdjustment = -0.6; // Negative to lower shoulders
1652
- const tempEuler = new THREE.Euler();
1653
- const tempQuaternion = new THREE.Quaternion();
1654
-
1655
1655
  // Get shoulder bones directly from armature
1656
1656
  const leftShoulderBone = this.armature.getObjectByName('LeftShoulder');
1657
1657
  const rightShoulderBone = this.armature.getObjectByName('RightShoulder');
1658
1658
 
1659
+ if (!leftShoulderBone || !rightShoulderBone) return;
1660
+
1661
+ const tempEuler = new THREE.Euler();
1662
+ const tempQuaternion = new THREE.Quaternion();
1663
+
1664
+ // Target relaxed shoulder rotation for natural appearance
1665
+ // Reduce X rotation (forward tilt) to lower shoulders
1666
+ // Typical values: 1.5-1.8 (high/stiff) -> 0.9-1.1 (relaxed)
1667
+ const maxX = 1.0; // Maximum X rotation for relaxed shoulders
1668
+
1659
1669
  // Adjust left shoulder bone directly
1660
- if (leftShoulderBone && leftShoulderBone.quaternion) {
1670
+ if (leftShoulderBone.quaternion) {
1661
1671
  tempEuler.setFromQuaternion(leftShoulderBone.quaternion, 'XYZ');
1662
- tempEuler.x += shoulderAdjustment; // Reduce X rotation to lower shoulder
1672
+ // Reduce X rotation if it's too high for relaxed shoulders
1673
+ if (tempEuler.x > maxX) {
1674
+ // Smooth interpolation towards relaxed position
1675
+ tempEuler.x = Math.max(maxX, tempEuler.x - 0.4);
1676
+ }
1663
1677
  tempQuaternion.setFromEuler(tempEuler, 'XYZ');
1664
1678
  leftShoulderBone.quaternion.copy(tempQuaternion);
1665
1679
  leftShoulderBone.updateMatrixWorld(true);
1666
1680
  }
1667
1681
 
1668
1682
  // Adjust right shoulder bone directly
1669
- if (rightShoulderBone && rightShoulderBone.quaternion) {
1683
+ if (rightShoulderBone.quaternion) {
1670
1684
  tempEuler.setFromQuaternion(rightShoulderBone.quaternion, 'XYZ');
1671
- tempEuler.x += shoulderAdjustment; // Reduce X rotation to lower shoulder
1685
+ // Reduce X rotation if it's too high for relaxed shoulders
1686
+ if (tempEuler.x > maxX) {
1687
+ // Smooth interpolation towards relaxed position
1688
+ tempEuler.x = Math.max(maxX, tempEuler.x - 0.4);
1689
+ }
1672
1690
  tempQuaternion.setFromEuler(tempEuler, 'XYZ');
1673
1691
  rightShoulderBone.quaternion.copy(tempQuaternion);
1674
1692
  rightShoulderBone.updateMatrixWorld(true);