Skip to content

Commit f9a4b4d

Browse files
Merge pull request #160 from roxaskeyheart/chromatics-3.x
Chromatics 3.x
2 parents 44fca54 + 83d4584 commit f9a4b4d

27 files changed

Lines changed: 1784 additions & 246 deletions

Chromatics/Chromatics.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<TargetFramework>net8.0-windows7.0</TargetFramework>
66
<UseWindowsForms>true</UseWindowsForms>
77
<StartupObject>Chromatics.Program</StartupObject>
8-
<Version>3.0.8.2</Version>
8+
<Version>3.0.8.3</Version>
99
<Authors>Danielle Thompson</Authors>
1010
<ApplicationManifest>app.manifest</ApplicationManifest>
1111
<Copyright>Danielle Thompson 2024</Copyright>

Chromatics/Core/AppSettings.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public static class AppSettings
1414
private static SettingsModel _settings = new SettingsModel();
1515

1616
public static readonly string currentSettingsVersion = "2";
17-
public static readonly string currentEffectsVersion = "1";
17+
public static readonly string currentEffectsVersion = "2";
1818
public static readonly string currentPalettesVersion = "1";
1919
public static readonly string currentMappingLayerVersion = "1";
2020

Chromatics/Enums/PaletteTypes.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Linq;
66
using System.Text;
77
using System.Threading.Tasks;
8+
using System.Xml.Linq;
89

910
namespace Chromatics.Enums
1011
{
@@ -35,9 +36,11 @@ public enum PaletteTypes
3536
[Display(Name = "Reactive Weather")]
3637
ReactiveWeather = 10,
3738
[Display(Name = "Job Classes")]
38-
JobClasses = 11
39+
JobClasses = 11,
40+
[Display(Name = "Raid Effects")]
41+
RaidEffects = 12
3942
}
4043

