mirror of
https://github.com/ppy/osu
synced 2025-01-12 00:59:35 +00:00
fix rotated scale bounds again
This commit is contained in:
parent
ae38002777
commit
58eb7f6fe1
@ -69,6 +69,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
|
||||
private Dictionary<OsuHitObject, OriginalHitObjectState>? objectsInScale;
|
||||
private Vector2? defaultOrigin;
|
||||
private List<Vector2>? originalConvexHull;
|
||||
|
||||
public override void Begin()
|
||||
{
|
||||
@ -84,6 +85,9 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
? GeometryUtils.GetSurroundingQuad(slider.Path.ControlPoints.Select(p => slider.Position + p.Position))
|
||||
: GeometryUtils.GetSurroundingQuad(objectsInScale.Keys);
|
||||
defaultOrigin = OriginalSurroundingQuad.Value.Centre;
|
||||
originalConvexHull = objectsInScale.Count == 1 && objectsInScale.First().Key is Slider slider2
|
||||
? GeometryUtils.GetConvexHull(slider2.Path.ControlPoints.Select(p => slider2.Position + p.Position))
|
||||
: GeometryUtils.GetConvexHull(objectsInScale.Keys);
|
||||
}
|
||||
|
||||
public override void Update(Vector2 scale, Vector2? origin = null, Axes adjustAxis = Axes.Both, float axisRotation = 0)
|
||||
@ -211,12 +215,31 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
if (objectsInScale.Count == 1 && objectsInScale.First().Key is Slider slider)
|
||||
origin = slider.Position;
|
||||
|
||||
float cos = MathF.Cos(float.DegreesToRadians(-axisRotation));
|
||||
float sin = MathF.Sin(float.DegreesToRadians(-axisRotation));
|
||||
scale = clampScaleToAdjustAxis(scale, adjustAxis);
|
||||
Vector2 actualOrigin = origin ?? defaultOrigin.Value;
|
||||
var selectionQuad = OriginalSurroundingQuad.Value;
|
||||
IEnumerable<Vector2> points;
|
||||
|
||||
scale = clampToBound(scale, selectionQuad.BottomRight, OsuPlayfield.BASE_SIZE);
|
||||
scale = clampToBound(scale, selectionQuad.TopLeft, Vector2.Zero);
|
||||
if (axisRotation == 0)
|
||||
{
|
||||
var selectionQuad = OriginalSurroundingQuad.Value;
|
||||
points = new[]
|
||||
{
|
||||
selectionQuad.TopLeft,
|
||||
selectionQuad.TopRight,
|
||||
selectionQuad.BottomLeft,
|
||||
selectionQuad.BottomRight
|
||||
};
|
||||
}
|
||||
else
|
||||
points = originalConvexHull!;
|
||||
|
||||
foreach (var point in points)
|
||||
{
|
||||
scale = clampToBound(scale, point, Vector2.Zero);
|
||||
scale = clampToBound(scale, point, OsuPlayfield.BASE_SIZE);
|
||||
}
|
||||
|
||||
return Vector2.ComponentMax(scale, new Vector2(Precision.FLOAT_EPSILON));
|
||||
|
||||
@ -226,8 +249,6 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
{
|
||||
p -= actualOrigin;
|
||||
bound -= actualOrigin;
|
||||
float cos = MathF.Cos(float.DegreesToRadians(-axisRotation));
|
||||
float sin = MathF.Sin(float.DegreesToRadians(-axisRotation));
|
||||
var a = new Vector2(cos * cos * p.X - sin * cos * p.Y, -sin * cos * p.X + sin * sin * p.Y);
|
||||
var b = new Vector2(sin * sin * p.X + sin * cos * p.Y, sin * cos * p.X + cos * cos * p.Y);
|
||||
|
||||
|
@ -138,7 +138,52 @@ namespace osu.Game.Utils
|
||||
/// </summary>
|
||||
/// <param name="hitObjects">The hit objects to calculate a quad for.</param>
|
||||
public static Quad GetSurroundingQuad(IEnumerable<IHasPosition> hitObjects) =>
|
||||
GetSurroundingQuad(hitObjects.SelectMany(h =>
|
||||
GetSurroundingQuad(enumerateStartAndEndPositions(hitObjects));
|
||||
|
||||
/// <summary>
|
||||
/// Returns the points that make up the convex hull of the provided points.
|
||||
/// </summary>
|
||||
/// <param name="points">The points to calculate a convex hull.</param>
|
||||
public static List<Vector2> GetConvexHull(IEnumerable<Vector2> points)
|
||||
{
|
||||
List<Vector2> p = points.ToList();
|
||||
|
||||
if (p.Count <= 1)
|
||||
return p;
|
||||
|
||||
int n = p.Count, k = 0;
|
||||
List<Vector2> hull = new List<Vector2>(new Vector2[2 * n]);
|
||||
|
||||
p.Sort((a, b) => a.X == b.X ? a.Y.CompareTo(b.Y) : a.X.CompareTo(b.X));
|
||||
|
||||
// Build lower hull
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
while (k >= 2 && cross(hull[k - 2], hull[k - 1], p[i]) <= 0)
|
||||
k--;
|
||||
hull[k] = p[i];
|
||||
k++;
|
||||
}
|
||||
|
||||
// Build upper hull
|
||||
for (int i = n - 2, t = k + 1; i >= 0; i--)
|
||||
{
|
||||
while (k >= t && cross(hull[k - 2], hull[k - 1], p[i]) <= 0)
|
||||
k--;
|
||||
hull[k] = p[i];
|
||||
k++;
|
||||
}
|
||||
|
||||
return hull.Take(k - 1).ToList();
|
||||
|
||||
float cross(Vector2 o, Vector2 a, Vector2 b) => (a.X - o.X) * (b.Y - o.Y) - (a.Y - o.Y) * (b.X - o.X);
|
||||
}
|
||||
|
||||
public static List<Vector2> GetConvexHull(IEnumerable<IHasPosition> hitObjects) =>
|
||||
GetConvexHull(enumerateStartAndEndPositions(hitObjects));
|
||||
|
||||
private static IEnumerable<Vector2> enumerateStartAndEndPositions(IEnumerable<IHasPosition> hitObjects) =>
|
||||
hitObjects.SelectMany(h =>
|
||||
{
|
||||
if (h is IHasPath path)
|
||||
{
|
||||
@ -151,6 +196,6 @@ namespace osu.Game.Utils
|
||||
}
|
||||
|
||||
return new[] { h.Position };
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user