mirror of
https://github.com/ppy/osu.git
synced 2025-02-21 22:12:53 +08: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 Dictionary<OsuHitObject, OriginalHitObjectState>? objectsInScale;
|
||||||
private Vector2? defaultOrigin;
|
private Vector2? defaultOrigin;
|
||||||
|
private List<Vector2>? originalConvexHull;
|
||||||
|
|
||||||
public override void Begin()
|
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(slider.Path.ControlPoints.Select(p => slider.Position + p.Position))
|
||||||
: GeometryUtils.GetSurroundingQuad(objectsInScale.Keys);
|
: GeometryUtils.GetSurroundingQuad(objectsInScale.Keys);
|
||||||
defaultOrigin = OriginalSurroundingQuad.Value.Centre;
|
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)
|
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)
|
if (objectsInScale.Count == 1 && objectsInScale.First().Key is Slider slider)
|
||||||
origin = slider.Position;
|
origin = slider.Position;
|
||||||
|
|
||||||
|
float cos = MathF.Cos(float.DegreesToRadians(-axisRotation));
|
||||||
|
float sin = MathF.Sin(float.DegreesToRadians(-axisRotation));
|
||||||
scale = clampScaleToAdjustAxis(scale, adjustAxis);
|
scale = clampScaleToAdjustAxis(scale, adjustAxis);
|
||||||
Vector2 actualOrigin = origin ?? defaultOrigin.Value;
|
Vector2 actualOrigin = origin ?? defaultOrigin.Value;
|
||||||
var selectionQuad = OriginalSurroundingQuad.Value;
|
IEnumerable<Vector2> points;
|
||||||
|
|
||||||
scale = clampToBound(scale, selectionQuad.BottomRight, OsuPlayfield.BASE_SIZE);
|
if (axisRotation == 0)
|
||||||
scale = clampToBound(scale, selectionQuad.TopLeft, Vector2.Zero);
|
{
|
||||||
|
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));
|
return Vector2.ComponentMax(scale, new Vector2(Precision.FLOAT_EPSILON));
|
||||||
|
|
||||||
@ -226,8 +249,6 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
{
|
{
|
||||||
p -= actualOrigin;
|
p -= actualOrigin;
|
||||||
bound -= 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 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);
|
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>
|
/// </summary>
|
||||||
/// <param name="hitObjects">The hit objects to calculate a quad for.</param>
|
/// <param name="hitObjects">The hit objects to calculate a quad for.</param>
|
||||||
public static Quad GetSurroundingQuad(IEnumerable<IHasPosition> hitObjects) =>
|
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)
|
if (h is IHasPath path)
|
||||||
{
|
{
|
||||||
@ -151,6 +196,6 @@ namespace osu.Game.Utils
|
|||||||
}
|
}
|
||||||
|
|
||||||
return new[] { h.Position };
|
return new[] { h.Position };
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user