Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add B-Spline slider curve type #24457

Closed
wants to merge 10 commits into from

Conversation

minetoblend
Copy link
Contributor

@minetoblend minetoblend commented Aug 3, 2023

Summary

RFC. Added b-splines as a curve type for sliders.

Changes made

  • SliderPath.cs
    • Approximate b-spline curve segments
  • PathControlPiece.cs
    • Added a custom color for displaying b-spline controlpoints in the editor
  • ControlPointVisualiser.cs
    • Added a context menu entry to to change controlPoint type to b-spline
  • LegacyBeatmapEncoder.cs
    • Add encoding for b-spline controlPoints
  • LegacyBeatmapExporter.cs
    • When converting sliders to bezier, don't skip single-segment sliders if the path type is b-spline
  • BezierConverter.cs
    • Add conversion logic to turn b-spline segments into bezier segments
  • ConvertHitObjectParser.cs
    • Add b-spline path type to beatmap parsing
  • TestSceneSlider.cs
    • Add test case for b-spline sliders
  • TestSceneBezierConverter.cs
    • Add test cases for b-spline to bezier conversion

Reasoning

B-spline curves combine some of the benefits of both bezier & catmull sliders. They follow the control points more strictly, similar to catmull sliders, while maintaining the aesthetics of bezier sliders. Since they follow the control points more closely, they are easier to work with for new mappers, compared to bezier sliders, where the generated curve can vary widely from the actual control points.

Examples

image
image
image

Thanks to @OliBomby for helping me with this

Copy link
Collaborator

@bdach bdach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surface level review to start with. Will need to look at the conversion logic properly later

Comment on lines +406 to +411
string name = type switch
{
null => "Inherit",
PathType.BSpline => "B-Spline",
_ => type.ToString().Humanize()
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than do this I'd much prefer to stop relying on humanizer at all and instead explicitly annotate the enum members with [Description] or [LocalisableDescription].

Comment on lines +74 to +75
if (segmentCount == 0 || (segmentCount == 1 && hasPath.Path.ControlPoints[0].Type != PathType.BSpline))
continue;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure this should be something like

Suggested change
if (segmentCount == 0 || (segmentCount == 1 && hasPath.Path.ControlPoints[0].Type != PathType.BSpline))
continue;
if (segmentCount <= 1 && hasPath.Path.ControlPoints.All(p => p.Type != PathType.BSpline))

because you can have multiple B-spline segments in a slider. And as soon as you get one you need to convert (but you also need to convert if you have more, or if it isn't first, which the current condition isn't checking).

@@ -87,6 +87,11 @@ public static List<Vector2> ConvertToLegacyBezier(IList<PathControlPoint> contro

break;

case PathType.BSpline:
result.AddRange(from segment in ConvertBSplineToBezierAnchors(segmentVertices) from v in segment select v + position);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ew it's the fake sql syntax. I'll look away because it's already being used elsewhere but I kinda hate it.

@peppy
Copy link
Sponsor Member

peppy commented Aug 3, 2023

TO note before we get too deep in this: I am not sure this should exist as a new option. We already have enough curve types that the learning curve (ha) is quite high. Adding a new one which is very specialised to people who know how to manipulate it, where there is no inherit value as the same shapes can be made with existing multi segment is not necessarily a great direction IMO.

Not to say this can't exist, but I'm not sure how it should fit in the UX.

@OliBomby
Copy link
Contributor

OliBomby commented Aug 6, 2023

TO note before we get too deep in this: I am not sure this should exist as a new option. We already have enough curve types that the learning curve (ha) is quite high. Adding a new one which is very specialised to people who know how to manipulate it, where there is no inherit value as the same shapes can be made with existing multi segment is not necessarily a great direction IMO.

Not to say this can't exist, but I'm not sure how it should fit in the UX.

Calling the B-splines "very specialised to people who know how to manipulate it" is not fair, because using B-spline to create smooth slider shapes is actually much more intuitive than Bézier due to the anchors in B-splines having a fixed and local area of influence. For that reason, I think B-spline is suitable as a replacement for Bézier as the default curve type in path segments with >3 anchors. Though, adding an option to choose whether you want to have Bézier or B-spline as the default will be required, because a lot of mappers right now are so used to the quirks of Bézier already.

@OliBomby
Copy link
Contributor

OliBomby commented Dec 1, 2023

This PR is probably redundant since #25409

@bdach bdach closed this Dec 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants