From f45f17339c9d6c4d4c7d61020cbcfdd8ad090ac3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 24 Oct 2019 18:09:20 +0900 Subject: [PATCH] Implement slider path distance snapping --- .../Blueprints/Sliders/SliderPlacementBlueprint.cs | 11 +++++++++-- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 4 ++++ .../Edit/Compose/Components/DistanceSnapGrid.cs | 7 +++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs index b7b8d0af88..e1478a062c 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs @@ -33,6 +33,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders private PlacementState state; + [Resolved] + private HitObjectComposer composer { get; set; } + public SliderPlacementBlueprint() : base(new Objects.Slider()) { @@ -131,8 +134,12 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders private void updateSlider() { - var newControlPoints = segments.SelectMany(s => s.ControlPoints).Concat(cursor.Yield()).ToArray(); - HitObject.Path = new SliderPath(newControlPoints.Length > 2 ? PathType.Bezier : PathType.Linear, newControlPoints); + Vector2[] newControlPoints = segments.SelectMany(s => s.ControlPoints).Concat(cursor.Yield()).ToArray(); + + var unsnappedPath = new SliderPath(newControlPoints.Length > 2 ? PathType.Bezier : PathType.Linear, newControlPoints); + var snappedDistance = composer.GetSnappedDistance((float)unsnappedPath.Distance); + + HitObject.Path = new SliderPath(newControlPoints.Length > 2 ? PathType.Bezier : PathType.Linear, newControlPoints, snappedDistance); bodyPiece.UpdateFrom(HitObject); headCirclePiece.UpdateFrom(HitObject.HeadCircle); diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 6396301add..f9d2734e80 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -261,6 +261,8 @@ namespace osu.Game.Rulesets.Edit public override double GetSnappedTime(double startTime, Vector2 position) => distanceSnapGrid?.GetSnapTime(position) ?? startTime; + public override float GetSnappedDistance(float distance) => distanceSnapGrid?.GetSnapDistance(distance) ?? distance; + protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); @@ -313,5 +315,7 @@ namespace osu.Game.Rulesets.Edit public abstract Vector2 GetSnappedPosition(Vector2 position); public abstract double GetSnappedTime(double startTime, Vector2 screenSpacePosition); + + public abstract float GetSnappedDistance(float distance); } } diff --git a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs index 096ff0a6dd..3bedff79f5 100644 --- a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs @@ -128,6 +128,13 @@ namespace osu.Game.Screens.Edit.Compose.Components /// The time at the snapped position. public double GetSnapTime(Vector2 position) => startTime + (position - CentrePosition).Length / Velocity; + /// + /// Snaps a distance by the snap distance of this grid. + /// + /// The distance to snap. + /// The snapped distance. + public float GetSnapDistance(float distance) => (int)(distance / DistanceSpacing) * DistanceSpacing; + /// /// Retrieves the applicable colour for a beat index. ///