@sage-rsc/talking-head-react 1.0.34 → 1.0.36
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/fbxAnimationLoader-CNrfhJRz.cjs +1 -0
- package/dist/{fbxAnimationLoader-YIg1EylY.js → fbxAnimationLoader-DJjaYKNo.js} +4 -3
- package/dist/index.cjs +7 -1
- package/dist/index.js +7644 -9
- package/package.json +1 -1
- package/src/components/CurriculumLearning.jsx +20 -3
- package/dist/fbxAnimationLoader-BrjaqtTU.cjs +0 -1
- package/dist/index-CdCA-KAp.cjs +0 -13
- package/dist/index-Dd7BPF7g.js +0 -12170
package/package.json
CHANGED
|
@@ -457,7 +457,22 @@ const CurriculumLearning = forwardRef(({
|
|
|
457
457
|
// Start teaching the lesson
|
|
458
458
|
const startTeaching = useCallback(() => {
|
|
459
459
|
const currentLesson = getCurrentLesson();
|
|
460
|
-
if
|
|
460
|
+
// Combine body and avatar_script if both exist, or use whichever is available
|
|
461
|
+
// If both exist, combine them with a period and space for natural flow
|
|
462
|
+
let teachingText = null;
|
|
463
|
+
if (currentLesson?.avatar_script && currentLesson?.body) {
|
|
464
|
+
// Both exist - combine them with proper punctuation
|
|
465
|
+
const script = currentLesson.avatar_script.trim();
|
|
466
|
+
const body = currentLesson.body.trim();
|
|
467
|
+
// Add period if script doesn't end with punctuation
|
|
468
|
+
const separator = script.match(/[.!?]$/) ? ' ' : '. ';
|
|
469
|
+
teachingText = `${script}${separator}${body}`;
|
|
470
|
+
} else {
|
|
471
|
+
// Use whichever is available
|
|
472
|
+
teachingText = currentLesson?.avatar_script || currentLesson?.body || null;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
if (avatarRef.current && avatarRef.current.isReady && teachingText) {
|
|
461
476
|
stateRef.current.isTeaching = true;
|
|
462
477
|
stateRef.current.isQuestionMode = false;
|
|
463
478
|
|
|
@@ -495,7 +510,7 @@ const CurriculumLearning = forwardRef(({
|
|
|
495
510
|
});
|
|
496
511
|
|
|
497
512
|
// Wait for avatar to finish speaking before moving to questions
|
|
498
|
-
avatarRef.current.speakText(
|
|
513
|
+
avatarRef.current.speakText(teachingText, {
|
|
499
514
|
lipsyncLang: config.lipsyncLang,
|
|
500
515
|
onSpeechEnd: () => {
|
|
501
516
|
stateRef.current.isTeaching = false;
|
|
@@ -663,7 +678,9 @@ const CurriculumLearning = forwardRef(({
|
|
|
663
678
|
const handleAvatarReady = useCallback((talkingHead) => {
|
|
664
679
|
console.log('Avatar is ready!', talkingHead);
|
|
665
680
|
const currentLesson = getCurrentLesson();
|
|
666
|
-
if (
|
|
681
|
+
// Check if there's teaching content (either avatar_script or body)
|
|
682
|
+
const hasTeachingContent = currentLesson?.avatar_script || currentLesson?.body;
|
|
683
|
+
if (autoStart && hasTeachingContent) {
|
|
667
684
|
setTimeout(() => {
|
|
668
685
|
if (startTeachingRef.current) {
|
|
669
686
|
startTeachingRef.current();
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("three"),l=require("./index-CdCA-KAp.cjs");function m(s){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(s){for(const t in s)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(s,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>s[t]})}}return e.default=s,Object.freeze(e)}const r=m(c);class h{constructor(e){this.avatar=e,this.THREE=r,this.loader=new l.FBXLoader,this.animations=new Map,this.currentAnimation=null,this.mixer=null,this.clock=new r.Clock,e&&e.armature&&(this.mixer=new r.AnimationMixer(e.armature))}async loadGestureAnimations(e){const t=l.getAnimation(e);if(!t||!t.enabled)return console.warn(`No FBX animations configured for gesture: ${e}`),[];const n=[];for(const o of t.files)try{console.log(`Loading FBX animation: ${o}`);const i=await this.loadFBXAnimation(o);i&&n.push({clip:i,config:t,filePath:o})}catch(i){console.error(`Failed to load FBX animation ${o}:`,i)}return this.animations.set(e,n),n}async loadFBXAnimation(e){const t=e.split(".").pop().toLowerCase();if(t!=="fbx"){const n=`Invalid file type for FBX animation: ${e}. Expected .fbx file, got .${t}`;return console.error(n),Promise.reject(new Error(n))}return new Promise((n,o)=>{this.loader.load(e,i=>{try{const a=i.animations;a&&a.length>0?(console.log(`Loaded ${a.length} animation clips from ${e}`),n(a[0])):(console.warn(`No animation clips found in ${e}`),n(null))}catch(a){console.error(`Error processing FBX file ${e}:`,a),o(a)}},i=>{i.total>0&&console.log(`Loading progress for ${e}: ${(i.loaded/i.total*100).toFixed(1)}%`)},i=>{console.error(`Failed to load FBX file ${e}:`,i),i.message&&i.message.includes("version number")&&(console.error("FBX Loader Error: Cannot find version number"),console.error("This usually means:"),console.error("1. The file is not a valid FBX file"),console.error("2. The file might be corrupted"),console.error("3. The file path might be incorrect"),console.error("4. The file might be a GLB file instead of FBX"),console.error("5. The file might not exist at the specified path")),o(i)})})}async playGestureAnimation(e,t=1){if(!this.mixer){console.warn("Animation mixer not initialized");return}this.stopCurrentAnimation();let n=this.animations.get(e);if(n||(n=await this.loadGestureAnimations(e)),n.length===0){console.warn(`No animations available for gesture: ${e}`);return}const o=n[Math.floor(Math.random()*n.length)],i=o.config,a=this.mixer.clipAction(o.clip);a.setEffectiveWeight(i.weight*t),a.setLoop(i.loop?r.LoopRepeat:r.LoopOnce,1/0),a.clampWhenFinished=!0,a.reset(),a.fadeIn(i.blendTime),a.play(),this.currentAnimation={action:a,gestureType:e,config:i},console.log(`Playing FBX animation: ${e} with intensity: ${t}`)}async testFBXCompatibility(e){return new Promise(t=>{this.loader.load(e,n=>{try{const o={success:!0,hasAnimations:n.animations&&n.animations.length>0,animationCount:n.animations?n.animations.length:0,hasSkeleton:n.children.some(i=>i.type==="SkinnedMesh"||i.skeleton),hasGeometry:n.children.some(i=>i.geometry&&i.geometry.attributes),duration:n.animations&&n.animations.length>0?n.animations[0].duration:0,tracks:n.animations&&n.animations.length>0?n.animations[0].tracks.length:0,boneNames:this.extractBoneNames(n),error:null};t(o)}catch(o){t({success:!1,error:o.message,hasAnimations:!1,animationCount:0,hasSkeleton:!1,hasGeometry:!1,boneNames:[]})}},n=>{console.log(`Loading ${e}: ${(n.loaded/n.total*100).toFixed(1)}%`)},n=>{t({success:!1,error:n.message||"Failed to load file",hasAnimations:!1,animationCount:0,hasSkeleton:!1,hasGeometry:!1,boneNames:[]})})})}extractBoneNames(e){const t=[];return e.traverse(n=>{(n.isBone||n.type==="Bone")&&t.push(n.name),n.skeleton&&n.skeleton.bones.forEach(o=>{t.includes(o.name)||t.push(o.name)})}),t}stopCurrentAnimation(){this.currentAnimation&&this.currentAnimation.action&&(this.currentAnimation.action.fadeOut(.2),setTimeout(()=>{this.currentAnimation.action.stop(),this.currentAnimation=null},200))}update(){this.mixer&&this.mixer.update(this.clock.getDelta())}setIntensity(e){if(this.currentAnimation&&this.currentAnimation.action){const t=this.currentAnimation.config;this.currentAnimation.action.setEffectiveWeight(t.weight*e)}}hasAnimations(e){return this.animations.has(e)&&this.animations.get(e).length>0}getLoadedGestures(){return Array.from(this.animations.keys())}async preloadAnimations(e){console.log("Preloading FBX animations...");const t=e.map(n=>this.loadGestureAnimations(n));try{await Promise.all(t),console.log("All FBX animations preloaded successfully")}catch(n){console.error("Error preloading animations:",n)}}dispose(){this.stopCurrentAnimation(),this.animations.clear(),this.mixer=null}}exports.FBXAnimationLoader=h;
|