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); } }
/// <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); } }