Skip to content

Commit

Permalink
Working visualizer
Browse files Browse the repository at this point in the history
  • Loading branch information
davepl committed Dec 16, 2023
1 parent f94d2c9 commit 993bb4e
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 105 deletions.
132 changes: 68 additions & 64 deletions Server/Effects/FireEffect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,22 @@ public class FireEffect : LEDEffect
public uint _Size = 0; // How big the drawing area is; will be repeated if strip is bigger
public double _SparkProbability = 0.5; // Chance of a new spark
double[] _Temperatures; // Internal table of cell temperatures
public uint _speed;

public Palette _Palette;

public uint _CellsPerLED = 1;

public Random _rand = new Random();

public FireEffect(uint cSize, bool bMirrored, uint cellsPerLED = 1, Palette palette = null)
public FireEffect(uint cSize, bool bMirrored, uint cellsPerLED = 1, uint speed = 1, Palette palette = null)
{
_CellsPerLED = cellsPerLED;

_Size = cSize * _CellsPerLED;
_Mirrored = bMirrored;
_Palette = palette;
_speed = speed;
}

DateTime _lastUpdate = DateTime.UtcNow;
Expand All @@ -41,92 +43,94 @@ protected virtual CRGB ConvertHeatToColor(double temp)

protected override void Render(ILEDGraphics graphics)
{
if (_Temperatures == null)
_Temperatures = new double[_Size];
for (int iSpeed = 0; iSpeed < _speed; iSpeed++)
{
if (_Temperatures == null)
_Temperatures = new double[_Size];

_lastUpdate = DateTime.UtcNow;
_lastUpdate = DateTime.UtcNow;

// Erase the drawing area
graphics.FillSolid(CRGB.Black);
// Erase the drawing area
graphics.FillSolid(CRGB.Black);

double cooldown = _rand.NextDouble() * _Cooling * (DateTime.UtcNow - _lastUpdate).TotalSeconds;
_lastUpdate = DateTime.UtcNow;
double cooldown = _rand.NextDouble() * _Cooling * (DateTime.UtcNow - _lastUpdate).TotalSeconds;
_lastUpdate = DateTime.UtcNow;

for (int i = 0; i < _Temperatures.Length; i++)
{
if (cooldown > _Temperatures[i])
{
_Temperatures[i] = 0;
}
else
for (int i = 0; i < _Temperatures.Length; i++)
{
_Temperatures[i] = _Temperatures[i] - (double) cooldown;
if (cooldown > _Temperatures[i])
{
_Temperatures[i] = 0;
}
else
{
_Temperatures[i] = _Temperatures[i] - (double)cooldown;
}
}
}

// Heat from each cell drifts 'up' and diffuses a little
// Heat from each cell drifts 'up' and diffuses a little

for (int pass = 0; pass < _Drift; pass++)
for (int k = _Temperatures.Length - 1; k >= 2; k--)
_Temperatures[k] = (_Temperatures[k - 1] + _Temperatures[k - 2]) / 2.0f;
for (int pass = 0; pass < _Drift; pass++)
for (int k = _Temperatures.Length - 1; k >= 2; k--)
_Temperatures[k] = (_Temperatures[k - 1] + _Temperatures[k - 2]) / 2.0f;

// Randomly ignite new 'sparks' near the bottom
// Randomly ignite new 'sparks' near the bottom

for (int frame = 0; frame < _Sparks; frame++)
{
if (_rand.NextDouble() < _SparkProbability)
for (int frame = 0; frame < _Sparks; frame++)
{
// NB: This randomly rolls over sometimes of course, and that's essential to the effect
int y = (int)(_rand.NextDouble() * _SparkHeight);
_Temperatures[y] = (_Temperatures[y] + _rand.NextDouble() * 0.4 + 0.06);

if (!_Afterburners)
while (_Temperatures[y] > 1.0)
_Temperatures[y] -= 1.0f;
else
_Temperatures[y] = Math.Min(_Temperatures[y], 1.0f);
if (_rand.NextDouble() < _SparkProbability)
{
// NB: This randomly rolls over sometimes of course, and that's essential to the effect
int y = (int)(_rand.NextDouble() * _SparkHeight);
_Temperatures[y] = (_Temperatures[y] + _rand.NextDouble() * 0.4 + 0.06);

if (!_Afterburners)
while (_Temperatures[y] > 1.0)
_Temperatures[y] -= 1.0f;
else
_Temperatures[y] = Math.Min(_Temperatures[y], 1.0f);
}
}
}

// Hack for weird TV layout
for (int j = _Temperatures.Length; j < graphics.DotCount; j++)
{
graphics.DrawPixel((uint) j, 0, ConvertHeatToColor(_Temperatures[j-(uint) _Temperatures.Length]));
}

if (_Mirrored)
{
uint len = _Size / _CellsPerLED;
// Hack for weird TV layout
for (int j = _Temperatures.Length; j < graphics.DotCount; j++)
{
graphics.DrawPixel((uint)j, 0, ConvertHeatToColor(_Temperatures[j - (uint)_Temperatures.Length]));
}

for (uint j = 0; j < len / 2; j+=1)
if (_Mirrored)
{
if (_Reversed)
{
graphics.DrawPixel(j, 0, ConvertHeatToColor(_Temperatures[j * _CellsPerLED]));
graphics.DrawPixel((uint)(len - 1 - j), 0, ConvertHeatToColor(_Temperatures[j * _CellsPerLED]));
uint len = _Size / _CellsPerLED;

}
else
for (uint j = 0; j < len / 2; j += 1)
{
graphics.DrawPixel(((uint)(len - 1 - j)), 0, ConvertHeatToColor(_Temperatures[j * _CellsPerLED]));
graphics.DrawPixel(j, 0, ConvertHeatToColor(_Temperatures[j * _CellsPerLED]));
if (_Reversed)
{
graphics.DrawPixel(j, 0, ConvertHeatToColor(_Temperatures[j * _CellsPerLED]));
graphics.DrawPixel((uint)(len - 1 - j), 0, ConvertHeatToColor(_Temperatures[j * _CellsPerLED]));

}
else
{
graphics.DrawPixel(((uint)(len - 1 - j)), 0, ConvertHeatToColor(_Temperatures[j * _CellsPerLED]));
graphics.DrawPixel(j, 0, ConvertHeatToColor(_Temperatures[j * _CellsPerLED]));
}
}
}
}
else
{
for (uint j = 0; j < _Temperatures.Length; j+=_CellsPerLED)
else
{
uint len = _Size / _CellsPerLED;
uint i = j / _CellsPerLED;
for (uint j = 0; j < _Temperatures.Length; j += _CellsPerLED)
{
uint len = _Size / _CellsPerLED;
uint i = j / _CellsPerLED;

if (_Reversed)
graphics.DrawPixel(i, 0, ConvertHeatToColor(_Temperatures[j]));
else
graphics.DrawPixel((uint)(len - 1 - i), 0, ConvertHeatToColor(_Temperatures[j]));
if (_Reversed)
graphics.DrawPixel(i, 0, ConvertHeatToColor(_Temperatures[j]));
else
graphics.DrawPixel((uint)(len - 1 - i), 0, ConvertHeatToColor(_Temperatures[j]));
}
}
}

graphics.Blur(1);
}
}
Expand Down
20 changes: 10 additions & 10 deletions Server/Effects/PaletteEffect.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using NightDriver;


