For @Tomeno; Shader form of Cooldown Animation (#1113)
Co-authored-by: Tomeno <tomeno@lulzsec.co.uk>
This commit is contained in:
@@ -3,11 +3,26 @@ using Robust.Client.Interfaces.GameObjects.Components;
|
|||||||
using Robust.Client.Interfaces.Graphics;
|
using Robust.Client.Interfaces.Graphics;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using System;
|
using System;
|
||||||
|
using Robust.Client.Graphics.Shaders;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Robust.Client.UserInterface.Controls
|
namespace Robust.Client.UserInterface.Controls
|
||||||
{
|
{
|
||||||
|
|
||||||
public class CooldownGraphic : Control
|
public class CooldownGraphic : Control
|
||||||
{
|
{
|
||||||
|
|
||||||
|
[Dependency] private readonly IPrototypeManager _protoMan = default!;
|
||||||
|
|
||||||
|
private ShaderInstance _shader;
|
||||||
|
|
||||||
|
public CooldownGraphic()
|
||||||
|
{
|
||||||
|
IoCManager.InjectDependencies(this);
|
||||||
|
_shader = _protoMan.Index<ShaderPrototype>("CooldownAnimation").InstanceUnique();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Progress of the cooldown animation.
|
/// Progress of the cooldown animation.
|
||||||
/// Possible values range from 1 to -1, where 1 to 0 is a depleting circle animation and 0 to -1 is a blink animation.
|
/// Possible values range from 1 to -1, where 1 to 0 is a depleting circle animation and 0 to -1 is a blink animation.
|
||||||
@@ -16,41 +31,26 @@ namespace Robust.Client.UserInterface.Controls
|
|||||||
|
|
||||||
protected override void Draw(DrawingHandleScreen handle)
|
protected override void Draw(DrawingHandleScreen handle)
|
||||||
{
|
{
|
||||||
const int maxSegments = 64;
|
Color color;
|
||||||
const float segment = MathHelper.TwoPi / maxSegments;
|
|
||||||
|
|
||||||
var effective_fraction = Progress >= 0f ? Progress : 1f; // we want the full circle for the blink
|
var lerp = 1f - Math.Abs(Progress); // for future bikeshedding purposes
|
||||||
|
|
||||||
var segments = (int)Math.Max(2, Math.Ceiling(maxSegments * effective_fraction) + 1); // ensure that we always have at least 3 vertices, we also need one more segment
|
|
||||||
var max = MathHelper.TwoPi * effective_fraction;
|
|
||||||
var outer_radius = (Math.Min(SizeBox.Height, SizeBox.Width) / 2) * 0.875f; // 28/32 = 0.875 - 2 pixels inwards from the edge
|
|
||||||
var inner_radius = (Math.Min(SizeBox.Height, SizeBox.Width) / 2) * 0.5625f; // 18/32 = 0.5625 - 5 pixels thick
|
|
||||||
|
|
||||||
Span <Vector2> vertices = stackalloc Vector2[segments * 2];
|
|
||||||
var center = PixelPosition + SizeBox.Center;
|
|
||||||
for (int i = 0; i < segments; i++)
|
|
||||||
{
|
|
||||||
var angle = MathHelper.Pi + Math.Min(max, segment * i);
|
|
||||||
vertices[2*i] = center + new Vector2((float) Math.Sin(angle) * outer_radius, (float) Math.Cos(angle) * outer_radius);
|
|
||||||
vertices[2*i + 1] = center + new Vector2((float) Math.Sin(angle) * inner_radius, (float) Math.Cos(angle) * inner_radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
Color draw_color;
|
|
||||||
|
|
||||||
var fraction_lerp = 1f - Math.Abs(Progress); // for future bikeshedding purposes
|
|
||||||
|
|
||||||
if (Progress >= 0f)
|
if (Progress >= 0f)
|
||||||
{
|
{
|
||||||
var hue = (5f / 18f) * fraction_lerp;
|
var hue = (5f / 18f) * lerp;
|
||||||
draw_color = Color.FromHsv((hue, 0.75f, 0.75f, 0.50f));
|
color = Color.FromHsv((hue, 0.75f, 0.75f, 0.50f));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var alpha = Math.Clamp(0.5f * fraction_lerp, 0f, 0.5f);
|
var alpha = Math.Clamp(0.5f * lerp, 0f, 0.5f);
|
||||||
draw_color = new Color(1f, 1f, 1f, alpha);
|
color = new Color(1f, 1f, 1f, alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
handle.DrawPrimitives(DrawPrimitiveTopology.TriangleStrip, vertices, draw_color);
|
_shader.SetParameter("progress", Progress);
|
||||||
|
handle.UseShader(_shader);
|
||||||
|
handle.DrawRect(PixelSizeBox, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
6
Resources/Prototypes/Shaders/cooldown.yml
Normal file
6
Resources/Prototypes/Shaders/cooldown.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
- type: shader
|
||||||
|
id: CooldownAnimation
|
||||||
|
kind: source
|
||||||
|
path: "/Shaders/cooldown.swsl"
|
||||||
|
params:
|
||||||
|
progress: 0
|
||||||
25
Resources/Shaders/cooldown.swsl
Normal file
25
Resources/Shaders/cooldown.swsl
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
light_mode unshaded;
|
||||||
|
|
||||||
|
const float PI = 3.14159265;
|
||||||
|
|
||||||
|
uniform float progress = 0.0;
|
||||||
|
|
||||||
|
void fragment() {
|
||||||
|
vec4 col = texture(TEXTURE, UV);
|
||||||
|
vec2 center = vec2(0.5,0.5);
|
||||||
|
vec2 delta = UV.xy - center;
|
||||||
|
|
||||||
|
float angle = atan(delta.x, -delta.y) + PI;
|
||||||
|
|
||||||
|
float dist = length(delta);
|
||||||
|
float dist_fwidth = fwidth(dist) * 0.67;
|
||||||
|
|
||||||
|
float dist_alpha = smoothstep(0.1-dist_fwidth, 0.1, abs(dist-0.35));
|
||||||
|
|
||||||
|
float angle_delta = (progress * PI * 2) - angle;
|
||||||
|
float arc_length = angle_delta * dist;
|
||||||
|
|
||||||
|
float angle_alpha = progress > 0 ? smoothstep(dist_fwidth, 0.0, arc_length) : 0.0;
|
||||||
|
|
||||||
|
COLOR = vec4(col.xyz, 1-max(dist_alpha, angle_alpha));
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user