1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-12 18:23:04 +08:00

Construct online visible lines

This commit is contained in:
Dean Herbert 2020-05-18 21:27:26 +09:00
parent b35b150f38
commit 406f39e8bf
3 changed files with 81 additions and 65 deletions

View File

@ -61,7 +61,7 @@ namespace osu.Game.Rulesets.Mania.Tests
float relativePosition = Playfield.Stages[0].HitObjectContainer.ToLocalSpace(e.ScreenSpaceMousePosition).Y / Playfield.Stages[0].HitObjectContainer.DrawHeight; float relativePosition = Playfield.Stages[0].HitObjectContainer.ToLocalSpace(e.ScreenSpaceMousePosition).Y / Playfield.Stages[0].HitObjectContainer.DrawHeight;
double timeValue = scrollingInfo.TimeRange.Value * relativePosition; double timeValue = scrollingInfo.TimeRange.Value * relativePosition;
beatSnapGrid.SetRange(timeValue, timeValue); beatSnapGrid.SelectionTimeRange = (timeValue, timeValue);
return true; return true;
} }

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Caching;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
@ -22,7 +23,7 @@ namespace osu.Game.Rulesets.Mania.Edit
{ {
public class ManiaBeatSnapGrid : Component public class ManiaBeatSnapGrid : Component
{ {
private const double visible_range = 1500; private const double visible_range = 750;
[Resolved] [Resolved]
private IManiaHitObjectComposer composer { get; set; } private IManiaHitObjectComposer composer { get; set; }
@ -44,6 +45,34 @@ namespace osu.Game.Rulesets.Mania.Edit
private readonly List<ScrollingHitObjectContainer> grids = new List<ScrollingHitObjectContainer>(); private readonly List<ScrollingHitObjectContainer> grids = new List<ScrollingHitObjectContainer>();
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] [BackgroundDependencyLoader]
private void load() private void load()
{ {
@ -61,49 +90,65 @@ namespace osu.Game.Rulesets.Mania.Edit
beatDivisor.BindValueChanged(_ => createLines(), true); 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() private void createLines()
{ {
foreach (var grid in grids) foreach (var grid in grids)
grid.Clear(); 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]; time += timingPoint.BeatLength / beatDivisor.Value;
var until = i + 1 < beatmap.ControlPointInfo.TimingPoints.Count ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : working.Value.Track.Length; 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; beat = 0;
Color4 colour; timingPoint = nextTimingPoint;
}
if (indexInBeat == 0) Color4 colour = BindableBeatDivisor.GetColourFor(
colour = BindableBeatDivisor.GetColourFor(1, colours); 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<DrawableGridLine>())
{
time = line.HitObject.StartTime;
if (time >= range.start && time <= range.end)
line.Alpha = 1;
else else
{ {
var divisor = BindableBeatDivisor.GetDivisorForBeatIndex(beat, beatDivisor.Value); double timeSeparation = time < range.start ? range.start - time : time - range.end;
colour = BindableBeatDivisor.GetColourFor(divisor, colours); 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 @@ namespace osu.Game.Rulesets.Mania.Edit
{ {
float minDist = float.PositiveInfinity; float minDist = float.PositiveInfinity;
DrawableGridLine minDistLine = null; DrawableGridLine minDistLine = null;
Vector2 minDistLinePosition = Vector2.Zero; Vector2 minDistLinePosition = Vector2.Zero;
foreach (var grid in grids) foreach (var grid in grids)
@ -137,33 +183,6 @@ namespace osu.Game.Rulesets.Mania.Edit
return (new Vector2(position.X, minDistLinePosition.Y + noteOffset), minDistLine.HitObject.StartTime); 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<DrawableGridLine>())
{
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 private class DrawableGridLine : DrawableHitObject
{ {
[Resolved] [Resolved]

View File

@ -68,18 +68,15 @@ namespace osu.Game.Rulesets.Mania.Edit
{ {
if (EditorBeatmap.SelectedHitObjects.Any()) if (EditorBeatmap.SelectedHitObjects.Any())
{ {
beatSnapGrid.SetRange(EditorBeatmap.SelectedHitObjects.Min(h => h.StartTime), EditorBeatmap.SelectedHitObjects.Max(h => h.GetEndTime())); beatSnapGrid.SelectionTimeRange = (EditorBeatmap.SelectedHitObjects.Min(h => h.StartTime), EditorBeatmap.SelectedHitObjects.Max(h => h.GetEndTime()));
beatSnapGrid.Show();
} }
else else
beatSnapGrid.Hide(); beatSnapGrid.SelectionTimeRange = null;
} }
else else
{ {
var placementTime = GetSnappedPosition(ToLocalSpace(inputManager.CurrentState.Mouse.Position), 0).time; var placementTime = GetSnappedPosition(ToLocalSpace(inputManager.CurrentState.Mouse.Position), 0).time;
beatSnapGrid.SetRange(placementTime, placementTime); beatSnapGrid.SelectionTimeRange = (placementTime, placementTime);
beatSnapGrid.Show();
} }
} }