public class PaletteEffect : LEDEffect
{
private double _iPixel = 0;

protected double _iColor;
protected double _iColor;
protected ILEDGraphics _graphics;
protected DateTime _lastDraw = DateTime.UtcNow;
protected DateTime _lastDraw = DateTime.UtcNow;

public Palette _Palette = new Palette(CRGB.Rainbow);
public Palette _Palette = new Palette(CRGB.Rainbow) { Blend = false };
public double _LEDColorPerSecond = -50.0;
public double _LEDScrollSpeed = 50.0;
public double _Density = 1.0;
public double _EveryNthDot = 25.0f;
public uint _EveryNthDot = 25;
public uint _DotSize = 5;
public bool _RampedColor = false;
public double _Brightness = 1.0;
Expand All @@ -42,17 +43,16 @@ protected override void Render(ILEDGraphics graphics)
_iPixel %= graphics.DotCount;

double cColorsToScroll = secondsElapsed * _LEDColorPerSecond;
_iColor += cColorsToScroll / graphics.PixelsPerMeter;
_iColor -= (long)_iColor;

double iColor = _iColor;

uint cLength = (_Mirrored ? graphics.DotCount / 2 : graphics.DotCount);

for (double i = 0; i < cLength; i += _EveryNthDot)
for (uint i=0; i < cLength; i += _EveryNthDot)
{
int count = 0;
for (uint j = 0; j < _DotSize && (i + j) < cLength; j++)
for (var j = 0; j < _DotSize && (i + j) < cLength; j++)
{
double iPixel = (i + j + _iPixel) % cLength;

Expand All @@ -66,15 +66,15 @@ protected override void Render(ILEDGraphics graphics)
count++;

}

// Avoid pixel 0 flicker as it scrolls by copying pixel 1 onto 0

if (graphics.DotCount > 1)
graphics.DrawPixel(0, graphics.GetPixel(1));

iColor += count * (_Density / graphics.PixelsPerMeter) * _EveryNthDot;
}
}

}
}
}

