public float Evaluate(
            AnimationCurve curve, float time,
            float fadeInTime, float fadeOutTime,
            float parameterFadeInTime, float parameterFadeOutTime,
            float motionWeight, float currentValue)
        {
            if (curve.length <= 0)
            {
                return(currentValue);
            }



            // Motion fade.
            if (parameterFadeInTime < 0.0f &&
                parameterFadeOutTime < 0.0f)
            {
                return(currentValue + (curve.Evaluate(time) - currentValue) * motionWeight);
            }



            // Parameter fade.
            float fadeInWeight, fadeOutWeight;

            if (parameterFadeInTime < 0.0f)
            {
                fadeInWeight = fadeInTime;
            }
            else
            {
                fadeInWeight = (parameterFadeInTime < float.Epsilon)
                    ? 1.0f
                    : CubismFadeMath.GetEasingSine(time / parameterFadeInTime);
            }

            if (parameterFadeOutTime < 0.0f)
            {
                fadeOutWeight = fadeOutTime;
            }
            else
            {
                fadeOutWeight = (parameterFadeOutTime < float.Epsilon)
                    ? 1.0f
                    : CubismFadeMath.GetEasingSine((curve[curve.length - 1].time - Time.time) / parameterFadeOutTime);
            }

            var parameterWeight = fadeInWeight * fadeOutWeight;


            return(currentValue + (curve.Evaluate(time) - currentValue) * parameterWeight);
        }
        /// <summary>
        /// Update motion fade.
        /// </summary>
        /// <param name="stateObserver">Fade state observer.</param>
        private void UpdateFade(ICubismFadeState fadeState)
        {
            var playingMotions = fadeState.GetPlayingMotions();

            if (playingMotions == null || playingMotions.Count <= 1)
            {
                // Do not process if there is only one motion, if it does not switch.
                return;
            }

            // Weight set for the layer being processed.
            // (In the case of the layer located at the top, it is forced to 1.)
            var layerWeight = fadeState.GetLayerWeight();

            var time = Time.time;

            // Calculate MotionFade.
            for (var i = 0; i < playingMotions.Count; i++)
            {
                var playingMotion = playingMotions[i];

                var fadeMotion = playingMotion.Motion;
                if (fadeMotion == null)
                {
                    continue;
                }

                var erapsedTime = time - playingMotion.StartTime;


                var fadeInTime  = fadeMotion.FadeInTime;
                var fadeOutTime = fadeMotion.FadeOutTime;


                var fadeInWeight = (fadeInTime <= 0.0f)
                    ? 1.0f
                    : CubismFadeMath.GetEasingSine(erapsedTime / fadeInTime);
                var fadeOutWeight = (fadeOutTime <= 0.0f)
                    ? 1.0f
                    : CubismFadeMath.GetEasingSine((playingMotion.EndTime - Time.time) / fadeOutTime);
                var motionWeight = (i == 0)
                    ? (fadeInWeight * fadeOutWeight)
                    : (fadeInWeight * fadeOutWeight * layerWeight);

                // Apply to parameter values
                for (var j = 0; j < DestinationParameters.Length; ++j)
                {
                    var index = -1;
                    for (var k = 0; k < fadeMotion.ParameterIds.Length; ++k)
                    {
                        if (fadeMotion.ParameterIds[k] != DestinationParameters[j].Id)
                        {
                            continue;
                        }

                        index = k;
                        break;
                    }

                    if (index < 0)
                    {
                        // There is not target ID curve in motion.
                        continue;
                    }

                    DestinationParameters[j].Value = Evaluate(
                        fadeMotion.ParameterCurves[index], erapsedTime,
                        fadeInWeight, fadeOutWeight,
                        fadeMotion.ParameterFadeInTimes[index], fadeMotion.ParameterFadeOutTimes[index],
                        motionWeight, DestinationParameters[j].Value);
                }

                // Apply to part opacities
                for (var j = 0; j < DestinationParts.Length; ++j)
                {
                    var index = -1;
                    for (var k = 0; k < fadeMotion.ParameterIds.Length; ++k)
                    {
                        if (fadeMotion.ParameterIds[k] != DestinationParts[j].Id)
                        {
                            continue;
                        }

                        index = k;
                        break;
                    }

                    if (index < 0)
                    {
                        // There is not target ID curve in motion.
                        continue;
                    }

                    DestinationParts[j].Opacity = Evaluate(
                        fadeMotion.ParameterCurves[index], erapsedTime,
                        fadeInWeight, fadeOutWeight,
                        fadeMotion.ParameterFadeInTimes[index], fadeMotion.ParameterFadeOutTimes[index],
                        motionWeight, DestinationParts[j].Opacity);
                }
            }

            if (!fadeState.GetStateTransitionFinished())
            {
                return;
            }

            fadeState.SetStateTransitionFinished(false);

            var playingMotionCount = playingMotions.Count - 1;

            for (var i = playingMotionCount; i >= 0; --i)
            {
                var playingMotion = playingMotions[i];

                if (Time.time <= playingMotion.EndTime)
                {
                    continue;
                }

                // If fade-in has been completed, delete the motion that has been played back.
                fadeState.StopAnimation(i);
            }
        }
