Skip to content

Commit 83d4584

Browse files
Added remaining raid effects
1 parent 99203a9 commit 83d4584

12 files changed

Lines changed: 568 additions & 34 deletions

File tree

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+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
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 BPMSINDecorator : AbstractUpdateAwareDecorator, ILedGroupDecorator
12+
{
13+
private readonly ListLedGroup ledGroup;
14+
private readonly Random random = new Random();
15+
private readonly double waveFrequency;
16+
private readonly Color[] colors;
17+
private readonly Color baseColor;
18+
private readonly int groupSize;
19+
private readonly List<Led> leds;
20+
private ConcurrentDictionary<Led, double> ledPositions;
21+
private Dictionary<Led, Color> currentColors;
22+
private Dictionary<Led, Color> targetColors;
23+
private Dictionary<Led, double> transitionStartTimes;
24+
private double Timing;
25+
private double nextBeatTime;
26+
private double interval;
27+
private int bpm;
28+
private double fadeTime;
29+
30+
public BPMSINDecorator(ListLedGroup _ledGroup, int bpm, double waveFrequency, Color[] colors, double fadeTime, int groupSize, RGBSurface surface, bool updateIfDisabled = false, Color baseColor = default(Color)) : base(surface, updateIfDisabled)
31+
{
32+
this.ledGroup = _ledGroup;
33+
this.bpm = bpm;
34+
this.waveFrequency = waveFrequency;
35+
this.colors = colors;
36+
this.baseColor = baseColor == default(Color) ? Color.Transparent : baseColor;
37+
this.fadeTime = fadeTime;
38+
this.groupSize = groupSize;
39+
40+
leds = ledGroup.OrderBy(led => led.Id).ToList(); // Ensure the list is ordered correctly
41+
CalculateInterval();
42+
ledPositions = new ConcurrentDictionary<Led, double>();
43+
currentColors = new Dictionary<Led, Color>();
44+
targetColors = new Dictionary<Led, Color>();
45+
transitionStartTimes = new Dictionary<Led, double>();
46+
Timing = 0;
47+
nextBeatTime = interval; // Initialize nextBeatTime
48+
}
49+
50+
private void CalculateInterval()
51+
{
52+
// Convert BPM to interval in seconds (interval = 60 / BPM)
53+
interval = 60.0 / bpm;
54+
}
55+
56+
public override void OnAttached(IDecoratable decoratable)
57+
{
58+
base.OnAttached(decoratable);
59+
ledGroup.Detach();
60+
61+
Debug.WriteLine("Arena Light Show Decorator Attached");
62+
63+
foreach (var led in leds)
64+
{
65+
ledPositions.TryAdd(led, random.NextDouble() * Math.PI * 2);
66+
var initialColor = colors[random.Next(colors.Length)];
67+
currentColors[led] = initialColor;
68+
targetColors[led] = initialColor;
69+
transitionStartTimes[led] = 0;
70+
}
71+
}
72+
73+
public override void OnDetached(IDecoratable decoratable)
74+
{
75+
base.OnDetached(decoratable);
76+
ledPositions.Clear();
77+
currentColors.Clear();
78+
targetColors.Clear();
79+
transitionStartTimes.Clear();
80+
Timing = 0;
81+
nextBeatTime = interval;
82+
83+
Debug.WriteLine("Arena Light Show Decorator Detached");
84+
}
85+
86+
protected override void Update(double deltaTime)
87+
{
88+
try
89+
{
90+
if (ledGroup == null) return;
91+
92+
Timing += deltaTime;
93+
94+
// Check if it's time for the next beat
95+
if (Timing >= nextBeatTime)
96+
{
97+
nextBeatTime += interval; // Schedule next beat
98+
99+
foreach (var led in leds)
100+
{
101+
int groupIndex = groupSize == 0 ? random.Next(leds.Count) : (int)(leds.IndexOf(led) % groupSize);
102+
int colorIndex = (groupIndex + (int)(Timing / interval)) % colors.Length;
103+
104+
targetColors[led] = colors[colorIndex];
105+
transitionStartTimes[led] = Timing;
106+
}
107+
}
108+
109+
foreach (var led in leds)
110+
{
111+
if (!ledPositions.ContainsKey(led)) continue;
112+
113+
double timeSinceTransitionStart = Timing - transitionStartTimes[led];
114+
float transitionProgress = fadeTime > 0 ? (float)Math.Min(timeSinceTransitionStart / fadeTime, 1.0) : 1.0f;
115+
float sineProgress = (float)Math.Sin(transitionProgress * Math.PI * 0.5); // Use sine for smooth transitions
116+
117+
var color = fadeTime == 0 ? targetColors[led] : Lerp(currentColors[led], targetColors[led], sineProgress);
118+
led.Color = color;
119+
120+
// Update the current color if the transition is complete
121+
if (transitionProgress >= 1.0)
122+
{
123+
currentColors[led] = targetColors[led];
124+
}
125+
}
126+
}
127+
catch (Exception ex)
128+
{
129+
#if DEBUG
130+
Debug.WriteLine($"Exception: {ex.Message}");
131+
#endif
132+
}
133+
}
134+
135+
private static Color Lerp(Color start, Color end, float amount)
136+
{
137+
float r = start.R + (end.R - start.R) * amount;
138+
float g = start.G + (end.G - start.G) * amount;
139+
float b = start.B + (end.B - start.B) * amount;
140+
141+
return new Color((byte)(r * 255), (byte)(g * 255), (byte)(b * 255));
142+
}
143+
}
144+
}

0 commit comments

Comments
 (0)