mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 19:03:08 +08:00
Construct online visible lines
This commit is contained in:
parent
b35b150f38
commit
406f39e8bf
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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 point = beatmap.ControlPointInfo.TimingPoints[i];
|
|
||||||
var until = i + 1 < beatmap.ControlPointInfo.TimingPoints.Count ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : working.Value.Track.Length;
|
|
||||||
|
|
||||||
|
var range = selectionTimeRange.Value;
|
||||||
|
|
||||||
|
var timingPoint = beatmap.ControlPointInfo.TimingPointAt(range.start - visible_range);
|
||||||
|
|
||||||
|
double time = timingPoint.Time;
|
||||||
int beat = 0;
|
int beat = 0;
|
||||||
|
|
||||||
for (double t = point.Time; t < until; t += point.BeatLength / beatDivisor.Value)
|
// progress time until in the visible range.
|
||||||
|
while (time < range.start - visible_range)
|
||||||
{
|
{
|
||||||
var indexInBeat = beat % beatDivisor.Value;
|
time += timingPoint.BeatLength / beatDivisor.Value;
|
||||||
Color4 colour;
|
beat++;
|
||||||
|
}
|
||||||
|
|
||||||
if (indexInBeat == 0)
|
while (time < range.end + visible_range)
|
||||||
colour = BindableBeatDivisor.GetColourFor(1, colours);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
var divisor = BindableBeatDivisor.GetDivisorForBeatIndex(beat, beatDivisor.Value);
|
var nextTimingPoint = beatmap.ControlPointInfo.TimingPointAt(time);
|
||||||
colour = BindableBeatDivisor.GetColourFor(divisor, colours);
|
|
||||||
|
// switch to the next timing point if we have reached it.
|
||||||
|
if (nextTimingPoint != timingPoint)
|
||||||
|
{
|
||||||
|
beat = 0;
|
||||||
|
timingPoint = nextTimingPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
foreach (var grid in grids)
|
||||||
grid.Add(new DrawableGridLine(t, colour));
|
{
|
||||||
|
// required to update ScrollingHitObjectContainer's cache.
|
||||||
|
grid.UpdateSubTree();
|
||||||
|
|
||||||
beat++;
|
foreach (var line in grid.Objects.OfType<DrawableGridLine>())
|
||||||
|
{
|
||||||
|
time = line.HitObject.StartTime;
|
||||||
|
|
||||||
|
if (time >= range.start && time <= range.end)
|
||||||
|
line.Alpha = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double timeSeparation = time < range.start ? range.start - time : time - range.end;
|
||||||
|
line.Alpha = (float)Math.Max(0, 1 - timeSeparation / visible_range);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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]
|
||||||
|
@ -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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user