@sage-rsc/talking-head-react 1.1.3 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +2 -2
- package/dist/index.js +577 -547
- package/package.json +1 -1
- package/src/lib/talkinghead.mjs +80 -4
package/package.json
CHANGED
package/src/lib/talkinghead.mjs
CHANGED
|
@@ -5419,6 +5419,9 @@ class TalkingHead {
|
|
|
5419
5419
|
'L_Middle1': 'LeftHandMiddle1',
|
|
5420
5420
|
'L_Middle2': 'LeftHandMiddle2',
|
|
5421
5421
|
'L_Middle3': 'LeftHandMiddle3',
|
|
5422
|
+
'L_Mid1': 'LeftHandMiddle1',
|
|
5423
|
+
'L_Mid2': 'LeftHandMiddle2',
|
|
5424
|
+
'L_Mid3': 'LeftHandMiddle3',
|
|
5422
5425
|
'L_Ring1': 'LeftHandRing1',
|
|
5423
5426
|
'L_Ring2': 'LeftHandRing2',
|
|
5424
5427
|
'L_Ring3': 'LeftHandRing3',
|
|
@@ -5440,6 +5443,9 @@ class TalkingHead {
|
|
|
5440
5443
|
'R_Middle1': 'RightHandMiddle1',
|
|
5441
5444
|
'R_Middle2': 'RightHandMiddle2',
|
|
5442
5445
|
'R_Middle3': 'RightHandMiddle3',
|
|
5446
|
+
'R_Mid1': 'RightHandMiddle1',
|
|
5447
|
+
'R_Mid2': 'RightHandMiddle2',
|
|
5448
|
+
'R_Mid3': 'RightHandMiddle3',
|
|
5443
5449
|
'R_Ring1': 'RightHandRing1',
|
|
5444
5450
|
'R_Ring2': 'RightHandRing2',
|
|
5445
5451
|
'R_Ring3': 'RightHandRing3',
|
|
@@ -5504,8 +5510,8 @@ class TalkingHead {
|
|
|
5504
5510
|
}
|
|
5505
5511
|
}
|
|
5506
5512
|
|
|
5507
|
-
// Pattern: R_Middle1/2/3 -> RightHandMiddle1/2/3
|
|
5508
|
-
const middleMatch = lowerNormalized.match(/^[rl]
|
|
5513
|
+
// Pattern: R_Middle1/2/3 or R_Mid1/2/3 -> RightHandMiddle1/2/3
|
|
5514
|
+
const middleMatch = lowerNormalized.match(/^[rl]_(?:middle|mid)(\d+)$/);
|
|
5509
5515
|
if (middleMatch) {
|
|
5510
5516
|
const digit = middleMatch[1];
|
|
5511
5517
|
const side = lowerNormalized.startsWith('r') ? 'Right' : 'Left';
|
|
@@ -5535,8 +5541,12 @@ class TalkingHead {
|
|
|
5535
5541
|
}
|
|
5536
5542
|
}
|
|
5537
5543
|
|
|
5538
|
-
// Pattern: R_UpperarmTwist01/02 -> ignore (twist bones)
|
|
5539
|
-
if (lowerNormalized.includes('upperarmtwist') ||
|
|
5544
|
+
// Pattern: R_UpperarmTwist01/02 -> ignore (twist bones and other extra bones)
|
|
5545
|
+
if (lowerNormalized.includes('upperarmtwist') ||
|
|
5546
|
+
lowerNormalized.includes('forearmtwist') ||
|
|
5547
|
+
lowerNormalized.includes('ribstwist') ||
|
|
5548
|
+
lowerNormalized.includes('breast') ||
|
|
5549
|
+
lowerNormalized.includes('twist')) {
|
|
5540
5550
|
return null;
|
|
5541
5551
|
}
|
|
5542
5552
|
|
|
@@ -5604,6 +5614,72 @@ class TalkingHead {
|
|
|
5604
5614
|
const newTrack = track.clone();
|
|
5605
5615
|
newTrack.name = newTrackName;
|
|
5606
5616
|
|
|
5617
|
+
// Fix rotations for arm/hand bones that might be inverted
|
|
5618
|
+
// If hands are folding behind instead of in front, we need to adjust rotations
|
|
5619
|
+
const isArmBone = mappedBoneName.includes('Arm') || mappedBoneName.includes('Hand') || mappedBoneName.includes('Shoulder');
|
|
5620
|
+
const isForearmBone = mappedBoneName.includes('ForeArm');
|
|
5621
|
+
|
|
5622
|
+
if (isArmBone && (property === 'quaternion' || property === 'rotation')) {
|
|
5623
|
+
// For quaternion tracks, we might need to adjust the rotation
|
|
5624
|
+
// Check if this is a quaternion track
|
|
5625
|
+
if (property === 'quaternion' && newTrack.values && newTrack.values.length >= 4) {
|
|
5626
|
+
// Quaternion format: [x, y, z, w] per keyframe
|
|
5627
|
+
// For arm bones, we might need to invert Y or Z rotation
|
|
5628
|
+
// Adjust quaternion values to fix hand position
|
|
5629
|
+
const numKeyframes = newTrack.times.length;
|
|
5630
|
+
for (let i = 0; i < numKeyframes; i++) {
|
|
5631
|
+
const baseIdx = i * 4;
|
|
5632
|
+
if (baseIdx + 3 < newTrack.values.length) {
|
|
5633
|
+
// Get quaternion values
|
|
5634
|
+
let x = newTrack.values[baseIdx];
|
|
5635
|
+
let y = newTrack.values[baseIdx + 1];
|
|
5636
|
+
let z = newTrack.values[baseIdx + 2];
|
|
5637
|
+
let w = newTrack.values[baseIdx + 3];
|
|
5638
|
+
|
|
5639
|
+
// For arms, adjust rotation to flip hands from back to front
|
|
5640
|
+
// This is a common fix for FBX animations with different coordinate systems
|
|
5641
|
+
if (isForearmBone || mappedBoneName.includes('Hand')) {
|
|
5642
|
+
// Rotate 180 degrees around X axis to flip hands from behind to in front
|
|
5643
|
+
// Create a 180-degree rotation around X axis
|
|
5644
|
+
const flipAngle = Math.PI;
|
|
5645
|
+
const flipX = Math.cos(flipAngle / 2); // w component
|
|
5646
|
+
const flipY = Math.sin(flipAngle / 2); // x component (axis X = 1,0,0)
|
|
5647
|
+
|
|
5648
|
+
// Multiply quaternions: q_result = q_flip * q_original
|
|
5649
|
+
// For rotation around X axis: q_flip = (sin(θ/2), 0, 0, cos(θ/2))
|
|
5650
|
+
const qw = flipX * w - flipY * x;
|
|
5651
|
+
const qx = flipX * x + flipY * w;
|
|
5652
|
+
const qy = flipX * y - flipY * z;
|
|
5653
|
+
const qz = flipX * z + flipY * y;
|
|
5654
|
+
|
|
5655
|
+
x = qx;
|
|
5656
|
+
y = qy;
|
|
5657
|
+
z = qz;
|
|
5658
|
+
w = qw;
|
|
5659
|
+
}
|
|
5660
|
+
|
|
5661
|
+
newTrack.values[baseIdx] = x;
|
|
5662
|
+
newTrack.values[baseIdx + 1] = y;
|
|
5663
|
+
newTrack.values[baseIdx + 2] = z;
|
|
5664
|
+
newTrack.values[baseIdx + 3] = w;
|
|
5665
|
+
}
|
|
5666
|
+
}
|
|
5667
|
+
} else if (property === 'rotation' && newTrack.values && newTrack.values.length >= 3) {
|
|
5668
|
+
// Euler rotation format: [x, y, z] per keyframe
|
|
5669
|
+
const numKeyframes = newTrack.times.length;
|
|
5670
|
+
for (let i = 0; i < numKeyframes; i++) {
|
|
5671
|
+
const baseIdx = i * 3;
|
|
5672
|
+
if (baseIdx + 2 < newTrack.values.length) {
|
|
5673
|
+
// For arm bones, adjust Y rotation to flip hands
|
|
5674
|
+
if (isForearmBone || mappedBoneName.includes('Hand')) {
|
|
5675
|
+
// Add 180 degrees (PI radians) to Y rotation
|
|
5676
|
+
newTrack.values[baseIdx + 1] += Math.PI;
|
|
5677
|
+
}
|
|
5678
|
+
}
|
|
5679
|
+
}
|
|
5680
|
+
}
|
|
5681
|
+
}
|
|
5682
|
+
|
|
5607
5683
|
validTracks.push(newTrack);
|
|
5608
5684
|
|
|
5609
5685
|
// Track mappings for logging
|