Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Offset start of distance snap grid drawing if reference object's start time doesn't align #20941

Merged
merged 3 commits into from
Oct 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 40 additions & 3 deletions osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@
#nullable disable

using System;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
using osu.Framework.Testing;
using osu.Framework.Utils;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Overlays;
Expand Down Expand Up @@ -52,6 +55,7 @@ public class TestSceneOsuDistanceSnapGrid : OsuManualInputManagerTestScene
};

private OsuDistanceSnapGrid grid;
private SnappingCursorContainer cursor;

public TestSceneOsuDistanceSnapGrid()
{
Expand Down Expand Up @@ -88,8 +92,8 @@ public void Setup() => Schedule(() =>
RelativeSizeAxes = Axes.Both,
Colour = Color4.SlateGray
},
cursor = new SnappingCursorContainer { GetSnapPosition = v => grid.GetSnappedPosition(grid.ToLocalSpace(v)).position },
grid = new OsuDistanceSnapGrid(new HitCircle { Position = grid_position }),
new SnappingCursorContainer { GetSnapPosition = v => grid.GetSnappedPosition(grid.ToLocalSpace(v)).position }
};
});

Expand Down Expand Up @@ -154,6 +158,37 @@ public void TestDistanceSpacingAdjust(float multiplier, float expectedDistance)
assertSnappedDistance(expectedDistance);
}

[Test]
public void TestReferenceObjectNotOnSnapGrid()
{
AddStep("create grid", () =>
{
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.SlateGray
},
cursor = new SnappingCursorContainer { GetSnapPosition = v => grid.GetSnappedPosition(grid.ToLocalSpace(v)).position },
grid = new OsuDistanceSnapGrid(new HitCircle
{
Position = grid_position,
// This is important. It sets the reference object to a point in time that isn't on the current snap divisor's grid.
// We are testing that the grid's display is offset correctly.
StartTime = 40,
}),
};
});

AddStep("move mouse to point", () => InputManager.MoveMouseTo(grid.ToScreenSpace(grid_position + new Vector2(beat_length, 0) * 2)));

AddAssert("Ensure cursor is on a grid line", () =>
{
return grid.ChildrenOfType<CircularProgress>().Any(p => Precision.AlmostEquals(p.ScreenSpaceDrawQuad.TopRight.X, grid.ToScreenSpace(cursor.LastSnappedPosition).X));
});
}

[Test]
public void TestLimitedDistance()
{
Expand All @@ -166,8 +201,8 @@ public void TestLimitedDistance()
RelativeSizeAxes = Axes.Both,
Colour = Color4.SlateGray
},
cursor = new SnappingCursorContainer { GetSnapPosition = v => grid.GetSnappedPosition(grid.ToLocalSpace(v)).position },
grid = new OsuDistanceSnapGrid(new HitCircle { Position = grid_position }, new HitCircle { StartTime = 200 }),
new SnappingCursorContainer { GetSnapPosition = v => grid.GetSnappedPosition(grid.ToLocalSpace(v)).position }
};
});

Expand All @@ -186,6 +221,8 @@ private class SnappingCursorContainer : CompositeDrawable
{
public Func<Vector2, Vector2> GetSnapPosition;

public Vector2 LastSnappedPosition { get; private set; }

private readonly Drawable cursor;

private InputManager inputManager;
Expand Down Expand Up @@ -214,7 +251,7 @@ protected override void LoadComplete()
protected override void Update()
{
base.Update();
cursor.Position = GetSnapPosition.Invoke(inputManager.CurrentState.Mouse.Position);
cursor.Position = LastSnappedPosition = GetSnapPosition.Invoke(inputManager.CurrentState.Mouse.Position);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,16 @@ protected override void CreateContent()
float maxDistance = new Vector2(dx, dy).Length;
int requiredCircles = Math.Min(MaxIntervals, (int)(maxDistance / DistanceBetweenTicks));

// We need to offset the drawn lines to the next valid snap for the currently selected divisor.
//
// Picture the scenario where the user has just placed an object on a 1/2 snap, then changes to
// 1/3 snap and expects to be able to place the next object on a valid 1/3 snap, regardless of the
// fact that the 1/2 snap reference object is not valid for 1/3 snapping.
float offset = SnapProvider.FindSnappedDistance(ReferenceObject, 0);

for (int i = 0; i < requiredCircles; i++)
{
float diameter = (i + 1) * DistanceBetweenTicks * 2;
float diameter = (offset + (i + 1) * DistanceBetweenTicks) * 2;

AddInternal(new Ring(ReferenceObject, GetColourForIndexFromPlacement(i))
{
Expand Down