1
0
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:
smoogipoo 2019-12-18 17:21:38 +09:00
parent f150d22eaf
commit 602ce698d5
7 changed files with 94 additions and 16 deletions

View File

@ -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;
}

View File

@ -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>();

View File

@ -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
{

View File

@ -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
{

View File

@ -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.

View 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);
}
}

View File

@ -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;