From 66176f2882895dd9ecb93e42f28388da5995065d Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Mon, 22 Jan 2018 12:36:38 +0100 Subject: [PATCH 1/5] fix RepeatPoint animations - FadeIn and -Out for RepeatPoints are now calculated instead of fixed values - TimePreempt is now cut down if too long for RepeatPoints following the first one to only show up to two RepeatPoints at any given time --- .../Objects/Drawables/DrawableRepeatPoint.cs | 16 ++++++++-------- .../Objects/Drawables/DrawableSlider.cs | 14 ++++---------- osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs | 14 ++++++++++++++ osu.Game.Rulesets.Osu/Objects/Slider.cs | 17 +++++++++-------- osu.Game.Rulesets.Osu/Tests/TestCaseSlider.cs | 1 + 5 files changed, 36 insertions(+), 26 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs index 28ff4b4cdf..520b4eccfa 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly DrawableSlider drawableSlider; public double FadeInTime; - public double FadeOutTime; + private double animDuration; public DrawableRepeatPoint(RepeatPoint repeatPoint, DrawableSlider drawableSlider) : base(repeatPoint) @@ -48,11 +48,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void UpdatePreemptState() { - var animIn = Math.Min(150, repeatPoint.StartTime - FadeInTime); + animDuration = Math.Min(150, repeatPoint.StartTime - FadeInTime); - this.FadeIn(animIn).ScaleTo(1.2f, animIn) + this.FadeIn(animDuration).ScaleTo(1.2f, animDuration / 2) .Then() - .ScaleTo(1, 150, Easing.Out); + .ScaleTo(1, animDuration / 2, Easing.Out); } protected override void UpdateCurrentState(ArmedState state) @@ -60,14 +60,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables switch (state) { case ArmedState.Idle: - this.Delay(FadeOutTime - repeatPoint.StartTime).FadeOut(); + this.Delay(HitObject.TimePreempt).FadeOut(); break; case ArmedState.Miss: - this.FadeOut(160); + this.FadeOut(animDuration); break; case ArmedState.Hit: - this.FadeOut(120, Easing.OutQuint) - .ScaleTo(Scale * 1.5f, 120, Easing.OutQuint); + this.FadeOut(animDuration, Easing.OutQuint) + .ScaleTo(Scale * 1.5f, animDuration, Easing.OutQuint); break; } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index 232964587c..99c664a575 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -72,12 +72,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables AddNested(InitialCircle); - var repeatDuration = s.Curve.Distance / s.Velocity; foreach (var tick in s.NestedHitObjects.OfType()) { - var repeatStartTime = s.StartTime + tick.RepeatIndex * repeatDuration; + var repeatStartTime = s.StartTime + tick.RepeatIndex * s.RepeatDuration; var fadeInTime = repeatStartTime + (tick.StartTime - repeatStartTime) / 2 - (tick.RepeatIndex == 0 ? HitObject.TimeFadein : HitObject.TimeFadein / 2); - var fadeOutTime = repeatStartTime + repeatDuration; + var fadeOutTime = repeatStartTime + s.RepeatDuration; var drawableTick = new DrawableSliderTick(tick) { @@ -92,15 +91,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables foreach (var repeatPoint in s.NestedHitObjects.OfType()) { - var repeatStartTime = s.StartTime + repeatPoint.RepeatIndex * repeatDuration; - var fadeInTime = repeatStartTime + (repeatPoint.StartTime - repeatStartTime) / 2 - (repeatPoint.RepeatIndex == 0 ? HitObject.TimeFadein : HitObject.TimeFadein / 2); - var fadeOutTime = repeatStartTime + repeatDuration; - var drawableRepeatPoint = new DrawableRepeatPoint(repeatPoint, this) { - FadeInTime = fadeInTime, - FadeOutTime = fadeOutTime, - Position = repeatPoint.Position, + FadeInTime = repeatPoint.StartTime - s.RepeatDuration / 2, + Position = repeatPoint.Position }; repeatPoints.Add(drawableRepeatPoint); diff --git a/osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs b/osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs index abdbb97072..42aff7ebaf 100644 --- a/osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs @@ -1,10 +1,24 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; + namespace osu.Game.Rulesets.Osu.Objects { public class RepeatPoint : OsuHitObject { public int RepeatIndex { get; set; } + public double RepeatDuration { get; set; } + + protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) + { + base.ApplyDefaultsToSelf(controlPointInfo, difficulty); + + // We want to show the first RepeatPoint as the TimePreempt dictates but on short (and possibly fast) sliders + // we may need to cut down this time on following RepeatPoints to only show up to two RepeatPoints at any given time. + if (RepeatIndex > 1 && TimePreempt > RepeatDuration * 2) + TimePreempt = (float)RepeatDuration * 2; + } } } diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 2da285a434..55de38a602 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -60,6 +60,11 @@ namespace osu.Game.Rulesets.Osu.Objects public List> RepeatSamples { get; set; } = new List>(); public int RepeatCount { get; set; } = 1; + /// + /// The length of one repeat if any repeats are present, otherwise it equals the . + /// + public double RepeatDuration => RepeatCount > 1 ? Distance / Velocity : Duration; + private int stackHeight; public override int StackHeight @@ -114,13 +119,12 @@ namespace osu.Game.Rulesets.Osu.Objects var length = Curve.Distance; var tickDistance = Math.Min(TickDistance, length); - var repeatDuration = length / Velocity; var minDistanceFromEnd = Velocity * 0.01; for (var repeat = 0; repeat < RepeatCount; repeat++) { - var repeatStartTime = StartTime + repeat * repeatDuration; + var repeatStartTime = StartTime + repeat * RepeatDuration; var reversed = repeat % 2 == 1; for (var d = tickDistance; d <= length; d += tickDistance) @@ -145,7 +149,7 @@ namespace osu.Game.Rulesets.Osu.Objects AddNested(new SliderTick { RepeatIndex = repeat, - StartTime = repeatStartTime + timeProgress * repeatDuration, + StartTime = repeatStartTime + timeProgress * RepeatDuration, Position = Curve.PositionAt(distanceProgress), StackHeight = StackHeight, Scale = Scale, @@ -158,16 +162,13 @@ namespace osu.Game.Rulesets.Osu.Objects private void createRepeatPoints() { - var repeatDuration = Distance / Velocity; - for (var repeat = 1; repeat < RepeatCount; repeat++) { - var repeatStartTime = StartTime + repeat * repeatDuration; - AddNested(new RepeatPoint { RepeatIndex = repeat, - StartTime = repeatStartTime, + RepeatDuration = RepeatDuration, + StartTime = StartTime + repeat * RepeatDuration, Position = Curve.PositionAt(repeat % 2), StackHeight = StackHeight, Scale = Scale, diff --git a/osu.Game.Rulesets.Osu/Tests/TestCaseSlider.cs b/osu.Game.Rulesets.Osu/Tests/TestCaseSlider.cs index c395c5edb8..2e47b2c72a 100644 --- a/osu.Game.Rulesets.Osu/Tests/TestCaseSlider.cs +++ b/osu.Game.Rulesets.Osu/Tests/TestCaseSlider.cs @@ -63,6 +63,7 @@ namespace osu.Game.Rulesets.Osu.Tests AddStep("Fast Short Slider", () => testShortHighSpeed()); AddStep("Fast Short Slider 1 Repeat", () => testShortHighSpeed(1)); AddStep("Fast Short Slider 2 Repeats", () => testShortHighSpeed(2)); + AddStep("Fast Short Slider 6 Repeats", () => testShortHighSpeed(6)); AddStep("Perfect Curve", testCurve); // TODO more curve types? From b726f90c3714ff85f0714eee7d0f1ba0d4cbf8d1 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Mon, 22 Jan 2018 12:44:55 +0100 Subject: [PATCH 2/5] remove unnecessary variable --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs | 3 +-- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs index 520b4eccfa..b62c1fa984 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs @@ -16,7 +16,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly RepeatPoint repeatPoint; private readonly DrawableSlider drawableSlider; - public double FadeInTime; private double animDuration; public DrawableRepeatPoint(RepeatPoint repeatPoint, DrawableSlider drawableSlider) @@ -48,7 +47,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void UpdatePreemptState() { - animDuration = Math.Min(150, repeatPoint.StartTime - FadeInTime); + animDuration = Math.Min(150, repeatPoint.RepeatDuration / 2); this.FadeIn(animDuration).ScaleTo(1.2f, animDuration / 2) .Then() diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index 99c664a575..044bce7eca 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -93,7 +93,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { var drawableRepeatPoint = new DrawableRepeatPoint(repeatPoint, this) { - FadeInTime = repeatPoint.StartTime - s.RepeatDuration / 2, Position = repeatPoint.Position }; From 2c0dd1815cdcb0c98d65b8310bfd4fffd9a0ec09 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Tue, 23 Jan 2018 09:09:19 +0100 Subject: [PATCH 3/5] Updated submodule osu-framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 26c01ca606..736a139a74 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 26c01ca6069296621f76d8ffbfe31ecf8074c687 +Subproject commit 736a139a748eba7cebea41a09b404d47ca589522 From 4baadfdd16beac1cd024cc7ac143792e472e823a Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Tue, 23 Jan 2018 16:44:33 +0100 Subject: [PATCH 4/5] fix oversight --- osu.Game.Rulesets.Osu/Objects/Slider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index faf0da8339..073ff476c1 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -63,7 +63,7 @@ namespace osu.Game.Rulesets.Osu.Objects /// /// The length of one repeat if any repeats are present, otherwise it equals the . /// - public double SpanDuration => RepeatCount > 1 ? Distance / Velocity : Duration; + public double SpanDuration => RepeatCount > 0 ? Distance / Velocity : Duration; private int stackHeight; From 52c4d22c410e31cfe0d1b592893736cea067248e Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Wed, 24 Jan 2018 09:44:50 +0100 Subject: [PATCH 5/5] review changes - use doubles instead of floats - simplify logic --- osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs | 4 ++-- osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 2 +- osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs | 4 ++-- osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs | 5 +++-- osu.Game.Rulesets.Osu/Objects/Slider.cs | 4 ++-- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs index d42338f20e..3dad5b508c 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs @@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps continue; double endTime = (stackBaseObject as IHasEndTime)?.EndTime ?? stackBaseObject.StartTime; - float stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f; + double stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f; if (objectN.StartTime - endTime > stackThreshold) //We are no longer within stacking range of the next object. @@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps OsuHitObject objectI = beatmap.HitObjects[i]; if (objectI.StackHeight != 0 || objectI is Spinner) continue; - float stackThreshold = objectI.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f; + double stackThreshold = objectI.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f; /* If this object is a hitcircle, then we enter this "special" case. * It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider. diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index 3a486e7763..b4dd08eadb 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override string Description => @"Play with no approach circles and fading notes for a slight score advantage."; public override double ScoreMultiplier => 1.06; - private const float fade_in_duration_multiplier = 0.4f; + private const double fade_in_duration_multiplier = 0.4; private const double fade_out_duration_multiplier = 0.3; public void ApplyToDrawableHitObjects(IEnumerable drawables) diff --git a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs index 0e7c2f3d4d..f217ae89e9 100644 --- a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs @@ -20,8 +20,8 @@ namespace osu.Game.Rulesets.Osu.Objects public double HitWindow100 = 80; public double HitWindow300 = 30; - public float TimePreempt = 600; - public float TimeFadein = 400; + public double TimePreempt = 600; + public double TimeFadein = 400; public Vector2 Position { get; set; } public float X => Position.X; diff --git a/osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs b/osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs index c55235611c..eaaa8d7a7e 100644 --- a/osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; @@ -17,8 +18,8 @@ namespace osu.Game.Rulesets.Osu.Objects // We want to show the first RepeatPoint as the TimePreempt dictates but on short (and possibly fast) sliders // we may need to cut down this time on following RepeatPoints to only show up to two RepeatPoints at any given time. - if (RepeatIndex > 0 && TimePreempt > SpanDuration * 2) - TimePreempt = (float)SpanDuration * 2; + if (RepeatIndex > 0) + TimePreempt = Math.Min(SpanDuration * 2, TimePreempt); } } } diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 073ff476c1..79bb14a475 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -61,9 +61,9 @@ namespace osu.Game.Rulesets.Osu.Objects public int RepeatCount { get; set; } /// - /// The length of one repeat if any repeats are present, otherwise it equals the . + /// The length of one span of this . /// - public double SpanDuration => RepeatCount > 0 ? Distance / Velocity : Duration; + public double SpanDuration => Duration / this.SpanCount(); private int stackHeight;