mirror of
https://github.com/osukey/osukey.git
synced 2025-06-08 21:07:59 +09:00
Copy stable smoke's fade/alpha values, blending, scale, and rotation
This commit is contained in:
parent
6852577dad
commit
a0e31018a1
@ -4,6 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Rendering;
|
using osu.Framework.Graphics.Rendering;
|
||||||
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Skinning.Default
|
namespace osu.Game.Rulesets.Osu.Skinning.Default
|
||||||
@ -40,12 +41,12 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
|
|||||||
fadeOutTime = SmokeStartTime + fade_out_speed * (CurrentTime - (SmokeEndTime + fade_out_delay));
|
fadeOutTime = SmokeStartTime + fade_out_speed * (CurrentTime - (SmokeEndTime + fade_out_delay));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Color4 ColorAtTime(double pointTime)
|
protected override Color4 PointColor(SmokePoint point)
|
||||||
{
|
{
|
||||||
var color = Color4.White;
|
var color = Color4.White;
|
||||||
color.A = alpha;
|
color.A = alpha;
|
||||||
|
|
||||||
double timeDoingFadeOut = fadeOutTime - pointTime;
|
double timeDoingFadeOut = fadeOutTime - point.Time;
|
||||||
|
|
||||||
if (timeDoingFadeOut > 0)
|
if (timeDoingFadeOut > 0)
|
||||||
{
|
{
|
||||||
@ -56,6 +57,16 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
|
|||||||
|
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override float PointScale(SmokePoint point)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Vector2 PointDirection(SmokePoint point)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,29 +4,59 @@
|
|||||||
using System;
|
using System;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Rendering;
|
using osu.Framework.Graphics.Rendering;
|
||||||
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||||
{
|
{
|
||||||
public class LegacySmoke : Smoke
|
public class LegacySmoke : Smoke
|
||||||
{
|
{
|
||||||
private const double initial_fade_out_duration = 2500;
|
// fade values
|
||||||
|
private const double initial_fade_out_duration = 4000;
|
||||||
|
|
||||||
private const double re_fade_in_speed = 3;
|
private const double re_fade_in_speed = 3;
|
||||||
private const double re_fade_in_duration = 50;
|
private const double re_fade_in_duration = 50;
|
||||||
|
|
||||||
private const double final_fade_out_duration = 7500;
|
private const double final_fade_out_speed = 2;
|
||||||
|
private const double final_fade_out_duration = 8000;
|
||||||
|
|
||||||
private const float initial_alpha = 0.8f;
|
private const float initial_alpha = 0.6f;
|
||||||
private const float re_fade_in_alpha = 1.4f;
|
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;
|
||||||
|
|
||||||
|
private int rotationSeed = RNG.Next();
|
||||||
|
|
||||||
|
protected int RotationSeed
|
||||||
|
{
|
||||||
|
get => rotationSeed;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (rotationSeed == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rotationSeed = value;
|
||||||
|
Invalidate(Invalidation.DrawNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override double LifetimeAfterSmokeEnd
|
protected override double LifetimeAfterSmokeEnd
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
double initialFadeOutDurationTrunc = Math.Min(initial_fade_out_duration, SmokeEndTime - SmokeStartTime);
|
double initialFadeOutDurationTrunc = Math.Min(initial_fade_out_duration, SmokeEndTime - SmokeStartTime);
|
||||||
return final_fade_out_duration + initialFadeOutDurationTrunc * (1 + re_fade_in_speed);
|
return final_fade_out_duration + initialFadeOutDurationTrunc / re_fade_in_speed + initialFadeOutDurationTrunc / final_fade_out_speed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,11 +79,16 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
|||||||
|
|
||||||
protected class LegacySmokeDrawNode : SmokeDrawNode
|
protected class LegacySmokeDrawNode : SmokeDrawNode
|
||||||
{
|
{
|
||||||
|
protected new LegacySmoke Source => (LegacySmoke)base.Source;
|
||||||
|
|
||||||
private double initialFadeOutDurationTrunc;
|
private double initialFadeOutDurationTrunc;
|
||||||
private double initialFadeOutTime;
|
private double initialFadeOutTime;
|
||||||
private double reFadeInTime;
|
private double reFadeInTime;
|
||||||
private double finalFadeOutTime;
|
private double finalFadeOutTime;
|
||||||
|
|
||||||
|
private int rotationSeed;
|
||||||
|
private Random rotationRNG = new Random();
|
||||||
|
|
||||||
public LegacySmokeDrawNode(ITexturedShaderDrawable source)
|
public LegacySmokeDrawNode(ITexturedShaderDrawable source)
|
||||||
: base(source)
|
: base(source)
|
||||||
{
|
{
|
||||||
@ -64,34 +99,35 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
|||||||
base.ApplyState();
|
base.ApplyState();
|
||||||
|
|
||||||
initialFadeOutDurationTrunc = Math.Min(initial_fade_out_duration, SmokeEndTime - SmokeStartTime);
|
initialFadeOutDurationTrunc = Math.Min(initial_fade_out_duration, SmokeEndTime - SmokeStartTime);
|
||||||
|
rotationSeed = Source.RotationSeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateDrawVariables(IRenderer renderer)
|
protected override void UpdateDrawVariables(IRenderer renderer)
|
||||||
{
|
{
|
||||||
base.UpdateDrawVariables(renderer);
|
base.UpdateDrawVariables(renderer);
|
||||||
|
|
||||||
|
rotationRNG = new Random(rotationSeed);
|
||||||
initialFadeOutTime = Math.Min(CurrentTime, SmokeEndTime);
|
initialFadeOutTime = Math.Min(CurrentTime, SmokeEndTime);
|
||||||
reFadeInTime = re_fade_in_speed * (CurrentTime - SmokeEndTime) + SmokeEndTime - initialFadeOutDurationTrunc;
|
reFadeInTime = re_fade_in_speed * (CurrentTime - SmokeEndTime) + SmokeEndTime - initialFadeOutDurationTrunc;
|
||||||
finalFadeOutTime = CurrentTime - initialFadeOutDurationTrunc * (1 + 1 / re_fade_in_speed);
|
finalFadeOutTime = final_fade_out_speed * (CurrentTime - SmokeEndTime) + SmokeEndTime - initialFadeOutDurationTrunc * (1 + 1 / re_fade_in_speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Color4 ColorAtTime(double pointTime)
|
protected override Color4 PointColor(SmokePoint point)
|
||||||
{
|
{
|
||||||
var color = Color4.White;
|
var color = Color4.White;
|
||||||
|
|
||||||
double timeDoingInitialFadeOut = initialFadeOutTime - pointTime;
|
double timeDoingInitialFadeOut = initialFadeOutTime - point.Time;
|
||||||
|
|
||||||
if (timeDoingInitialFadeOut > 0)
|
if (timeDoingInitialFadeOut > 0)
|
||||||
{
|
{
|
||||||
float fraction = Math.Clamp((float)(timeDoingInitialFadeOut / initial_fade_out_duration), 0, 1);
|
float fraction = Math.Clamp((float)(timeDoingInitialFadeOut / initial_fade_out_duration), 0, 1);
|
||||||
fraction = MathF.Pow(fraction, 5);
|
|
||||||
color.A = (1 - fraction) * initial_alpha;
|
color.A = (1 - fraction) * initial_alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (color.A > 0)
|
if (color.A > 0)
|
||||||
{
|
{
|
||||||
double timeDoingReFadeIn = reFadeInTime - pointTime;
|
double timeDoingReFadeIn = reFadeInTime - point.Time;
|
||||||
double timeDoingFinalFadeOut = finalFadeOutTime - pointTime;
|
double timeDoingFinalFadeOut = finalFadeOutTime - point.Time;
|
||||||
|
|
||||||
if (timeDoingFinalFadeOut > 0)
|
if (timeDoingFinalFadeOut > 0)
|
||||||
{
|
{
|
||||||
@ -109,6 +145,31 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
|||||||
|
|
||||||
return color;
|
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 toVector2(angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float nextRotation() => max_rotation * ((float)rotationRNG.NextDouble() * 2 - 1);
|
||||||
|
|
||||||
|
private Vector2 toVector2(float angle) => new Vector2(MathF.Sin(angle), -MathF.Cos(angle));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,21 +42,6 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int rotationSeed = RNG.Next();
|
|
||||||
|
|
||||||
protected int RotationSeed
|
|
||||||
{
|
|
||||||
get => rotationSeed;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (rotationSeed == value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
rotationSeed = value;
|
|
||||||
Invalidate(Invalidation.DrawNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Texture? texture;
|
private Texture? texture;
|
||||||
|
|
||||||
protected Texture? Texture
|
protected Texture? Texture
|
||||||
@ -195,6 +180,12 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
|||||||
SmokeStartTime = Time.Current;
|
SmokeStartTime = Time.Current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Vector2 nextPointDirection()
|
||||||
|
{
|
||||||
|
float angle = RNG.NextSingle(0, 2 * MathF.PI);
|
||||||
|
return new Vector2(MathF.Sin(angle), -MathF.Cos(angle));
|
||||||
|
}
|
||||||
|
|
||||||
private void onSmokeMoved(Vector2 position, double time)
|
private void onSmokeMoved(Vector2 position, double time)
|
||||||
{
|
{
|
||||||
if (!IsActive)
|
if (!IsActive)
|
||||||
@ -229,6 +220,7 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
|||||||
{
|
{
|
||||||
Position = pointPos,
|
Position = pointPos,
|
||||||
Time = time,
|
Time = time,
|
||||||
|
Direction = nextPointDirection(),
|
||||||
});
|
});
|
||||||
|
|
||||||
pointPos += increment;
|
pointPos += increment;
|
||||||
@ -303,6 +295,7 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
|||||||
{
|
{
|
||||||
public Vector2 Position;
|
public Vector2 Position;
|
||||||
public double Time;
|
public double Time;
|
||||||
|
public Vector2 Direction;
|
||||||
|
|
||||||
public struct UpperBoundComparer : IComparer<SmokePoint>
|
public struct UpperBoundComparer : IComparer<SmokePoint>
|
||||||
{
|
{
|
||||||
@ -339,9 +332,6 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
|||||||
|
|
||||||
private IFrameBasedClock? clock;
|
private IFrameBasedClock? clock;
|
||||||
|
|
||||||
private int rotationSeed;
|
|
||||||
private Random rotationRNG = new Random();
|
|
||||||
|
|
||||||
protected SmokeDrawNode(ITexturedShaderDrawable source)
|
protected SmokeDrawNode(ITexturedShaderDrawable source)
|
||||||
: base(source)
|
: base(source)
|
||||||
{
|
{
|
||||||
@ -362,8 +352,6 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
|||||||
|
|
||||||
SmokeStartTime = Source.SmokeStartTime;
|
SmokeStartTime = Source.SmokeStartTime;
|
||||||
SmokeEndTime = Source.SmokeEndTime;
|
SmokeEndTime = Source.SmokeEndTime;
|
||||||
|
|
||||||
rotationSeed = Source.RotationSeed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed override void Draw(IRenderer renderer)
|
public sealed override void Draw(IRenderer renderer)
|
||||||
@ -377,6 +365,9 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
|||||||
Texture ??= renderer.WhitePixel;
|
Texture ??= renderer.WhitePixel;
|
||||||
|
|
||||||
var shader = GetAppropriateShader(renderer);
|
var shader = GetAppropriateShader(renderer);
|
||||||
|
|
||||||
|
renderer.SetBlend(BlendingParameters.Additive);
|
||||||
|
|
||||||
shader.Bind();
|
shader.Bind();
|
||||||
Texture.Bind();
|
Texture.Bind();
|
||||||
|
|
||||||
@ -390,7 +381,11 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
|||||||
? ((SRGBColour)DrawColourInfo.Colour).Linear
|
? ((SRGBColour)DrawColourInfo.Colour).Linear
|
||||||
: DrawColourInfo.Colour.Interpolate(Vector2.Divide(localPos, DrawSize)).Linear;
|
: DrawColourInfo.Colour.Interpolate(Vector2.Divide(localPos, DrawSize)).Linear;
|
||||||
|
|
||||||
protected abstract Color4 ColorAtTime(double pointTime);
|
protected abstract Color4 PointColor(SmokePoint point);
|
||||||
|
|
||||||
|
protected abstract float PointScale(SmokePoint point);
|
||||||
|
|
||||||
|
protected abstract Vector2 PointDirection(SmokePoint point);
|
||||||
|
|
||||||
protected virtual void UpdateDrawVariables(IRenderer renderer)
|
protected virtual void UpdateDrawVariables(IRenderer renderer)
|
||||||
{
|
{
|
||||||
@ -399,7 +394,6 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
|||||||
|
|
||||||
CurrentTime = clock.CurrentTime;
|
CurrentTime = clock.CurrentTime;
|
||||||
TextureRect = Texture.GetTextureRect();
|
TextureRect = Texture.GetTextureRect();
|
||||||
rotationRNG = new Random(rotationSeed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void UpdateVertexBuffer()
|
protected virtual void UpdateVertexBuffer()
|
||||||
@ -408,24 +402,19 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
|||||||
drawPointQuad(point);
|
drawPointQuad(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector2 nextTextureDirection()
|
|
||||||
{
|
|
||||||
float angle = (float)rotationRNG.NextDouble() * 2 * MathF.PI;
|
|
||||||
return new Vector2(MathF.Sin(angle), -MathF.Cos(angle));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void drawPointQuad(SmokePoint point)
|
private void drawPointQuad(SmokePoint point)
|
||||||
{
|
{
|
||||||
Debug.Assert(QuadBatch != null);
|
Debug.Assert(QuadBatch != null);
|
||||||
|
|
||||||
var color = ColorAtTime(point.Time);
|
var color = PointColor(point);
|
||||||
var dir = nextTextureDirection();
|
float scale = PointScale(point);
|
||||||
|
var dir = PointDirection(point);
|
||||||
var ortho = dir.PerpendicularLeft;
|
var ortho = dir.PerpendicularLeft;
|
||||||
|
|
||||||
var localTopLeft = point.Position + (Radius * (-ortho - dir)) - PositionOffset;
|
var localTopLeft = point.Position + (Radius * scale * (-ortho - dir)) - PositionOffset;
|
||||||
var localTopRight = point.Position + (Radius * (-ortho + dir)) - PositionOffset;
|
var localTopRight = point.Position + (Radius * scale * (-ortho + dir)) - PositionOffset;
|
||||||
var localBotLeft = point.Position + (Radius * (ortho - dir)) - PositionOffset;
|
var localBotLeft = point.Position + (Radius * scale * (ortho - dir)) - PositionOffset;
|
||||||
var localBotRight = point.Position + (Radius * (ortho + dir)) - PositionOffset;
|
var localBotRight = point.Position + (Radius * scale * (ortho + dir)) - PositionOffset;
|
||||||
|
|
||||||
QuadBatch.Add(new TexturedVertex2D
|
QuadBatch.Add(new TexturedVertex2D
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user