mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 13:22:55 +08:00
Refactor b-spline path conversion code to better handle linear segments
This commit is contained in:
parent
0a5444d091
commit
e69e78ad41
@ -8,7 +8,6 @@ using System.Diagnostics;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
@ -203,17 +202,44 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
|
|||||||
private void updateSliderPathFromBSplineBuilder()
|
private void updateSliderPathFromBSplineBuilder()
|
||||||
{
|
{
|
||||||
IReadOnlyList<Vector2> builderPoints = bSplineBuilder.ControlPoints;
|
IReadOnlyList<Vector2> builderPoints = bSplineBuilder.ControlPoints;
|
||||||
BindableList<PathControlPoint> sliderPoints = HitObject.Path.ControlPoints;
|
|
||||||
|
|
||||||
sliderPoints.RemoveRange(1, sliderPoints.Count - 1);
|
if (builderPoints.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
// Add the control points from the BSpline builder while converting control points that repeat
|
int lastSegmentStart = 0;
|
||||||
// three or more times to a single PathControlPoint with linear type.
|
PathType? lastPathType = null;
|
||||||
for (int i = 1; i < builderPoints.Count; i++)
|
|
||||||
|
HitObject.Path.ControlPoints.Clear();
|
||||||
|
|
||||||
|
// Iterate through generated points, finding each segment and adding non-inheriting path types where appropriate.
|
||||||
|
// Importantly, the B-Spline builder returns three Vector2s at the same location when a new segment is to be started.
|
||||||
|
for (int i = 0; i < builderPoints.Count; i++)
|
||||||
{
|
{
|
||||||
bool isSharp = i < builderPoints.Count - 2 && builderPoints[i] == builderPoints[i + 1] && builderPoints[i] == builderPoints[i + 2];
|
bool isLastPoint = i == builderPoints.Count - 1;
|
||||||
sliderPoints.Add(new PathControlPoint(builderPoints[i], isSharp ? PathType.BSpline(3) : null));
|
bool isNewSegment = i < builderPoints.Count - 2 && builderPoints[i] == builderPoints[i + 1] && builderPoints[i] == builderPoints[i + 2];
|
||||||
if (isSharp) i += 2;
|
|
||||||
|
if (isNewSegment || isLastPoint)
|
||||||
|
{
|
||||||
|
int pointsInSegment = i - lastSegmentStart;
|
||||||
|
|
||||||
|
// Where possible, we can use the simpler LINEAR path type.
|
||||||
|
PathType? pathType = pointsInSegment == 1 ? PathType.LINEAR : PathType.BSpline(3);
|
||||||
|
|
||||||
|
// Linear segments can be combined, as two adjacent linear sections are computationally the same as one with the points combined.
|
||||||
|
if (lastPathType == pathType && lastPathType == PathType.LINEAR)
|
||||||
|
pathType = null;
|
||||||
|
|
||||||
|
HitObject.Path.ControlPoints.Add(new PathControlPoint(builderPoints[lastSegmentStart], pathType));
|
||||||
|
for (int j = lastSegmentStart + 1; j < i; j++)
|
||||||
|
HitObject.Path.ControlPoints.Add(new PathControlPoint(builderPoints[j]));
|
||||||
|
|
||||||
|
if (isLastPoint)
|
||||||
|
HitObject.Path.ControlPoints.Add(new PathControlPoint(builderPoints[i]));
|
||||||
|
|
||||||
|
// Skip the redundant duplicated points (see isNewSegment above) which have been coalesced into a path type.
|
||||||
|
lastSegmentStart = (i += 2);
|
||||||
|
if (pathType != null) lastPathType = pathType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user