From 2aa3d0bb39f7a0e0cd8b82e2c6285197f3609e23 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 10 Oct 2019 21:55:48 +0900 Subject: [PATCH 01/10] Implement base class for beat snapping grids --- .../Visual/Editor/TestSceneBeatSnapGrid.cs | 210 ++++++++++++++++++ .../Edit/Compose/Components/BeatSnapGrid.cs | 149 +++++++++++++ 2 files changed, 359 insertions(+) create mode 100644 osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs create mode 100644 osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs diff --git a/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs b/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs new file mode 100644 index 0000000000..8502cefdeb --- /dev/null +++ b/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs @@ -0,0 +1,210 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osu.Framework.MathUtils; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Osu.Beatmaps; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Screens.Edit; +using osu.Game.Screens.Edit.Compose.Components; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Tests.Visual.Editor +{ + public class TestSceneBeatSnapGrid : EditorClockTestScene + { + private const double beat_length = 100; + private static readonly Vector2 grid_position = new Vector2(512, 384); + + [Cached(typeof(IEditorBeatmap))] + private readonly EditorBeatmap editorBeatmap; + + private TestBeatSnapGrid grid; + + public TestSceneBeatSnapGrid() + { + editorBeatmap = new EditorBeatmap(new OsuBeatmap()); + } + + [SetUp] + public void Setup() => Schedule(() => + { + Clear(); + + editorBeatmap.ControlPointInfo.TimingPoints.Clear(); + editorBeatmap.ControlPointInfo.TimingPoints.Add(new TimingControlPoint { BeatLength = beat_length }); + + BeatDivisor.Value = 1; + }); + + [TestCase(1)] + [TestCase(2)] + [TestCase(3)] + [TestCase(4)] + [TestCase(6)] + [TestCase(8)] + [TestCase(12)] + [TestCase(16)] + public void TestInitialBeatDivisor(int divisor) + { + AddStep($"set beat divisor = {divisor}", () => BeatDivisor.Value = divisor); + createGrid(); + + float expectedDistance = (float)beat_length / divisor; + AddAssert($"spacing is {expectedDistance}", () => Precision.AlmostEquals(grid.DistanceSpacing, expectedDistance)); + } + + [Test] + public void TestChangeBeatDivisor() + { + createGrid(); + AddStep("set beat divisor = 2", () => BeatDivisor.Value = 2); + + const float expected_distance = (float)beat_length / 2; + AddAssert($"spacing is {expected_distance}", () => Precision.AlmostEquals(grid.DistanceSpacing, expected_distance)); + } + + [TestCase(100)] + [TestCase(200)] + public void TestBeatLength(double beatLength) + { + AddStep($"set beat length = {beatLength}", () => + { + editorBeatmap.ControlPointInfo.TimingPoints.Clear(); + editorBeatmap.ControlPointInfo.TimingPoints.Add(new TimingControlPoint { BeatLength = beatLength }); + }); + + createGrid(); + AddAssert($"spacing is {beatLength}", () => Precision.AlmostEquals(grid.DistanceSpacing, beatLength)); + } + + [TestCase(1)] + [TestCase(2)] + public void TestGridVelocity(float velocity) + { + createGrid(g => g.Velocity = velocity); + + float expectedDistance = (float)beat_length * velocity; + AddAssert($"spacing is {expectedDistance}", () => Precision.AlmostEquals(grid.DistanceSpacing, expectedDistance)); + } + + [Test] + public void TestGetSnappedTime() + { + createGrid(); + + Vector2 screenSpacePosition = Vector2.Zero; + AddStep("get first tick position", () => screenSpacePosition = grid.ToScreenSpace(grid_position + new Vector2((float)beat_length, 0))); + AddAssert("snap time is 1 beat away", () => Precision.AlmostEquals(beat_length, grid.GetSnapTime(screenSpacePosition), 0.01)); + + createGrid(g => g.Velocity = 2, " with velocity = 2"); + AddAssert("snap time is now 0.5 beats away", () => Precision.AlmostEquals(beat_length / 2, grid.GetSnapTime(screenSpacePosition), 0.01)); + } + + private void createGrid(Action func = null, string description = null) + { + AddStep($"create grid {description ?? string.Empty}", () => + { + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.SlateGray + }, + grid = new TestBeatSnapGrid(new HitObject(), grid_position) + }; + + func?.Invoke(grid); + }); + } + + private class TestBeatSnapGrid : BeatSnapGrid + { + public new float Velocity = 1; + + public new float DistanceSpacing => base.DistanceSpacing; + + public TestBeatSnapGrid(HitObject hitObject, Vector2 startPosition) + : base(hitObject, startPosition) + { + } + + protected override void CreateGrid(Vector2 startPosition) + { + AddInternal(new Circle + { + Origin = Anchor.Centre, + Size = new Vector2(5), + Position = startPosition + }); + + int beatIndex = 0; + + for (float s = startPosition.X + DistanceSpacing; s <= DrawWidth; s += DistanceSpacing, beatIndex++) + { + AddInternal(new Circle + { + Origin = Anchor.Centre, + Size = new Vector2(5, 10), + Position = new Vector2(s, startPosition.Y), + Colour = GetColourForBeatIndex(beatIndex) + }); + } + + beatIndex = 0; + + for (float s = startPosition.X - DistanceSpacing; s >= 0; s -= DistanceSpacing, beatIndex++) + { + AddInternal(new Circle + { + Origin = Anchor.Centre, + Size = new Vector2(5, 10), + Position = new Vector2(s, startPosition.Y), + Colour = GetColourForBeatIndex(beatIndex) + }); + } + + beatIndex = 0; + + for (float s = startPosition.Y + DistanceSpacing; s <= DrawHeight; s += DistanceSpacing, beatIndex++) + { + AddInternal(new Circle + { + Origin = Anchor.Centre, + Size = new Vector2(10, 5), + Position = new Vector2(startPosition.X, s), + Colour = GetColourForBeatIndex(beatIndex) + }); + } + + beatIndex = 0; + + for (float s = startPosition.Y - DistanceSpacing; s >= 0; s -= DistanceSpacing, beatIndex++) + { + AddInternal(new Circle + { + Origin = Anchor.Centre, + Size = new Vector2(10, 5), + Position = new Vector2(startPosition.X, s), + Colour = GetColourForBeatIndex(beatIndex) + }); + } + } + + protected override float GetVelocity(double time, ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) + => Velocity; + + public override Vector2 GetSnapPosition(Vector2 screenSpacePosition) + => Vector2.Zero; + } + } +} diff --git a/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs new file mode 100644 index 0000000000..957e752fa2 --- /dev/null +++ b/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs @@ -0,0 +1,149 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Caching; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Timing; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Graphics; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; +using osuTK; + +namespace osu.Game.Screens.Edit.Compose.Components +{ + public abstract class BeatSnapGrid : CompositeDrawable + { + protected double Velocity { get; private set; } + + protected float DistanceSpacing { get; private set; } + + [Resolved] + private IFrameBasedClock framedClock { get; set; } + + [Resolved] + private IEditorBeatmap beatmap { get; set; } + + [Resolved] + private BindableBeatDivisor beatDivisor { get; set; } + + [Resolved] + private OsuColour colours { get; set; } + + private readonly Cached gridCache = new Cached(); + private readonly HitObject hitObject; + private readonly Vector2 startPosition; + + private double startTime; + private double beatLength; + + protected BeatSnapGrid(HitObject hitObject, Vector2 startPosition) + { + this.hitObject = hitObject; + this.startPosition = startPosition; + + RelativeSizeAxes = Axes.Both; + } + + [BackgroundDependencyLoader] + private void load() + { + startTime = (hitObject as IHasEndTime)?.EndTime ?? hitObject.StartTime; + beatLength = beatmap.ControlPointInfo.TimingPointAt(startTime).BeatLength; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + beatDivisor.BindValueChanged(_ => updateSpacing(), true); + } + + private void updateSpacing() + { + Velocity = GetVelocity(startTime, beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty); + DistanceSpacing = (float)(beatLength / beatDivisor.Value * Velocity); + gridCache.Invalidate(); + } + + public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) + { + if ((invalidation & Invalidation.RequiredParentSizeToFit) > 0) + gridCache.Invalidate(); + + return base.Invalidate(invalidation, source, shallPropagate); + } + + protected override void Update() + { + base.Update(); + + if (!gridCache.IsValid) + { + ClearInternal(); + CreateGrid(startPosition); + gridCache.Validate(); + } + } + + /// + /// Draws the grid. + /// + protected abstract void CreateGrid(Vector2 startPosition); + + /// + /// Retrieves the velocity of gameplay at a time. + /// + /// The time to retrieve the velocity at. + /// The beatmap's at the requested time. + /// The beatmap's at the requested time. + /// The velocity in pixels per millisecond. + protected abstract float GetVelocity(double time, ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty); + + /// + /// Snaps a position to this grid. + /// + /// The original screen-space position. + /// The snapped position. + public abstract Vector2 GetSnapPosition(Vector2 screenSpacePosition); + + /// + /// Retrieves the time at a snapped position. + /// + /// The snapped position. + /// The time at the snapped position. + public double GetSnapTime(Vector2 snappedPosition) => startTime + (ToLocalSpace(snappedPosition) - startPosition).Length / Velocity; + + /// + /// Retrieves the applicable colour for a beat index. + /// + /// The 0-based beat index. + /// The applicable colour. + protected ColourInfo GetColourForBeatIndex(int index) + { + int divIndex = beatDivisor.Value - (index % beatDivisor.Value) - 1; + + ColourInfo colour = colours.Gray5; + + { + for (int i = 0; i < BindableBeatDivisor.VALID_DIVISORS.Length; i++) + { + int divisor = BindableBeatDivisor.VALID_DIVISORS[i]; + + if ((divIndex * divisor) % beatDivisor.Value == 0) + { + colour = BindableBeatDivisor.GetColourFor(divisor, colours); + break; + } + } + } + + int repeatIndex = index / beatDivisor.Value; + return colour.MultiplyAlpha(0.5f / (repeatIndex + 1)); + } + } +} From 824595427d6739cabc48a8759bddbc40578e480d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 Oct 2019 13:53:49 +0900 Subject: [PATCH 02/10] Remove extra whitespace --- osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs b/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs index 8502cefdeb..6419b0c2e2 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs @@ -105,7 +105,7 @@ namespace osu.Game.Tests.Visual.Editor AddStep("get first tick position", () => screenSpacePosition = grid.ToScreenSpace(grid_position + new Vector2((float)beat_length, 0))); AddAssert("snap time is 1 beat away", () => Precision.AlmostEquals(beat_length, grid.GetSnapTime(screenSpacePosition), 0.01)); - createGrid(g => g.Velocity = 2, " with velocity = 2"); + createGrid(g => g.Velocity = 2, "with velocity = 2"); AddAssert("snap time is now 0.5 beats away", () => Precision.AlmostEquals(beat_length / 2, grid.GetSnapTime(screenSpacePosition), 0.01)); } From 2df519ddfad597931c038876ebebfaf7e1740dd1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 Oct 2019 14:01:36 +0900 Subject: [PATCH 03/10] Simplify colour retrieval function --- .../Edit/Compose/Components/BeatSnapGrid.cs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs index 957e752fa2..0630fc5099 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs @@ -125,20 +125,17 @@ namespace osu.Game.Screens.Edit.Compose.Components /// The applicable colour. protected ColourInfo GetColourForBeatIndex(int index) { - int divIndex = beatDivisor.Value - (index % beatDivisor.Value) - 1; - + int beat = (index + 1) % beatDivisor.Value; ColourInfo colour = colours.Gray5; + for (int i = 0; i < BindableBeatDivisor.VALID_DIVISORS.Length; i++) { - for (int i = 0; i < BindableBeatDivisor.VALID_DIVISORS.Length; i++) - { - int divisor = BindableBeatDivisor.VALID_DIVISORS[i]; + int divisor = BindableBeatDivisor.VALID_DIVISORS[i]; - if ((divIndex * divisor) % beatDivisor.Value == 0) - { - colour = BindableBeatDivisor.GetColourFor(divisor, colours); - break; - } + if ((beat * divisor) % beatDivisor.Value == 0) + { + colour = BindableBeatDivisor.GetColourFor(divisor, colours); + break; } } From 97d4a8e59e384e321996653bd1de8831ad44fafb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 Oct 2019 15:30:20 +0900 Subject: [PATCH 04/10] Remove unnecessary dependency --- osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs index 0630fc5099..9135931823 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs @@ -22,8 +22,6 @@ namespace osu.Game.Screens.Edit.Compose.Components protected float DistanceSpacing { get; private set; } - [Resolved] - private IFrameBasedClock framedClock { get; set; } [Resolved] private IEditorBeatmap beatmap { get; set; } From 66e0fef85b6ff60aff277da7f81f70735bb45ae4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 Oct 2019 15:30:31 +0900 Subject: [PATCH 05/10] Expose StartPosition for derived grids to use --- osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs index 9135931823..d44d53dca7 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs @@ -6,7 +6,6 @@ using osu.Framework.Caching; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; -using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics; @@ -22,6 +21,7 @@ namespace osu.Game.Screens.Edit.Compose.Components protected float DistanceSpacing { get; private set; } + protected readonly Vector2 StartPosition; [Resolved] private IEditorBeatmap beatmap { get; set; } @@ -34,7 +34,6 @@ namespace osu.Game.Screens.Edit.Compose.Components private readonly Cached gridCache = new Cached(); private readonly HitObject hitObject; - private readonly Vector2 startPosition; private double startTime; private double beatLength; @@ -42,7 +41,7 @@ namespace osu.Game.Screens.Edit.Compose.Components protected BeatSnapGrid(HitObject hitObject, Vector2 startPosition) { this.hitObject = hitObject; - this.startPosition = startPosition; + this.StartPosition = startPosition; RelativeSizeAxes = Axes.Both; } @@ -83,7 +82,7 @@ namespace osu.Game.Screens.Edit.Compose.Components if (!gridCache.IsValid) { ClearInternal(); - CreateGrid(startPosition); + CreateGrid(StartPosition); gridCache.Validate(); } } @@ -114,7 +113,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// The snapped position. /// The time at the snapped position. - public double GetSnapTime(Vector2 snappedPosition) => startTime + (ToLocalSpace(snappedPosition) - startPosition).Length / Velocity; + public double GetSnapTime(Vector2 snappedPosition) => startTime + (ToLocalSpace(snappedPosition) - StartPosition).Length / Velocity; /// /// Retrieves the applicable colour for a beat index. From 8fb2628f9e07185dbdf1b3211a753839c3561ac1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 Oct 2019 15:41:01 +0900 Subject: [PATCH 06/10] Improve xmldocs --- .../Edit/Compose/Components/BeatSnapGrid.cs | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs index d44d53dca7..175d61fd32 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs @@ -17,8 +17,14 @@ namespace osu.Game.Screens.Edit.Compose.Components { public abstract class BeatSnapGrid : CompositeDrawable { + /// + /// The velocity of the beatmap at the point of placement in pixels per millisecond. + /// protected double Velocity { get; private set; } + /// + /// The spacing between each tick of the beat snapping grid. + /// protected float DistanceSpacing { get; private set; } protected readonly Vector2 StartPosition; @@ -88,32 +94,32 @@ namespace osu.Game.Screens.Edit.Compose.Components } /// - /// Draws the grid. + /// Creates the content which visualises the grid ticks. /// protected abstract void CreateGrid(Vector2 startPosition); /// - /// Retrieves the velocity of gameplay at a time. + /// Retrieves the velocity of gameplay at a point in time in pixels per millisecond. /// /// The time to retrieve the velocity at. - /// The beatmap's at the requested time. - /// The beatmap's at the requested time. - /// The velocity in pixels per millisecond. + /// The beatmap's at the point in time. + /// The beatmap's at the point in time. + /// The velocity. protected abstract float GetVelocity(double time, ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty); /// - /// Snaps a position to this grid. + /// Snaps a screen-space position to this grid. /// /// The original screen-space position. - /// The snapped position. + /// The snapped screen-space position. public abstract Vector2 GetSnapPosition(Vector2 screenSpacePosition); /// - /// Retrieves the time at a snapped position. + /// Retrieves the time at a snapped screen-space position. /// - /// The snapped position. + /// The snapped screen-space position. /// The time at the snapped position. - public double GetSnapTime(Vector2 snappedPosition) => startTime + (ToLocalSpace(snappedPosition) - StartPosition).Length / Velocity; + public double GetSnapTime(Vector2 screenSpacePosition) => startTime + (ToLocalSpace(screenSpacePosition) - CentrePosition).Length / Velocity; /// /// Retrieves the applicable colour for a beat index. From 5f0cd356d764ffab48ab4396c18f4a017600e4f0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 Oct 2019 15:41:21 +0900 Subject: [PATCH 07/10] Rename startPosition to centrePosition --- osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs | 4 ++-- .../Screens/Edit/Compose/Components/BeatSnapGrid.cs | 10 +++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs b/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs index 6419b0c2e2..9f9b884cdd 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs @@ -133,8 +133,8 @@ namespace osu.Game.Tests.Visual.Editor public new float DistanceSpacing => base.DistanceSpacing; - public TestBeatSnapGrid(HitObject hitObject, Vector2 startPosition) - : base(hitObject, startPosition) + public TestBeatSnapGrid(HitObject hitObject, Vector2 centrePosition) + : base(hitObject, centrePosition) { } diff --git a/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs index 175d61fd32..24926995e6 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs @@ -27,7 +27,11 @@ namespace osu.Game.Screens.Edit.Compose.Components /// protected float DistanceSpacing { get; private set; } - protected readonly Vector2 StartPosition; + /// + /// The position which the grid is centred on. + /// The first beat snapping tick is located at + in the desired direction. + /// + protected readonly Vector2 CentrePosition; [Resolved] private IEditorBeatmap beatmap { get; set; } @@ -44,10 +48,10 @@ namespace osu.Game.Screens.Edit.Compose.Components private double startTime; private double beatLength; - protected BeatSnapGrid(HitObject hitObject, Vector2 startPosition) + protected BeatSnapGrid(HitObject hitObject, Vector2 centrePosition) { this.hitObject = hitObject; - this.StartPosition = startPosition; + this.CentrePosition = centrePosition; RelativeSizeAxes = Axes.Both; } From 9ecec806c2343d90c03eb48b71b264e1f82dba0e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 Oct 2019 15:41:40 +0900 Subject: [PATCH 08/10] Rename grid creation method + parameter --- .../Visual/Editor/TestSceneBeatSnapGrid.cs | 20 +++++++++---------- .../Edit/Compose/Components/BeatSnapGrid.cs | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs b/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs index 9f9b884cdd..345fe245fe 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs @@ -138,63 +138,63 @@ namespace osu.Game.Tests.Visual.Editor { } - protected override void CreateGrid(Vector2 startPosition) + protected override void CreateContent(Vector2 centrePosition) { AddInternal(new Circle { Origin = Anchor.Centre, Size = new Vector2(5), - Position = startPosition + Position = centrePosition }); int beatIndex = 0; - for (float s = startPosition.X + DistanceSpacing; s <= DrawWidth; s += DistanceSpacing, beatIndex++) + for (float s = centrePosition.X + DistanceSpacing; s <= DrawWidth; s += DistanceSpacing, beatIndex++) { AddInternal(new Circle { Origin = Anchor.Centre, Size = new Vector2(5, 10), - Position = new Vector2(s, startPosition.Y), + Position = new Vector2(s, centrePosition.Y), Colour = GetColourForBeatIndex(beatIndex) }); } beatIndex = 0; - for (float s = startPosition.X - DistanceSpacing; s >= 0; s -= DistanceSpacing, beatIndex++) + for (float s = centrePosition.X - DistanceSpacing; s >= 0; s -= DistanceSpacing, beatIndex++) { AddInternal(new Circle { Origin = Anchor.Centre, Size = new Vector2(5, 10), - Position = new Vector2(s, startPosition.Y), + Position = new Vector2(s, centrePosition.Y), Colour = GetColourForBeatIndex(beatIndex) }); } beatIndex = 0; - for (float s = startPosition.Y + DistanceSpacing; s <= DrawHeight; s += DistanceSpacing, beatIndex++) + for (float s = centrePosition.Y + DistanceSpacing; s <= DrawHeight; s += DistanceSpacing, beatIndex++) { AddInternal(new Circle { Origin = Anchor.Centre, Size = new Vector2(10, 5), - Position = new Vector2(startPosition.X, s), + Position = new Vector2(centrePosition.X, s), Colour = GetColourForBeatIndex(beatIndex) }); } beatIndex = 0; - for (float s = startPosition.Y - DistanceSpacing; s >= 0; s -= DistanceSpacing, beatIndex++) + for (float s = centrePosition.Y - DistanceSpacing; s >= 0; s -= DistanceSpacing, beatIndex++) { AddInternal(new Circle { Origin = Anchor.Centre, Size = new Vector2(10, 5), - Position = new Vector2(startPosition.X, s), + Position = new Vector2(centrePosition.X, s), Colour = GetColourForBeatIndex(beatIndex) }); } diff --git a/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs index 24926995e6..98ad0dd3e8 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs @@ -92,7 +92,7 @@ namespace osu.Game.Screens.Edit.Compose.Components if (!gridCache.IsValid) { ClearInternal(); - CreateGrid(StartPosition); + CreateContent(CentrePosition); gridCache.Validate(); } } @@ -100,7 +100,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// Creates the content which visualises the grid ticks. /// - protected abstract void CreateGrid(Vector2 startPosition); + protected abstract void CreateContent(Vector2 centrePosition); /// /// Retrieves the velocity of gameplay at a point in time in pixels per millisecond. From 050d86a741b5908d45ea588d7d25d3f8ae9c079b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 Oct 2019 15:46:11 +0900 Subject: [PATCH 09/10] Always use the local coordinate space --- .../Visual/Editor/TestSceneBeatSnapGrid.cs | 8 ++++---- .../Edit/Compose/Components/BeatSnapGrid.cs | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs b/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs index 345fe245fe..d6ddd4cc86 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs @@ -101,12 +101,12 @@ namespace osu.Game.Tests.Visual.Editor { createGrid(); - Vector2 screenSpacePosition = Vector2.Zero; - AddStep("get first tick position", () => screenSpacePosition = grid.ToScreenSpace(grid_position + new Vector2((float)beat_length, 0))); - AddAssert("snap time is 1 beat away", () => Precision.AlmostEquals(beat_length, grid.GetSnapTime(screenSpacePosition), 0.01)); + Vector2 snapPosition = Vector2.Zero; + AddStep("get first tick position", () => snapPosition = grid_position + new Vector2((float)beat_length, 0)); + AddAssert("snap time is 1 beat away", () => Precision.AlmostEquals(beat_length, grid.GetSnapTime(snapPosition), 0.01)); createGrid(g => g.Velocity = 2, "with velocity = 2"); - AddAssert("snap time is now 0.5 beats away", () => Precision.AlmostEquals(beat_length / 2, grid.GetSnapTime(screenSpacePosition), 0.01)); + AddAssert("snap time is now 0.5 beats away", () => Precision.AlmostEquals(beat_length / 2, grid.GetSnapTime(snapPosition), 0.01)); } private void createGrid(Action func = null, string description = null) diff --git a/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs index 98ad0dd3e8..9040843144 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BeatSnapGrid.cs @@ -112,18 +112,18 @@ namespace osu.Game.Screens.Edit.Compose.Components protected abstract float GetVelocity(double time, ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty); /// - /// Snaps a screen-space position to this grid. + /// Snaps a position to this grid. /// - /// The original screen-space position. - /// The snapped screen-space position. - public abstract Vector2 GetSnapPosition(Vector2 screenSpacePosition); + /// The original position in coordinate space local to this . + /// The snapped position in coordinate space local to this . + public abstract Vector2 GetSnapPosition(Vector2 position); /// - /// Retrieves the time at a snapped screen-space position. + /// Retrieves the time at a snapped position. /// - /// The snapped screen-space position. + /// The snapped position in coordinate space local to this . /// The time at the snapped position. - public double GetSnapTime(Vector2 screenSpacePosition) => startTime + (ToLocalSpace(screenSpacePosition) - CentrePosition).Length / Velocity; + public double GetSnapTime(Vector2 position) => startTime + (position - CentrePosition).Length / Velocity; /// /// Retrieves the applicable colour for a beat index. From 631f1555547581f0383a864e174683dc54ff9692 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 Oct 2019 17:17:08 +0900 Subject: [PATCH 10/10] Add grid to make the test not appear empty --- osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs b/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs index d6ddd4cc86..073cec7315 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneBeatSnapGrid.cs @@ -32,6 +32,9 @@ namespace osu.Game.Tests.Visual.Editor public TestSceneBeatSnapGrid() { editorBeatmap = new EditorBeatmap(new OsuBeatmap()); + editorBeatmap.ControlPointInfo.TimingPoints.Add(new TimingControlPoint { BeatLength = beat_length }); + + createGrid(); } [SetUp]