41-
public static int TypeCount = 11;
44+
public static int TypeCount = 12;
4245
}
4346
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
using RGB.NET.Core;
2+
using System;
3+
using System.Collections.Concurrent;
4+
using System.Collections.Generic;
5+
using System.Diagnostics;
6+
using System.Linq;
7+
using Color = RGB.NET.Core.Color;
8+
9+
namespace Chromatics.Extensions.RGB.NET.Decorators
10+
{
11+
public class ArenaLightShowDecorator : AbstractUpdateAwareDecorator, ILedGroupDecorator
12+
{
13+
private readonly ListLedGroup ledGroup;
14+
private readonly Random random = new Random();
15+
private readonly double interval;
16+
private readonly double waveSpeed;
17+
private readonly double waveFrequency;
18+
private readonly Color[] colors;
19+
private readonly Color baseColor;
20+
private ConcurrentDictionary<Led, double> ledPositions;
21+
private Dictionary<Led, float> currentBrightness;
22+
private Dictionary<Led, Color> currentColors;
23+
private double Timing;
24+
25+
public ArenaLightShowDecorator(ListLedGroup _ledGroup, double interval, double waveSpeed, double waveFrequency, Color[] colors, RGBSurface surface, bool updateIfDisabled = false, Color baseColor = default(Color)) : base(surface, updateIfDisabled)
26+
{
27+
this.ledGroup = _ledGroup;
28+
this.interval = interval;
29+
this.waveSpeed = waveSpeed;
30+
this.waveFrequency = waveFrequency;
31+
this.colors = colors;
32+
this.baseColor = baseColor == default(Color) ? Color.Transparent : baseColor;
33+
34+
ledPositions = new ConcurrentDictionary<Led, double>();
35+
currentBrightness = new Dictionary<Led, float>();
36+
currentColors = new Dictionary<Led, Color>();
37+
Timing = 0;
38+
}
39+
40+
public override void OnAttached(IDecoratable decoratable)
41+
{
42+
base.OnAttached(decoratable);
43+
ledGroup.Detach();
44+
45+
Debug.WriteLine("Arena Light Show Decorator Attached");
46+
47+
foreach (var led in ledGroup)
48+
{
49+
ledPositions.TryAdd(led, random.NextDouble() * Math.PI * 2);
50+
currentColors.TryAdd(led, colors[random.Next(colors.Length)]);
51+
}
52+
}
53+
54+
public override void OnDetached(IDecoratable decoratable)
55+
{
56+
base.OnDetached(decoratable);
57+
ledPositions.Clear();
58+
currentColors.Clear();
59+
currentBrightness.Clear();
60+
Timing = 0;
61+
62+
Debug.WriteLine("Arena Light Show Decorator Detached");
63+
}
64+
65+
protected override void Update(double deltaTime)
66+
{
67+
try
68+
{
69+
if (ledGroup == null) return;
70+
71+
Timing += deltaTime * waveSpeed;
72+
73+
foreach (var led in ledGroup)
74+
{
75+
if (!ledPositions.ContainsKey(led)) continue;
76+
77+
double position = ledPositions[led] + Timing;
78+
double intensity = (Math.Sin(position * waveFrequency) + 1) / 2; // Sine wave for smooth transition
79+
80+
var colorIndex = (int)(Math.Floor((position / Math.PI) % colors.Length));
81+
var nextColorIndex = (colorIndex + 1) % colors.Length;
82+
83+
var currentColor = colors[colorIndex];
84+
var nextColor = colors[nextColorIndex];
85+
86+
var color = Lerp(currentColor, nextColor, (float)intensity);
87+
88+
var newCol = new Color(
89+
(int)(color.R * 255 * intensity + baseColor.R * (1 - intensity)),
90+
(int)(color.G * 255 * intensity + baseColor.G * (1 - intensity)),
91+
(int)(color.B * 255 * intensity + baseColor.B * (1 - intensity))
92+
);
93+
94+
led.Color = newCol;
95+
}
96+
}
97+
catch (Exception ex)
98+
{
99+
#if DEBUG
100+
Debug.WriteLine($"Exception: {ex.Message}");
101+
#endif
102+
}
103+
}
104+
105+
private static Color Lerp(Color start, Color end, float amount)
106+
{
107+
float r = start.R + (end.R - start.R) * amount;
108+
float g = start.G + (end.G - start.G) * amount;
109+
float b = start.B + (end.B - start.B) * amount;
110+
111+
return new Color((int)(r * 255), (int)(g * 255), (int)(b * 255));
112+
}
113+
}
114+
}
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
using RGB.NET.Core;
2+
using System;
3+
using System.Collections.Concurrent;
4+
using System.Collections.Generic;
5+
using System.Diagnostics;
6+
using System.Linq;
7+
using Color = RGB.NET.Core.Color;
8+
9+
namespace Chromatics.Extensions.RGB.NET.Decorators
10+
{
11+
public class BPMFastStarfieldDecorator : AbstractUpdateAwareDecorator, ILedGroupDecorator
12+
{
13+
private readonly ListLedGroup ledGroup;
14+
private readonly Random random = new Random();
15+
private readonly int numberOfLeds;
16+
private readonly double fadeSpeed;
17+
private readonly double densityMultiplier;
18+
private readonly Color[] colors;
19+
private readonly Color baseColor;
20+
private ConcurrentDictionary<Led, Color> fadingInLeds;
21+
private ConcurrentDictionary<Led, Color> fadingOutLeds;
22+
private Dictionary<Led, float> currentBrightness;
23+
private Dictionary<Led, Color> currentColors;
24+
private Dictionary<Led, double> startTimes;
25+
private double Timing;
26+
private double startDelay;
27+
private double updateCounter = 0;
28+
private double interval;
29+
30+
public BPMFastStarfieldDecorator(ListLedGroup _ledGroup, int numberOfLeds, int bpm, double fadeSpeed, Color[] colors, RGBSurface surface, double densityMultiplier = 1.0, bool updateIfDisabled = false, Color baseColor = default(Color)) : base(surface, updateIfDisabled)
31+
{
32+
this.ledGroup = _ledGroup;
33+
this.numberOfLeds = numberOfLeds;
34+
this.fadeSpeed = fadeSpeed;
35+
this.colors = colors;
36+
this.baseColor = baseColor == default(Color) ? Color.Transparent : baseColor;
37+
this.densityMultiplier = densityMultiplier;
38+
39+
CalculateInterval(bpm);
40+
startTimes = new Dictionary<Led, double>();
41+
fadingInLeds = new ConcurrentDictionary<Led, Color>();
42+
fadingOutLeds = new ConcurrentDictionary<Led, Color>();
43+
currentBrightness = new Dictionary<Led, float>();
44+
currentColors = new Dictionary<Led, Color>();
45+
Timing = 0;
46+
startDelay = 0;
47+
}
48+
49+
private void CalculateInterval(int bpm)
50+
{
51+
// Convert BPM to interval in seconds (interval = 60 / BPM)
52+
interval = 60.0 / bpm;
53+
}
54+
55+
public override void OnAttached(IDecoratable decoratable)
56+
{
57+
base.OnAttached(decoratable);
58+
ledGroup.Detach();
59+
}
60+
61+
public override void OnDetached(IDecoratable decoratable)
62+
{
63+
base.OnDetached(decoratable);
64+
currentBrightness.Clear();
65+
fadingInLeds.Clear();
66+
fadingOutLeds.Clear();
67+
currentColors.Clear();
68+
startTimes.Clear();
69+
Timing = 0;
70+
startDelay = 0;
71+
}
72+
73+
protected override void Update(double deltaTime)
74+
{
75+
try
76+
{
77+
if (ledGroup == null || fadingInLeds == null || fadingOutLeds == null) return;
78+
79+
Timing += deltaTime;
80+
81+
var minBrightness = 0;
82+
var maxBrightness = 1;
83+
84+
if (Timing >= startDelay)
85+
{
86+
var availableLeds = ledGroup.Where(led => !fadingInLeds.ContainsKey(led) && !fadingOutLeds.ContainsKey(led));
87+
var selectedLeds = availableLeds.OrderBy(x => Guid.NewGuid()).Take((int)(numberOfLeds * densityMultiplier));
88+
89+
foreach (var led in selectedLeds)
90+
{
91+
fadingInLeds.TryAdd(led, baseColor);
92+
var colorIndex = random.Next(colors.Length);
93+
94+
if (!currentColors.ContainsKey(led))
95+
currentColors.Add(led, colors[colorIndex]);
96+
97+
if (!startTimes.ContainsKey(led))
98+
{
99+
var rng = Timing + GetRandomStartTime();
100+
startTimes.Add(led, rng);
101+
}
102+
}
103+
104+
startDelay = Timing + (((fadeSpeed * 2) - 50) / 1000);
105+
}
106+
107+
foreach (var led in fadingInLeds)
108+
{
109+
if (Timing >= startTimes[led.Key])
110+
{
111+
if (!currentBrightness.ContainsKey(led.Key))
112+
{
113+
currentBrightness.Add(led.Key, minBrightness);
114+
}
115+
116+
currentBrightness[led.Key] += (float)(deltaTime * (maxBrightness - minBrightness) / (fadeSpeed / 1000));
117+
118+
if (currentBrightness[led.Key] >= maxBrightness)
119+
{
120+
fadingOutLeds.TryAdd(led.Key, currentColors[led.Key]);
121+
fadingInLeds.TryRemove(led);
122+
}
123+
else
124+
{
125+
var lerpAmount = Map(currentBrightness[led.Key], minBrightness, maxBrightness, 0, 1);
126+
var color = Lerp(baseColor, currentColors[led.Key], lerpAmount);
127+
fadingInLeds[led.Key] = color;
128+
}
129+
}
130+
}
131+
132+
foreach (var led in fadingOutLeds)
133+
{
134+
if (!currentBrightness.ContainsKey(led.Key))
135+
{
136+
currentBrightness.Add(led.Key, maxBrightness);
137+
}
138+
139+
currentBrightness[led.Key] -= (float)(deltaTime * (maxBrightness - minBrightness) / (fadeSpeed / 1000));
140+
141+
if (currentBrightness[led.Key] <= minBrightness)
142+
{
143+
fadingOutLeds.TryRemove(led);
144+
currentBrightness.Remove(led.Key);
145+
currentColors.Remove(led.Key);
146+
startTimes.Remove(led.Key);
147+
}
148+
else
149+
{
150+
var lerpAmount = Map(currentBrightness[led.Key], minBrightness, maxBrightness, 0, 1);
151+
var color = Lerp(baseColor, currentColors[led.Key], lerpAmount);
152+
fadingOutLeds[led.Key] = color;
153+
}
154+
}
155+
156+
foreach (var led in ledGroup)
157+
{
158+
if (fadingInLeds != null && fadingInLeds.ContainsKey(led))
159+
{
160+
led.Color = fadingInLeds[led];
161+
}
162+
else if (fadingOutLeds != null && fadingOutLeds.ContainsKey(led))
163+
{
164+
led.Color = fadingOutLeds[led];
165+
}
166+
else
167+
{
168+
led.Color = baseColor;
169+
}
170+
}
171+
}
172+
catch (Exception ex)
173+
{
174+
#if DEBUG
175+
Debug.WriteLine($"Exception: {ex.Message}");
176+
#endif
177+
}
178+
}
179+
180+
private double GetRandomStartTime()
181+
{
182+
return random.NextDouble() * (interval * 0.05);
183+
}
184+
185+
private float Map(float value, float fromMin, float fromMax, float toMin, float toMax)
186+
{
187+
return (value - fromMin) * (toMax - toMin) / (fromMax - fromMin) + toMin;
188+
}
189+
190+
private static Color Lerp(Color start, Color end, float amount)
191+
{
192+
float r = start.R + (end.R - start.R) * amount;
193+
float g = start.G + (end.G - start.G) * amount;
194+
float b = start.B + (end.B - start.B) * amount;
195+
196+
return new Color((int)(r * 255), (int)(g * 255), (int)(b * 255));
197+
}
198+
}
199+
}

0 commit comments

Comments
 (0)