public override RibbonParameters GetHoldRibbonParameters(RuntimeNote startNote, RuntimeNote endNote, float now, NoteMetrics noteMetrics, NoteAnimationMetrics animationMetrics) { var tp1 = NoteAnimationHelper.CalculateNoteTimePoints(startNote, animationMetrics); var tp2 = NoteAnimationHelper.CalculateNoteTimePoints(endNote, animationMetrics); var t1 = GetTransformedTime(startNote, now, tp1); var t2 = GetTransformedTime(endNote, now, tp2); var tperc = startNote.IsHold() ? 0.5 : 0.4; var tm = MathHelperEx.Lerp(t1, t2, tperc); var x1 = GetNoteX(startNote, now, noteMetrics, animationMetrics); var x2 = GetNoteX(endNote, now, noteMetrics, animationMetrics); var startStatus = NoteAnimationHelper.GetOnStageStatusOf(startNote, now, tp1); float y1; if (startStatus == OnStageStatus.Passed) { y1 = animationMetrics.Bottom; } else { y1 = GetNoteOnStageY(t1, animationMetrics); } var endStatus = NoteAnimationHelper.GetOnStageStatusOf(endNote, now, tp2); float y2; if (endStatus == OnStageStatus.Incoming) { y2 = animationMetrics.Top; } else { y2 = GetNoteOnStageY(t2, animationMetrics); } // CGSS-like //var xm = GetNoteOnStageX(endNote.StartX, endNote.EndX, tm, animationMetrics); // Naive guess //var xm = (x1 + x2) / 2; var xm = MathHelperEx.Lerp(x1, x2, 0.5f); if (startNote.IsSlide()) { if (endNote.EndX < startNote.EndX) { xm -= animationMetrics.Width * 0.02f * ((tp2.Leave - now) / (tp2.Leave - tp1.Enter)); } else if (endNote.EndX > startNote.EndX) { xm += animationMetrics.Width * 0.02f * ((tp2.Leave - now) / (tp2.Leave - tp1.Enter)); } } var ym = GetNoteOnStageY(tm, animationMetrics); var(cx1, cx2) = GetBezierFromQuadratic(x1, xm, x2); var(cy1, cy2) = GetBezierFromQuadratic(y1, ym, y2); return(new RibbonParameters(x1, y1, cx1, cy1, cx2, cy2, x2, y2)); }
public override RibbonParameters GetSlideRibbonParameters(RuntimeNote startNote, RuntimeNote endNote, float now, NoteMetrics noteMetrics, NoteAnimationMetrics animationMetrics) { var tp1 = NoteAnimationHelper.CalculateNoteTimePoints(startNote, animationMetrics); var thisStatus = NoteAnimationHelper.GetOnStageStatusOf(startNote, now, tp1); if (thisStatus < OnStageStatus.Passed) { return(GetHoldRibbonParameters(startNote, endNote, now, noteMetrics, animationMetrics)); } var tp2 = NoteAnimationHelper.CalculateNoteTimePoints(endNote, animationMetrics); var t1 = GetTransformedTime(startNote, now, tp1); var t2 = GetTransformedTime(endNote, now, tp2); var tperc = startNote.IsHold() ? 0.5 : 0.4; var tm = MathHelperEx.Lerp(t1, t2, tperc); var trackCount = animationMetrics.TrackCount; var leftMarginRatio = animationMetrics.NoteEndXRatios[0]; var rightMarginRatio = animationMetrics.NoteEndXRatios[trackCount - 1]; var startXRatio = leftMarginRatio + (rightMarginRatio - leftMarginRatio) * (startNote.EndX / (trackCount - 1)); var endXRatio = leftMarginRatio + (rightMarginRatio - leftMarginRatio) * (endNote.EndX / (trackCount - 1)); var perc = (now - startNote.HitTime) / (endNote.HitTime - startNote.HitTime); var x1Ratio = MathHelperEx.Lerp(startXRatio, endXRatio, perc); var x1 = animationMetrics.Width * x1Ratio; var y1 = animationMetrics.Bottom; var x2 = GetNoteX(endNote, now, noteMetrics, animationMetrics); var y2 = GetNoteOnStageY(t2, animationMetrics); // CGSS-like //var xm = GetNoteOnStageX(endNote.StartX, endNote.EndX, tm, animationMetrics); // Naive guess //var xm = (x1 + x2) / 2; var xm = MathHelperEx.Lerp(x1, x2, 0.5f); if (startNote.IsSlide()) { if (endNote.EndX < startNote.EndX) { xm -= animationMetrics.Width * 0.02f * ((tp2.Leave - now) / (tp2.Leave - tp1.Enter)); } else if (endNote.EndX > startNote.EndX) { xm += animationMetrics.Width * 0.02f * ((tp2.Leave - now) / (tp2.Leave - tp1.Enter)); } } var ym = GetNoteOnStageY(tm, animationMetrics); var(cx1, cx2) = GetBezierFromQuadratic(x1, xm, x2); var(cy1, cy2) = GetBezierFromQuadratic(y1, ym, y2); return(new RibbonParameters(x1, y1, cx1, cy1, cx2, cy2, x2, y2)); }