1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 20:07:25 +08:00

remove the need for caching points in segment

This commit is contained in:
OliBomby 2024-01-13 20:54:44 +01:00
parent b4f9878b46
commit da4d83f8ca
2 changed files with 27 additions and 32 deletions

View File

@ -37,8 +37,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
public Action<DragEvent> DragInProgress; public Action<DragEvent> DragInProgress;
public Action DragEnded; public Action DragEnded;
public List<PathControlPoint> PointsInSegment;
public readonly BindableBool IsSelected = new BindableBool(); public readonly BindableBool IsSelected = new BindableBool();
public readonly PathControlPoint ControlPoint; public readonly PathControlPoint ControlPoint;

View File

@ -9,7 +9,6 @@ using System.Collections.Specialized;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using Humanizer; using Humanizer;
using JetBrains.Annotations;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
@ -55,9 +54,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
[Resolved(CanBeNull = true)] [Resolved(CanBeNull = true)]
private IDistanceSnapProvider distanceSnapProvider { get; set; } private IDistanceSnapProvider distanceSnapProvider { get; set; }
[UsedImplicitly]
private readonly IBindable<int> hitObjectVersion;
public PathControlPointVisualiser(T hitObject, bool allowSelection) public PathControlPointVisualiser(T hitObject, bool allowSelection)
{ {
this.hitObject = hitObject; this.hitObject = hitObject;
@ -70,8 +66,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
Connections = new Container<PathControlPointConnectionPiece<T>> { RelativeSizeAxes = Axes.Both }, Connections = new Container<PathControlPointConnectionPiece<T>> { RelativeSizeAxes = Axes.Both },
Pieces = new Container<PathControlPointPiece<T>> { RelativeSizeAxes = Axes.Both } Pieces = new Container<PathControlPointPiece<T>> { RelativeSizeAxes = Axes.Both }
}; };
hitObjectVersion = hitObject.Path.Version.GetBoundCopy();
} }
protected override void LoadComplete() protected override void LoadComplete()
@ -85,20 +79,20 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
// schedule ensure that updates are only applied after all operations from a single frame are applied. // schedule ensure that updates are only applied after all operations from a single frame are applied.
// this avoids inadvertently changing the hit object path type for batch operations. // this avoids inadvertently changing the hit object path type for batch operations.
hitObject.Path.Validating += cachePointsAndEnsureValidPathTypes; hitObject.Path.Validating += ensureValidPathTypes;
} }
protected override void Dispose(bool isDisposing) protected override void Dispose(bool isDisposing)
{ {
base.Dispose(isDisposing); base.Dispose(isDisposing);
hitObject.Path.Validating -= cachePointsAndEnsureValidPathTypes; hitObject.Path.Validating -= ensureValidPathTypes;
} }
/// <summary> /// <summary>
/// Caches the PointsInSegment of Pieces and handles correction of invalid path types. /// Handles correction of invalid path types.
/// </summary> /// </summary>
private void cachePointsAndEnsureValidPathTypes() private void ensureValidPathTypes()
{ {
List<PathControlPoint> pointsInCurrentSegment = new List<PathControlPoint>(); List<PathControlPoint> pointsInCurrentSegment = new List<PathControlPoint>();
@ -107,31 +101,33 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
if (controlPoint.Type != null) if (controlPoint.Type != null)
{ {
pointsInCurrentSegment.Add(controlPoint); pointsInCurrentSegment.Add(controlPoint);
pointsInCurrentSegment = new List<PathControlPoint>(); ensureValidPathType(pointsInCurrentSegment);
pointsInCurrentSegment.Clear();
} }
pointsInCurrentSegment.Add(controlPoint); pointsInCurrentSegment.Add(controlPoint);
// Pieces might not be ordered so we need to find the piece corresponding to the current control point.
Pieces.Single(o => o.ControlPoint == controlPoint).PointsInSegment = pointsInCurrentSegment;
} }
foreach (var piece in Pieces) ensureValidPathType(pointsInCurrentSegment);
{ }
if (piece.ControlPoint.Type != PathType.PERFECT_CURVE)
continue;
if (piece.PointsInSegment.Count > 3) private void ensureValidPathType(IReadOnlyList<PathControlPoint> segment)
piece.ControlPoint.Type = PathType.BEZIER; {
var first = segment[0];
if (piece.PointsInSegment.Count != 3) if (first.Type != PathType.PERFECT_CURVE)
continue; return;
ReadOnlySpan<Vector2> points = piece.PointsInSegment.Select(p => p.Position).ToArray(); if (segment.Count > 3)
RectangleF boundingBox = PathApproximator.CircularArcBoundingBox(points); first.Type = PathType.BEZIER;
if (boundingBox.Width >= 640 || boundingBox.Height >= 480)
piece.ControlPoint.Type = PathType.BEZIER; if (segment.Count != 3)
} return;
ReadOnlySpan<Vector2> points = segment.Select(p => p.Position).ToArray();
RectangleF boundingBox = PathApproximator.CircularArcBoundingBox(points);
if (boundingBox.Width >= 640 || boundingBox.Height >= 480)
first.Type = PathType.BEZIER;
} }
/// <summary> /// <summary>
@ -298,7 +294,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
/// <param name="type">The path type we want to assign to the given control point piece.</param> /// <param name="type">The path type we want to assign to the given control point piece.</param>
private void updatePathType(PathControlPointPiece<T> piece, PathType? type) private void updatePathType(PathControlPointPiece<T> piece, PathType? type)
{ {
int indexInSegment = piece.PointsInSegment.IndexOf(piece.ControlPoint); var pointsInSegment = hitObject.Path.PointsInSegment(piece.ControlPoint);
int indexInSegment = pointsInSegment.IndexOf(piece.ControlPoint);
if (type?.Type == SplineType.PerfectCurve) if (type?.Type == SplineType.PerfectCurve)
{ {
@ -307,8 +304,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
// and one segment of the previous type. // and one segment of the previous type.
int thirdPointIndex = indexInSegment + 2; int thirdPointIndex = indexInSegment + 2;
if (piece.PointsInSegment.Count > thirdPointIndex + 1) if (pointsInSegment.Count > thirdPointIndex + 1)
piece.PointsInSegment[thirdPointIndex].Type = piece.PointsInSegment[0].Type; pointsInSegment[thirdPointIndex].Type = pointsInSegment[0].Type;
} }
hitObject.Path.ExpectedDistance.Value = null; hitObject.Path.ExpectedDistance.Value = null;