mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-01-01 10:13:30 +00:00
Updated project folder names Show only selected layer in visualization Added rectangle support
85 lines
3.5 KiB
C#
85 lines
3.5 KiB
C#
using System;
|
|
using Artemis.Core.Models.Profile;
|
|
using Artemis.Core.Plugins.LayerBrush;
|
|
using Artemis.Plugins.LayerBrushes.Noise.Utilities;
|
|
using SkiaSharp;
|
|
|
|
namespace Artemis.Plugins.LayerBrushes.Noise
|
|
{
|
|
public class NoiseBrush : LayerBrush
|
|
{
|
|
private const int Scale = 6;
|
|
private static readonly Random Rand = new Random();
|
|
private readonly OpenSimplexNoise _noise;
|
|
private float _z;
|
|
|
|
public NoiseBrush(Layer layer, NoiseBrushSettings settings, LayerBrushDescriptor descriptor) : base(layer, settings, descriptor)
|
|
{
|
|
Settings = settings;
|
|
|
|
_z = Rand.Next(0, 4096);
|
|
_noise = new OpenSimplexNoise(Rand.Next(0, 4096));
|
|
}
|
|
|
|
public new NoiseBrushSettings Settings { get; }
|
|
|
|
|
|
public override void Update(double deltaTime)
|
|
{
|
|
// TODO: Come up with a better way to use deltaTime
|
|
_z += Settings.AnimationSpeed / 500f / 0.04f * (float) deltaTime;
|
|
|
|
if (_z >= float.MaxValue)
|
|
_z = 0;
|
|
|
|
base.Update(deltaTime);
|
|
}
|
|
|
|
public override LayerBrushViewModel GetViewModel()
|
|
{
|
|
return new NoiseBrushViewModel(this);
|
|
}
|
|
|
|
public override void Render(SKCanvas canvas)
|
|
{
|
|
// Scale down the render path to avoid computing a value for every pixel
|
|
var width = (int) (Math.Max(Layer.Rectangle.Width, Layer.Rectangle.Height) / Scale);
|
|
var height = (int) (Math.Max(Layer.Rectangle.Width, Layer.Rectangle.Height) / Scale);
|
|
var opacity = (float) Math.Round(Settings.Color.Alpha / 255.0, 2, MidpointRounding.AwayFromZero);
|
|
using (var bitmap = new SKBitmap(new SKImageInfo(width, height)))
|
|
{
|
|
bitmap.Erase(new SKColor(0, 0, 0, 0));
|
|
// Only compute pixels inside LEDs, due to scaling there may be some rounding issues but it's neglect-able
|
|
foreach (var artemisLed in Layer.Leds)
|
|
{
|
|
var xStart = artemisLed.AbsoluteRenderRectangle.Left / Scale;
|
|
var xEnd = artemisLed.AbsoluteRenderRectangle.Right / Scale;
|
|
var yStart = artemisLed.AbsoluteRenderRectangle.Top / Scale;
|
|
var yEnd = artemisLed.AbsoluteRenderRectangle.Bottom / Scale;
|
|
|
|
for (var x = xStart; x < xEnd; x++)
|
|
{
|
|
for (var y = yStart; y < yEnd; y++)
|
|
{
|
|
var v = _noise.Evaluate(Settings.XScale * x / width, Settings.YScale * y / height, _z);
|
|
var alpha = (byte) ((v + 1) * 127 * opacity);
|
|
// There's some fun stuff we can do here, like creating hard lines
|
|
// if (alpha > 128)
|
|
// alpha = 255;
|
|
// else
|
|
// alpha = 0;
|
|
var color = new SKColor(Settings.Color.Red, Settings.Color.Green, Settings.Color.Blue, alpha);
|
|
bitmap.SetPixel((int) x, (int) y, color);
|
|
}
|
|
}
|
|
}
|
|
|
|
using (var sh = SKShader.CreateBitmap(bitmap, SKShaderTileMode.Mirror, SKShaderTileMode.Mirror, SKMatrix.MakeScale(Scale, Scale)))
|
|
using (var paint = new SKPaint {Shader = sh, BlendMode = Settings.BlendMode})
|
|
{
|
|
canvas.DrawPath(Layer.LayerShape.RenderPath, paint);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |