private void DisplayPoseOnModel(BSFacePose pose) { if (MeshRenderer == null) { return; } int modelBlendshapesCount = MeshRenderer.sharedMesh.blendShapeCount; for (int i = 0; i < modelBlendshapesCount; i++) { IEnumerable <BSBlendshape> correspondingPoseBlendshapes = pose.Blendshapes.Where(curr => curr.Index == i); int actualCount = correspondingPoseBlendshapes.Count(); // If there is at least one pose if (actualCount != 0) { // If there are several poses, it's a problem: signal it if (actualCount > 1) { Debug.LogError("DANGER: several blendshapes are defined in your pose with the same index. The first in the list will be used."); } BSBlendshape firstBlendshape = correspondingPoseBlendshapes.First(); MeshRenderer.SetBlendShapeWeight(i, firstBlendshape.Value); } // Otherwise there is no pose else { MeshRenderer.SetBlendShapeWeight(i, 0); } } }
public void Awake() { CurrentPose = SilencePose; lastEmotion = CurrentEmotion; currentLipsyncOnly = SilencePose; currentEmotionOnly = CurrentCompleteEmotionPose; }
private IEnumerator BlendEmotionsCoroutine(BSFacePose start, BSFacePose target) { TargetEmotionPose = target; for (float i = 0; i < EmotionBlendingTime; i += BlendingStep) { currentEmotionOnly = BSFacePose.Lerp(start, target, i / (EmotionBlendingTime)); CurrentPose = MixLipSyncAndEmotion(currentLipsyncOnly, currentEmotionOnly); DisplayPoseOnModel(CurrentPose); yield return(new WaitForSeconds(BlendingStep)); } }
public void SetEmotionPose(Emotion emotion, BSFacePose pose) { if (EmotionPoses.Where(lPose => lPose.AssociatedEmotion == emotion).Count() > 0) { EmotionPoses.Where(lPose => lPose.AssociatedEmotion == emotion).First().Pose = pose; } else { EmotionPoses.Add(new BSLabelledEmotionPose() { AssociatedEmotion = emotion, Pose = pose }); } }
private IEnumerator BlendLipSyncCoroutine(BSFacePose one, BSFacePose two) { BlendingLipSync = true; TargetLipSyncPose = two; for (float i = 0; i < BlendingTime; i += BlendingStep) { currentLipsyncOnly = BSFacePose.Lerp(one, two, i / BlendingTime); CurrentPose = MixLipSyncAndEmotion(currentLipsyncOnly, currentEmotionOnly); DisplayPoseOnModel(CurrentPose); yield return(new WaitForSeconds(BlendingStep)); } TargetLipSyncPose = null; currentLipsyncOnly = two; CurrentPose = MixLipSyncAndEmotion(two, CurrentCompleteEmotionPose); DisplayPoseOnModel(CurrentPose); BlendingLipSync = false; }
public static BSFacePose LerpEmotion(BSFacePose lipSync, BSFacePose emotion, float t) { if (lipSync == null && emotion != null) { return(emotion); } else if (emotion == null && lipSync != null) { return(lipSync); } else if (emotion == null && lipSync == null) { throw new Exception("Can't lerp the poses: they are both null."); } BSFacePose result = new BSFacePose() { Blendshapes = new List <BSBlendshape>() }; Dictionary <int, float> lipsyncPoses = new Dictionary <int, float>(); foreach (BSBlendshape lsBlendshape in lipSync.Blendshapes) { lipsyncPoses.Add(lsBlendshape.Index, lsBlendshape.Value); } foreach (BSBlendshape emBlendshape in emotion.Blendshapes) { if (lipsyncPoses.ContainsKey(emBlendshape.Index)) { //lipsyncPoses[emBlendshape.Index] = Mathf.Lerp(lipsyncPoses[emBlendshape.Index], emBlendshape.Value, t); result.Blendshapes.Add(new BSBlendshape() { Index = emBlendshape.Index, Value = Mathf.Lerp(lipsyncPoses[emBlendshape.Index], emBlendshape.Value, t) }); lipsyncPoses.Remove(emBlendshape.Index); } else { result.Blendshapes.Add(new BSBlendshape() { Index = emBlendshape.Index, Value = emBlendshape.Value }); } } // For each lipsync blendshape that has not been blended with an emotion, just add it foreach (KeyValuePair <int, float> kvp in lipsyncPoses) { result.Blendshapes.Add(new BSBlendshape() { Index = kvp.Key, Value = kvp.Value }); } lipsyncPoses.Clear(); return(result); }
public static BSFacePose Lerp(BSFacePose one, BSFacePose two, float t) { if (one == null && two != null) { return(two); } else if (two == null && one != null) { return(one); } else if (two == null && one == null) { throw new Exception("Can't lerp the poses: they are both null."); } BSFacePose result = new BSFacePose() { Blendshapes = new List <BSBlendshape>() }; // Map the poses Dictionary <int, ValuePair> map = new Dictionary <int, ValuePair>(); foreach (BSBlendshape bsOne in one.Blendshapes) { map.Add(bsOne.Index, new ValuePair() { PoseOne = bsOne.Value, PoseTwo = 0 }); } foreach (BSBlendshape bsTwo in two.Blendshapes) { if (map.ContainsKey(bsTwo.Index)) { map[bsTwo.Index].PoseTwo = bsTwo.Value; } else { map.Add(bsTwo.Index, new ValuePair() { PoseOne = 0, PoseTwo = bsTwo.Value }); } } foreach (var entry in map.ToList()) { int index = entry.Key; float valueOne = entry.Value.PoseOne; float valueTwo = entry.Value.PoseTwo; float finalValue = Mathf.Lerp(valueOne, valueTwo, t); result.Blendshapes.Add(new BSBlendshape() { Index = index, Value = finalValue }); } //Debug.Log(sb.ToString()); return(result); }
private BSFacePose MixLipSyncAndEmotion(BSFacePose lipSync, BSFacePose emotion) { return(BSFacePose.LerpEmotion(lipSync, emotion, EmotionIntensity)); }