mirror of
https://github.com/ppy/osu.git
synced 2024-12-13 08:32:57 +08:00
Fix storyboard vectorscale and scale cross-pollution
This commit is contained in:
parent
f150d22eaf
commit
602ce698d5
@ -176,7 +176,7 @@ namespace osu.Game.Beatmaps.Formats
|
||||
{
|
||||
var startValue = float.Parse(split[4], CultureInfo.InvariantCulture);
|
||||
var endValue = split.Length > 5 ? float.Parse(split[5], CultureInfo.InvariantCulture) : startValue;
|
||||
timelineGroup?.Scale.Add(easing, startTime, endTime, new Vector2(startValue), new Vector2(endValue));
|
||||
timelineGroup?.Scale.Add(easing, startTime, endTime, startValue, endValue);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@ namespace osu.Game.Beatmaps.Formats
|
||||
var startY = float.Parse(split[5], CultureInfo.InvariantCulture);
|
||||
var endX = split.Length > 6 ? float.Parse(split[6], CultureInfo.InvariantCulture) : startX;
|
||||
var endY = split.Length > 7 ? float.Parse(split[7], CultureInfo.InvariantCulture) : startY;
|
||||
timelineGroup?.Scale.Add(easing, startTime, endTime, new Vector2(startX, startY), new Vector2(endX, endY));
|
||||
timelineGroup?.VectorScale.Add(easing, startTime, endTime, new Vector2(startX, startY), new Vector2(endX, endY));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,8 @@ namespace osu.Game.Storyboards
|
||||
{
|
||||
public CommandTimeline<float> X = new CommandTimeline<float>();
|
||||
public CommandTimeline<float> Y = new CommandTimeline<float>();
|
||||
public CommandTimeline<Vector2> Scale = new CommandTimeline<Vector2>();
|
||||
public CommandTimeline<float> Scale = new CommandTimeline<float>();
|
||||
public CommandTimeline<Vector2> VectorScale = new CommandTimeline<Vector2>();
|
||||
public CommandTimeline<float> Rotation = new CommandTimeline<float>();
|
||||
public CommandTimeline<Color4> Colour = new CommandTimeline<Color4>();
|
||||
public CommandTimeline<float> Alpha = new CommandTimeline<float>();
|
||||
|
@ -8,21 +8,44 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Animations;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Game.Beatmaps;
|
||||
|
||||
namespace osu.Game.Storyboards.Drawables
|
||||
{
|
||||
public class DrawableStoryboardAnimation : TextureAnimation, IFlippable
|
||||
public class DrawableStoryboardAnimation : TextureAnimation, IFlippable, IVectorScalable
|
||||
{
|
||||
public StoryboardAnimation Animation { get; private set; }
|
||||
|
||||
public bool FlipH { get; set; }
|
||||
public bool FlipV { get; set; }
|
||||
|
||||
private Vector2 vectorScale = Vector2.One;
|
||||
|
||||
public Vector2 VectorScale
|
||||
{
|
||||
get => vectorScale;
|
||||
set
|
||||
{
|
||||
if (Math.Abs(value.X) < Precision.FLOAT_EPSILON)
|
||||
value.X = Precision.FLOAT_EPSILON;
|
||||
if (Math.Abs(value.Y) < Precision.FLOAT_EPSILON)
|
||||
value.Y = Precision.FLOAT_EPSILON;
|
||||
|
||||
if (vectorScale == value)
|
||||
return;
|
||||
|
||||
if (!Validation.IsFinite(value)) throw new ArgumentException($@"{nameof(VectorScale)} must be finite, but is {value}.");
|
||||
|
||||
vectorScale = value;
|
||||
Invalidate(Invalidation.MiscGeometry);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool RemoveWhenNotAlive => false;
|
||||
|
||||
protected override Vector2 DrawScale
|
||||
=> new Vector2(FlipH ? -base.DrawScale.X : base.DrawScale.X, FlipV ? -base.DrawScale.Y : base.DrawScale.Y);
|
||||
=> new Vector2(FlipH ? -base.DrawScale.X : base.DrawScale.X, FlipV ? -base.DrawScale.Y : base.DrawScale.Y) * VectorScale;
|
||||
|
||||
public override Anchor Origin
|
||||
{
|
||||
|
@ -8,21 +8,44 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Game.Beatmaps;
|
||||
|
||||
namespace osu.Game.Storyboards.Drawables
|
||||
{
|
||||
public class DrawableStoryboardSprite : Sprite, IFlippable
|
||||
public class DrawableStoryboardSprite : Sprite, IFlippable, IVectorScalable
|
||||
{
|
||||
public StoryboardSprite Sprite { get; private set; }
|
||||
|
||||
public bool FlipH { get; set; }
|
||||
public bool FlipV { get; set; }
|
||||
|
||||
private Vector2 vectorScale = Vector2.One;
|
||||
|
||||
public Vector2 VectorScale
|
||||
{
|
||||
get => vectorScale;
|
||||
set
|
||||
{
|
||||
if (Math.Abs(value.X) < Precision.FLOAT_EPSILON)
|
||||
value.X = Precision.FLOAT_EPSILON;
|
||||
if (Math.Abs(value.Y) < Precision.FLOAT_EPSILON)
|
||||
value.Y = Precision.FLOAT_EPSILON;
|
||||
|
||||
if (vectorScale == value)
|
||||
return;
|
||||
|
||||
if (!Validation.IsFinite(value)) throw new ArgumentException($@"{nameof(VectorScale)} must be finite, but is {value}.");
|
||||
|
||||
vectorScale = value;
|
||||
Invalidate(Invalidation.MiscGeometry);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool RemoveWhenNotAlive => false;
|
||||
|
||||
protected override Vector2 DrawScale
|
||||
=> new Vector2(FlipH ? -base.DrawScale.X : base.DrawScale.X, FlipV ? -base.DrawScale.Y : base.DrawScale.Y);
|
||||
=> new Vector2(FlipH ? -base.DrawScale.X : base.DrawScale.X, FlipV ? -base.DrawScale.Y : base.DrawScale.Y) * VectorScale;
|
||||
|
||||
public override Anchor Origin
|
||||
{
|
||||
|
@ -6,13 +6,13 @@ using osu.Framework.Graphics.Transforms;
|
||||
|
||||
namespace osu.Game.Storyboards.Drawables
|
||||
{
|
||||
public interface IFlippable : ITransformable
|
||||
internal interface IFlippable : ITransformable
|
||||
{
|
||||
bool FlipH { get; set; }
|
||||
bool FlipV { get; set; }
|
||||
}
|
||||
|
||||
public class TransformFlipH : Transform<bool, IFlippable>
|
||||
internal class TransformFlipH : Transform<bool, IFlippable>
|
||||
{
|
||||
private bool valueAt(double time)
|
||||
=> time < EndTime ? StartValue : EndValue;
|
||||
@ -23,7 +23,7 @@ namespace osu.Game.Storyboards.Drawables
|
||||
protected override void ReadIntoStartValue(IFlippable d) => StartValue = d.FlipH;
|
||||
}
|
||||
|
||||
public class TransformFlipV : Transform<bool, IFlippable>
|
||||
internal class TransformFlipV : Transform<bool, IFlippable>
|
||||
{
|
||||
private bool valueAt(double time)
|
||||
=> time < EndTime ? StartValue : EndValue;
|
||||
@ -34,7 +34,7 @@ namespace osu.Game.Storyboards.Drawables
|
||||
protected override void ReadIntoStartValue(IFlippable d) => StartValue = d.FlipV;
|
||||
}
|
||||
|
||||
public static class FlippableExtensions
|
||||
internal static class FlippableExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adjusts <see cref="IFlippable.FlipH"/> after a delay.
|
||||
|
21
osu.Game/Storyboards/Drawables/IVectorScalable.cs
Normal file
21
osu.Game/Storyboards/Drawables/IVectorScalable.cs
Normal file
@ -0,0 +1,21 @@
|
||||
// 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 osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Transforms;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Storyboards.Drawables
|
||||
{
|
||||
internal interface IVectorScalable : ITransformable
|
||||
{
|
||||
Vector2 VectorScale { get; set; }
|
||||
}
|
||||
|
||||
internal static class VectorScalableExtensions
|
||||
{
|
||||
public static TransformSequence<T> VectorScaleTo<T>(this T target, Vector2 newVectorScale, double duration = 0, Easing easing = Easing.None)
|
||||
where T : class, IVectorScalable
|
||||
=> target.TransformTo(nameof(IVectorScalable.VectorScale), newVectorScale, duration, easing);
|
||||
}
|
||||
}
|
@ -65,20 +65,30 @@ namespace osu.Game.Storyboards
|
||||
{
|
||||
applyCommands(drawable, getCommands(g => g.X, triggeredGroups), (d, value) => d.X = value, (d, value, duration, easing) => d.MoveToX(value, duration, easing));
|
||||
applyCommands(drawable, getCommands(g => g.Y, triggeredGroups), (d, value) => d.Y = value, (d, value, duration, easing) => d.MoveToY(value, duration, easing));
|
||||
applyCommands(drawable, getCommands(g => g.Scale, triggeredGroups), (d, value) => d.Scale = value, (d, value, duration, easing) => d.ScaleTo(value, duration, easing));
|
||||
applyCommands(drawable, getCommands(g => g.Scale, triggeredGroups), (d, value) => d.Scale = new Vector2(value), (d, value, duration, easing) => d.ScaleTo(value, duration, easing));
|
||||
applyCommands(drawable, getCommands(g => g.Rotation, triggeredGroups), (d, value) => d.Rotation = value, (d, value, duration, easing) => d.RotateTo(value, duration, easing));
|
||||
applyCommands(drawable, getCommands(g => g.Colour, triggeredGroups), (d, value) => d.Colour = value, (d, value, duration, easing) => d.FadeColour(value, duration, easing));
|
||||
applyCommands(drawable, getCommands(g => g.Alpha, triggeredGroups), (d, value) => d.Alpha = value, (d, value, duration, easing) => d.FadeTo(value, duration, easing));
|
||||
applyCommands(drawable, getCommands(g => g.BlendingParameters, triggeredGroups), (d, value) => d.Blending = value, (d, value, duration, easing) => d.TransformBlendingMode(value, duration), false);
|
||||
applyCommands(drawable, getCommands(g => g.BlendingParameters, triggeredGroups), (d, value) => d.Blending = value, (d, value, duration, easing) => d.TransformBlendingMode(value, duration),
|
||||
false);
|
||||
|
||||
if (drawable is IVectorScalable vectorScalable)
|
||||
{
|
||||
applyCommands(drawable, getCommands(g => g.VectorScale, triggeredGroups), (d, value) => vectorScalable.VectorScale = value,
|
||||
(d, value, duration, easing) => vectorScalable.VectorScaleTo(value, duration, easing));
|
||||
}
|
||||
|
||||
if (drawable is IFlippable flippable)
|
||||
{
|
||||
applyCommands(drawable, getCommands(g => g.FlipH, triggeredGroups), (d, value) => flippable.FlipH = value, (d, value, duration, easing) => flippable.TransformFlipH(value, duration), false);
|
||||
applyCommands(drawable, getCommands(g => g.FlipV, triggeredGroups), (d, value) => flippable.FlipV = value, (d, value, duration, easing) => flippable.TransformFlipV(value, duration), false);
|
||||
applyCommands(drawable, getCommands(g => g.FlipH, triggeredGroups), (d, value) => flippable.FlipH = value, (d, value, duration, easing) => flippable.TransformFlipH(value, duration),
|
||||
false);
|
||||
applyCommands(drawable, getCommands(g => g.FlipV, triggeredGroups), (d, value) => flippable.FlipV = value, (d, value, duration, easing) => flippable.TransformFlipV(value, duration),
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
private void applyCommands<T>(Drawable drawable, IEnumerable<CommandTimeline<T>.TypedCommand> commands, DrawablePropertyInitializer<T> initializeProperty, DrawableTransformer<T> transform, bool alwaysInitialize = true)
|
||||
private void applyCommands<T>(Drawable drawable, IEnumerable<CommandTimeline<T>.TypedCommand> commands, DrawablePropertyInitializer<T> initializeProperty, DrawableTransformer<T> transform,
|
||||
bool alwaysInitialize = true)
|
||||
where T : struct
|
||||
{
|
||||
var initialized = false;
|
||||
|
Loading…
Reference in New Issue
Block a user