예제 #1
0
        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);
                }
            }
        }
예제 #2
0
 public void Awake()
 {
     CurrentPose        = SilencePose;
     lastEmotion        = CurrentEmotion;
     currentLipsyncOnly = SilencePose;
     currentEmotionOnly = CurrentCompleteEmotionPose;
 }
예제 #3
0
 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));
     }
 }
예제 #4
0
 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
         });
     }
 }
예제 #5
0
        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;
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
 private BSFacePose MixLipSyncAndEmotion(BSFacePose lipSync, BSFacePose emotion)
 {
     return(BSFacePose.LerpEmotion(lipSync, emotion, EmotionIntensity));
 }