diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj
index 64bf4f094..00c4b7a28 100644
--- a/src/Artemis.Core/Artemis.Core.csproj
+++ b/src/Artemis.Core/Artemis.Core.csproj
@@ -159,6 +159,7 @@
+
diff --git a/src/Artemis.Core/Extensions/FloatExtensions.cs b/src/Artemis.Core/Extensions/FloatExtensions.cs
new file mode 100644
index 000000000..a5496896b
--- /dev/null
+++ b/src/Artemis.Core/Extensions/FloatExtensions.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace Artemis.Core.Extensions
+{
+ public static class FloatExtensions
+ {
+ public static int RoundToInt(this float number)
+ {
+ return (int)Math.Round(number, MidpointRounding.AwayFromZero);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Plugins.LayerElements.Noise/NoiseLayerElement.cs b/src/Artemis.Plugins.LayerElements.Noise/NoiseLayerElement.cs
index e6afc64f6..8d128de48 100644
--- a/src/Artemis.Plugins.LayerElements.Noise/NoiseLayerElement.cs
+++ b/src/Artemis.Plugins.LayerElements.Noise/NoiseLayerElement.cs
@@ -7,16 +7,16 @@ namespace Artemis.Plugins.LayerElements.Noise
{
public class NoiseLayerElement : LayerElement
{
- private static Random _rand = new Random();
+ private const int Scale = 6;
+ private static readonly Random Rand = new Random();
private readonly OpenSimplexNoise _noise;
private float _z;
- private const int Scale = 6;
public NoiseLayerElement(Layer layer, Guid guid, NoiseLayerElementSettings settings, LayerElementDescriptor descriptor) : base(layer, guid, settings, descriptor)
{
Settings = settings;
- _z = _rand.Next(0, 4096);
+ _z = Rand.Next(0, 4096);
_noise = new OpenSimplexNoise(Guid.GetHashCode());
}
@@ -41,25 +41,30 @@ namespace Artemis.Plugins.LayerElements.Noise
public override void Render(SKPath framePath, SKCanvas canvas)
{
- // Scale down the render path
- var width = (int) Math.Round(Math.Max(Layer.RenderRectangle.Width, Layer.RenderRectangle.Height) / Scale);
- var height = (int) Math.Round(Math.Max(Layer.RenderRectangle.Width, Layer.RenderRectangle.Height) / Scale);
-
+ // Scale down the render path to avoid computing a value for every pixel
+ var width = (int) (Math.Max(Layer.RenderRectangle.Width, Layer.RenderRectangle.Height) / Scale);
+ var height = (int) (Math.Max(Layer.RenderRectangle.Width, Layer.RenderRectangle.Height) / Scale);
+
using (var bitmap = new SKBitmap(new SKImageInfo(width, height)))
{
- for (var x = 0; x < width; x++)
+ // 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)
{
- for (var y = 0; y < height; y++)
- {
- // This check is actually more expensive then _noise.Evaluate() ^.^'
- // if (!framePath.Contains(x * Scale, y * Scale))
- // continue;
+ var xStart = artemisLed.AbsoluteRenderRectangle.Left / Scale;
+ var xEnd = artemisLed.AbsoluteRenderRectangle.Right / Scale;
+ var yStart = artemisLed.AbsoluteRenderRectangle.Top / Scale;
+ var yEnd = artemisLed.AbsoluteRenderRectangle.Bottom / Scale;
- var v = _noise.Evaluate(Settings.XScale * x / width, Settings.YScale * y / height, _z);
- bitmap.SetPixel(x, y, new SKColor(0, 0, 0, (byte) ((v + 1) * 127)));
+ 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);
+ bitmap.SetPixel((int) x, (int) y, new SKColor(0, 0, 0, (byte) ((v + 1) * 127)));
+ }
}
}
-
+
using (var sh = SKShader.CreateBitmap(bitmap, SKShaderTileMode.Mirror, SKShaderTileMode.Mirror, SKMatrix.MakeScale(Scale, Scale)))
using (var paint = new SKPaint {Shader = sh})
{