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

Rotation not working correctly on some sliders #14215

Open
minetoblend opened this issue Aug 10, 2021 · 3 comments
Open

Rotation not working correctly on some sliders #14215

minetoblend opened this issue Aug 10, 2021 · 3 comments
Labels
area:editor priority:2 Moderately important. Relied on by some users or impeding the usability of the game ruleset/osu!

Comments

@minetoblend
Copy link
Contributor

Describe the bug:
Some sliders aren't rotating around their center. The amount of rotation also doesn't seem to match what my mouse is doing on those sliders. I can't tell exactly if this is happening only on some sliders or if the amount of error is just small enough to not be unnoticeable, but I see this in a lot of beatmaps, especially on longer or more complex sliders.

Steps to reproduce:
https://osu.ppy.sh/beatmapsets/889855#osu/1860169
07:01:880 (1) - Happens on this slider.

https://osu.ppy.sh/beatmapsets/832309#osu/1984424
01:17:177 (1) - Also on this slider.

Screenshots or videos showing encountered issue:

https://streamable.com/v854n0

https://streamable.com/ep6dub

osu!lazer version:
2021.809.0

Logs:
logs.zip

@bdach
Copy link
Collaborator

bdach commented Aug 10, 2021

This is happening because the bounding box computation for the slider is an approximation, basically - the centre of rotation used currently is the midpoint between the start position and the end position of the slider. That works for "most" sliders that are somewhat linear in nature, but won't work for things like blanket sliders or the sliderart in maps linked above.

This can be improved for instance by throwing more points at it, at the cost of more allocations. Example patch below (numbers taken out of rear, not tweaked properly at all):

diff --git a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs
index 358a44e0e6..275e7d546e 100644
--- a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs
+++ b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs
@@ -1,6 +1,7 @@
 // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
 // See the LICENCE file in the repository root for full licence text.
 
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using osu.Framework.Graphics;
@@ -282,12 +283,10 @@ private Vector2 getClampedScale(OsuHitObject[] hitObjects, Anchor reference, Vec
             {
                 if (h is IHasPath path)
                 {
-                    return new[]
-                    {
-                        h.Position,
-                        // can't use EndPosition for reverse slider cases.
-                        h.Position + path.Path.PositionAt(1)
-                    };
+                    int estimationPointCount = Math.Max(2, (int)(path.Path.ControlPoints.Count * 0.2f));
+
+                    return Enumerable.Range(0, estimationPointCount)
+                                     .Select(i => h.Position + path.Path.PositionAt((float)i / estimationPointCount));
                 }
 
                 return new[] { h.Position };

Unsure if there are any better ideas than the above?

@minetoblend
Copy link
Contributor Author

I don't know if this approach is any good, but by obtaining the selection blueprint for the slider the SelectionQuad property could be used to get the slider bounds.

Getting the bounds from the blueprints like this seems to be working:

private Quad getSurroundingQuad(OsuHitObject[] hitObjects) =>
    GetSurroundingQuad(hitObjects.SelectMany(h =>
    {
        if (h is IHasPath path)
        {
            var blueprint = SelectedBlueprints.First(b => b.Item == h);

            // shrinking the quad by the object radius to get the bounds of the center line of the path
            return new[]
            {
                ToLocalSpace(blueprint.SelectionQuad.TopLeft) + new Vector2((float)h.Radius),
                ToLocalSpace(blueprint.SelectionQuad.BottomRight) - new Vector2((float)h.Radius)
            };
        }

        return new[] { h.Position };
    }));

@bdach
Copy link
Collaborator

bdach commented Aug 11, 2021

I'm not sure whether the radius adjustment is entirely accurate, since the blueprint's SelectionQuad is sourced from the drawable slider, so I'd have to check whether there aren't any shadows/borders/suchlike that would increase that Radius offset, but otherwise that seems like a tolerable workaround and generally the better suggestion than what I had at least...

@peppy peppy added the priority:2 Moderately important. Relied on by some users or impeding the usability of the game label Aug 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:editor priority:2 Moderately important. Relied on by some users or impeding the usability of the game ruleset/osu!
Projects
None yet
Development

No branches or pull requests

3 participants