From 406f39e8bfc281fc91c3e96ce12077423974006f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 18 May 2020 21:27:26 +0900 Subject: [PATCH] Construct online visible lines --- .../TestSceneManiaBeatSnapGrid.cs | 2 +- .../Edit/ManiaBeatSnapGrid.cs | 135 ++++++++++-------- .../Edit/ManiaHitObjectComposer.cs | 9 +- 3 files changed, 81 insertions(+), 65 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneManiaBeatSnapGrid.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneManiaBeatSnapGrid.cs index 84419313e6..941cf4e7c8 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneManiaBeatSnapGrid.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneManiaBeatSnapGrid.cs @@ -61,7 +61,7 @@ protected override bool OnMouseMove(MouseMoveEvent e) float relativePosition = Playfield.Stages[0].HitObjectContainer.ToLocalSpace(e.ScreenSpaceMousePosition).Y / Playfield.Stages[0].HitObjectContainer.DrawHeight; double timeValue = scrollingInfo.TimeRange.Value * relativePosition; - beatSnapGrid.SetRange(timeValue, timeValue); + beatSnapGrid.SelectionTimeRange = (timeValue, timeValue); return true; } diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaBeatSnapGrid.cs b/osu.Game.Rulesets.Mania/Edit/ManiaBeatSnapGrid.cs index e771a9753f..a16fb52f01 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaBeatSnapGrid.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaBeatSnapGrid.cs @@ -6,6 +6,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Caching; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; @@ -22,7 +23,7 @@ namespace osu.Game.Rulesets.Mania.Edit { public class ManiaBeatSnapGrid : Component { - private const double visible_range = 1500; + private const double visible_range = 750; [Resolved] private IManiaHitObjectComposer composer { get; set; } @@ -44,6 +45,34 @@ public class ManiaBeatSnapGrid : Component private readonly List grids = new List(); + private readonly Cached lineCache = new Cached(); + + private (double start, double end)? selectionTimeRange; + + public (double start, double end)? SelectionTimeRange + { + get => selectionTimeRange; + set + { + if (value == selectionTimeRange) + return; + + selectionTimeRange = value; + lineCache.Invalidate(); + } + } + + protected override void Update() + { + base.Update(); + + if (!lineCache.IsValid) + { + lineCache.Validate(); + createLines(); + } + } + [BackgroundDependencyLoader] private void load() { @@ -61,49 +90,65 @@ private void load() beatDivisor.BindValueChanged(_ => createLines(), true); } - public override void Hide() - { - base.Hide(); - foreach (var grid in grids) - grid.Hide(); - } - - public override void Show() - { - base.Show(); - foreach (var grid in grids) - grid.Show(); - } - private void createLines() { foreach (var grid in grids) grid.Clear(); - for (int i = 0; i < beatmap.ControlPointInfo.TimingPoints.Count; i++) + if (selectionTimeRange == null) + return; + + var range = selectionTimeRange.Value; + + var timingPoint = beatmap.ControlPointInfo.TimingPointAt(range.start - visible_range); + + double time = timingPoint.Time; + int beat = 0; + + // progress time until in the visible range. + while (time < range.start - visible_range) { - var point = beatmap.ControlPointInfo.TimingPoints[i]; - var until = i + 1 < beatmap.ControlPointInfo.TimingPoints.Count ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : working.Value.Track.Length; + time += timingPoint.BeatLength / beatDivisor.Value; + beat++; + } - int beat = 0; + while (time < range.end + visible_range) + { + var nextTimingPoint = beatmap.ControlPointInfo.TimingPointAt(time); - for (double t = point.Time; t < until; t += point.BeatLength / beatDivisor.Value) + // switch to the next timing point if we have reached it. + if (nextTimingPoint != timingPoint) { - var indexInBeat = beat % beatDivisor.Value; - Color4 colour; + beat = 0; + timingPoint = nextTimingPoint; + } - if (indexInBeat == 0) - colour = BindableBeatDivisor.GetColourFor(1, colours); + Color4 colour = BindableBeatDivisor.GetColourFor( + BindableBeatDivisor.GetDivisorForBeatIndex(Math.Max(1, beat), beatDivisor.Value), colours); + + foreach (var grid in grids) + grid.Add(new DrawableGridLine(time, colour)); + + beat++; + time += timingPoint.BeatLength / beatDivisor.Value; + } + + foreach (var grid in grids) + { + // required to update ScrollingHitObjectContainer's cache. + grid.UpdateSubTree(); + + foreach (var line in grid.Objects.OfType()) + { + time = line.HitObject.StartTime; + + if (time >= range.start && time <= range.end) + line.Alpha = 1; else { - var divisor = BindableBeatDivisor.GetDivisorForBeatIndex(beat, beatDivisor.Value); - colour = BindableBeatDivisor.GetColourFor(divisor, colours); + double timeSeparation = time < range.start ? range.start - time : time - range.end; + line.Alpha = (float)Math.Max(0, 1 - timeSeparation / visible_range); } - - foreach (var grid in grids) - grid.Add(new DrawableGridLine(t, colour)); - - beat++; } } } @@ -112,6 +157,7 @@ private void createLines() { float minDist = float.PositiveInfinity; DrawableGridLine minDistLine = null; + Vector2 minDistLinePosition = Vector2.Zero; foreach (var grid in grids) @@ -137,33 +183,6 @@ private void createLines() return (new Vector2(position.X, minDistLinePosition.Y + noteOffset), minDistLine.HitObject.StartTime); } - public void SetRange(double minTime, double maxTime) - { - if (LoadState >= LoadState.Ready) - setRange(minTime, maxTime); - else - Schedule(() => setRange(minTime, maxTime)); - } - - private void setRange(double minTime, double maxTime) - { - foreach (var grid in grids) - { - foreach (var line in grid.Objects.OfType()) - { - double lineTime = line.HitObject.StartTime; - - if (lineTime >= minTime && lineTime <= maxTime) - line.Colour = Color4.White; - else - { - double timeSeparation = lineTime < minTime ? minTime - lineTime : lineTime - maxTime; - line.Colour = OsuColour.Gray((float)Math.Max(0, 1 - timeSeparation / visible_range)); - } - } - } - } - private class DrawableGridLine : DrawableHitObject { [Resolved] diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs index 1266761d12..475320ece3 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs @@ -68,18 +68,15 @@ protected override void UpdateAfterChildren() { if (EditorBeatmap.SelectedHitObjects.Any()) { - beatSnapGrid.SetRange(EditorBeatmap.SelectedHitObjects.Min(h => h.StartTime), EditorBeatmap.SelectedHitObjects.Max(h => h.GetEndTime())); - beatSnapGrid.Show(); + beatSnapGrid.SelectionTimeRange = (EditorBeatmap.SelectedHitObjects.Min(h => h.StartTime), EditorBeatmap.SelectedHitObjects.Max(h => h.GetEndTime())); } else - beatSnapGrid.Hide(); + beatSnapGrid.SelectionTimeRange = null; } else { var placementTime = GetSnappedPosition(ToLocalSpace(inputManager.CurrentState.Mouse.Position), 0).time; - beatSnapGrid.SetRange(placementTime, placementTime); - - beatSnapGrid.Show(); + beatSnapGrid.SelectionTimeRange = (placementTime, placementTime); } }