mirror of
https://github.com/ppy/osu.git
synced 2026-05-25 03:49:55 +08:00
Move control point double-up logic to LegacyBeatmapExporter
Done for two reasons: - During review it was requested for the logic to be moved out of `BezierConverter` as `BezierConverter` was intended to produce "lazer style" sliders with per-control-point curve types, as a future usability / code layering concern. - It is also relevant for encode-decode stability. With how the logic was structured between the Bezier converter and the legacy beatmap encoder, the encoder would leave behind per-control-point Bezier curve specs that stable ignored, but subsequent encodes and decodes in lazer would end up multiplying the doubled-up control points ad nauseam. Instead, it is sufficient to only specify the curve type for the head control point as Bezier, not specify any further curve types later on, and instead just keep the double-up-control-point for new implicit segment logic which is enough to make stable cooperate (and also as close to outputting the slider exactly as stable would have produced it as we've ever been)
This commit is contained in:
@@ -120,18 +120,30 @@ namespace osu.Game.Database
|
||||
if (BezierConverter.CountSegments(hasPath.Path.ControlPoints) <= 1
|
||||
&& hasPath.Path.ControlPoints[0].Type!.Value.Degree == null) continue;
|
||||
|
||||
var newControlPoints = BezierConverter.ConvertToModernBezier(hasPath.Path.ControlPoints);
|
||||
|
||||
// Truncate control points to integer positions
|
||||
foreach (var pathControlPoint in newControlPoints)
|
||||
{
|
||||
pathControlPoint.Position = new Vector2(
|
||||
(float)Math.Floor(pathControlPoint.Position.X),
|
||||
(float)Math.Floor(pathControlPoint.Position.Y));
|
||||
}
|
||||
var convertedToBezier = BezierConverter.ConvertToModernBezier(hasPath.Path.ControlPoints);
|
||||
|
||||
hasPath.Path.ControlPoints.Clear();
|
||||
hasPath.Path.ControlPoints.AddRange(newControlPoints);
|
||||
|
||||
for (int i = 0; i < convertedToBezier.Count; i++)
|
||||
{
|
||||
var convertedPoint = convertedToBezier[i];
|
||||
|
||||
// Truncate control points to integer positions
|
||||
var position = new Vector2(
|
||||
(float)Math.Floor(convertedPoint.Position.X),
|
||||
(float)Math.Floor(convertedPoint.Position.Y));
|
||||
|
||||
// stable only supports a single curve type specification per slider.
|
||||
// we exploit the fact that the converted-to-Bézier path only has Bézier segments,
|
||||
// and thus we specify the Bézier curve type once ever at the start of the slider.
|
||||
hasPath.Path.ControlPoints.Add(new PathControlPoint(position, i == 0 ? PathType.BEZIER : null));
|
||||
|
||||
// however, the Bézier path as output by the converter has multiple segments.
|
||||
// `LegacyBeatmapEncoder` will attempt to encode this by emitting per-control-point curve type specs which don't do anything for stable.
|
||||
// instead, stable expects control points that start a segment to be present in the path twice in succession.
|
||||
if (convertedPoint.Type == PathType.BEZIER)
|
||||
hasPath.Path.ControlPoints.Add(new PathControlPoint(position));
|
||||
}
|
||||
}
|
||||
|
||||
// Encode to legacy format
|
||||
|
||||
@@ -136,7 +136,6 @@ namespace osu.Game.Rulesets.Objects
|
||||
{
|
||||
for (int j = 0; j < segment.Length - 1; j++)
|
||||
{
|
||||
if (result.Count > 0 && j == 0) result.Add(new PathControlPoint(segment[j]));
|
||||
result.Add(new PathControlPoint(segment[j], j == 0 ? PathType.BEZIER : null));
|
||||
}
|
||||
}
|
||||
@@ -148,7 +147,6 @@ namespace osu.Game.Rulesets.Objects
|
||||
{
|
||||
for (int j = 0; j < segment.Length - 1; j++)
|
||||
{
|
||||
if (result.Count > 0 && j == 0) result.Add(new PathControlPoint(segment[j]));
|
||||
result.Add(new PathControlPoint(segment[j], j == 0 ? PathType.BEZIER : null));
|
||||
}
|
||||
}
|
||||
@@ -160,7 +158,6 @@ namespace osu.Game.Rulesets.Objects
|
||||
|
||||
for (int j = 0; j < circleResult.Length - 1; j++)
|
||||
{
|
||||
if (result.Count > 0 && j == 0) result.Add(new PathControlPoint(circleResult[j]));
|
||||
result.Add(new PathControlPoint(circleResult[j], j == 0 ? PathType.BEZIER : null));
|
||||
}
|
||||
|
||||
@@ -173,7 +170,6 @@ namespace osu.Game.Rulesets.Objects
|
||||
|
||||
for (int j = 0; j < bSplineResult.Length - 1; j++)
|
||||
{
|
||||
if (result.Count > 0 && j == 0) result.Add(new PathControlPoint(bSplineResult[j]));
|
||||
result.Add(new PathControlPoint(bSplineResult[j], j == 0 ? PathType.BEZIER : null));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user