diff --git a/osu.Game/Rulesets/Objects/SliderPath.cs b/osu.Game/Rulesets/Objects/SliderPath.cs index c9d2928dc3..13cc6361cf 100644 --- a/osu.Game/Rulesets/Objects/SliderPath.cs +++ b/osu.Game/Rulesets/Objects/SliderPath.cs @@ -42,6 +42,7 @@ namespace osu.Game.Rulesets.Objects private readonly List calculatedPath = new List(); private readonly List cumulativeLength = new List(); + private readonly List segmentEnds = new List(); private readonly Cached pathCache = new Cached(); private double calculatedLength; @@ -196,6 +197,16 @@ namespace osu.Game.Rulesets.Objects return pointsInCurrentSegment; } + /// + /// Returns the progress values at which segments of the path end. + /// + public IEnumerable GetSegmentEnds() + { + ensureValid(); + + return segmentEnds.Select(i => cumulativeLength[i] / calculatedLength); + } + private void invalidate() { pathCache.Invalidate(); @@ -216,6 +227,7 @@ namespace osu.Game.Rulesets.Objects private void calculatePath() { calculatedPath.Clear(); + segmentEnds.Clear(); if (ControlPoints.Count == 0) return; @@ -241,6 +253,9 @@ namespace osu.Game.Rulesets.Objects calculatedPath.Add(t); } + // Remember the index of the segment end + segmentEnds.Add(calculatedPath.Count - 1); + // Start the new segment at the current vertex start = i; } @@ -306,6 +321,10 @@ namespace osu.Game.Rulesets.Objects { cumulativeLength.RemoveAt(cumulativeLength.Count - 1); calculatedPath.RemoveAt(pathEndIndex--); + + // Shorten the last segment to the expected distance + if (segmentEnds.Count > 0) + segmentEnds[^1]--; } }