/*
     * Start
     */
    void Start()
    {
        // Set starting to either given startEmotion or default to the first in the list
        bool givenStartEmotionExists = false;

        for (int i = 0; i < goToEmotionList.Count; i++)
        {
            if (goToEmotionList[i].name.Equals(startEmotion))
            {
                givenStartEmotionExists = true;
            }
        }

        if (!givenStartEmotionExists)
        {
            Debug.LogError("Given starting emotion does not exist.");
            //currentlyPlaying = emotionObjects[goToEmotionList[0].indexInEmotionObjects].name;  // If not given, assume some default value
            IFAClip startingClip = new IFAClip(playablesDict, mixerEmotionPlayable, emotionObjects[goToEmotionList[0].indexInEmotionObjects].name + "0", true);
            startingClip.setWeight(1.0f);
            currentlyPlayingClips.Add(startingClip);
        }
        else
        {
            //currentlyPlaying = startEmotion;
            IFAClip startingClip = new IFAClip(playablesDict, mixerEmotionPlayable, startEmotion + "0", true);
            startingClip.setWeight(1.0f);
            currentlyPlayingClips.Add(startingClip);
        }

        // Plays the Playables Graph, i.e. starts playing animations
        playableGraph.Play();
    }
 public IFABlenderTransition(List <IFAClip> oldMain, IFAClip transition, IFAClip newMain, string interpolationMode, DrawGraphOnImage drawGraphOnImage,
                             float blendDuration, float bezierP1, float bezierP2)
     : this(oldMain, transition, newMain, interpolationMode, drawGraphOnImage)
 {
     this.blendDuration = blendDuration;
     this.pBezierP1     = bezierP1;
     this.pBezierP2     = bezierP2;
 }
 // Constructor
 public IFABlenderMain(List <IFAClip> oldMain, IFAClip newMain, string interpolationMode, DrawGraphOnImage drawGraphOnImage)
 {
     this.oldMainClips      = oldMain;
     this.newMainClip       = newMain;
     this.interpolationMode = interpolationMode;
     this.drawGraphOnImage  = drawGraphOnImage;
     createAllClips();
     createOldMainClipsInitialWeights();
 }
 // addActiveClips Extension
 private bool isClipAlreadyinClips(IFAClip clip, List <IFAClip> clipList)
 {
     foreach (IFAClip clipInList in clipList)
     {
         if (clipInList.playablesEmotionKey.Equals(clip.playablesEmotionKey))
         {
             return(true);
         }
     }
     return(false);
 }
    /*
     * Update
     */
    void LateUpdate()
    {
        if (HACKFixStuckBlendshapes)
        {
            animator.runtimeAnimatorController = null;          // Necessary to fix a bug where blendshapes "get stuck" on SetInputWeight changes. Reassigned at the end of Update.
        }

        // Check if new Transitions were requested and add them to the queue
        checkForNewTransitions();

        // If there is a blending request, prepare next blending
        if (goToEmotionNext.Count > 0)
        {
            // Get the next
            NextEmotion nextEmotion = goToEmotionNext.Dequeue();
            transitionEmotion = emotionObjects[nextEmotion.indexInEmotionObjects].name;
            fBlending         = true;

            // Randomly select one of the clips sets of the emotion
            for (int j = 0; j < emotionObjects.Count; j++)
            {
                if (emotionObjects[j].name.Equals(transitionEmotion))
                {
                    emotionNumber      = Random.Range(0, emotionObjects[j].animationGroupList.Count);
                    emotionNumberCount = emotionObjects[j].animationGroupList.Count;                // Later used in the switchBetweenTracks part
                }
            }
            // Or if a specific clip is requested, select that
            if (nextEmotion.emotionNumber != -1)
            {
                emotionNumber = nextEmotion.emotionNumber;
            }

            // Get the clips that were last active in the last blending process, in case this blending interrupts the previous one
            if (blender != null)
            {
                blender.addActiveClips(currentlyPlayingClips);
            }

            // Flag wether there is a transitionIn animation or not
            // Instantiate containers appropriately
            if (playablesDict.ContainsKey(transitionEmotion + "TransitionIn" + emotionNumber) && nextEmotion.withTransitionInIfPossible)
            {
                IFAClip transitionClip  = new IFAClip(playablesDict, mixerEmotionPlayable, transitionEmotion + "TransitionIn" + emotionNumber, false);
                IFAClip nextEmotionClip = new IFAClip(playablesDict, mixerEmotionPlayable, transitionEmotion + emotionNumber, true);
                blender = new IFABlenderTransition(currentlyPlayingClips, transitionClip, nextEmotionClip, interpolationMode.ToString(), drawGraphOnImage);
            }
            else
            {
                IFAClip nextEmotionClip = new IFAClip(playablesDict, mixerEmotionPlayable, transitionEmotion + emotionNumber, true);
                blender = new IFABlenderMain(currentlyPlayingClips, nextEmotionClip, interpolationMode.ToString(), drawGraphOnImage);
            }

            // Draw for display purposes
            if (GOWithDrawGraphOnImage)
            {
                drawGraphOnImage.clear();
            }
        }

        // Main Part
        if (!fBlending)
        {
            // Call all functions that need to be called each frame
            foreach (IFAClip clip in currentlyPlayingClips)
            {
                clip.update();
            }

            if (switchBetweenTracks)
            {
                // Randomly queue a transition to another clip within the same emotion, making sure it is no the same clip
                if (Random.Range(0, switchingProbabilityMax) < switchingProbability &&
                    emotionNumberCount > 1 &&
                    goToEmotionNext.Count == 0)
                {
                    // Get a random number that is not the old number
                    int newEmotionNumber = Random.Range(0, emotionNumberCount - 1);
                    if (newEmotionNumber >= emotionNumber)
                    {
                        newEmotionNumber++;
                    }
                    // Queue the transition for the next frame
                    playEmotion(transitionEmotion, newEmotionNumber, false);
                }
            }
        }
        // Blending Part
        if (fBlending)
        {
            // Call all functions that need to be called each frame
            blender.update();

            // If Blending has finished, clean up
            if (blender.isBlendingDone())
            {
                Debug.Log("Blending is done");
                fBlending = false;

                // Update currentlyPlayingClips
                blender.addActiveClips(currentlyPlayingClips);

                // Remove dead clips from currentlyPlayingClips
                List <int> tempToRemove = new List <int>();
                for (int i = currentlyPlayingClips.Count - 1; i >= 0; i--)
                {
                    if (currentlyPlayingClips[i].getWeight() <= 0)
                    {
                        tempToRemove.Add(i);
                    }
                }
                foreach (int index in tempToRemove)
                {
                    Debug.Log("Removed: " + currentlyPlayingClips[index].GetType());
                    currentlyPlayingClips.RemoveAt(index);
                }
            }
        }

        // If weights were changed, normalize them
        //if (normalize) normalizeWeights();
        normalizeWeights();

        if (HACKFixStuckBlendshapes)
        {
            animator.runtimeAnimatorController = runtimeAnimController;
        }

        //Debug.Log("Happy Wieght: " + mixerEmotionPlayable.GetInputWeight(0));
        //Debug.Log("Angry Wieght: " + mixerEmotionPlayable.GetInputWeight(2));
        //Debug.Log("TPose Wieght: " + mixerEmotionPlayable.GetInputWeight(4));
    }