1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-18 00:49:53 +08:00

Merge pull request #35316 from kennyaja/round_control_points

Round slider control points to integer positions (instead of truncating them)
This commit is contained in:
Bartłomiej Dach
2025-10-17 11:46:52 +02:00
committed by GitHub
Unverified
3 changed files with 35 additions and 6 deletions
@@ -59,7 +59,15 @@ namespace osu.Game.Tests.Beatmaps.IO
// Ensure importer encoding is correct
AddStep("import beatmap", () => beatmap = importBeatmapFromArchives(@"fractional-coordinates.olz"));
AddAssert("hit object has fractional position", () => ((IHasYPosition)beatmap.Beatmap.HitObjects[1]).Y, () => Is.EqualTo(383.99997).Within(0.00001));
AddAssert("second slider has fractional position",
() => ((IHasXPosition)beatmap.Beatmap.HitObjects[1]).X,
() => Is.EqualTo(-3.0517578E-05).Within(0.00001));
AddAssert("second slider path has fractional coordinates",
() => ((IHasPath)beatmap.Beatmap.HitObjects[1]).Path.ControlPoints[1].Position.X,
() => Is.EqualTo(191.999939).Within(0.00001));
AddAssert("second hit circle has fractional position",
() => ((IHasYPosition)beatmap.Beatmap.HitObjects[3]).Y,
() => Is.EqualTo(383.99997).Within(0.00001));
// Ensure exporter legacy conversion is correct
AddStep("export", () =>
@@ -71,7 +79,15 @@ namespace osu.Game.Tests.Beatmaps.IO
});
AddStep("import beatmap again", () => beatmap = importBeatmapFromStream(outStream));
AddAssert("hit object is snapped", () => ((IHasYPosition)beatmap.Beatmap.HitObjects[1]).Y, () => Is.EqualTo(384).Within(0.00001));
AddAssert("second slider is snapped",
() => ((IHasXPosition)beatmap.Beatmap.HitObjects[1]).X,
() => Is.EqualTo(0).Within(0.00001));
AddAssert("second slider path is snapped",
() => ((IHasPath)beatmap.Beatmap.HitObjects[1]).Path.ControlPoints[1].Position.X,
() => Is.EqualTo(192).Within(0.00001));
AddAssert("second hit circle is snapped",
() => ((IHasYPosition)beatmap.Beatmap.HitObjects[3]).Y,
() => Is.EqualTo(384).Within(0.00001));
}
[Test]
+17 -4
View File
@@ -132,7 +132,20 @@ namespace osu.Game.Database
hasPath.Path.ControlPoints[^1].Type = null;
if (BezierConverter.CountSegments(hasPath.Path.ControlPoints) <= 1
&& hasPath.Path.ControlPoints[0].Type!.Value.Degree == null) continue;
&& hasPath.Path.ControlPoints[0].Type!.Value.Degree == null)
{
// Round every control point to integer positions before skipping to the next hit object
for (int i = 0; i < hasPath.Path.ControlPoints.Count; i++)
{
var position = new Vector2(
MathF.Round(hasPath.Path.ControlPoints[i].Position.X),
MathF.Round(hasPath.Path.ControlPoints[i].Position.Y));
hasPath.Path.ControlPoints[i].Position = position;
}
continue;
}
var convertedToBezier = BezierConverter.ConvertToModernBezier(hasPath.Path.ControlPoints);
@@ -142,10 +155,10 @@ namespace osu.Game.Database
{
var convertedPoint = convertedToBezier[i];
// Truncate control points to integer positions
// Round control points to integer positions
var position = new Vector2(
(float)Math.Floor(convertedPoint.Position.X),
(float)Math.Floor(convertedPoint.Position.Y));
MathF.Round(convertedPoint.Position.X),
MathF.Round(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,