1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-15 08:22:56 +08:00

Fix segmentEnds being calculated incorrectly

This commit is contained in:
Pasi4K5 2023-08-18 04:34:10 +02:00
parent 58bffa13cd
commit 3481c41a22
2 changed files with 16 additions and 13 deletions

View File

@ -202,7 +202,7 @@ namespace osu.Game.Rulesets.Objects
{ {
ensureValid(); ensureValid();
return segmentEnds.Select(i => cumulativeLength[Math.Clamp(i, 0, cumulativeLength.Count - 1)] / calculatedLength); return segmentEnds.Select(i => cumulativeLength[i] / Distance);
} }
private void invalidate() private void invalidate()
@ -251,8 +251,9 @@ namespace osu.Game.Rulesets.Objects
calculatedPath.Add(t); calculatedPath.Add(t);
} }
// Remember the index of the segment end if (i > 0)
segmentEnds.Add(calculatedPath.Count - 1); // Remember the index of the segment end
segmentEnds.Add(calculatedPath.Count - 1);
// Start the new segment at the current vertex // Start the new segment at the current vertex
start = i; start = i;
@ -314,15 +315,11 @@ namespace osu.Game.Rulesets.Objects
if (calculatedLength > expectedDistance) if (calculatedLength > expectedDistance)
{ {
// The path will be shortened further, in which case we should trim any more unnecessary lengths and their associated path segments // The path will be shortened further, in which case we should trim any more unnecessary lengths
while (cumulativeLength.Count > 0 && cumulativeLength[^1] >= expectedDistance) while (cumulativeLength.Count > 0 && cumulativeLength[^1] >= expectedDistance)
{ {
cumulativeLength.RemoveAt(cumulativeLength.Count - 1); cumulativeLength.RemoveAt(cumulativeLength.Count - 1);
calculatedPath.RemoveAt(pathEndIndex--); calculatedPath.RemoveAt(pathEndIndex--);
// Shorten the last segment to the expected distance
if (segmentEnds.Count > 0)
segmentEnds[^1]--;
} }
} }
@ -339,6 +336,12 @@ namespace osu.Game.Rulesets.Objects
calculatedPath[pathEndIndex] = calculatedPath[pathEndIndex - 1] + dir * (float)(expectedDistance - cumulativeLength[^1]); calculatedPath[pathEndIndex] = calculatedPath[pathEndIndex - 1] + dir * (float)(expectedDistance - cumulativeLength[^1]);
cumulativeLength.Add(expectedDistance); cumulativeLength.Add(expectedDistance);
// Shorten the segments to the expected distance
for (int i = 0; i < segmentEnds.Count; i++)
{
segmentEnds[i] = Math.Min(segmentEnds[i], cumulativeLength.Count - 1);
}
} }
} }

View File

@ -45,9 +45,9 @@ namespace osu.Game.Rulesets.Objects
double[] distinctSegmentEnds = truncateEndingDuplicates(segmentEnds); double[] distinctSegmentEnds = truncateEndingDuplicates(segmentEnds);
// Remove control points at the end which do not affect the visual slider path ("invisible" control points). // Remove control points at the end which do not affect the visual slider path ("invisible" control points).
if (segmentEnds.Length >= 2 && Precision.AlmostEquals(segmentEnds[^1], segmentEnds[^2]) && distinctSegmentEnds.Length > 1) if (segmentEnds.Length >= 2 && Precision.AlmostEquals(segmentEnds[^1], segmentEnds[^2]) && distinctSegmentEnds.Length > 0)
{ {
int numVisibleSegments = distinctSegmentEnds.Length - 2; int numVisibleSegments = distinctSegmentEnds.Length - 1;
var nonInheritedControlPoints = controlPoints.Where(p => p.Type is not null).ToList(); var nonInheritedControlPoints = controlPoints.Where(p => p.Type is not null).ToList();
int lastVisibleControlPointIndex = controlPoints.IndexOf(nonInheritedControlPoints[numVisibleSegments]); int lastVisibleControlPointIndex = controlPoints.IndexOf(nonInheritedControlPoints[numVisibleSegments]);
@ -69,9 +69,9 @@ namespace osu.Game.Rulesets.Objects
inheritedLinearPoints.ForEach(p => p.Type = null); inheritedLinearPoints.ForEach(p => p.Type = null);
// Recalculate perfect curve at the end of the slider path. // Recalculate perfect curve at the end of the slider path.
if (controlPoints.Count >= 3 && controlPoints[^3].Type == PathType.PerfectCurve && controlPoints[^2].Type is null && distinctSegmentEnds.Length > 1) if (controlPoints.Count >= 3 && controlPoints[^3].Type == PathType.PerfectCurve && controlPoints[^2].Type is null && distinctSegmentEnds.Length > 0)
{ {
double lastSegmentStart = distinctSegmentEnds[^2]; double lastSegmentStart = distinctSegmentEnds.Length > 1 ? distinctSegmentEnds[^2] : 0;
double lastSegmentEnd = distinctSegmentEnds[^1]; double lastSegmentEnd = distinctSegmentEnds[^1];
var circleArcPath = new List<Vector2>(); var circleArcPath = new List<Vector2>();
@ -95,7 +95,7 @@ namespace osu.Game.Rulesets.Objects
var result = arr.ToList(); var result = arr.ToList();
while (Precision.AlmostEquals(result[^1], result[^2]) && result.Count > 1) while (result.Count > 1 && Precision.AlmostEquals(result[^1], result[^2]))
result.RemoveAt(result.Count - 1); result.RemoveAt(result.Count - 1);
return result.ToArray(); return result.ToArray();