1
0
mirror of https://github.com/ppy/osu.git synced 2025-03-10 22:17:20 +08:00

Merge pull request #32158 from bdach/scaling-crash

Fix possible crash when scaling objects in editor
This commit is contained in:
Dean Herbert 2025-03-04 13:40:41 +09:00 committed by GitHub
commit 3fe92fb83c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 32 additions and 26 deletions

View File

@ -18,3 +18,6 @@ M:Humanizer.InflectorExtensions.Pascalize(System.String);Humanizer's .Pascalize(
M:Humanizer.InflectorExtensions.Camelize(System.String);Humanizer's .Camelize() extension method changes behaviour depending on CultureInfo.CurrentCulture. Use StringDehumanizeExtensions.ToCamelCase() instead. M:Humanizer.InflectorExtensions.Camelize(System.String);Humanizer's .Camelize() extension method changes behaviour depending on CultureInfo.CurrentCulture. Use StringDehumanizeExtensions.ToCamelCase() instead.
M:Humanizer.InflectorExtensions.Underscore(System.String);Humanizer's .Underscore() extension method changes behaviour depending on CultureInfo.CurrentCulture. Use StringDehumanizeExtensions.ToSnakeCase() instead. M:Humanizer.InflectorExtensions.Underscore(System.String);Humanizer's .Underscore() extension method changes behaviour depending on CultureInfo.CurrentCulture. Use StringDehumanizeExtensions.ToSnakeCase() instead.
M:Humanizer.InflectorExtensions.Kebaberize(System.String);Humanizer's .Kebaberize() extension method changes behaviour depending on CultureInfo.CurrentCulture. Use StringDehumanizeExtensions.ToKebabCase() instead. M:Humanizer.InflectorExtensions.Kebaberize(System.String);Humanizer's .Kebaberize() extension method changes behaviour depending on CultureInfo.CurrentCulture. Use StringDehumanizeExtensions.ToKebabCase() instead.
M:osuTK.MathHelper.Clamp(System.Int32,System.Int32,System.Int32)~System.Int32;Use Math.Clamp() instead.
M:osuTK.MathHelper.Clamp(System.Single,System.Single,System.Single)~System.Single;This osuTK helper has unsafe semantics when one of the bounds provided is NaN. Use Math.Clamp() instead.
M:osuTK.MathHelper.Clamp(System.Double,System.Double,System.Double)~System.Double;This osuTK helper has unsafe semantics when one of the bounds provided is NaN. Use Math.Clamp() instead.

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
@ -9,7 +10,6 @@ using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Pippidon.Objects; using osu.Game.Rulesets.Pippidon.Objects;
using osu.Game.Rulesets.Pippidon.UI; using osu.Game.Rulesets.Pippidon.UI;
using osuTK;
namespace osu.Game.Rulesets.Pippidon.Beatmaps namespace osu.Game.Rulesets.Pippidon.Beatmaps
{ {
@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Pippidon.Beatmaps
}; };
} }
private int getLane(HitObject hitObject) => (int)MathHelper.Clamp( private int getLane(HitObject hitObject) => (int)Math.Clamp(
(getUsablePosition(hitObject) - minPosition) / (maxPosition - minPosition) * PippidonPlayfield.LANE_COUNT, 0, PippidonPlayfield.LANE_COUNT - 1); (getUsablePosition(hitObject) - minPosition) / (maxPosition - minPosition) * PippidonPlayfield.LANE_COUNT, 0, PippidonPlayfield.LANE_COUNT - 1);
private float getUsablePosition(HitObject h) => (h as IHasYPosition)?.Y ?? ((IHasXPosition)h).X; private float getUsablePosition(HitObject h) => (h as IHasYPosition)?.Y ?? ((IHasXPosition)h).X;

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
@ -110,7 +111,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon
double duration = ObjectState.HitObject.StartTime - ObjectState.DisplayStartTime; double duration = ObjectState.HitObject.StartTime - ObjectState.DisplayStartTime;
fadeContent.Alpha = MathHelper.Clamp( fadeContent.Alpha = Math.Clamp(
Interpolation.ValueAt( Interpolation.ValueAt(
Time.Current, 1f, 0f, Time.Current, 1f, 0f,
ObjectState.DisplayStartTime + duration * lens_flare_start, ObjectState.DisplayStartTime + duration * lens_flare_start,

View File

@ -3,6 +3,7 @@
#nullable disable #nullable disable
using System;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
@ -76,7 +77,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components
if (hasReachedObject && showHitMarkers.Value) if (hasReachedObject && showHitMarkers.Value)
{ {
float alpha = Interpolation.ValueAt(editorTime, 0, 1f, hitObjectTime, hitObjectTime + FADE_OUT_EXTENSION, Easing.In); float alpha = Interpolation.ValueAt(editorTime, 0, 1f, hitObjectTime, hitObjectTime + FADE_OUT_EXTENSION, Easing.In);
float ringScale = MathHelper.Clamp(Interpolation.ValueAt(editorTime, 0, 1f, hitObjectTime, hitObjectTime + FADE_OUT_EXTENSION / 2, Easing.OutQuint), 0, 1); float ringScale = Math.Clamp(Interpolation.ValueAt(editorTime, 0, 1f, hitObjectTime, hitObjectTime + FADE_OUT_EXTENSION / 2, Easing.OutQuint), 0, 1);
ring.Scale = new Vector2(1 + 0.1f * ringScale); ring.Scale = new Vector2(1 + 0.1f * ringScale);
content.Alpha = 0.9f * (1 - alpha); content.Alpha = 0.9f * (1 - alpha);

View File

@ -270,14 +270,14 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
if (adjustVelocity) if (adjustVelocity)
{ {
proposedVelocity = proposedDistance / oldDuration; proposedVelocity = proposedDistance / oldDuration;
proposedDistance = MathHelper.Clamp(proposedDistance, 0.1 * oldDuration, 10 * oldDuration); proposedDistance = Math.Clamp(proposedDistance, 0.1 * oldDuration, 10 * oldDuration);
} }
else else
{ {
double minDistance = distanceSnapProvider?.GetBeatSnapDistance() * oldVelocityMultiplier ?? 1; double minDistance = distanceSnapProvider?.GetBeatSnapDistance() * oldVelocityMultiplier ?? 1;
// Add a small amount to the proposed distance to make it easier to snap to the full length of the slider. // Add a small amount to the proposed distance to make it easier to snap to the full length of the slider.
proposedDistance = distanceSnapProvider?.FindSnappedDistance((float)proposedDistance + 1, HitObject.StartTime, HitObject) ?? proposedDistance; proposedDistance = distanceSnapProvider?.FindSnappedDistance((float)proposedDistance + 1, HitObject.StartTime, HitObject) ?? proposedDistance;
proposedDistance = MathHelper.Clamp(proposedDistance, minDistance, HitObject.Path.CalculatedDistance); proposedDistance = Math.Clamp(proposedDistance, minDistance, HitObject.Path.CalculatedDistance);
} }
if (Precision.AlmostEquals(proposedDistance, HitObject.Path.Distance) && Precision.AlmostEquals(proposedVelocity, HitObject.SliderVelocityMultiplier)) if (Precision.AlmostEquals(proposedDistance, HitObject.Path.Distance) && Precision.AlmostEquals(proposedVelocity, HitObject.SliderVelocityMultiplier))

View File

@ -263,12 +263,12 @@ namespace osu.Game.Rulesets.Osu.Edit
{ {
case Axes.X: case Axes.X:
(sLowerBound, sUpperBound) = computeBounds(lowerBounds - b, upperBounds - b, a); (sLowerBound, sUpperBound) = computeBounds(lowerBounds - b, upperBounds - b, a);
s.X = MathHelper.Clamp(s.X, sLowerBound, sUpperBound); s.X = Math.Clamp(s.X, sLowerBound, sUpperBound);
break; break;
case Axes.Y: case Axes.Y:
(sLowerBound, sUpperBound) = computeBounds(lowerBounds - a, upperBounds - a, b); (sLowerBound, sUpperBound) = computeBounds(lowerBounds - a, upperBounds - a, b);
s.Y = MathHelper.Clamp(s.Y, sLowerBound, sUpperBound); s.Y = Math.Clamp(s.Y, sLowerBound, sUpperBound);
break; break;
case Axes.Both: case Axes.Both:
@ -276,11 +276,11 @@ namespace osu.Game.Rulesets.Osu.Edit
// Therefore the ratio s.X / s.Y will be maintained // Therefore the ratio s.X / s.Y will be maintained
(sLowerBound, sUpperBound) = computeBounds(lowerBounds, upperBounds, a * s.X + b * s.Y); (sLowerBound, sUpperBound) = computeBounds(lowerBounds, upperBounds, a * s.X + b * s.Y);
s.X = s.X < 0 s.X = s.X < 0
? MathHelper.Clamp(s.X, s.X * sUpperBound, s.X * sLowerBound) ? Math.Clamp(s.X, s.X * sUpperBound, s.X * sLowerBound)
: MathHelper.Clamp(s.X, s.X * sLowerBound, s.X * sUpperBound); : Math.Clamp(s.X, s.X * sLowerBound, s.X * sUpperBound);
s.Y = s.Y < 0 s.Y = s.Y < 0
? MathHelper.Clamp(s.Y, s.Y * sUpperBound, s.Y * sLowerBound) ? Math.Clamp(s.Y, s.Y * sUpperBound, s.Y * sLowerBound)
: MathHelper.Clamp(s.Y, s.Y * sLowerBound, s.Y * sUpperBound); : Math.Clamp(s.Y, s.Y * sLowerBound, s.Y * sUpperBound);
break; break;
} }

View File

@ -174,7 +174,7 @@ namespace osu.Game.Overlays
} }
height = toastFlow.DrawHeight + 120; height = toastFlow.DrawHeight + 120;
alpha = MathHelper.Clamp(toastFlow.DrawHeight / 41, 0, 1) * maxNotificationAlpha; alpha = Math.Clamp(toastFlow.DrawHeight / 41, 0, 1) * maxNotificationAlpha;
} }
toastContentBackground.Height = (float)Interpolation.DampContinuously(toastContentBackground.Height, height, 10, Clock.ElapsedFrameTime); toastContentBackground.Height = (float)Interpolation.DampContinuously(toastContentBackground.Height, height, 10, Clock.ElapsedFrameTime);

View File

@ -277,18 +277,18 @@ namespace osu.Game.Screens.Play
if (rulesetComponents != null) if (rulesetComponents != null)
processDrawables(rulesetComponents); processDrawables(rulesetComponents);
if (lowestTopScreenSpaceRight.HasValue) if (lowestTopScreenSpaceRight.HasValue && DrawHeight - TopRightElements.DrawHeight > 0)
TopRightElements.Y = MathHelper.Clamp(ToLocalSpace(new Vector2(0, lowestTopScreenSpaceRight.Value)).Y, 0, DrawHeight - TopRightElements.DrawHeight); TopRightElements.Y = Math.Clamp(ToLocalSpace(new Vector2(0, lowestTopScreenSpaceRight.Value)).Y, 0, DrawHeight - TopRightElements.DrawHeight);
else else
TopRightElements.Y = 0; TopRightElements.Y = 0;
if (lowestTopScreenSpaceLeft.HasValue) if (lowestTopScreenSpaceLeft.HasValue && DrawHeight - LeaderboardFlow.DrawHeight > 0)
LeaderboardFlow.Y = MathHelper.Clamp(ToLocalSpace(new Vector2(0, lowestTopScreenSpaceLeft.Value)).Y, 0, DrawHeight - LeaderboardFlow.DrawHeight); LeaderboardFlow.Y = Math.Clamp(ToLocalSpace(new Vector2(0, lowestTopScreenSpaceLeft.Value)).Y, 0, DrawHeight - LeaderboardFlow.DrawHeight);
else else
LeaderboardFlow.Y = 0; LeaderboardFlow.Y = 0;
if (highestBottomScreenSpace.HasValue) if (highestBottomScreenSpace.HasValue && DrawHeight - bottomRightElements.DrawHeight > 0)
bottomRightElements.Y = BottomScoringElementsHeight = -MathHelper.Clamp(DrawHeight - ToLocalSpace(highestBottomScreenSpace.Value).Y, 0, DrawHeight - bottomRightElements.DrawHeight); bottomRightElements.Y = BottomScoringElementsHeight = -Math.Clamp(DrawHeight - ToLocalSpace(highestBottomScreenSpace.Value).Y, 0, DrawHeight - bottomRightElements.DrawHeight);
else else
bottomRightElements.Y = 0; bottomRightElements.Y = 0;

View File

@ -201,8 +201,8 @@ namespace osu.Game.Screens.Utility
{ {
double preempt = (float)IBeatmapDifficultyInfo.DifficultyRange(SampleApproachRate.Value, 1800, 1200, 450); double preempt = (float)IBeatmapDifficultyInfo.DifficultyRange(SampleApproachRate.Value, 1800, 1200, 450);
approach.Scale = new Vector2(1 + 4 * (float)MathHelper.Clamp((HitTime - Clock.CurrentTime) / preempt, 0, 100)); approach.Scale = new Vector2(1 + 4 * (float)Math.Clamp((HitTime - Clock.CurrentTime) / preempt, 0, 100));
Alpha = (float)MathHelper.Clamp((Clock.CurrentTime - HitTime + 600) / 400, 0, 1); Alpha = (float)Math.Clamp((Clock.CurrentTime - HitTime + 600) / 400, 0, 1);
if (Clock.CurrentTime > HitTime + duration) if (Clock.CurrentTime > HitTime + duration)
Expire(); Expire();

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
@ -55,22 +56,22 @@ namespace osu.Game.Screens.Utility.SampleComponents
{ {
case Key.F: case Key.F:
case Key.Up: case Key.Up:
box.Y = MathHelper.Clamp(box.Y - movementAmount, 0.1f, 0.9f); box.Y = Math.Clamp(box.Y - movementAmount, 0.1f, 0.9f);
break; break;
case Key.J: case Key.J:
case Key.Down: case Key.Down:
box.Y = MathHelper.Clamp(box.Y + movementAmount, 0.1f, 0.9f); box.Y = Math.Clamp(box.Y + movementAmount, 0.1f, 0.9f);
break; break;
case Key.Z: case Key.Z:
case Key.Left: case Key.Left:
box.X = MathHelper.Clamp(box.X - movementAmount, 0.1f, 0.9f); box.X = Math.Clamp(box.X - movementAmount, 0.1f, 0.9f);
break; break;
case Key.X: case Key.X:
case Key.Right: case Key.Right:
box.X = MathHelper.Clamp(box.X + movementAmount, 0.1f, 0.9f); box.X = Math.Clamp(box.X + movementAmount, 0.1f, 0.9f);
break; break;
} }
} }

View File

@ -165,7 +165,7 @@ namespace osu.Game.Screens.Utility
{ {
double preempt = (float)IBeatmapDifficultyInfo.DifficultyRange(SampleApproachRate.Value, 1800, 1200, 450); double preempt = (float)IBeatmapDifficultyInfo.DifficultyRange(SampleApproachRate.Value, 1800, 1200, 450);
Alpha = (float)MathHelper.Clamp((Clock.CurrentTime - HitTime + 600) / 400, 0, 1); Alpha = (float)Math.Clamp((Clock.CurrentTime - HitTime + 600) / 400, 0, 1);
Y = judgement_position - (float)((HitTime - Clock.CurrentTime) / preempt); Y = judgement_position - (float)((HitTime - Clock.CurrentTime) / preempt);
if (Clock.CurrentTime > HitTime + duration) if (Clock.CurrentTime > HitTime + duration)