From b0a948df459440dc7aefcf661e446a3eefe732bd Mon Sep 17 00:00:00 2001 From: Alden Wu Date: Tue, 4 Oct 2022 00:17:00 -0700 Subject: [PATCH] Move `LegacySmoke` animation implementation to `Smoke` --- WeatherConfig.dat | 3 + .../Skinning/Default/DefaultSmoke.cs | 52 ------- .../Skinning/Legacy/LegacySmoke.cs | 144 +----------------- .../Legacy/OsuLegacySkinTransformer.cs | 2 +- osu.Game.Rulesets.Osu/Skinning/Smoke.cs | 127 +++++++++++++-- 5 files changed, 121 insertions(+), 207 deletions(-) create mode 100644 WeatherConfig.dat diff --git a/WeatherConfig.dat b/WeatherConfig.dat new file mode 100644 index 0000000000..88a312bf91 --- /dev/null +++ b/WeatherConfig.dat @@ -0,0 +1,3 @@ +5363943 +La Jolla,US +F diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSmoke.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSmoke.cs index 65ae490882..c3bc04a858 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSmoke.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSmoke.cs @@ -1,65 +1,13 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; -using osu.Framework.Graphics; -using osuTK; -using osuTK.Graphics; - namespace osu.Game.Rulesets.Osu.Skinning.Default { public class DefaultSmoke : Smoke { - private const double fade_out_delay = 8000; - private const double fade_out_speed = 3; - private const double fade_out_duration = 50; - private const float alpha = 0.5f; - - public override double LifetimeEnd => SmokeEndTime + fade_out_delay + fade_out_duration + (SmokeEndTime - SmokeStartTime) / fade_out_speed; - public DefaultSmoke() { Radius = 2; } - - protected override DrawNode CreateDrawNode() => new DefaultSmokeDrawNode(this); - - private class DefaultSmokeDrawNode : SmokeDrawNode - { - private double fadeOutTime; - - public DefaultSmokeDrawNode(ITexturedShaderDrawable source) - : base(source) - { - } - - public override void ApplyState() - { - base.ApplyState(); - - fadeOutTime = SmokeStartTime + fade_out_speed * (CurrentTime - (SmokeEndTime + fade_out_delay)); - } - - protected override Color4 PointColour(SmokePoint point) - { - var color = Color4.White; - color.A = alpha; - - double timeDoingFadeOut = fadeOutTime - point.Time; - - if (timeDoingFadeOut > 0) - { - float fraction = Math.Clamp((float)(1 - (timeDoingFadeOut / fade_out_duration)), 0, 1); - fraction = MathF.Pow(fraction, 5); - color.A *= fraction; - } - - return color; - } - - protected override float PointScale(SmokePoint point) => 1f; - - protected override Vector2 PointDirection(SmokePoint point) => point.Direction; - } } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySmoke.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySmoke.cs index b8d70c1c6d..89e90cd4c8 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySmoke.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySmoke.cs @@ -1,157 +1,19 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; -using osu.Framework.Graphics; -using osu.Framework.Utils; +using osu.Framework.Allocation; using osu.Game.Skinning; -using osuTK; -using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Legacy { public class LegacySmoke : Smoke { - // fade values - private const double initial_fade_out_duration = 4000; - - private const double re_fade_in_speed = 3; - private const double re_fade_in_duration = 50; - - private const double final_fade_out_speed = 2; - private const double final_fade_out_duration = 8000; - - private const float initial_alpha = 0.6f; - private const float re_fade_in_alpha = 1f; - - // scale values - private const double scale_duration = 1200; - - private const float initial_scale = 0.65f; - private const float final_scale = 1f; - - // rotation values - private const double rotation_duration = 500; - - private const float max_rotation = 0.25f; - - protected int RotationSeed { get; set; } = RNG.Next(); - - public override double LifetimeEnd - { - get - { - double initialFadeOutDurationTrunc = Math.Min(initial_fade_out_duration, SmokeEndTime - SmokeStartTime); - return SmokeEndTime + final_fade_out_duration + initialFadeOutDurationTrunc / re_fade_in_speed + initialFadeOutDurationTrunc / final_fade_out_speed; - } - } - - private readonly ISkin skin; - - public LegacySmoke(ISkin skin) - { - this.skin = skin; - } - - protected override void LoadComplete() + [BackgroundDependencyLoader] + private void load(ISkinSource skin) { base.LoadComplete(); Texture = skin.GetTexture("cursor-smoke"); } - - protected override DrawNode CreateDrawNode() => new LegacySmokeDrawNode(this); - - protected class LegacySmokeDrawNode : SmokeDrawNode - { - protected new LegacySmoke Source => (LegacySmoke)base.Source; - - private double initialFadeOutDurationTrunc; - private double firstVisiblePointTime; - - private double initialFadeOutTime; - private double reFadeInTime; - private double finalFadeOutTime; - - private int rotationSeed; - private Random rotationRNG = new Random(); - - public LegacySmokeDrawNode(ITexturedShaderDrawable source) - : base(source) - { - } - - public override void ApplyState() - { - base.ApplyState(); - - rotationSeed = Source.RotationSeed; - rotationRNG = new Random(rotationSeed); - - initialFadeOutDurationTrunc = Math.Min(initial_fade_out_duration, SmokeEndTime - SmokeStartTime); - firstVisiblePointTime = SmokeEndTime - initialFadeOutDurationTrunc; - - initialFadeOutTime = CurrentTime; - reFadeInTime = CurrentTime - initialFadeOutDurationTrunc - firstVisiblePointTime * (1 - 1 / re_fade_in_speed); - finalFadeOutTime = CurrentTime - initialFadeOutDurationTrunc - firstVisiblePointTime * (1 - 1 / final_fade_out_speed); - } - - protected override Color4 PointColour(SmokePoint point) - { - var color = Color4.White; - - double timeDoingInitialFadeOut = Math.Min(initialFadeOutTime, SmokeEndTime) - point.Time; - - if (timeDoingInitialFadeOut > 0) - { - float fraction = Math.Clamp((float)(timeDoingInitialFadeOut / initial_fade_out_duration), 0, 1); - color.A = (1 - fraction) * initial_alpha; - } - - if (color.A > 0) - { - double timeDoingReFadeIn = reFadeInTime - point.Time / re_fade_in_speed; - double timeDoingFinalFadeOut = finalFadeOutTime - point.Time / final_fade_out_speed; - - if (timeDoingFinalFadeOut > 0) - { - float fraction = Math.Clamp((float)(timeDoingFinalFadeOut / final_fade_out_duration), 0, 1); - fraction = MathF.Pow(fraction, 5); - color.A = (1 - fraction) * re_fade_in_alpha; - } - else if (timeDoingReFadeIn > 0) - { - float fraction = Math.Clamp((float)(timeDoingReFadeIn / re_fade_in_duration), 0, 1); - fraction = 1 - MathF.Pow(1 - fraction, 5); - color.A = fraction * (re_fade_in_alpha - color.A) + color.A; - } - } - - return color; - } - - protected override float PointScale(SmokePoint point) - { - double timeDoingScale = CurrentTime - point.Time; - float fraction = Math.Clamp((float)(timeDoingScale / scale_duration), 0, 1); - fraction = 1 - MathF.Pow(1 - fraction, 5); - return fraction * (final_scale - initial_scale) + initial_scale; - } - - protected override Vector2 PointDirection(SmokePoint point) - { - float initialAngle = MathF.Atan2(point.Direction.Y, point.Direction.X); - float finalAngle = initialAngle + nextRotation(); - - double timeDoingRotation = CurrentTime - point.Time; - float fraction = Math.Clamp((float)(timeDoingRotation / rotation_duration), 0, 1); - fraction = 1 - MathF.Pow(1 - fraction, 5); - float angle = fraction * (finalAngle - initialAngle) + initialAngle; - - return new Vector2(MathF.Sin(angle), -MathF.Cos(angle)); - } - - private float nextRotation() => max_rotation * ((float)rotationRNG.NextDouble() * 2 - 1); - } } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs index a9186f821e..d44d2b031a 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs @@ -108,7 +108,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy case OsuSkinComponents.Smoke: if (GetTexture("cursor-smoke") != null) - return new LegacySmoke(this); + return new LegacySmoke(); return null; diff --git a/osu.Game.Rulesets.Osu/Skinning/Smoke.cs b/osu.Game.Rulesets.Osu/Skinning/Smoke.cs index fae875eedb..5d2aa2b1f6 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Smoke.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Smoke.cs @@ -25,6 +25,15 @@ namespace osu.Game.Rulesets.Osu.Skinning public IShader? TextureShader { get; private set; } public IShader? RoundedTextureShader { get; private set; } + public override double LifetimeEnd + { + get + { + double initialFadeOutDurationTrunc = Math.Min(initial_fade_out_duration, SmokeEndTime - SmokeStartTime); + return SmokeEndTime + final_fade_out_duration + initialFadeOutDurationTrunc / re_fade_in_speed + initialFadeOutDurationTrunc / final_fade_out_speed; + } + } + private float? radius; protected float Radius @@ -39,21 +48,45 @@ namespace osu.Game.Rulesets.Osu.Skinning protected double SmokeEndTime { get; private set; } = double.MaxValue; - protected virtual float PointInterval => Radius * 7f / 8; - protected readonly List SmokePoints = new List(); + protected virtual float PointInterval => Radius * 7f / 8; + private float totalDistance; private Vector2? lastPosition; + private SmokeContainer? smokeContainer; private const int max_point_count = 18_000; - [Resolved(CanBeNull = true)] - private SmokeContainer? smokeContainer { get; set; } + // fade anim values + private const double initial_fade_out_duration = 4000; + + private const double re_fade_in_speed = 3; + private const double re_fade_in_duration = 50; + + private const double final_fade_out_speed = 2; + private const double final_fade_out_duration = 8000; + + private const float initial_alpha = 0.6f; + private const float re_fade_in_alpha = 1f; + + private readonly int rotationSeed = RNG.Next(); + + // scale anim values + private const double scale_duration = 1200; + + private const float initial_scale = 0.65f; + private const float final_scale = 1f; + + // rotation anim values + private const double rotation_duration = 500; + + private const float max_rotation = 0.25f; [BackgroundDependencyLoader] - private void load(ShaderManager shaders) + private void load(SmokeContainer container, ShaderManager shaders) { + smokeContainer = container; RoundedTextureShader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); TextureShader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE); } @@ -128,8 +161,6 @@ namespace osu.Game.Rulesets.Osu.Skinning onSmokeEnded(time); } - public abstract override double LifetimeEnd { get; } - private void onSmokeEnded(double time) { if (smokeContainer != null) @@ -141,7 +172,7 @@ namespace osu.Game.Rulesets.Osu.Skinning SmokeEndTime = time; } - protected abstract override DrawNode CreateDrawNode(); + protected override DrawNode CreateDrawNode() => new SmokeDrawNode(this); protected override void Update() { @@ -181,7 +212,7 @@ namespace osu.Game.Rulesets.Osu.Skinning } } - protected abstract class SmokeDrawNode : TexturedShaderDrawNode + protected class SmokeDrawNode : TexturedShaderDrawNode { protected new Smoke Source => (Smoke)base.Source; @@ -195,7 +226,17 @@ namespace osu.Game.Rulesets.Osu.Skinning private Vector2 drawSize; private Texture? texture; - protected SmokeDrawNode(ITexturedShaderDrawable source) + // anim calculation vars (color, scale, direction) + private double initialFadeOutDurationTrunc; + private double firstVisiblePointTime; + + private double initialFadeOutTime; + private double reFadeInTime; + private double finalFadeOutTime; + + private Random rotationRNG = new Random(); + + public SmokeDrawNode(ITexturedShaderDrawable source) : base(source) { } @@ -214,6 +255,15 @@ namespace osu.Game.Rulesets.Osu.Skinning SmokeStartTime = Source.SmokeStartTime; SmokeEndTime = Source.SmokeEndTime; CurrentTime = Source.Clock.CurrentTime; + + rotationRNG = new Random(Source.rotationSeed); + + initialFadeOutDurationTrunc = Math.Min(initial_fade_out_duration, SmokeEndTime - SmokeStartTime); + firstVisiblePointTime = SmokeEndTime - initialFadeOutDurationTrunc; + + initialFadeOutTime = CurrentTime; + reFadeInTime = CurrentTime - initialFadeOutDurationTrunc - firstVisiblePointTime * (1 - 1 / re_fade_in_speed); + finalFadeOutTime = CurrentTime - initialFadeOutDurationTrunc - firstVisiblePointTime * (1 - 1 / final_fade_out_speed); } public sealed override void Draw(IRenderer renderer) @@ -246,11 +296,62 @@ namespace osu.Game.Rulesets.Osu.Skinning ? ((SRGBColour)DrawColourInfo.Colour).Linear : DrawColourInfo.Colour.Interpolate(Vector2.Divide(localPos, drawSize)).Linear; - protected abstract Color4 PointColour(SmokePoint point); + protected virtual Color4 PointColour(SmokePoint point) + { + var color = Color4.White; - protected abstract float PointScale(SmokePoint point); + double timeDoingInitialFadeOut = Math.Min(initialFadeOutTime, SmokeEndTime) - point.Time; - protected abstract Vector2 PointDirection(SmokePoint point); + if (timeDoingInitialFadeOut > 0) + { + float fraction = Math.Clamp((float)(timeDoingInitialFadeOut / initial_fade_out_duration), 0, 1); + color.A = (1 - fraction) * initial_alpha; + } + + if (color.A > 0) + { + double timeDoingReFadeIn = reFadeInTime - point.Time / re_fade_in_speed; + double timeDoingFinalFadeOut = finalFadeOutTime - point.Time / final_fade_out_speed; + + if (timeDoingFinalFadeOut > 0) + { + float fraction = Math.Clamp((float)(timeDoingFinalFadeOut / final_fade_out_duration), 0, 1); + fraction = MathF.Pow(fraction, 5); + color.A = (1 - fraction) * re_fade_in_alpha; + } + else if (timeDoingReFadeIn > 0) + { + float fraction = Math.Clamp((float)(timeDoingReFadeIn / re_fade_in_duration), 0, 1); + fraction = 1 - MathF.Pow(1 - fraction, 5); + color.A = fraction * (re_fade_in_alpha - color.A) + color.A; + } + } + + return color; + } + + protected virtual float PointScale(SmokePoint point) + { + double timeDoingScale = CurrentTime - point.Time; + float fraction = Math.Clamp((float)(timeDoingScale / scale_duration), 0, 1); + fraction = 1 - MathF.Pow(1 - fraction, 5); + return fraction * (final_scale - initial_scale) + initial_scale; + } + + protected virtual Vector2 PointDirection(SmokePoint point) + { + float initialAngle = MathF.Atan2(point.Direction.Y, point.Direction.X); + float finalAngle = initialAngle + nextRotation(); + + double timeDoingRotation = CurrentTime - point.Time; + float fraction = Math.Clamp((float)(timeDoingRotation / rotation_duration), 0, 1); + fraction = 1 - MathF.Pow(1 - fraction, 5); + float angle = fraction * (finalAngle - initialAngle) + initialAngle; + + return new Vector2(MathF.Sin(angle), -MathF.Cos(angle)); + } + + private float nextRotation() => max_rotation * ((float)rotationRNG.NextDouble() * 2 - 1); private void drawPointQuad(SmokePoint point, RectangleF textureRect) {