1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 17:32:54 +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();
return segmentEnds.Select(i => cumulativeLength[Math.Clamp(i, 0, cumulativeLength.Count - 1)] / calculatedLength);
return segmentEnds.Select(i => cumulativeLength[i] / Distance);
}
private void invalidate()
@ -251,8 +251,9 @@ namespace osu.Game.Rulesets.Objects
calculatedPath.Add(t);
}
// Remember the index of the segment end
segmentEnds.Add(calculatedPath.Count - 1);
if (i > 0)
// Remember the index of the segment end
segmentEnds.Add(calculatedPath.Count - 1);
// Start the new segment at the current vertex
start = i;
@ -314,15 +315,11 @@ namespace osu.Game.Rulesets.Objects
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)
{
cumulativeLength.RemoveAt(cumulativeLength.Count - 1);
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]);
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);
// 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();
int lastVisibleControlPointIndex = controlPoints.IndexOf(nonInheritedControlPoints[numVisibleSegments]);
@ -69,9 +69,9 @@ namespace osu.Game.Rulesets.Objects
inheritedLinearPoints.ForEach(p => p.Type = null);
// 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];
var circleArcPath = new List<Vector2>();
@ -95,7 +95,7 @@ namespace osu.Game.Rulesets.Objects
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);
return result.ToArray();