From 926636cc035a17543d987ba9a9ba9c47fa5e7f7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Mu=CC=88ller-Ho=CC=88hne?= Date: Wed, 8 Nov 2023 19:43:54 +0900 Subject: [PATCH] Generalize Bezier curves to BSplines of Nth degree --- .../TestSceneJuiceStreamSelectionBlueprint.cs | 8 +- .../JuiceStreamPathTest.cs | 4 +- .../Mods/TestSceneCatchModPerfect.cs | 2 +- .../Mods/TestSceneCatchModRelax.cs | 2 +- .../TestSceneAutoJuiceStream.cs | 2 +- .../TestSceneCatchModHidden.cs | 2 +- .../TestSceneDrawableHitObjects.cs | 2 +- .../TestSceneJuiceStream.cs | 2 +- .../Blueprints/Components/EditablePath.cs | 2 +- .../Objects/JuiceStreamPath.cs | 2 +- .../Checks/CheckOffscreenObjectsTest.cs | 12 +-- .../Editor/TestSceneObjectMerging.cs | 10 +-- .../TestSceneOsuEditorSelectInvalidPath.cs | 2 +- .../TestScenePathControlPointVisualiser.cs | 36 ++++----- .../TestSceneSliderControlPointPiece.cs | 28 +++---- .../Editor/TestSceneSliderLengthValidity.cs | 8 +- .../TestSceneSliderPlacementBlueprint.cs | 42 +++++------ .../Editor/TestSceneSliderReversal.cs | 4 +- .../TestSceneSliderSelectionBlueprint.cs | 2 +- .../Editor/TestSceneSliderSnapping.cs | 10 +-- .../Editor/TestSceneSliderSplitting.cs | 28 +++---- .../Editor/TestSliderScaling.cs | 2 +- .../Mods/TestSceneOsuModHidden.cs | 10 +-- .../Mods/TestSceneOsuModPerfect.cs | 2 +- .../OsuHitObjectGenerationUtilsTest.cs | 6 +- .../TestSceneHitCircleLateFade.cs | 2 +- .../TestSceneLegacyHitPolicy.cs | 18 ++--- .../TestSceneSlider.cs | 14 ++-- .../TestSceneSliderApplication.cs | 6 +- .../TestSceneSliderFollowCircleInput.cs | 2 +- .../TestSceneSliderInput.cs | 8 +- .../TestSceneSliderSnaking.cs | 6 +- .../TestSceneStartTimeOrderedHitPolicy.cs | 10 +-- .../Components/PathControlPointPiece.cs | 20 +++-- .../Components/PathControlPointVisualiser.cs | 26 +++---- .../Sliders/SliderPlacementBlueprint.cs | 14 ++-- .../Edit/OsuSelectionHandler.cs | 4 +- osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs | 2 +- .../Formats/LegacyBeatmapDecoderTest.cs | 36 ++++----- .../Formats/LegacyBeatmapEncoderTest.cs | 6 +- .../Editing/LegacyEditorBeatmapPatcherTest.cs | 4 +- .../Editing/TestSceneEditorClipboard.cs | 2 +- .../Editing/TestSceneHitObjectComposer.cs | 2 +- .../Gameplay/TestSceneBezierConverter.cs | 40 +++++----- .../TestSceneGameplaySampleTriggerSource.cs | 2 +- .../Visual/Gameplay/TestSceneSliderPath.cs | 73 +++++++++++-------- .../Beatmaps/Formats/LegacyBeatmapEncoder.cs | 15 ++-- osu.Game/Database/LegacyBeatmapExporter.cs | 4 +- osu.Game/Rulesets/Objects/BezierConverter.cs | 32 ++++---- .../Objects/Legacy/ConvertHitObjectParser.cs | 20 ++--- osu.Game/Rulesets/Objects/SliderPath.cs | 13 ++-- .../Rulesets/Objects/SliderPathExtensions.cs | 6 +- osu.Game/Rulesets/Objects/Types/PathType.cs | 50 ++++++++++++- .../Screens/Play/HUD/ArgonHealthDisplay.cs | 10 +-- 54 files changed, 372 insertions(+), 305 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs index 05d7a38a95..16b51d414a 100644 --- a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs @@ -140,7 +140,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor AddStep("update hit object path", () => { - hitObject.Path = new SliderPath(PathType.PerfectCurve, new[] + hitObject.Path = new SliderPath(PathType.PERFECTCURVE, new[] { Vector2.Zero, new Vector2(100, 100), @@ -190,16 +190,16 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor [Test] public void TestVertexResampling() { - addBlueprintStep(100, 100, new SliderPath(PathType.PerfectCurve, new[] + addBlueprintStep(100, 100, new SliderPath(PathType.PERFECTCURVE, new[] { Vector2.Zero, new Vector2(100, 100), new Vector2(50, 200), }), 0.5); AddAssert("1 vertex per 1 nested HO", () => getVertices().Count == hitObject.NestedHitObjects.Count); - AddAssert("slider path not yet changed", () => hitObject.Path.ControlPoints[0].Type == PathType.PerfectCurve); + AddAssert("slider path not yet changed", () => hitObject.Path.ControlPoints[0].Type == PathType.PERFECTCURVE); addAddVertexSteps(150, 150); - AddAssert("slider path change to linear", () => hitObject.Path.ControlPoints[0].Type == PathType.Linear); + AddAssert("slider path change to linear", () => hitObject.Path.ControlPoints[0].Type == PathType.LINEAR); } private void addBlueprintStep(double time, float x, SliderPath sliderPath, double velocity) => AddStep("add selection blueprint", () => diff --git a/osu.Game.Rulesets.Catch.Tests/JuiceStreamPathTest.cs b/osu.Game.Rulesets.Catch.Tests/JuiceStreamPathTest.cs index 95b4fdc07e..82f24633b5 100644 --- a/osu.Game.Rulesets.Catch.Tests/JuiceStreamPathTest.cs +++ b/osu.Game.Rulesets.Catch.Tests/JuiceStreamPathTest.cs @@ -154,7 +154,7 @@ namespace osu.Game.Rulesets.Catch.Tests } while (rng.Next(2) != 0); int length = sliderPath.ControlPoints.Count - start + 1; - sliderPath.ControlPoints[start].Type = length <= 2 ? PathType.Linear : length == 3 ? PathType.PerfectCurve : PathType.Bezier; + sliderPath.ControlPoints[start].Type = length <= 2 ? PathType.LINEAR : length == 3 ? PathType.PERFECTCURVE : PathType.BEZIER; } while (rng.Next(3) != 0); if (rng.Next(5) == 0) @@ -215,7 +215,7 @@ namespace osu.Game.Rulesets.Catch.Tests foreach (var point in sliderPath.ControlPoints) { - Assert.That(point.Type, Is.EqualTo(PathType.Linear).Or.Null); + Assert.That(point.Type, Is.EqualTo(PathType.LINEAR).Or.Null); Assert.That(sliderStartY + point.Position.Y, Is.InRange(0, JuiceStreamPath.OSU_PLAYFIELD_HEIGHT)); } diff --git a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModPerfect.cs b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModPerfect.cs index 71df523951..45e7d7aa28 100644 --- a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModPerfect.cs +++ b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModPerfect.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Mods var stream = new JuiceStream { StartTime = 1000, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(100, 0), diff --git a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs index 5835ccaf78..a161615579 100644 --- a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs +++ b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs @@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Mods { X = CatchPlayfield.CENTER_X, StartTime = 3000, - Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, Vector2.UnitY * 200 }) + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, Vector2.UnitY * 200 }) } } } diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs index 3261fb656e..202f010680 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Catch.Tests beatmap.HitObjects.Add(new JuiceStream { X = CatchPlayfield.CENTER_X - width / 2, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(width, 0) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModHidden.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModHidden.cs index a44575a46e..419a846ec3 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModHidden.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModHidden.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Catch.Tests new JuiceStream { StartTime = 1000, - Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, new Vector2(0, -192) }), + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(0, -192) }), X = CatchPlayfield.WIDTH / 2 } } diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs index 11d6419507..9c5cd68201 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs @@ -126,7 +126,7 @@ namespace osu.Game.Rulesets.Catch.Tests { X = xCoords, StartTime = playfieldTime + 1000, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(0, 200) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs index c31a7ca99f..9a923adaab 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Catch.Tests new JuiceStream { X = CatchPlayfield.CENTER_X, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(0, 100) diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs index df76bf0a8c..86f92d16ca 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs @@ -74,7 +74,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components path.ConvertFromSliderPath(sliderPath, hitObject.Velocity); // If the original slider path has non-linear type segments, resample the vertices at nested hit object times to reduce the number of vertices. - if (sliderPath.ControlPoints.Any(p => p.Type != null && p.Type != PathType.Linear)) + if (sliderPath.ControlPoints.Any(p => p.Type != null && p.Type != PathType.LINEAR)) { path.ResampleVertices(hitObject.NestedHitObjects .Skip(1).TakeWhile(h => !(h is Fruit)) // Only droplets in the first span are used. diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStreamPath.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStreamPath.cs index 0633151ddd..57acf7cee2 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStreamPath.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStreamPath.cs @@ -236,7 +236,7 @@ namespace osu.Game.Rulesets.Catch.Objects for (int i = 1; i < vertices.Count; i++) { - sliderPath.ControlPoints[^1].Type = PathType.Linear; + sliderPath.ControlPoints[^1].Type = PathType.LINEAR; float deltaX = vertices[i].X - lastPosition.X; double length = (vertices[i].Time - currentTime) * velocity; diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckOffscreenObjectsTest.cs b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckOffscreenObjectsTest.cs index a72aaa966c..8612a8eb57 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckOffscreenObjectsTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckOffscreenObjectsTest.cs @@ -107,7 +107,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks Position = new Vector2(420, 240), Path = new SliderPath(new[] { - new PathControlPoint(new Vector2(0, 0), PathType.Linear), + new PathControlPoint(new Vector2(0, 0), PathType.LINEAR), new PathControlPoint(new Vector2(-100, 0)) }), } @@ -128,7 +128,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks Position = playfield_centre, Path = new SliderPath(new[] { - new PathControlPoint(new Vector2(0, 0), PathType.Linear), + new PathControlPoint(new Vector2(0, 0), PathType.LINEAR), new PathControlPoint(new Vector2(0, -playfield_centre.Y + 5)) }), } @@ -149,7 +149,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks Position = playfield_centre, Path = new SliderPath(new[] { - new PathControlPoint(new Vector2(0, 0), PathType.Linear), + new PathControlPoint(new Vector2(0, 0), PathType.LINEAR), new PathControlPoint(new Vector2(0, -playfield_centre.Y + 5)) }), StackHeight = 5 @@ -171,7 +171,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks Position = new Vector2(0, 0), Path = new SliderPath(new[] { - new PathControlPoint(new Vector2(0, 0), PathType.Linear), + new PathControlPoint(new Vector2(0, 0), PathType.LINEAR), new PathControlPoint(playfield_centre) }), } @@ -192,7 +192,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks Position = playfield_centre, Path = new SliderPath(new[] { - new PathControlPoint(new Vector2(0, 0), PathType.Linear), + new PathControlPoint(new Vector2(0, 0), PathType.LINEAR), new PathControlPoint(-playfield_centre) }), } @@ -214,7 +214,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks Path = new SliderPath(new[] { // Circular arc shoots over the top of the screen. - new PathControlPoint(new Vector2(0, 0), PathType.PerfectCurve), + new PathControlPoint(new Vector2(0, 0), PathType.PERFECTCURVE), new PathControlPoint(new Vector2(-100, -200)), new PathControlPoint(new Vector2(100, -200)) }), diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectMerging.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectMerging.cs index 8d8386cae1..3d35ab79f7 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectMerging.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectMerging.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor mergeSelection(); AddAssert("slider created", () => circle1 is not null && circle2 is not null && sliderCreatedFor( - (pos: circle1.Position, pathType: PathType.Linear), + (pos: circle1.Position, pathType: PathType.LINEAR), (pos: circle2.Position, pathType: null))); AddStep("undo", () => Editor.Undo()); @@ -73,11 +73,11 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor var controlPoints = slider.Path.ControlPoints; (Vector2, PathType?)[] args = new (Vector2, PathType?)[controlPoints.Count + 2]; - args[0] = (circle1.Position, PathType.Linear); + args[0] = (circle1.Position, PathType.LINEAR); for (int i = 0; i < controlPoints.Count; i++) { - args[i + 1] = (controlPoints[i].Position + slider.Position, i == controlPoints.Count - 1 ? PathType.Linear : controlPoints[i].Type); + args[i + 1] = (controlPoints[i].Position + slider.Position, i == controlPoints.Count - 1 ? PathType.LINEAR : controlPoints[i].Type); } args[^1] = (circle2.Position, null); @@ -172,7 +172,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor mergeSelection(); AddAssert("slider created", () => circle1 is not null && circle2 is not null && sliderCreatedFor( - (pos: circle1.Position, pathType: PathType.Linear), + (pos: circle1.Position, pathType: PathType.LINEAR), (pos: circle2.Position, pathType: null))); AddAssert("samples exist", sliderSampleExist); @@ -227,7 +227,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor mergeSelection(); AddAssert("slider created", () => circle1 is not null && circle2 is not null && sliderCreatedFor( - (pos: circle1.Position, pathType: PathType.Linear), + (pos: circle1.Position, pathType: PathType.LINEAR), (pos: circle2.Position, pathType: null))); } diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorSelectInvalidPath.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorSelectInvalidPath.cs index 37a109de18..7ea4d40b90 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorSelectInvalidPath.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorSelectInvalidPath.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor PathControlPoint[] points = { - new PathControlPoint(new Vector2(0), PathType.PerfectCurve), + new PathControlPoint(new Vector2(0), PathType.PERFECTCURVE), new PathControlPoint(new Vector2(-100, 0)), new PathControlPoint(new Vector2(100, 20)) }; diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestScenePathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestScenePathControlPointVisualiser.cs index c267cd1f63..16800997f4 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestScenePathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestScenePathControlPointVisualiser.cs @@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor { createVisualiser(true); - addControlPointStep(new Vector2(200), PathType.Bezier); + addControlPointStep(new Vector2(200), PathType.BEZIER); addControlPointStep(new Vector2(300)); addControlPointStep(new Vector2(500, 300)); addControlPointStep(new Vector2(700, 200)); @@ -63,9 +63,9 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddStep("select control point", () => visualiser.Pieces[1].IsSelected.Value = true); addContextMenuItemStep("Perfect curve"); - assertControlPointPathType(0, PathType.Bezier); - assertControlPointPathType(1, PathType.PerfectCurve); - assertControlPointPathType(3, PathType.Bezier); + assertControlPointPathType(0, PathType.BEZIER); + assertControlPointPathType(1, PathType.PERFECTCURVE); + assertControlPointPathType(3, PathType.BEZIER); } [Test] @@ -73,7 +73,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor { createVisualiser(true); - addControlPointStep(new Vector2(200), PathType.Bezier); + addControlPointStep(new Vector2(200), PathType.BEZIER); addControlPointStep(new Vector2(300)); addControlPointStep(new Vector2(500, 300)); addControlPointStep(new Vector2(700, 200)); @@ -83,8 +83,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddStep("select control point", () => visualiser.Pieces[2].IsSelected.Value = true); addContextMenuItemStep("Perfect curve"); - assertControlPointPathType(0, PathType.Bezier); - assertControlPointPathType(2, PathType.PerfectCurve); + assertControlPointPathType(0, PathType.BEZIER); + assertControlPointPathType(2, PathType.PERFECTCURVE); assertControlPointPathType(4, null); } @@ -93,7 +93,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor { createVisualiser(true); - addControlPointStep(new Vector2(200), PathType.Bezier); + addControlPointStep(new Vector2(200), PathType.BEZIER); addControlPointStep(new Vector2(300)); addControlPointStep(new Vector2(500, 300)); addControlPointStep(new Vector2(700, 200)); @@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddStep("select control point", () => visualiser.Pieces[3].IsSelected.Value = true); addContextMenuItemStep("Perfect curve"); - assertControlPointPathType(0, PathType.Bezier); + assertControlPointPathType(0, PathType.BEZIER); AddAssert("point 3 is not inherited", () => slider.Path.ControlPoints[3].Type != null); } @@ -112,7 +112,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor { createVisualiser(true); - addControlPointStep(new Vector2(200), PathType.Linear); + addControlPointStep(new Vector2(200), PathType.LINEAR); addControlPointStep(new Vector2(300)); addControlPointStep(new Vector2(500, 300)); addControlPointStep(new Vector2(700, 200)); @@ -123,9 +123,9 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddStep("select control point", () => visualiser.Pieces[1].IsSelected.Value = true); addContextMenuItemStep("Perfect curve"); - assertControlPointPathType(0, PathType.Linear); - assertControlPointPathType(1, PathType.PerfectCurve); - assertControlPointPathType(3, PathType.Linear); + assertControlPointPathType(0, PathType.LINEAR); + assertControlPointPathType(1, PathType.PERFECTCURVE); + assertControlPointPathType(3, PathType.LINEAR); } [Test] @@ -133,18 +133,18 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor { createVisualiser(true); - addControlPointStep(new Vector2(200), PathType.Bezier); - addControlPointStep(new Vector2(300), PathType.PerfectCurve); + addControlPointStep(new Vector2(200), PathType.BEZIER); + addControlPointStep(new Vector2(300), PathType.PERFECTCURVE); addControlPointStep(new Vector2(500, 300)); - addControlPointStep(new Vector2(700, 200), PathType.Bezier); + addControlPointStep(new Vector2(700, 200), PathType.BEZIER); addControlPointStep(new Vector2(500, 100)); moveMouseToControlPoint(3); AddStep("select control point", () => visualiser.Pieces[3].IsSelected.Value = true); addContextMenuItemStep("Inherit"); - assertControlPointPathType(0, PathType.Bezier); - assertControlPointPathType(1, PathType.Bezier); + assertControlPointPathType(0, PathType.BEZIER); + assertControlPointPathType(1, PathType.BEZIER); assertControlPointPathType(3, null); } diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderControlPointPiece.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderControlPointPiece.cs index 408205d6b2..1d8d2cf01a 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderControlPointPiece.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderControlPointPiece.cs @@ -38,9 +38,9 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor Position = new Vector2(256, 192), Path = new SliderPath(new[] { - new PathControlPoint(Vector2.Zero, PathType.PerfectCurve), + new PathControlPoint(Vector2.Zero, PathType.PERFECTCURVE), new PathControlPoint(new Vector2(150, 150)), - new PathControlPoint(new Vector2(300, 0), PathType.PerfectCurve), + new PathControlPoint(new Vector2(300, 0), PathType.PERFECTCURVE), new PathControlPoint(new Vector2(400, 0)), new PathControlPoint(new Vector2(400, 150)) }) @@ -182,7 +182,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddStep("release", () => InputManager.ReleaseButton(MouseButton.Left)); assertControlPointPosition(1, new Vector2(150, 50)); - assertControlPointType(0, PathType.PerfectCurve); + assertControlPointType(0, PathType.PERFECTCURVE); } [Test] @@ -210,7 +210,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddAssert("three control point pieces selected", () => this.ChildrenOfType>().Count(piece => piece.IsSelected.Value) == 3); assertControlPointPosition(2, new Vector2(450, 50)); - assertControlPointType(2, PathType.PerfectCurve); + assertControlPointType(2, PathType.PERFECTCURVE); assertControlPointPosition(3, new Vector2(550, 50)); @@ -249,7 +249,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddAssert("slider moved", () => Precision.AlmostEquals(slider.Position, new Vector2(256, 192) + new Vector2(150, 50))); assertControlPointPosition(0, Vector2.Zero); - assertControlPointType(0, PathType.PerfectCurve); + assertControlPointType(0, PathType.PERFECTCURVE); assertControlPointPosition(1, new Vector2(0, 100)); @@ -272,7 +272,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddStep("release", () => InputManager.ReleaseButton(MouseButton.Left)); assertControlPointPosition(1, new Vector2(400, 0.01f)); - assertControlPointType(0, PathType.Bezier); + assertControlPointType(0, PathType.BEZIER); } [Test] @@ -282,13 +282,13 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddStep("hold", () => InputManager.PressButton(MouseButton.Left)); addMovementStep(new Vector2(400, 0.01f)); - assertControlPointType(0, PathType.Bezier); + assertControlPointType(0, PathType.BEZIER); addMovementStep(new Vector2(150, 50)); AddStep("release", () => InputManager.ReleaseButton(MouseButton.Left)); assertControlPointPosition(1, new Vector2(150, 50)); - assertControlPointType(0, PathType.PerfectCurve); + assertControlPointType(0, PathType.PERFECTCURVE); } [Test] @@ -298,32 +298,32 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddStep("hold", () => InputManager.PressButton(MouseButton.Left)); addMovementStep(new Vector2(350, 0.01f)); - assertControlPointType(2, PathType.Bezier); + assertControlPointType(2, PathType.BEZIER); addMovementStep(new Vector2(150, 150)); AddStep("release", () => InputManager.ReleaseButton(MouseButton.Left)); assertControlPointPosition(4, new Vector2(150, 150)); - assertControlPointType(2, PathType.PerfectCurve); + assertControlPointType(2, PathType.PERFECTCURVE); } [Test] public void TestDragControlPointPathAfterChangingType() { - AddStep("change type to bezier", () => slider.Path.ControlPoints[2].Type = PathType.Bezier); + AddStep("change type to bezier", () => slider.Path.ControlPoints[2].Type = PathType.BEZIER); AddStep("add point", () => slider.Path.ControlPoints.Add(new PathControlPoint(new Vector2(500, 10)))); - AddStep("change type to perfect", () => slider.Path.ControlPoints[3].Type = PathType.PerfectCurve); + AddStep("change type to perfect", () => slider.Path.ControlPoints[3].Type = PathType.PERFECTCURVE); moveMouseToControlPoint(4); AddStep("hold", () => InputManager.PressButton(MouseButton.Left)); - assertControlPointType(3, PathType.PerfectCurve); + assertControlPointType(3, PathType.PERFECTCURVE); addMovementStep(new Vector2(350, 0.01f)); AddStep("release", () => InputManager.ReleaseButton(MouseButton.Left)); assertControlPointPosition(4, new Vector2(350, 0.01f)); - assertControlPointType(3, PathType.Bezier); + assertControlPointType(3, PathType.BEZIER); } private void addMovementStep(Vector2 relativePosition) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderLengthValidity.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderLengthValidity.cs index 77e828e80a..38ebeb7e8f 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderLengthValidity.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderLengthValidity.cs @@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor PathControlPoint[] points = { - new PathControlPoint(new Vector2(0), PathType.Linear), + new PathControlPoint(new Vector2(0), PathType.LINEAR), new PathControlPoint(new Vector2(100, 0)), }; @@ -82,7 +82,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor PathControlPoint[] points = { - new PathControlPoint(new Vector2(0), PathType.Linear), + new PathControlPoint(new Vector2(0), PathType.LINEAR), new PathControlPoint(new Vector2(100, 0)), }; @@ -126,7 +126,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor PathControlPoint[] points = { - new PathControlPoint(new Vector2(0), PathType.PerfectCurve), + new PathControlPoint(new Vector2(0), PathType.PERFECTCURVE), new PathControlPoint(new Vector2(100, 0)), new PathControlPoint(new Vector2(0, 10)) }; @@ -165,7 +165,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor PathControlPoint[] points = { - new PathControlPoint(new Vector2(0), PathType.Linear), + new PathControlPoint(new Vector2(0), PathType.LINEAR), new PathControlPoint(new Vector2(0, 50)), new PathControlPoint(new Vector2(0, 100)) }; diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderPlacementBlueprint.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderPlacementBlueprint.cs index 7d29670daa..4b120c1a3f 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderPlacementBlueprint.cs @@ -58,7 +58,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor assertPlaced(true); assertLength(200); assertControlPointCount(2); - assertControlPointType(0, PathType.Linear); + assertControlPointType(0, PathType.LINEAR); } [Test] @@ -72,7 +72,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor assertPlaced(true); assertControlPointCount(2); - assertControlPointType(0, PathType.Linear); + assertControlPointType(0, PathType.LINEAR); } [Test] @@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor assertPlaced(true); assertControlPointCount(3); assertControlPointPosition(1, new Vector2(100, 0)); - assertControlPointType(0, PathType.PerfectCurve); + assertControlPointType(0, PathType.PERFECTCURVE); } [Test] @@ -112,7 +112,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor assertControlPointCount(4); assertControlPointPosition(1, new Vector2(100, 0)); assertControlPointPosition(2, new Vector2(100, 100)); - assertControlPointType(0, PathType.Bezier); + assertControlPointType(0, PathType.BEZIER); } [Test] @@ -131,8 +131,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor assertPlaced(true); assertControlPointCount(3); assertControlPointPosition(1, new Vector2(100, 0)); - assertControlPointType(0, PathType.Linear); - assertControlPointType(1, PathType.Linear); + assertControlPointType(0, PathType.LINEAR); + assertControlPointType(1, PathType.LINEAR); } [Test] @@ -150,7 +150,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor assertPlaced(true); assertControlPointCount(2); - assertControlPointType(0, PathType.Linear); + assertControlPointType(0, PathType.LINEAR); assertLength(100); } @@ -172,7 +172,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor assertPlaced(true); assertControlPointCount(3); - assertControlPointType(0, PathType.PerfectCurve); + assertControlPointType(0, PathType.PERFECTCURVE); } [Test] @@ -196,7 +196,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor assertPlaced(true); assertControlPointCount(4); - assertControlPointType(0, PathType.Bezier); + assertControlPointType(0, PathType.BEZIER); } [Test] @@ -216,8 +216,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor assertControlPointCount(3); assertControlPointPosition(1, new Vector2(100, 0)); assertControlPointPosition(2, new Vector2(100)); - assertControlPointType(0, PathType.Linear); - assertControlPointType(1, PathType.Linear); + assertControlPointType(0, PathType.LINEAR); + assertControlPointType(1, PathType.LINEAR); } [Test] @@ -240,8 +240,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor assertControlPointCount(4); assertControlPointPosition(1, new Vector2(100, 0)); assertControlPointPosition(2, new Vector2(100)); - assertControlPointType(0, PathType.Linear); - assertControlPointType(1, PathType.PerfectCurve); + assertControlPointType(0, PathType.LINEAR); + assertControlPointType(1, PathType.PERFECTCURVE); } [Test] @@ -269,8 +269,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor assertControlPointPosition(2, new Vector2(100)); assertControlPointPosition(3, new Vector2(200, 100)); assertControlPointPosition(4, new Vector2(200)); - assertControlPointType(0, PathType.PerfectCurve); - assertControlPointType(2, PathType.PerfectCurve); + assertControlPointType(0, PathType.PERFECTCURVE); + assertControlPointType(2, PathType.PERFECTCURVE); } [Test] @@ -287,7 +287,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor assertPlaced(true); assertLength(200); assertControlPointCount(2); - assertControlPointType(0, PathType.Linear); + assertControlPointType(0, PathType.LINEAR); } [Test] @@ -306,7 +306,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor assertPlaced(true); assertControlPointCount(3); - assertControlPointType(0, PathType.Bezier); + assertControlPointType(0, PathType.BEZIER); } [Test] @@ -326,7 +326,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor assertPlaced(true); assertControlPointCount(3); - assertControlPointType(0, PathType.PerfectCurve); + assertControlPointType(0, PathType.PERFECTCURVE); } [Test] @@ -347,7 +347,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor assertPlaced(true); assertControlPointCount(3); - assertControlPointType(0, PathType.PerfectCurve); + assertControlPointType(0, PathType.PERFECTCURVE); } [Test] @@ -368,7 +368,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor assertPlaced(true); assertControlPointCount(3); - assertControlPointType(0, PathType.Bezier); + assertControlPointType(0, PathType.BEZIER); } [Test] @@ -385,7 +385,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor assertPlaced(true); assertControlPointCount(3); - assertControlPointType(0, PathType.PerfectCurve); + assertControlPointType(0, PathType.PERFECTCURVE); } private void addMovementStep(Vector2 position) => AddStep($"move mouse to {position}", () => InputManager.MoveMouseTo(InputManager.ToScreenSpace(position))); diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderReversal.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderReversal.cs index 9c5eb83e3c..0ddfc40946 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderReversal.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderReversal.cs @@ -22,12 +22,12 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor private readonly PathControlPoint[][] paths = { createPathSegment( - PathType.PerfectCurve, + PathType.PERFECTCURVE, new Vector2(200, -50), new Vector2(250, 0) ), createPathSegment( - PathType.Linear, + PathType.LINEAR, new Vector2(100, 0), new Vector2(100, 100) ) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSelectionBlueprint.cs index 413a3c3dfd..d4d99e1019 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSelectionBlueprint.cs @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor slider = new Slider { Position = new Vector2(256, 192), - Path = new SliderPath(PathType.Bezier, new[] + Path = new SliderPath(PathType.BEZIER, new[] { Vector2.Zero, new Vector2(150, 150), diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs index 0ae14bdde8..c984d9168e 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs @@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor { ControlPoints = { - new PathControlPoint(Vector2.Zero, PathType.PerfectCurve), + new PathControlPoint(Vector2.Zero, PathType.PERFECTCURVE), new PathControlPoint(new Vector2(136, 205)), new PathControlPoint(new Vector2(-4, 226)) } @@ -181,7 +181,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor { OsuSelectionHandler selectionHandler; - AddAssert("first control point perfect", () => slider.Path.ControlPoints[0].Type == PathType.PerfectCurve); + AddAssert("first control point perfect", () => slider.Path.ControlPoints[0].Type == PathType.PERFECTCURVE); AddStep("select slider", () => EditorBeatmap.SelectedHitObjects.Add(slider)); AddStep("rotate 90 degrees ccw", () => @@ -190,7 +190,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor selectionHandler.HandleRotation(-90); }); - AddAssert("first control point still perfect", () => slider.Path.ControlPoints[0].Type == PathType.PerfectCurve); + AddAssert("first control point still perfect", () => slider.Path.ControlPoints[0].Type == PathType.PERFECTCURVE); } [Test] @@ -223,7 +223,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor { OsuSelectionHandler selectionHandler; - AddAssert("first control point perfect", () => slider.Path.ControlPoints[0].Type == PathType.PerfectCurve); + AddAssert("first control point perfect", () => slider.Path.ControlPoints[0].Type == PathType.PERFECTCURVE); AddStep("select slider", () => EditorBeatmap.SelectedHitObjects.Add(slider)); AddStep("flip slider horizontally", () => @@ -232,7 +232,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor selectionHandler.OnPressed(new KeyBindingPressEvent(InputManager.CurrentState, GlobalAction.EditorFlipVertically)); }); - AddAssert("first control point still perfect", () => slider.Path.ControlPoints[0].Type == PathType.PerfectCurve); + AddAssert("first control point still perfect", () => slider.Path.ControlPoints[0].Type == PathType.PERFECTCURVE); } [Test] diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSplitting.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSplitting.cs index ad37258c9b..cded9165f4 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSplitting.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSplitting.cs @@ -45,9 +45,9 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor Position = new Vector2(0, 50), Path = new SliderPath(new[] { - new PathControlPoint(Vector2.Zero, PathType.PerfectCurve), + new PathControlPoint(Vector2.Zero, PathType.PERFECTCURVE), new PathControlPoint(new Vector2(150, 150)), - new PathControlPoint(new Vector2(300, 0), PathType.PerfectCurve), + new PathControlPoint(new Vector2(300, 0), PathType.PERFECTCURVE), new PathControlPoint(new Vector2(400, 0)), new PathControlPoint(new Vector2(400, 150)) }) @@ -73,20 +73,20 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddAssert("slider split", () => slider is not null && EditorBeatmap.HitObjects.Count == 2 && sliderCreatedFor((Slider)EditorBeatmap.HitObjects[0], 0, EditorBeatmap.HitObjects[1].StartTime - split_gap, - (new Vector2(0, 50), PathType.PerfectCurve), + (new Vector2(0, 50), PathType.PERFECTCURVE), (new Vector2(150, 200), null), (new Vector2(300, 50), null) ) && sliderCreatedFor((Slider)EditorBeatmap.HitObjects[1], slider.StartTime, endTime + split_gap, - (new Vector2(300, 50), PathType.PerfectCurve), + (new Vector2(300, 50), PathType.PERFECTCURVE), (new Vector2(400, 50), null), (new Vector2(400, 200), null) )); AddStep("undo", () => Editor.Undo()); AddAssert("original slider restored", () => EditorBeatmap.HitObjects.Count == 1 && sliderCreatedFor((Slider)EditorBeatmap.HitObjects[0], 0, endTime, - (new Vector2(0, 50), PathType.PerfectCurve), + (new Vector2(0, 50), PathType.PERFECTCURVE), (new Vector2(150, 200), null), - (new Vector2(300, 50), PathType.PerfectCurve), + (new Vector2(300, 50), PathType.PERFECTCURVE), (new Vector2(400, 50), null), (new Vector2(400, 200), null) )); @@ -104,11 +104,11 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor Position = new Vector2(0, 50), Path = new SliderPath(new[] { - new PathControlPoint(Vector2.Zero, PathType.PerfectCurve), + new PathControlPoint(Vector2.Zero, PathType.PERFECTCURVE), new PathControlPoint(new Vector2(150, 150)), - new PathControlPoint(new Vector2(300, 0), PathType.Bezier), + new PathControlPoint(new Vector2(300, 0), PathType.BEZIER), new PathControlPoint(new Vector2(400, 0)), - new PathControlPoint(new Vector2(400, 150), PathType.Catmull), + new PathControlPoint(new Vector2(400, 150), PathType.CATMULL), new PathControlPoint(new Vector2(300, 200)), new PathControlPoint(new Vector2(400, 250)) }) @@ -139,15 +139,15 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddAssert("slider split", () => slider is not null && EditorBeatmap.HitObjects.Count == 3 && sliderCreatedFor((Slider)EditorBeatmap.HitObjects[0], 0, EditorBeatmap.HitObjects[1].StartTime - split_gap, - (new Vector2(0, 50), PathType.PerfectCurve), + (new Vector2(0, 50), PathType.PERFECTCURVE), (new Vector2(150, 200), null), (new Vector2(300, 50), null) ) && sliderCreatedFor((Slider)EditorBeatmap.HitObjects[1], EditorBeatmap.HitObjects[0].GetEndTime() + split_gap, slider.StartTime - split_gap, - (new Vector2(300, 50), PathType.Bezier), + (new Vector2(300, 50), PathType.BEZIER), (new Vector2(400, 50), null), (new Vector2(400, 200), null) ) && sliderCreatedFor((Slider)EditorBeatmap.HitObjects[2], EditorBeatmap.HitObjects[1].GetEndTime() + split_gap, endTime + split_gap * 2, - (new Vector2(400, 200), PathType.Catmull), + (new Vector2(400, 200), PathType.CATMULL), (new Vector2(300, 250), null), (new Vector2(400, 300), null) )); @@ -165,9 +165,9 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor Position = new Vector2(0, 50), Path = new SliderPath(new[] { - new PathControlPoint(Vector2.Zero, PathType.PerfectCurve), + new PathControlPoint(Vector2.Zero, PathType.PERFECTCURVE), new PathControlPoint(new Vector2(150, 150)), - new PathControlPoint(new Vector2(300, 0), PathType.PerfectCurve), + new PathControlPoint(new Vector2(300, 0), PathType.PERFECTCURVE), new PathControlPoint(new Vector2(400, 0)), new PathControlPoint(new Vector2(400, 150)) }) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSliderScaling.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSliderScaling.cs index 64d23090d0..021fdba225 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSliderScaling.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSliderScaling.cs @@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor PathControlPoint[] points = { - new PathControlPoint(new Vector2(0), PathType.Linear), + new PathControlPoint(new Vector2(0), PathType.LINEAR), new PathControlPoint(new Vector2(100, 0)), }; diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModHidden.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModHidden.cs index 3f84ac6935..58bdd805c1 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModHidden.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModHidden.cs @@ -81,12 +81,12 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods new Slider { StartTime = 3200, - Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, new Vector2(100, 0), }) + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(100, 0), }) }, new Slider { StartTime = 5200, - Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, new Vector2(100, 0), }) + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(100, 0), }) } } }, @@ -105,12 +105,12 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods new Slider { StartTime = 1000, - Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, new Vector2(100, 0), }) + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(100, 0), }) }, new Slider { StartTime = 4000, - Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, new Vector2(100, 0), }) + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(100, 0), }) }, } }, @@ -140,7 +140,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods { StartTime = 3000, Position = new Vector2(156, 242), - Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, new Vector2(200, 0), }) + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(200, 0), }) }, new Spinner { diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModPerfect.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModPerfect.cs index f0496efc19..26c4133bc4 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModPerfect.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModPerfect.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods var slider = new Slider { StartTime = 1000, - Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, new Vector2(100, 0), }) + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(100, 0), }) }; CreateHitObjectTest(new HitObjectTestData(slider), shouldMiss); diff --git a/osu.Game.Rulesets.Osu.Tests/OsuHitObjectGenerationUtilsTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuHitObjectGenerationUtilsTest.cs index daa914cac2..d78c32aa6a 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuHitObjectGenerationUtilsTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuHitObjectGenerationUtilsTest.cs @@ -26,9 +26,9 @@ namespace osu.Game.Rulesets.Osu.Tests { ControlPoints = { - new PathControlPoint(new Vector2(), PathType.Linear), - new PathControlPoint(new Vector2(-64, -128), PathType.Linear), // absolute position: (64, 0) - new PathControlPoint(new Vector2(-128, 0), PathType.Linear) // absolute position: (0, 128) + new PathControlPoint(new Vector2(), PathType.LINEAR), + new PathControlPoint(new Vector2(-64, -128), PathType.LINEAR), // absolute position: (64, 0) + new PathControlPoint(new Vector2(-128, 0), PathType.LINEAR) // absolute position: (0, 128) } }, RepeatCount = 1 diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleLateFade.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleLateFade.cs index 483155e646..7824f26251 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleLateFade.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleLateFade.cs @@ -167,7 +167,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = Time.Current + 500, Position = new Vector2(250), - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(0, 100), diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyHitPolicy.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyHitPolicy.cs index fa6aa580a3..e460da9bd5 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyHitPolicy.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyHitPolicy.cs @@ -264,7 +264,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = time_slider, Position = positionSlider, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(50, 0), @@ -308,7 +308,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = time_slider, Position = positionSlider, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(50, 0), @@ -391,7 +391,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = time_slider, Position = positionSlider, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(25, 0), @@ -428,7 +428,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = time_first_slider, Position = positionFirstSlider, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(25, 0), @@ -438,7 +438,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = time_second_slider, Position = positionSecondSlider, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(25, 0), @@ -521,7 +521,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = time_first_slider, Position = positionFirstSlider, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(25, 0), @@ -531,7 +531,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = time_second_slider, Position = positionSecondSlider, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(25, 0), @@ -571,7 +571,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = time_first_slider, Position = positionFirstSlider, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(25, 0), @@ -581,7 +581,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = time_second_slider, Position = positionSecondSlider, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(25, 0), diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs index b805e7ed63..60003e7950 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs @@ -219,7 +219,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = Time.Current + time_offset, Position = new Vector2(239, 176), - Path = new SliderPath(PathType.PerfectCurve, new[] + Path = new SliderPath(PathType.PERFECTCURVE, new[] { Vector2.Zero, new Vector2(154, 28), @@ -255,7 +255,7 @@ namespace osu.Game.Rulesets.Osu.Tests SliderVelocityMultiplier = speedMultiplier, StartTime = Time.Current + time_offset, Position = new Vector2(0, -(distance / 2)), - Path = new SliderPath(PathType.PerfectCurve, new[] + Path = new SliderPath(PathType.PERFECTCURVE, new[] { Vector2.Zero, new Vector2(0, distance), @@ -273,7 +273,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = Time.Current + time_offset, Position = new Vector2(-max_length / 2, 0), - Path = new SliderPath(PathType.PerfectCurve, new[] + Path = new SliderPath(PathType.PERFECTCURVE, new[] { Vector2.Zero, new Vector2(max_length / 2, max_length / 2), @@ -293,7 +293,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = Time.Current + time_offset, Position = new Vector2(-max_length / 2, 0), - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(max_length * 0.375f, max_length * 0.18f), @@ -316,7 +316,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = Time.Current + time_offset, Position = new Vector2(-max_length / 2, 0), - Path = new SliderPath(PathType.Bezier, new[] + Path = new SliderPath(PathType.BEZIER, new[] { Vector2.Zero, new Vector2(max_length * 0.375f, max_length * 0.18f), @@ -338,7 +338,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = Time.Current + time_offset, Position = new Vector2(0, 0), - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(-max_length / 2, 0), @@ -365,7 +365,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = Time.Current + time_offset, Position = new Vector2(-max_length / 4, 0), - Path = new SliderPath(PathType.Catmull, new[] + Path = new SliderPath(PathType.CATMULL, new[] { Vector2.Zero, new Vector2(max_length * 0.125f, max_length * 0.125f), diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderApplication.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderApplication.cs index 88b70a8836..f41dd913ab 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderApplication.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderApplication.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Osu.Tests Position = new Vector2(256, 192), IndexInCurrentCombo = 0, StartTime = Time.Current, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(150, 100), @@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Osu.Tests Position = new Vector2(256, 192), ComboIndex = 1, StartTime = dho.HitObject.StartTime, - Path = new SliderPath(PathType.Bezier, new[] + Path = new SliderPath(PathType.BEZIER, new[] { Vector2.Zero, new Vector2(150, 100), @@ -80,7 +80,7 @@ namespace osu.Game.Rulesets.Osu.Tests Position = new Vector2(256, 192), IndexInCurrentCombo = 0, StartTime = Time.Current, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(150, 100), diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs index d4bb789a12..fc9bb16cb7 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Osu.Tests StartTime = time_slider_start, Position = new Vector2(0, 0), SliderVelocityMultiplier = velocity, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(followCircleRadius, 0), diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index f718a5069f..08836ef819 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -62,7 +62,7 @@ namespace osu.Game.Rulesets.Osu.Tests Position = new Vector2(0, 0), SliderVelocityMultiplier = 10f, RepeatCount = repeatCount, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(sliderLength, 0), @@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Osu.Tests Position = new Vector2(0, 0), SliderVelocityMultiplier = 10f, RepeatCount = repeatCount, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(sliderLength, 0), @@ -145,7 +145,7 @@ namespace osu.Game.Rulesets.Osu.Tests StartTime = time_slider_start, Position = new Vector2(0, 0), SliderVelocityMultiplier = 10f, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(slider_path_length * 10, 0), @@ -478,7 +478,7 @@ namespace osu.Game.Rulesets.Osu.Tests StartTime = time_slider_start, Position = new Vector2(0, 0), SliderVelocityMultiplier = 0.1f, - Path = new SliderPath(PathType.PerfectCurve, new[] + Path = new SliderPath(PathType.PERFECTCURVE, new[] { Vector2.Zero, new Vector2(slider_path_length, 0), diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs index 13166c2b6b..ebc5143aed 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs @@ -217,7 +217,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = 3000, Position = new Vector2(100, 100), - Path = new SliderPath(PathType.PerfectCurve, new[] + Path = new SliderPath(PathType.PERFECTCURVE, new[] { Vector2.Zero, new Vector2(300, 200) @@ -227,7 +227,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = 13000, Position = new Vector2(100, 100), - Path = new SliderPath(PathType.PerfectCurve, new[] + Path = new SliderPath(PathType.PERFECTCURVE, new[] { Vector2.Zero, new Vector2(300, 200) @@ -238,7 +238,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = 23000, Position = new Vector2(100, 100), - Path = new SliderPath(PathType.PerfectCurve, new[] + Path = new SliderPath(PathType.PERFECTCURVE, new[] { Vector2.Zero, new Vector2(300, 200) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs index 3475680c71..895e9bbdee 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs @@ -196,7 +196,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = time_slider, Position = positionSlider, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(25, 0), @@ -238,7 +238,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = time_slider, Position = positionSlider, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(25, 0), @@ -318,7 +318,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = time_slider, Position = positionSlider, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(25, 0), @@ -352,7 +352,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = time_first_slider, Position = positionFirstSlider, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(25, 0), @@ -362,7 +362,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = time_second_slider, Position = positionSecondSlider, - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(25, 0), diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs index 12e5ca0236..9658e5f6c3 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs @@ -221,11 +221,11 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components /// private void updatePathType() { - if (ControlPoint.Type != PathType.PerfectCurve) + if (ControlPoint.Type != PathType.PERFECTCURVE) return; if (PointsInSegment.Count > 3) - ControlPoint.Type = PathType.Bezier; + ControlPoint.Type = PathType.BEZIER; if (PointsInSegment.Count != 3) return; @@ -233,7 +233,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components ReadOnlySpan points = PointsInSegment.Select(p => p.Position).ToArray(); RectangleF boundingBox = PathApproximator.CircularArcBoundingBox(points); if (boundingBox.Width >= 640 || boundingBox.Height >= 480) - ControlPoint.Type = PathType.Bezier; + ControlPoint.Type = PathType.BEZIER; } /// @@ -256,18 +256,22 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components private Color4 getColourFromNodeType() { - if (!(ControlPoint.Type is PathType pathType)) + if (ControlPoint.Type is not PathType pathType) return colours.Yellow; switch (pathType) { - case PathType.Catmull: + case { SplineType: SplineType.Catmull }: return colours.SeaFoam; - case PathType.Bezier: - return colours.Pink; + case { SplineType: SplineType.BSpline, Degree: null }: + return colours.PinkLighter; - case PathType.PerfectCurve: + case { SplineType: SplineType.BSpline, Degree: >= 1 }: + int idx = Math.Clamp(pathType.Degree.Value, 0, 3); + return new[] { colours.PinkDarker, colours.PinkDark, colours.Pink, colours.PinkLight }[idx]; + + case { SplineType: SplineType.PerfectCurve }: return colours.PurpleDark; default: diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs index f891d23bbd..b5c9016538 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs @@ -242,18 +242,15 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { int indexInSegment = piece.PointsInSegment.IndexOf(piece.ControlPoint); - switch (type) + if (type.HasValue && type.Value.SplineType == SplineType.PerfectCurve) { - case PathType.PerfectCurve: - // Can't always create a circular arc out of 4 or more points, - // so we split the segment into one 3-point circular arc segment - // and one segment of the previous type. - int thirdPointIndex = indexInSegment + 2; + // Can't always create a circular arc out of 4 or more points, + // so we split the segment into one 3-point circular arc segment + // and one segment of the previous type. + int thirdPointIndex = indexInSegment + 2; - if (piece.PointsInSegment.Count > thirdPointIndex + 1) - piece.PointsInSegment[thirdPointIndex].Type = piece.PointsInSegment[0].Type; - - break; + if (piece.PointsInSegment.Count > thirdPointIndex + 1) + piece.PointsInSegment[thirdPointIndex].Type = piece.PointsInSegment[0].Type; } hitObject.Path.ExpectedDistance.Value = null; @@ -370,10 +367,11 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components curveTypeItems.Add(createMenuItemForPathType(null)); // todo: hide/disable items which aren't valid for selected points - curveTypeItems.Add(createMenuItemForPathType(PathType.Linear)); - curveTypeItems.Add(createMenuItemForPathType(PathType.PerfectCurve)); - curveTypeItems.Add(createMenuItemForPathType(PathType.Bezier)); - curveTypeItems.Add(createMenuItemForPathType(PathType.Catmull)); + curveTypeItems.Add(createMenuItemForPathType(PathType.LINEAR)); + curveTypeItems.Add(createMenuItemForPathType(PathType.PERFECTCURVE)); + curveTypeItems.Add(createMenuItemForPathType(PathType.BEZIER)); + curveTypeItems.Add(createMenuItemForPathType(PathType.BSpline(3))); + curveTypeItems.Add(createMenuItemForPathType(PathType.CATMULL)); var menuItems = new List { diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs index 9b6adc04cf..8f0a2ee781 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs @@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders { RelativeSizeAxes = Axes.Both; - HitObject.Path.ControlPoints.Add(segmentStart = new PathControlPoint(Vector2.Zero, PathType.Linear)); + HitObject.Path.ControlPoints.Add(segmentStart = new PathControlPoint(Vector2.Zero, PathType.LINEAR)); currentSegmentLength = 1; } @@ -128,7 +128,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders Debug.Assert(lastPoint != null); segmentStart = lastPoint; - segmentStart.Type = PathType.Linear; + segmentStart.Type = PathType.LINEAR; currentSegmentLength = 1; } @@ -173,15 +173,15 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders { case 1: case 2: - segmentStart.Type = PathType.Linear; + segmentStart.Type = PathType.LINEAR; break; case 3: - segmentStart.Type = PathType.PerfectCurve; + segmentStart.Type = PathType.PERFECTCURVE; break; default: - segmentStart.Type = PathType.Bezier; + segmentStart.Type = PathType.BEZIER; break; } } @@ -195,7 +195,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders { HitObject.Path.ControlPoints.Add(cursor = new PathControlPoint { Position = Vector2.Zero }); - // The path type should be adjusted in the progression of updatePathType() (Linear -> PC -> Bezier). + // The path type should be adjusted in the progression of updatePathType() (LINEAR -> PC -> BEZIER). currentSegmentLength++; updatePathType(); } @@ -210,7 +210,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders HitObject.Path.ControlPoints.Remove(cursor); cursor = null; - // The path type should be adjusted in the reverse progression of updatePathType() (Bezier -> PC -> Linear). + // The path type should be adjusted in the reverse progression of updatePathType() (BEZIER -> PC -> LINEAR). currentSegmentLength--; updatePathType(); } diff --git a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs index e81941d254..b972f09136 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs @@ -320,7 +320,7 @@ namespace osu.Game.Rulesets.Osu.Edit if (mergedHitObject.Path.ControlPoints.Count == 0) { - mergedHitObject.Path.ControlPoints.Add(new PathControlPoint(Vector2.Zero, PathType.Linear)); + mergedHitObject.Path.ControlPoints.Add(new PathControlPoint(Vector2.Zero, PathType.LINEAR)); } // Merge all the selected hit objects into one slider path. @@ -350,7 +350,7 @@ namespace osu.Game.Rulesets.Osu.Edit // Turn the last control point into a linear type if this is the first merging circle in a sequence, so the subsequent control points can be inherited path type. if (!lastCircle) { - mergedHitObject.Path.ControlPoints.Last().Type = PathType.Linear; + mergedHitObject.Path.ControlPoints.Last().Type = PathType.LINEAR; } mergedHitObject.Path.ControlPoints.Add(new PathControlPoint(selectedMergeableObject.Position - mergedHitObject.Position)); diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs index 5f47d486e6..2a76782a08 100644 --- a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs @@ -116,7 +116,7 @@ namespace osu.Game.Rulesets.Taiko.Objects double IHasDistance.Distance => Duration * Velocity; SliderPath IHasPath.Path - => new SliderPath(PathType.Linear, new[] { Vector2.Zero, new Vector2(1) }, ((IHasDistance)this).Distance / LegacyBeatmapEncoder.LEGACY_TAIKO_VELOCITY_MULTIPLIER); + => new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(1) }, ((IHasDistance)this).Distance / LegacyBeatmapEncoder.LEGACY_TAIKO_VELOCITY_MULTIPLIER); #endregion } diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 66151a51e6..18c21046fb 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -663,7 +663,7 @@ namespace osu.Game.Tests.Beatmaps.Formats assertObjectHasBanks(hitObjects[9], HitSampleInfo.BANK_DRUM, HitSampleInfo.BANK_NORMAL); } - void assertObjectHasBanks(HitObject hitObject, string normalBank, string? additionsBank = null) + static void assertObjectHasBanks(HitObject hitObject, string normalBank, string? additionsBank = null) { Assert.AreEqual(normalBank, hitObject.Samples[0].Bank); @@ -808,14 +808,14 @@ namespace osu.Game.Tests.Beatmaps.Formats var first = ((IHasPath)decoded.HitObjects[0]).Path; Assert.That(first.ControlPoints[0].Position, Is.EqualTo(Vector2.Zero)); - Assert.That(first.ControlPoints[0].Type, Is.EqualTo(PathType.PerfectCurve)); + Assert.That(first.ControlPoints[0].Type, Is.EqualTo(PathType.PERFECTCURVE)); Assert.That(first.ControlPoints[1].Position, Is.EqualTo(new Vector2(161, -244))); Assert.That(first.ControlPoints[1].Type, Is.EqualTo(null)); // ReSharper disable once HeuristicUnreachableCode // weird one, see https://youtrack.jetbrains.com/issue/RIDER-70159. Assert.That(first.ControlPoints[2].Position, Is.EqualTo(new Vector2(376, -3))); - Assert.That(first.ControlPoints[2].Type, Is.EqualTo(PathType.Bezier)); + Assert.That(first.ControlPoints[2].Type, Is.EqualTo(PathType.BEZIER)); Assert.That(first.ControlPoints[3].Position, Is.EqualTo(new Vector2(68, 15))); Assert.That(first.ControlPoints[3].Type, Is.EqualTo(null)); Assert.That(first.ControlPoints[4].Position, Is.EqualTo(new Vector2(259, -132))); @@ -827,7 +827,7 @@ namespace osu.Game.Tests.Beatmaps.Formats var second = ((IHasPath)decoded.HitObjects[1]).Path; Assert.That(second.ControlPoints[0].Position, Is.EqualTo(Vector2.Zero)); - Assert.That(second.ControlPoints[0].Type, Is.EqualTo(PathType.PerfectCurve)); + Assert.That(second.ControlPoints[0].Type, Is.EqualTo(PathType.PERFECTCURVE)); Assert.That(second.ControlPoints[1].Position, Is.EqualTo(new Vector2(161, -244))); Assert.That(second.ControlPoints[1].Type, Is.EqualTo(null)); Assert.That(second.ControlPoints[2].Position, Is.EqualTo(new Vector2(376, -3))); @@ -837,14 +837,14 @@ namespace osu.Game.Tests.Beatmaps.Formats var third = ((IHasPath)decoded.HitObjects[2]).Path; Assert.That(third.ControlPoints[0].Position, Is.EqualTo(Vector2.Zero)); - Assert.That(third.ControlPoints[0].Type, Is.EqualTo(PathType.Bezier)); + Assert.That(third.ControlPoints[0].Type, Is.EqualTo(PathType.BEZIER)); Assert.That(third.ControlPoints[1].Position, Is.EqualTo(new Vector2(0, 192))); Assert.That(third.ControlPoints[1].Type, Is.EqualTo(null)); Assert.That(third.ControlPoints[2].Position, Is.EqualTo(new Vector2(224, 192))); Assert.That(third.ControlPoints[2].Type, Is.EqualTo(null)); Assert.That(third.ControlPoints[3].Position, Is.EqualTo(new Vector2(224, 0))); - Assert.That(third.ControlPoints[3].Type, Is.EqualTo(PathType.Bezier)); + Assert.That(third.ControlPoints[3].Type, Is.EqualTo(PathType.BEZIER)); Assert.That(third.ControlPoints[4].Position, Is.EqualTo(new Vector2(224, -192))); Assert.That(third.ControlPoints[4].Type, Is.EqualTo(null)); Assert.That(third.ControlPoints[5].Position, Is.EqualTo(new Vector2(480, -192))); @@ -856,7 +856,7 @@ namespace osu.Game.Tests.Beatmaps.Formats var fourth = ((IHasPath)decoded.HitObjects[3]).Path; Assert.That(fourth.ControlPoints[0].Position, Is.EqualTo(Vector2.Zero)); - Assert.That(fourth.ControlPoints[0].Type, Is.EqualTo(PathType.Bezier)); + Assert.That(fourth.ControlPoints[0].Type, Is.EqualTo(PathType.BEZIER)); Assert.That(fourth.ControlPoints[1].Position, Is.EqualTo(new Vector2(1, 1))); Assert.That(fourth.ControlPoints[1].Type, Is.EqualTo(null)); Assert.That(fourth.ControlPoints[2].Position, Is.EqualTo(new Vector2(2, 2))); @@ -870,7 +870,7 @@ namespace osu.Game.Tests.Beatmaps.Formats var fifth = ((IHasPath)decoded.HitObjects[4]).Path; Assert.That(fifth.ControlPoints[0].Position, Is.EqualTo(Vector2.Zero)); - Assert.That(fifth.ControlPoints[0].Type, Is.EqualTo(PathType.Bezier)); + Assert.That(fifth.ControlPoints[0].Type, Is.EqualTo(PathType.BEZIER)); Assert.That(fifth.ControlPoints[1].Position, Is.EqualTo(new Vector2(1, 1))); Assert.That(fifth.ControlPoints[1].Type, Is.EqualTo(null)); Assert.That(fifth.ControlPoints[2].Position, Is.EqualTo(new Vector2(2, 2))); @@ -881,7 +881,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.That(fifth.ControlPoints[4].Type, Is.EqualTo(null)); Assert.That(fifth.ControlPoints[5].Position, Is.EqualTo(new Vector2(4, 4))); - Assert.That(fifth.ControlPoints[5].Type, Is.EqualTo(PathType.Bezier)); + Assert.That(fifth.ControlPoints[5].Type, Is.EqualTo(PathType.BEZIER)); Assert.That(fifth.ControlPoints[6].Position, Is.EqualTo(new Vector2(5, 5))); Assert.That(fifth.ControlPoints[6].Type, Is.EqualTo(null)); @@ -889,12 +889,12 @@ namespace osu.Game.Tests.Beatmaps.Formats var sixth = ((IHasPath)decoded.HitObjects[5]).Path; Assert.That(sixth.ControlPoints[0].Position, Is.EqualTo(Vector2.Zero)); - Assert.That(sixth.ControlPoints[0].Type == PathType.Bezier); + Assert.That(sixth.ControlPoints[0].Type == PathType.BEZIER); Assert.That(sixth.ControlPoints[1].Position, Is.EqualTo(new Vector2(75, 145))); Assert.That(sixth.ControlPoints[1].Type == null); Assert.That(sixth.ControlPoints[2].Position, Is.EqualTo(new Vector2(170, 75))); - Assert.That(sixth.ControlPoints[2].Type == PathType.Bezier); + Assert.That(sixth.ControlPoints[2].Type == PathType.BEZIER); Assert.That(sixth.ControlPoints[3].Position, Is.EqualTo(new Vector2(300, 145))); Assert.That(sixth.ControlPoints[3].Type == null); Assert.That(sixth.ControlPoints[4].Position, Is.EqualTo(new Vector2(410, 20))); @@ -904,12 +904,12 @@ namespace osu.Game.Tests.Beatmaps.Formats var seventh = ((IHasPath)decoded.HitObjects[6]).Path; Assert.That(seventh.ControlPoints[0].Position, Is.EqualTo(Vector2.Zero)); - Assert.That(seventh.ControlPoints[0].Type == PathType.PerfectCurve); + Assert.That(seventh.ControlPoints[0].Type == PathType.PERFECTCURVE); Assert.That(seventh.ControlPoints[1].Position, Is.EqualTo(new Vector2(75, 145))); Assert.That(seventh.ControlPoints[1].Type == null); Assert.That(seventh.ControlPoints[2].Position, Is.EqualTo(new Vector2(170, 75))); - Assert.That(seventh.ControlPoints[2].Type == PathType.PerfectCurve); + Assert.That(seventh.ControlPoints[2].Type == PathType.PERFECTCURVE); Assert.That(seventh.ControlPoints[3].Position, Is.EqualTo(new Vector2(300, 145))); Assert.That(seventh.ControlPoints[3].Type == null); Assert.That(seventh.ControlPoints[4].Position, Is.EqualTo(new Vector2(410, 20))); @@ -1016,7 +1016,7 @@ namespace osu.Game.Tests.Beatmaps.Formats var controlPoints = ((IHasPath)decoded.HitObjects[0]).Path.ControlPoints; Assert.That(controlPoints.Count, Is.EqualTo(6)); - Assert.That(controlPoints.Single(c => c.Type != null).Type, Is.EqualTo(PathType.Catmull)); + Assert.That(controlPoints.Single(c => c.Type != null).Type, Is.EqualTo(PathType.CATMULL)); } } @@ -1032,9 +1032,9 @@ namespace osu.Game.Tests.Beatmaps.Formats var controlPoints = ((IHasPath)decoded.HitObjects[0]).Path.ControlPoints; Assert.That(controlPoints.Count, Is.EqualTo(4)); - Assert.That(controlPoints[0].Type, Is.EqualTo(PathType.Catmull)); - Assert.That(controlPoints[1].Type, Is.EqualTo(PathType.Catmull)); - Assert.That(controlPoints[2].Type, Is.EqualTo(PathType.Catmull)); + Assert.That(controlPoints[0].Type, Is.EqualTo(PathType.CATMULL)); + Assert.That(controlPoints[1].Type, Is.EqualTo(PathType.CATMULL)); + Assert.That(controlPoints[2].Type, Is.EqualTo(PathType.CATMULL)); Assert.That(controlPoints[3].Type, Is.Null); } } @@ -1051,7 +1051,7 @@ namespace osu.Game.Tests.Beatmaps.Formats var controlPoints = ((IHasPath)decoded.HitObjects[0]).Path.ControlPoints; Assert.That(controlPoints.Count, Is.EqualTo(4)); - Assert.That(controlPoints[0].Type, Is.EqualTo(PathType.Catmull)); + Assert.That(controlPoints[0].Type, Is.EqualTo(PathType.CATMULL)); Assert.That(controlPoints[0].Position, Is.EqualTo(Vector2.Zero)); Assert.That(controlPoints[1].Type, Is.Null); Assert.That(controlPoints[1].Position, Is.Not.EqualTo(Vector2.Zero)); diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index 5d9049ead7..db50273f27 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -77,7 +77,7 @@ namespace osu.Game.Tests.Beatmaps.Formats compareBeatmaps(decoded, decodedAfterEncode); - ControlPointInfo removeLegacyControlPointTypes(ControlPointInfo controlPointInfo) + static ControlPointInfo removeLegacyControlPointTypes(ControlPointInfo controlPointInfo) { // emulate non-legacy control points by cloning the non-legacy portion. // the assertion is that the encoder can recreate this losslessly from hitobject data. @@ -125,10 +125,10 @@ namespace osu.Game.Tests.Beatmaps.Formats Position = new Vector2(0.6f), Path = new SliderPath(new[] { - new PathControlPoint(Vector2.Zero, PathType.Bezier), + new PathControlPoint(Vector2.Zero, PathType.BEZIER), new PathControlPoint(new Vector2(0.5f)), new PathControlPoint(new Vector2(0.51f)), // This is actually on the same position as the previous one in legacy beatmaps (truncated to int). - new PathControlPoint(new Vector2(1f), PathType.Bezier), + new PathControlPoint(new Vector2(1f), PathType.BEZIER), new PathControlPoint(new Vector2(2f)) }) }, diff --git a/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs b/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs index 5af0366e6e..21d8a165ff 100644 --- a/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs +++ b/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs @@ -162,7 +162,7 @@ namespace osu.Game.Tests.Editing { new PathControlPoint(Vector2.Zero), new PathControlPoint(Vector2.One), - new PathControlPoint(new Vector2(2), PathType.Bezier), + new PathControlPoint(new Vector2(2), PathType.BEZIER), new PathControlPoint(new Vector2(3)), }, 50) }, @@ -179,7 +179,7 @@ namespace osu.Game.Tests.Editing StartTime = 2000, Path = new SliderPath(new[] { - new PathControlPoint(Vector2.Zero, PathType.Bezier), + new PathControlPoint(Vector2.Zero, PathType.BEZIER), new PathControlPoint(new Vector2(4)), new PathControlPoint(new Vector2(5)), }, 100) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs index c4c05278b5..a766b253aa 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs @@ -72,7 +72,7 @@ namespace osu.Game.Tests.Visual.Editing ControlPoints = { new PathControlPoint(), - new PathControlPoint(new Vector2(100, 0), PathType.Bezier) + new PathControlPoint(new Vector2(100, 0), PathType.BEZIER) } } }; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs index ed3bffe5c2..f392841ac7 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs @@ -57,7 +57,7 @@ namespace osu.Game.Tests.Visual.Editing new Slider { Position = new Vector2(128, 256), - Path = new SliderPath(PathType.Linear, new[] + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, new Vector2(216, 0), diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs index a40eab5948..5eb82ccbdc 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs @@ -114,23 +114,25 @@ namespace osu.Game.Tests.Visual.Gameplay { } - [TestCase(PathType.Linear)] - [TestCase(PathType.Bezier)] - [TestCase(PathType.Catmull)] - [TestCase(PathType.PerfectCurve)] - public void TestSingleSegment(PathType type) - => AddStep("create path", () => path.ControlPoints.AddRange(createSegment(type, Vector2.Zero, new Vector2(0, 100), new Vector2(100)))); + [TestCase(SplineType.Linear, null)] + [TestCase(SplineType.BSpline, null)] + [TestCase(SplineType.BSpline, 3)] + [TestCase(SplineType.Catmull, null)] + [TestCase(SplineType.PerfectCurve, null)] + public void TestSingleSegment(SplineType splineType, int? degree) + => AddStep("create path", () => path.ControlPoints.AddRange(createSegment(new PathType { SplineType = splineType, Degree = degree }, Vector2.Zero, new Vector2(0, 100), new Vector2(100)))); - [TestCase(PathType.Linear)] - [TestCase(PathType.Bezier)] - [TestCase(PathType.Catmull)] - [TestCase(PathType.PerfectCurve)] - public void TestMultipleSegment(PathType type) + [TestCase(SplineType.Linear, null)] + [TestCase(SplineType.BSpline, null)] + [TestCase(SplineType.BSpline, 3)] + [TestCase(SplineType.Catmull, null)] + [TestCase(SplineType.PerfectCurve, null)] + public void TestMultipleSegment(SplineType splineType, int? degree) { AddStep("create path", () => { - path.ControlPoints.AddRange(createSegment(PathType.Linear, Vector2.Zero)); - path.ControlPoints.AddRange(createSegment(type, new Vector2(0, 100), new Vector2(100), Vector2.Zero)); + path.ControlPoints.AddRange(createSegment(PathType.LINEAR, Vector2.Zero)); + path.ControlPoints.AddRange(createSegment(new PathType { SplineType = splineType, Degree = degree }, new Vector2(0, 100), new Vector2(100), Vector2.Zero)); }); } @@ -139,9 +141,9 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("create path", () => { - path.ControlPoints.AddRange(createSegment(PathType.Linear, Vector2.Zero, new Vector2(100, 0))); - path.ControlPoints.AddRange(createSegment(PathType.Bezier, new Vector2(100, 0), new Vector2(150, 30), new Vector2(100, 100))); - path.ControlPoints.AddRange(createSegment(PathType.PerfectCurve, new Vector2(100, 100), new Vector2(25, 50), Vector2.Zero)); + path.ControlPoints.AddRange(createSegment(PathType.LINEAR, Vector2.Zero, new Vector2(100, 0))); + path.ControlPoints.AddRange(createSegment(PathType.BEZIER, new Vector2(100, 0), new Vector2(150, 30), new Vector2(100, 100))); + path.ControlPoints.AddRange(createSegment(PathType.PERFECTCURVE, new Vector2(100, 100), new Vector2(25, 50), Vector2.Zero)); }); } @@ -157,7 +159,7 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("create path", () => { - path.ControlPoints.AddRange(createSegment(PathType.PerfectCurve, Vector2.Zero, new Vector2(width / 2, height), new Vector2(width, 0))); + path.ControlPoints.AddRange(createSegment(PathType.PERFECTCURVE, Vector2.Zero, new Vector2(width / 2, height), new Vector2(width, 0))); }); } @@ -170,11 +172,11 @@ namespace osu.Game.Tests.Visual.Gameplay switch (points) { case 2: - path.ControlPoints.AddRange(createSegment(PathType.PerfectCurve, Vector2.Zero, new Vector2(0, 100))); + path.ControlPoints.AddRange(createSegment(PathType.PERFECTCURVE, Vector2.Zero, new Vector2(0, 100))); break; case 4: - path.ControlPoints.AddRange(createSegment(PathType.PerfectCurve, Vector2.Zero, new Vector2(0, 100), new Vector2(100), new Vector2(100, 0))); + path.ControlPoints.AddRange(createSegment(PathType.PERFECTCURVE, Vector2.Zero, new Vector2(0, 100), new Vector2(100), new Vector2(100, 0))); break; } }); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySampleTriggerSource.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySampleTriggerSource.cs index 0f16d3f394..3cbd5eefac 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySampleTriggerSource.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySampleTriggerSource.cs @@ -88,7 +88,7 @@ namespace osu.Game.Tests.Visual.Gameplay { HitWindows = new HitWindows(), StartTime = t += spacing, - Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, Vector2.UnitY * 200 }), + Path = new SliderPath(PathType.LINEAR, new[] { Vector2.Zero, Vector2.UnitY * 200 }), Samples = new[] { new HitSampleInfo(HitSampleInfo.HIT_WHISTLE, HitSampleInfo.BANK_SOFT) }, }, }); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSliderPath.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSliderPath.cs index 635d9f9604..e4d99f6741 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSliderPath.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSliderPath.cs @@ -52,59 +52,68 @@ namespace osu.Game.Tests.Visual.Gameplay { } - [TestCase(PathType.Linear)] - [TestCase(PathType.Bezier)] - [TestCase(PathType.Catmull)] - [TestCase(PathType.PerfectCurve)] - public void TestSingleSegment(PathType type) - => AddStep("create path", () => path.ControlPoints.AddRange(createSegment(type, Vector2.Zero, new Vector2(0, 100), new Vector2(100)))); + [TestCase(SplineType.Linear, null)] + [TestCase(SplineType.BSpline, null)] + [TestCase(SplineType.BSpline, 3)] + [TestCase(SplineType.Catmull, null)] + [TestCase(SplineType.PerfectCurve, null)] + public void TestSingleSegment(SplineType splineType, int? degree) + => AddStep("create path", () => path.ControlPoints.AddRange(createSegment( + new PathType { SplineType = splineType, Degree = degree }, + Vector2.Zero, + new Vector2(0, 100), + new Vector2(100), + new Vector2(0, 200), + new Vector2(200) + ))); - [TestCase(PathType.Linear)] - [TestCase(PathType.Bezier)] - [TestCase(PathType.Catmull)] - [TestCase(PathType.PerfectCurve)] - public void TestMultipleSegment(PathType type) + [TestCase(SplineType.Linear, null)] + [TestCase(SplineType.BSpline, null)] + [TestCase(SplineType.BSpline, 3)] + [TestCase(SplineType.Catmull, null)] + [TestCase(SplineType.PerfectCurve, null)] + public void TestMultipleSegment(SplineType splineType, int? degree) { AddStep("create path", () => { - path.ControlPoints.AddRange(createSegment(PathType.Linear, Vector2.Zero)); - path.ControlPoints.AddRange(createSegment(type, new Vector2(0, 100), new Vector2(100), Vector2.Zero)); + path.ControlPoints.AddRange(createSegment(PathType.LINEAR, Vector2.Zero)); + path.ControlPoints.AddRange(createSegment(new PathType { SplineType = splineType, Degree = degree }, new Vector2(0, 100), new Vector2(100), Vector2.Zero)); }); } [Test] public void TestAddControlPoint() { - AddStep("create path", () => path.ControlPoints.AddRange(createSegment(PathType.Linear, Vector2.Zero, new Vector2(0, 100)))); + AddStep("create path", () => path.ControlPoints.AddRange(createSegment(PathType.LINEAR, Vector2.Zero, new Vector2(0, 100)))); AddStep("add point", () => path.ControlPoints.Add(new PathControlPoint { Position = new Vector2(100) })); } [Test] public void TestInsertControlPoint() { - AddStep("create path", () => path.ControlPoints.AddRange(createSegment(PathType.Linear, Vector2.Zero, new Vector2(100)))); + AddStep("create path", () => path.ControlPoints.AddRange(createSegment(PathType.LINEAR, Vector2.Zero, new Vector2(100)))); AddStep("insert point", () => path.ControlPoints.Insert(1, new PathControlPoint { Position = new Vector2(0, 100) })); } [Test] public void TestRemoveControlPoint() { - AddStep("create path", () => path.ControlPoints.AddRange(createSegment(PathType.Linear, Vector2.Zero, new Vector2(0, 100), new Vector2(100)))); + AddStep("create path", () => path.ControlPoints.AddRange(createSegment(PathType.LINEAR, Vector2.Zero, new Vector2(0, 100), new Vector2(100)))); AddStep("remove second point", () => path.ControlPoints.RemoveAt(1)); } [Test] public void TestChangePathType() { - AddStep("create path", () => path.ControlPoints.AddRange(createSegment(PathType.Linear, Vector2.Zero, new Vector2(0, 100), new Vector2(100)))); - AddStep("change type to bezier", () => path.ControlPoints[0].Type = PathType.Bezier); + AddStep("create path", () => path.ControlPoints.AddRange(createSegment(PathType.LINEAR, Vector2.Zero, new Vector2(0, 100), new Vector2(100)))); + AddStep("change type to bezier", () => path.ControlPoints[0].Type = PathType.BEZIER); } [Test] public void TestAddSegmentByChangingType() { - AddStep("create path", () => path.ControlPoints.AddRange(createSegment(PathType.Linear, Vector2.Zero, new Vector2(0, 100), new Vector2(100), new Vector2(100, 0)))); - AddStep("change second point type to bezier", () => path.ControlPoints[1].Type = PathType.Bezier); + AddStep("create path", () => path.ControlPoints.AddRange(createSegment(PathType.LINEAR, Vector2.Zero, new Vector2(0, 100), new Vector2(100), new Vector2(100, 0)))); + AddStep("change second point type to bezier", () => path.ControlPoints[1].Type = PathType.BEZIER); } [Test] @@ -112,8 +121,8 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("create path", () => { - path.ControlPoints.AddRange(createSegment(PathType.Linear, Vector2.Zero, new Vector2(0, 100), new Vector2(100), new Vector2(100, 0))); - path.ControlPoints[1].Type = PathType.Bezier; + path.ControlPoints.AddRange(createSegment(PathType.LINEAR, Vector2.Zero, new Vector2(0, 100), new Vector2(100), new Vector2(100, 0))); + path.ControlPoints[1].Type = PathType.BEZIER; }); AddStep("change second point type to null", () => path.ControlPoints[1].Type = null); @@ -124,8 +133,8 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("create path", () => { - path.ControlPoints.AddRange(createSegment(PathType.Linear, Vector2.Zero, new Vector2(0, 100), new Vector2(100), new Vector2(100, 0))); - path.ControlPoints[1].Type = PathType.Bezier; + path.ControlPoints.AddRange(createSegment(PathType.LINEAR, Vector2.Zero, new Vector2(0, 100), new Vector2(100), new Vector2(100, 0))); + path.ControlPoints[1].Type = PathType.BEZIER; }); AddStep("remove second point", () => path.ControlPoints.RemoveAt(1)); @@ -140,11 +149,11 @@ namespace osu.Game.Tests.Visual.Gameplay switch (points) { case 2: - path.ControlPoints.AddRange(createSegment(PathType.PerfectCurve, Vector2.Zero, new Vector2(0, 100))); + path.ControlPoints.AddRange(createSegment(PathType.PERFECTCURVE, Vector2.Zero, new Vector2(0, 100))); break; case 4: - path.ControlPoints.AddRange(createSegment(PathType.PerfectCurve, Vector2.Zero, new Vector2(0, 100), new Vector2(100), new Vector2(100, 0))); + path.ControlPoints.AddRange(createSegment(PathType.PERFECTCURVE, Vector2.Zero, new Vector2(0, 100), new Vector2(100), new Vector2(100, 0))); break; } }); @@ -153,35 +162,35 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestLengthenLastSegment() { - AddStep("create path", () => path.ControlPoints.AddRange(createSegment(PathType.Linear, Vector2.Zero, new Vector2(0, 100), new Vector2(100)))); + AddStep("create path", () => path.ControlPoints.AddRange(createSegment(PathType.LINEAR, Vector2.Zero, new Vector2(0, 100), new Vector2(100)))); AddStep("lengthen last segment", () => path.ExpectedDistance.Value = 300); } [Test] public void TestShortenLastSegment() { - AddStep("create path", () => path.ControlPoints.AddRange(createSegment(PathType.Linear, Vector2.Zero, new Vector2(0, 100), new Vector2(100)))); + AddStep("create path", () => path.ControlPoints.AddRange(createSegment(PathType.LINEAR, Vector2.Zero, new Vector2(0, 100), new Vector2(100)))); AddStep("shorten last segment", () => path.ExpectedDistance.Value = 150); } [Test] public void TestShortenFirstSegment() { - AddStep("create path", () => path.ControlPoints.AddRange(createSegment(PathType.Linear, Vector2.Zero, new Vector2(0, 100), new Vector2(100)))); + AddStep("create path", () => path.ControlPoints.AddRange(createSegment(PathType.LINEAR, Vector2.Zero, new Vector2(0, 100), new Vector2(100)))); AddStep("shorten first segment", () => path.ExpectedDistance.Value = 50); } [Test] public void TestShortenToZeroLength() { - AddStep("create path", () => path.ControlPoints.AddRange(createSegment(PathType.Linear, Vector2.Zero, new Vector2(0, 100), new Vector2(100)))); + AddStep("create path", () => path.ControlPoints.AddRange(createSegment(PathType.LINEAR, Vector2.Zero, new Vector2(0, 100), new Vector2(100)))); AddStep("shorten to 0 length", () => path.ExpectedDistance.Value = 0); } [Test] public void TestShortenToNegativeLength() { - AddStep("create path", () => path.ControlPoints.AddRange(createSegment(PathType.Linear, Vector2.Zero, new Vector2(0, 100), new Vector2(100)))); + AddStep("create path", () => path.ControlPoints.AddRange(createSegment(PathType.LINEAR, Vector2.Zero, new Vector2(0, 100), new Vector2(100)))); AddStep("shorten to -10 length", () => path.ExpectedDistance.Value = -10); } @@ -197,7 +206,7 @@ namespace osu.Game.Tests.Visual.Gameplay }; double[] distances = { 100d, 200d, 300d }; - AddStep("create path", () => path.ControlPoints.AddRange(positions.Select(p => new PathControlPoint(p, PathType.Linear)))); + AddStep("create path", () => path.ControlPoints.AddRange(positions.Select(p => new PathControlPoint(p, PathType.LINEAR)))); AddAssert("segment ends are correct", () => path.GetSegmentEnds(), () => Is.EqualTo(distances.Select(d => d / 300))); AddAssert("segment end positions recovered", () => path.GetSegmentEnds().Select(p => path.PositionAt(p)), () => Is.EqualTo(positions.Skip(1))); diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 4f8e935ee4..7029f61459 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; @@ -437,7 +438,7 @@ namespace osu.Game.Beatmaps.Formats // Explicit segments have a new format in which the type is injected into the middle of the control point string. // To preserve compatibility with osu-stable as much as possible, explicit segments with the same type are converted to use implicit segments by duplicating the control point. // One exception are consecutive perfect curves, which aren't supported in osu!stable and can lead to decoding issues if encoded as implicit segments - bool needsExplicitSegment = point.Type != lastType || point.Type == PathType.PerfectCurve; + bool needsExplicitSegment = point.Type != lastType || point.Type == PathType.PERFECTCURVE; // Another exception to this is when the last two control points of the last segment were duplicated. This is not a scenario supported by osu!stable. // Lazer does not add implicit segments for the last two control points of _any_ explicit segment, so an explicit segment is forced in order to maintain consistency with the decoder. @@ -455,19 +456,23 @@ namespace osu.Game.Beatmaps.Formats { switch (point.Type) { - case PathType.Bezier: + case { SplineType: SplineType.BSpline, Degree: > 0 }: + writer.Write($"B{point.Type.Value.Degree}|"); + break; + + case { SplineType: SplineType.BSpline, Degree: <= 0 }: writer.Write("B|"); break; - case PathType.Catmull: + case { SplineType: SplineType.Catmull }: writer.Write("C|"); break; - case PathType.PerfectCurve: + case { SplineType: SplineType.PerfectCurve }: writer.Write("P|"); break; - case PathType.Linear: + case { SplineType: SplineType.Linear }: writer.Write("L|"); break; } diff --git a/osu.Game/Database/LegacyBeatmapExporter.cs b/osu.Game/Database/LegacyBeatmapExporter.cs index ece705f685..9ca12a79dd 100644 --- a/osu.Game/Database/LegacyBeatmapExporter.cs +++ b/osu.Game/Database/LegacyBeatmapExporter.cs @@ -78,10 +78,10 @@ namespace osu.Game.Database // wherein the last control point of an otherwise-single-segment slider path has a different type than previous, // which would lead to sliders being mangled when exported back to stable. // normally, that would be handled by the `BezierConverter.ConvertToModernBezier()` call below, - // which outputs a slider path containing only Bezier control points, + // which outputs a slider path containing only BEZIER control points, // but a non-inherited last control point is (rightly) not considered to be starting a new segment, // therefore it would fail to clear the `CountSegments() <= 1` check. - // by clearing explicitly we both fix the issue and avoid unnecessary conversions to Bezier. + // by clearing explicitly we both fix the issue and avoid unnecessary conversions to BEZIER. if (hasPath.Path.ControlPoints.Count > 1) hasPath.Path.ControlPoints[^1].Type = null; diff --git a/osu.Game/Rulesets/Objects/BezierConverter.cs b/osu.Game/Rulesets/Objects/BezierConverter.cs index 0c878fa1fd..74fbe7d8f9 100644 --- a/osu.Game/Rulesets/Objects/BezierConverter.cs +++ b/osu.Game/Rulesets/Objects/BezierConverter.cs @@ -68,26 +68,26 @@ namespace osu.Game.Rulesets.Objects // The current vertex ends the segment var segmentVertices = vertices.AsSpan().Slice(start, i - start + 1); - var segmentType = controlPoints[start].Type ?? PathType.Linear; + var segmentType = controlPoints[start].Type ?? PathType.LINEAR; switch (segmentType) { - case PathType.Catmull: + case { SplineType: SplineType.Catmull }: result.AddRange(from segment in ConvertCatmullToBezierAnchors(segmentVertices) from v in segment select v + position); - break; - case PathType.Linear: + case { SplineType: SplineType.Linear }: result.AddRange(from segment in ConvertLinearToBezierAnchors(segmentVertices) from v in segment select v + position); - break; - case PathType.PerfectCurve: + case { SplineType: SplineType.PerfectCurve }: result.AddRange(ConvertCircleToBezierAnchors(segmentVertices).Select(v => v + position)); - break; default: + if (segmentType.Degree != null) + throw new NotImplementedException("BSpline conversion of arbitrary degree is not implemented."); + foreach (Vector2 v in segmentVertices) { result.Add(v + position); @@ -104,7 +104,7 @@ namespace osu.Game.Rulesets.Objects } /// - /// Converts a path of control points to an identical path using only Bezier type control points. + /// Converts a path of control points to an identical path using only BEZIER type control points. /// /// The control points of the path. /// The list of bezier control points. @@ -124,38 +124,38 @@ namespace osu.Game.Rulesets.Objects // The current vertex ends the segment var segmentVertices = vertices.AsSpan().Slice(start, i - start + 1); - var segmentType = controlPoints[start].Type ?? PathType.Linear; + var segmentType = controlPoints[start].Type ?? PathType.LINEAR; switch (segmentType) { - case PathType.Catmull: + case { SplineType: SplineType.Catmull }: foreach (var segment in ConvertCatmullToBezierAnchors(segmentVertices)) { for (int j = 0; j < segment.Length - 1; j++) { - result.Add(new PathControlPoint(segment[j], j == 0 ? PathType.Bezier : null)); + result.Add(new PathControlPoint(segment[j], j == 0 ? PathType.BEZIER : null)); } } break; - case PathType.Linear: + case { SplineType: SplineType.Linear }: foreach (var segment in ConvertLinearToBezierAnchors(segmentVertices)) { for (int j = 0; j < segment.Length - 1; j++) { - result.Add(new PathControlPoint(segment[j], j == 0 ? PathType.Bezier : null)); + result.Add(new PathControlPoint(segment[j], j == 0 ? PathType.BEZIER : null)); } } break; - case PathType.PerfectCurve: + case { SplineType: SplineType.PerfectCurve }: var circleResult = ConvertCircleToBezierAnchors(segmentVertices); for (int j = 0; j < circleResult.Length - 1; j++) { - result.Add(new PathControlPoint(circleResult[j], j == 0 ? PathType.Bezier : null)); + result.Add(new PathControlPoint(circleResult[j], j == 0 ? PathType.BEZIER : null)); } break; @@ -163,7 +163,7 @@ namespace osu.Game.Rulesets.Objects default: for (int j = 0; j < segmentVertices.Length - 1; j++) { - result.Add(new PathControlPoint(segmentVertices[j], j == 0 ? PathType.Bezier : null)); + result.Add(new PathControlPoint(segmentVertices[j], j == 0 ? segmentType : null)); } break; diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs index d20f2d31bb..30f4c092d9 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs @@ -224,16 +224,18 @@ namespace osu.Game.Rulesets.Objects.Legacy { default: case 'C': - return PathType.Catmull; + return new PathType(SplineType.Catmull); case 'B': - return PathType.Bezier; + if (input.Length > 1 && int.TryParse(input.Substring(1), out int degree) && degree > 0) + return new PathType { SplineType = SplineType.BSpline, Degree = degree }; + return new PathType(SplineType.BSpline); case 'L': - return PathType.Linear; + return new PathType(SplineType.Linear); case 'P': - return PathType.PerfectCurve; + return new PathType(SplineType.PerfectCurve); } } @@ -320,14 +322,14 @@ namespace osu.Game.Rulesets.Objects.Legacy readPoint(endPoint, offset, out vertices[^1]); // Edge-case rules (to match stable). - if (type == PathType.PerfectCurve) + if (type == PathType.PERFECTCURVE) { if (vertices.Length != 3) - type = PathType.Bezier; + type = PathType.BEZIER; else if (isLinear(vertices)) { // osu-stable special-cased colinear perfect curves to a linear path - type = PathType.Linear; + type = PathType.LINEAR; } } @@ -349,10 +351,10 @@ namespace osu.Game.Rulesets.Objects.Legacy if (vertices[endIndex].Position != vertices[endIndex - 1].Position) continue; - // Legacy Catmull sliders don't support multiple segments, so adjacent Catmull segments should be treated as a single one. + // Legacy CATMULL sliders don't support multiple segments, so adjacent CATMULL segments should be treated as a single one. // Importantly, this is not applied to the first control point, which may duplicate the slider path's position // resulting in a duplicate (0,0) control point in the resultant list. - if (type == PathType.Catmull && endIndex > 1 && FormatVersion < LegacyBeatmapEncoder.FIRST_LAZER_VERSION) + if (type == PathType.CATMULL && endIndex > 1 && FormatVersion < LegacyBeatmapEncoder.FIRST_LAZER_VERSION) continue; // The last control point of each segment is not allowed to start a new implicit segment. diff --git a/osu.Game/Rulesets/Objects/SliderPath.cs b/osu.Game/Rulesets/Objects/SliderPath.cs index 0ac057578b..4c24c111be 100644 --- a/osu.Game/Rulesets/Objects/SliderPath.cs +++ b/osu.Game/Rulesets/Objects/SliderPath.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.Linq; +using Microsoft.Toolkit.HighPerformance; using Newtonsoft.Json; using osu.Framework.Bindables; using osu.Framework.Caching; @@ -260,7 +261,7 @@ namespace osu.Game.Rulesets.Objects // The current vertex ends the segment var segmentVertices = vertices.AsSpan().Slice(start, i - start + 1); - var segmentType = ControlPoints[start].Type ?? PathType.Linear; + var segmentType = ControlPoints[start].Type ?? PathType.LINEAR; // No need to calculate path when there is only 1 vertex if (segmentVertices.Length == 1) @@ -288,12 +289,12 @@ namespace osu.Game.Rulesets.Objects private List calculateSubPath(ReadOnlySpan subControlPoints, PathType type) { - switch (type) + switch (type.SplineType) { - case PathType.Linear: + case SplineType.Linear: return PathApproximator.ApproximateLinear(subControlPoints); - case PathType.PerfectCurve: + case SplineType.PerfectCurve: if (subControlPoints.Length != 3) break; @@ -305,11 +306,11 @@ namespace osu.Game.Rulesets.Objects return subPath; - case PathType.Catmull: + case SplineType.Catmull: return PathApproximator.ApproximateCatmull(subControlPoints); } - return PathApproximator.ApproximateBezier(subControlPoints); + return PathApproximator.ApproximateBSpline(subControlPoints, type.Degree ?? subControlPoints.Length); } private void calculateLength() diff --git a/osu.Game/Rulesets/Objects/SliderPathExtensions.cs b/osu.Game/Rulesets/Objects/SliderPathExtensions.cs index 6c88f01249..d7e5e4574d 100644 --- a/osu.Game/Rulesets/Objects/SliderPathExtensions.cs +++ b/osu.Game/Rulesets/Objects/SliderPathExtensions.cs @@ -29,11 +29,11 @@ namespace osu.Game.Rulesets.Objects { var controlPoints = sliderPath.ControlPoints; - var inheritedLinearPoints = controlPoints.Where(p => sliderPath.PointsInSegment(p)[0].Type == PathType.Linear && p.Type is null).ToList(); + var inheritedLinearPoints = controlPoints.Where(p => sliderPath.PointsInSegment(p)[0].Type == PathType.LINEAR && p.Type is null).ToList(); // Inherited points after a linear point, as well as the first control point if it inherited, // should be treated as linear points, so their types are temporarily changed to linear. - inheritedLinearPoints.ForEach(p => p.Type = PathType.Linear); + inheritedLinearPoints.ForEach(p => p.Type = PathType.LINEAR); double[] segmentEnds = sliderPath.GetSegmentEnds().ToArray(); @@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.Objects inheritedLinearPoints.ForEach(p => p.Type = null); // Recalculate middle perfect curve control points at the end of the slider path. - if (controlPoints.Count >= 3 && controlPoints[^3].Type == PathType.PerfectCurve && controlPoints[^2].Type is null && segmentEnds.Any()) + if (controlPoints.Count >= 3 && controlPoints[^3].Type == PathType.PERFECTCURVE && controlPoints[^2].Type is null && segmentEnds.Any()) { double lastSegmentStart = segmentEnds.Length > 1 ? segmentEnds[^2] : 0; double lastSegmentEnd = segmentEnds[^1]; diff --git a/osu.Game/Rulesets/Objects/Types/PathType.cs b/osu.Game/Rulesets/Objects/Types/PathType.cs index 923ce9eba4..41472fd8b5 100644 --- a/osu.Game/Rulesets/Objects/Types/PathType.cs +++ b/osu.Game/Rulesets/Objects/Types/PathType.cs @@ -1,13 +1,59 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; +using System.Diagnostics; + namespace osu.Game.Rulesets.Objects.Types { - public enum PathType + public enum SplineType { Catmull, - Bezier, + BSpline, Linear, PerfectCurve } + + public struct PathType + { + public static readonly PathType CATMULL = new PathType(SplineType.Catmull); + public static readonly PathType BEZIER = new PathType(SplineType.BSpline); + public static readonly PathType LINEAR = new PathType(SplineType.Linear); + public static readonly PathType PERFECTCURVE = new PathType(SplineType.PerfectCurve); + + /// + /// The type of the spline that should be used to interpret the control points of the path. + /// + public SplineType SplineType { get; init; } + + /// + /// The degree of a BSpline. Unused if is not . + /// Null means the degree is equal to the number of control points, 1 means linear, 2 means quadratic, etc. + /// + public int? Degree { get; init; } + + public PathType(SplineType splineType) + { + SplineType = splineType; + Degree = null; + } + + public override int GetHashCode() + => HashCode.Combine(SplineType, Degree); + + public override bool Equals(object? obj) + => obj is PathType pathType && this == pathType; + + public static bool operator ==(PathType a, PathType b) + => a.SplineType == b.SplineType && a.Degree == b.Degree; + + public static bool operator !=(PathType a, PathType b) + => a.SplineType != b.SplineType || a.Degree != b.Degree; + + public static PathType BSpline(int degree) + { + Debug.Assert(degree > 0); + return new PathType { SplineType = SplineType.BSpline, Degree = degree }; + } + } } diff --git a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs index 793d43f7ef..a114529bf9 100644 --- a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs @@ -246,13 +246,13 @@ namespace osu.Game.Screens.Play.HUD barPath = new SliderPath(new[] { - new PathControlPoint(new Vector2(0, 0), PathType.Linear), - new PathControlPoint(new Vector2(curveStart - curve_smoothness, 0), PathType.Bezier), + new PathControlPoint(new Vector2(0, 0), PathType.LINEAR), + new PathControlPoint(new Vector2(curveStart - curve_smoothness, 0), PathType.BEZIER), new PathControlPoint(new Vector2(curveStart, 0)), - new PathControlPoint(new Vector2(curveStart, 0) + diagonalDir * curve_smoothness, PathType.Linear), - new PathControlPoint(new Vector2(curveEnd, BarHeight.Value) - diagonalDir * curve_smoothness, PathType.Bezier), + new PathControlPoint(new Vector2(curveStart, 0) + diagonalDir * curve_smoothness, PathType.LINEAR), + new PathControlPoint(new Vector2(curveEnd, BarHeight.Value) - diagonalDir * curve_smoothness, PathType.BEZIER), new PathControlPoint(new Vector2(curveEnd, BarHeight.Value)), - new PathControlPoint(new Vector2(curveEnd + curve_smoothness, BarHeight.Value), PathType.Linear), + new PathControlPoint(new Vector2(curveEnd + curve_smoothness, BarHeight.Value), PathType.LINEAR), new PathControlPoint(new Vector2(barLength, BarHeight.Value)), });