// PresentsEffect
Expand Down
2 changes: 2 additions & 0 deletions Server/Graphics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -587,9 +587,11 @@ public static CRGB[] makeGradient(CRGB start, CRGB end, int length = 16)
{
CRGB.Red,
CRGB.Orange,
CRGB.Yellow,
CRGB.Green,
CRGB.Cyan,
CRGB.Blue,
new CRGB(128, 0, 255),
CRGB.Purple,
};

Expand Down
2 changes: 1 addition & 1 deletion Server/LightStrip.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public LightStrip(string hostName, string friendlyName, bool compressData, uint
Reversed = reversed;
}

private byte[] GetPixelData(CRGB [] LEDs)
public byte[] GetPixelData(CRGB [] LEDs)
{
return LEDInterop.GetColorBytesAtOffset(LEDs, Offset, Width * Height, Reversed, RedGreenSwap);
}
Expand Down
13 changes: 6 additions & 7 deletions Server/Palette.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
Expand Down Expand Up @@ -26,16 +27,14 @@ public virtual CRGB this[double d]
{
get
{
while (d < 0)
d += 1.0;

d -= ((long)d); // Wrap around to 0-1 scale so that 3.4 -> 0.4, for example

double fracPerColor = 1.0 / colorEntries.Length; // How much, on 0-1 scale, each provided color take up (8 colors -> .125)
double indexD = d / fracPerColor; // Convert from 0-1 to 0-N (so if we have 8 colors, .275 becomes color # 2.2).
int index = (int)(d / fracPerColor) % colorEntries.Length; // The integer portion, which will be the base color (color #2 in this example)
double fraction = indexD - index; // How much of the next ordinal color to blend with (0.2 of the color to the right)

int index = (int)(indexD) % colorEntries.Length; // The integer portion, which will be the base color (color #2 in this example)
double fraction = indexD - index; // How much of the next ordinal color to blend with (0.2 of the color to the right)
//double fraction = indexD = Math.Floor(indexD); // How much of the next ordinal color to blend with (0.2 of the color to the right)

// Find the first integral color

CRGB color1 = colorEntries[index];
Expand Down
Loading

0 comments on commit 993bb4e

Please sign in to comment.