Exemple #3
0
        /// <summary>
        /// Update motion fade.
        /// </summary>
        /// <param name="fadeState">Fade state observer.</param>
        private void UpdateFade(ICubismFadeState fadeState)
        {
            var playingMotions = fadeState.GetPlayingMotions();

            if (playingMotions == null)
            {
                // Do not process if there is only one motion, if it does not switch.
                return;
            }

            // Weight set for the layer being processed.
            // (In the case of the layer located at the top, it is forced to 1.)
            var layerWeight = fadeState.GetLayerWeight();

            var time = Time.time;

            // Set playing motions end time.
            if ((playingMotions.Count > 0) && (playingMotions[playingMotions.Count - 1].Motion != null) && (playingMotions[playingMotions.Count - 1].IsLooping))
            {
                var motion = playingMotions[playingMotions.Count - 1];

                var newEndTime = time + motion.Motion.FadeOutTime;

                motion.EndTime = newEndTime;


                while (true)
                {
                    if ((motion.StartTime + motion.Motion.MotionLength) >= time)
                    {
                        break;
                    }

                    motion.StartTime += motion.Motion.MotionLength;
                }


                playingMotions[playingMotions.Count - 1] = motion;
            }


            // Calculate MotionFade.
            for (var i = 0; i < playingMotions.Count; i++)
            {
                var playingMotion = playingMotions[i];

                var fadeMotion = playingMotion.Motion;
                if (fadeMotion == null)
                {
                    continue;
                }

                var elapsedTime = time - playingMotion.StartTime;
                var endTime     = playingMotion.EndTime - elapsedTime;

                var fadeInTime  = fadeMotion.FadeInTime;
                var fadeOutTime = fadeMotion.FadeOutTime;


                var fadeInWeight = (fadeInTime <= 0.0f)
                    ? 1.0f
                    : CubismFadeMath.GetEasingSine(elapsedTime / fadeInTime);
                var fadeOutWeight = (fadeOutTime <= 0.0f)
                    ? 1.0f
                    : CubismFadeMath.GetEasingSine((playingMotion.EndTime - Time.time) / fadeOutTime);


                playingMotions[i] = playingMotion;

                var motionWeight = (i == 0)
                    ? (fadeInWeight * fadeOutWeight)
                    : (fadeInWeight * fadeOutWeight * layerWeight);

                // Apply to parameter values
                for (var j = 0; j < DestinationParameters.Length; ++j)
                {
                    var index = -1;
                    for (var k = 0; k < fadeMotion.ParameterIds.Length; ++k)
                    {
                        if (fadeMotion.ParameterIds[k] != DestinationParameters[j].Id)
                        {
                            continue;
                        }

                        index = k;
                        break;
                    }

                    if (index < 0)
                    {
                        // There is not target ID curve in motion.
                        continue;
                    }

                    DestinationParameters[j].Value = Evaluate(
                        fadeMotion.ParameterCurves[index], elapsedTime, endTime,
                        fadeInWeight, fadeOutWeight,
                        fadeMotion.ParameterFadeInTimes[index], fadeMotion.ParameterFadeOutTimes[index],
                        motionWeight, DestinationParameters[j].Value);
                }

                // Apply to part opacities
                for (var j = 0; j < DestinationParts.Length; ++j)
                {
                    var index = -1;
                    for (var k = 0; k < fadeMotion.ParameterIds.Length; ++k)
                    {
                        if (fadeMotion.ParameterIds[k] != DestinationParts[j].Id)
                        {
                            continue;
                        }

                        index = k;
                        break;
                    }

                    if (index < 0)
                    {
                        // There is not target ID curve in motion.
                        continue;
                    }

                    DestinationParts[j].Opacity = Evaluate(
                        fadeMotion.ParameterCurves[index], elapsedTime, endTime,
                        fadeInWeight, fadeOutWeight,
                        fadeMotion.ParameterFadeInTimes[index], fadeMotion.ParameterFadeOutTimes[index],
                        motionWeight, DestinationParts[j].Opacity);
                }
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="stateObserver"></param>
        private void UpdateFade(CubismFadeStateObserver stateObserver)
        {
            var playingMotions = stateObserver.PlayingMotions;

            if (playingMotions.Count <= 1)
            {
                // 再生中のモーションが一つ=切り替わらない場合は処理しない
                return;
            }


            // 処理中のレイヤーに設定されているWeight(最上段に配置されたレイヤーの場合は1に強制される)
            var layerWeight = stateObserver.LayerWeight;


            var time = Time.time;

            var isDoneAllFadeIn = true;

            // Calcurate MotionFade.
            for (var i = 0; i < playingMotions.Count; i++)
            {
                var playingMotion = playingMotions[i];

                var fadeMotion = playingMotion.Motion;
                if (fadeMotion == null)
                {
                    continue;
                }

                var erapsedTime = time - playingMotion.FadeInStartTime;


                var fadeInTime  = fadeMotion.FadeInTime;
                var fadeOutTime = fadeMotion.FadeOutTime;


                var fadeInWeight = (fadeInTime <= 0.0f)
                    ? 1.0f
                    : CubismFadeMath.GetEasingSine(erapsedTime / fadeInTime);
                var fadeOutWeight = (fadeOutTime <= 0.0f)
                    ? 1.0f
                    : CubismFadeMath.GetEasingSine((playingMotion.EndTime - Time.time) / fadeOutTime);
                var motionWeight = (i == 0)
                    ? fadeOutWeight * layerWeight
                    : (fadeInWeight * fadeOutWeight * layerWeight);

                // Apply to parameter values
                for (var j = 0; j < DestinationParameters.Length; ++j)
                {
                    var index = -1;
                    for (var k = 0; k < fadeMotion.ParameterIds.Length; ++k)
                    {
                        if (fadeMotion.ParameterIds[k] != DestinationParameters[j].Id)
                        {
                            continue;
                        }

                        index = k;
                        break;
                    }

                    if (index < 0)
                    {
                        // モーションにそのIDのカーブが存在しない
                        continue;
                    }

                    DestinationParameters[j].Value = Evaluate(
                        fadeMotion.ParameterCurves[index], erapsedTime,
                        fadeInWeight, fadeOutWeight,
                        fadeMotion.ParameterFadeInTimes[index], fadeMotion.ParameterFadeOutTimes[index],
                        motionWeight, DestinationParameters[j].Value);
                }

                // Apply to part opacities
                for (var j = 0; j < DestinationParts.Length; ++j)
                {
                    var index = -1;
                    for (var k = 0; k < fadeMotion.ParameterIds.Length; ++k)
                    {
                        if (fadeMotion.ParameterIds[k] != DestinationParts[j].Id)
                        {
                            continue;
                        }

                        index = k;
                        break;
                    }

                    if (index < 0)
                    {
                        // モーションにそのIDのカーブが存在しない
                        continue;
                    }

                    DestinationParts[j].Opacity = Evaluate(
                        fadeMotion.ParameterCurves[index], erapsedTime,
                        fadeInWeight, fadeOutWeight,
                        fadeMotion.ParameterFadeInTimes[index], fadeMotion.ParameterFadeOutTimes[index],
                        motionWeight, DestinationParts[j].Opacity);
                }


                if (erapsedTime > fadeInTime)
                {
                    continue;
                }
                isDoneAllFadeIn = false;
            }


            if ((!isDoneAllFadeIn) || (!stateObserver.IsStateTransitionFinished))
            {
                // 一つでもフェードインが終了していないモーションがあれば処理しない
                return;
            }


            stateObserver.IsStateTransitionFinished = false;

            var playingMotionCount = playingMotions.Count - 1;

            for (var i = playingMotionCount; i >= 0; --i)
            {
                var playingMotion = playingMotions[i];


                var fadeMotion = playingMotion.Motion;
                if (fadeMotion == null)
                {
                    continue;
                }


                var elapsedTime = time - playingMotion.StartTime;

                if (elapsedTime <= fadeMotion.MotionLength)
                {
                    continue;
                }

                // 全てのモーションのフェードインが終了している場合、再生が終了しているモーションは削除する
                stateObserver.PlayingMotions.RemoveAt(i);
            }
        }