Merge branch 'dev' of github.com:peter-slattery/Lumenarium into dev
This commit is contained in:
commit
27c6caa204
|
@ -1,92 +0,0 @@
|
||||||
lumenarium_animation_file;
|
|
||||||
animation_name: "ambient_0";
|
|
||||||
layers_count: 2;
|
|
||||||
blocks_count: 9;
|
|
||||||
playable_range:{
|
|
||||||
min: 0;
|
|
||||||
max: 1000;
|
|
||||||
};
|
|
||||||
layers:{
|
|
||||||
layer:{
|
|
||||||
name: "Color";
|
|
||||||
blend: "Add";
|
|
||||||
};
|
|
||||||
layer:{
|
|
||||||
name: "Mask";
|
|
||||||
blend: "Multiply";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
blocks:{
|
|
||||||
block:{
|
|
||||||
frame_range:{
|
|
||||||
min: 88;
|
|
||||||
max: 315;
|
|
||||||
};
|
|
||||||
layer_index: 0;
|
|
||||||
animation_name: "Pattern_Rotary";
|
|
||||||
};
|
|
||||||
block:{
|
|
||||||
frame_range:{
|
|
||||||
min: 156;
|
|
||||||
max: 429;
|
|
||||||
};
|
|
||||||
layer_index: 1;
|
|
||||||
animation_name: "Pattern_LeafyPatchy";
|
|
||||||
};
|
|
||||||
block:{
|
|
||||||
frame_range:{
|
|
||||||
min: 403;
|
|
||||||
max: 675;
|
|
||||||
};
|
|
||||||
layer_index: 1;
|
|
||||||
animation_name: "Pattern_Patchy";
|
|
||||||
};
|
|
||||||
block:{
|
|
||||||
frame_range:{
|
|
||||||
min: 643;
|
|
||||||
max: 997;
|
|
||||||
};
|
|
||||||
layer_index: 1;
|
|
||||||
animation_name: "Pattern_LeafyPatchy";
|
|
||||||
};
|
|
||||||
block:{
|
|
||||||
frame_range:{
|
|
||||||
min: 253;
|
|
||||||
max: 571;
|
|
||||||
};
|
|
||||||
layer_index: 0;
|
|
||||||
animation_name: "Pattern_VerticalLines";
|
|
||||||
};
|
|
||||||
block:{
|
|
||||||
frame_range:{
|
|
||||||
min: 522;
|
|
||||||
max: 772;
|
|
||||||
};
|
|
||||||
layer_index: 0;
|
|
||||||
animation_name: "Pattern_Rotary";
|
|
||||||
};
|
|
||||||
block:{
|
|
||||||
frame_range:{
|
|
||||||
min: 737;
|
|
||||||
max: 998;
|
|
||||||
};
|
|
||||||
layer_index: 0;
|
|
||||||
animation_name: "Pattern_VerticalLines";
|
|
||||||
};
|
|
||||||
block:{
|
|
||||||
frame_range:{
|
|
||||||
min: 0;
|
|
||||||
max: 117;
|
|
||||||
};
|
|
||||||
layer_index: 0;
|
|
||||||
animation_name: "Pattern_VerticalLines";
|
|
||||||
};
|
|
||||||
block:{
|
|
||||||
frame_range:{
|
|
||||||
min: 0;
|
|
||||||
max: 179;
|
|
||||||
};
|
|
||||||
layer_index: 1;
|
|
||||||
animation_name: "Pattern_StemSolid";
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -35,7 +35,7 @@ blocks:{
|
||||||
max: 2000;
|
max: 2000;
|
||||||
};
|
};
|
||||||
layer_index: 1;
|
layer_index: 1;
|
||||||
animation_name: "Pattern_VerticalLines";
|
animation_name: "Pattern_Leafy";
|
||||||
};
|
};
|
||||||
block:{
|
block:{
|
||||||
frame_range:{
|
frame_range:{
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
lumenarium_animation_file;
|
||||||
|
animation_name: "fishy_0";
|
||||||
|
layers_count: 3;
|
||||||
|
blocks_count: 3;
|
||||||
|
playable_range:{
|
||||||
|
min: 0;
|
||||||
|
max: 3600;
|
||||||
|
};
|
||||||
|
layers:{
|
||||||
|
layer:{
|
||||||
|
name: "[New Layer]";
|
||||||
|
blend: "Add";
|
||||||
|
};
|
||||||
|
layer:{
|
||||||
|
name: "[New Layer]";
|
||||||
|
blend: "Add";
|
||||||
|
};
|
||||||
|
layer:{
|
||||||
|
name: "Color";
|
||||||
|
blend: "Multiply";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
blocks:{
|
||||||
|
block:{
|
||||||
|
frame_range:{
|
||||||
|
min: 0;
|
||||||
|
max: 3600;
|
||||||
|
};
|
||||||
|
layer_index: 2;
|
||||||
|
animation_name: "Pattern_HueShift";
|
||||||
|
};
|
||||||
|
block:{
|
||||||
|
frame_range:{
|
||||||
|
min: 0;
|
||||||
|
max: 3600;
|
||||||
|
};
|
||||||
|
layer_index: 1;
|
||||||
|
animation_name: "Pattern_StemSolid";
|
||||||
|
};
|
||||||
|
block:{
|
||||||
|
frame_range:{
|
||||||
|
min: 0;
|
||||||
|
max: 3600;
|
||||||
|
};
|
||||||
|
layer_index: 0;
|
||||||
|
animation_name: "Pattern_Rotary";
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,36 @@
|
||||||
|
lumenarium_animation_file;
|
||||||
|
animation_name: "patchy_loading_bar_0";
|
||||||
|
layers_count: 2;
|
||||||
|
blocks_count: 2;
|
||||||
|
playable_range:{
|
||||||
|
min: 0;
|
||||||
|
max: 3350;
|
||||||
|
};
|
||||||
|
layers:{
|
||||||
|
layer:{
|
||||||
|
name: "[New Layer]";
|
||||||
|
blend: "Add";
|
||||||
|
};
|
||||||
|
layer:{
|
||||||
|
name: "[New Layer]";
|
||||||
|
blend: "Multiply";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
blocks:{
|
||||||
|
block:{
|
||||||
|
frame_range:{
|
||||||
|
min: 0;
|
||||||
|
max: 3600;
|
||||||
|
};
|
||||||
|
layer_index: 1;
|
||||||
|
animation_name: "Pattern_Patchy";
|
||||||
|
};
|
||||||
|
block:{
|
||||||
|
frame_range:{
|
||||||
|
min: 0;
|
||||||
|
max: 3600;
|
||||||
|
};
|
||||||
|
layer_index: 0;
|
||||||
|
animation_name: "Pattern_GrowFadeMask";
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,28 @@
|
||||||
|
lumenarium_animation_file;
|
||||||
|
animation_name: "primary_hue_0";
|
||||||
|
layers_count: 2;
|
||||||
|
blocks_count: 1;
|
||||||
|
playable_range:{
|
||||||
|
min: 0;
|
||||||
|
max: 360;
|
||||||
|
};
|
||||||
|
layers:{
|
||||||
|
layer:{
|
||||||
|
name: "[New Layer]";
|
||||||
|
blend: "Add";
|
||||||
|
};
|
||||||
|
layer:{
|
||||||
|
name: "[New Layer]";
|
||||||
|
blend: "Add";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
blocks:{
|
||||||
|
block:{
|
||||||
|
frame_range:{
|
||||||
|
min: 0;
|
||||||
|
max: 36000;
|
||||||
|
};
|
||||||
|
layer_index: 1;
|
||||||
|
animation_name: "Pattern_PrimaryHue";
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,28 @@
|
||||||
|
lumenarium_animation_file;
|
||||||
|
animation_name: "rainbow";
|
||||||
|
layers_count: 2;
|
||||||
|
blocks_count: 1;
|
||||||
|
playable_range:{
|
||||||
|
min: 0;
|
||||||
|
max: 360;
|
||||||
|
};
|
||||||
|
layers:{
|
||||||
|
layer:{
|
||||||
|
name: "Mask";
|
||||||
|
blend: "Add";
|
||||||
|
};
|
||||||
|
layer:{
|
||||||
|
name: "Color";
|
||||||
|
blend: "Add";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
blocks:{
|
||||||
|
block:{
|
||||||
|
frame_range:{
|
||||||
|
min: 0;
|
||||||
|
max: 360;
|
||||||
|
};
|
||||||
|
layer_index: 1;
|
||||||
|
animation_name: "Pattern_Rainbow";
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,28 @@
|
||||||
|
lumenarium_animation_file;
|
||||||
|
animation_name: "rainbow_loading_bar_0";
|
||||||
|
layers_count: 2;
|
||||||
|
blocks_count: 1;
|
||||||
|
playable_range:{
|
||||||
|
min: 0;
|
||||||
|
max: 9000;
|
||||||
|
};
|
||||||
|
layers:{
|
||||||
|
layer:{
|
||||||
|
name: "[New Layer]";
|
||||||
|
blend: "Add";
|
||||||
|
};
|
||||||
|
layer:{
|
||||||
|
name: "[New Layer]";
|
||||||
|
blend: "Add";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
blocks:{
|
||||||
|
block:{
|
||||||
|
frame_range:{
|
||||||
|
min: 0;
|
||||||
|
max: 9000;
|
||||||
|
};
|
||||||
|
layer_index: 1;
|
||||||
|
animation_name: "Pattern_RainbowLoadingBar";
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,28 @@
|
||||||
|
lumenarium_animation_file;
|
||||||
|
animation_name: "wavy_0";
|
||||||
|
layers_count: 2;
|
||||||
|
blocks_count: 1;
|
||||||
|
playable_range:{
|
||||||
|
min: 0;
|
||||||
|
max: 7200;
|
||||||
|
};
|
||||||
|
layers:{
|
||||||
|
layer:{
|
||||||
|
name: "[New Layer]";
|
||||||
|
blend: "Add";
|
||||||
|
};
|
||||||
|
layer:{
|
||||||
|
name: "Color";
|
||||||
|
blend: "Add";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
blocks:{
|
||||||
|
block:{
|
||||||
|
frame_range:{
|
||||||
|
min: 0;
|
||||||
|
max: 7200;
|
||||||
|
};
|
||||||
|
layer_index: 1;
|
||||||
|
animation_name: "Pattern_Wavy";
|
||||||
|
};
|
||||||
|
};
|
|
@ -1,16 +1,20 @@
|
||||||
lumenarium_animation_file;
|
lumenarium_animation_file;
|
||||||
animation_name: "voice_anim";
|
animation_name: "voice_anim";
|
||||||
layers_count: 1;
|
layers_count: 2;
|
||||||
blocks_count: 1;
|
blocks_count: 2;
|
||||||
playable_range:{
|
playable_range:{
|
||||||
min: 0;
|
min: 0;
|
||||||
max: 3600;
|
max: 3600;
|
||||||
};
|
};
|
||||||
layers:{
|
layers:{
|
||||||
layer:{
|
layer:{
|
||||||
name: "[New Layer]";
|
name: "Base";
|
||||||
blend: "Add";
|
blend: "Add";
|
||||||
};
|
};
|
||||||
|
layer:{
|
||||||
|
name: "Add In";
|
||||||
|
blend: "Overwrite";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
blocks:{
|
blocks:{
|
||||||
block:{
|
block:{
|
||||||
|
@ -21,4 +25,12 @@ blocks:{
|
||||||
layer_index: 0;
|
layer_index: 0;
|
||||||
animation_name: "Pattern_VoicePattern";
|
animation_name: "Pattern_VoicePattern";
|
||||||
};
|
};
|
||||||
|
block:{
|
||||||
|
frame_range:{
|
||||||
|
min: 0;
|
||||||
|
max: 3600;
|
||||||
|
};
|
||||||
|
layer_index: 1;
|
||||||
|
animation_name: "Pattern_VoiceAddIns";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
lumenarium_animation_file;
|
||||||
|
animation_name: "awaken";
|
||||||
|
layers_count: 3;
|
||||||
|
blocks_count: 5;
|
||||||
|
playable_range:{
|
||||||
|
min: 0;
|
||||||
|
max: 7200;
|
||||||
|
};
|
||||||
|
layers:{
|
||||||
|
layer:{
|
||||||
|
name: "[New Layer]";
|
||||||
|
blend: "Add";
|
||||||
|
};
|
||||||
|
layer:{
|
||||||
|
name: "[New Layer]";
|
||||||
|
blend: "Add";
|
||||||
|
};
|
||||||
|
layer:{
|
||||||
|
name: "[New Layer]";
|
||||||
|
blend: "Multiply";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
blocks:{
|
||||||
|
block:{
|
||||||
|
frame_range:{
|
||||||
|
min: 94;
|
||||||
|
max: 1363;
|
||||||
|
};
|
||||||
|
layer_index: 0;
|
||||||
|
animation_name: "Pattern_Leafy";
|
||||||
|
};
|
||||||
|
block:{
|
||||||
|
frame_range:{
|
||||||
|
min: 1169;
|
||||||
|
max: 7200;
|
||||||
|
};
|
||||||
|
layer_index: 0;
|
||||||
|
animation_name: "Pattern_BulbMask";
|
||||||
|
};
|
||||||
|
block:{
|
||||||
|
frame_range:{
|
||||||
|
min: 71;
|
||||||
|
max: 7200;
|
||||||
|
};
|
||||||
|
layer_index: 2;
|
||||||
|
animation_name: "Pattern_Wavy";
|
||||||
|
};
|
||||||
|
block:{
|
||||||
|
frame_range:{
|
||||||
|
min: 2135;
|
||||||
|
max: 2555;
|
||||||
|
};
|
||||||
|
layer_index: 1;
|
||||||
|
animation_name: "Pattern_None";
|
||||||
|
};
|
||||||
|
block:{
|
||||||
|
frame_range:{
|
||||||
|
min: 2470;
|
||||||
|
max: 7200;
|
||||||
|
};
|
||||||
|
layer_index: 1;
|
||||||
|
animation_name: "Pattern_StemSolid";
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,12 @@
|
||||||
|
lumenarium_animation_file;
|
||||||
|
animation_name: "off_anim";
|
||||||
|
layers_count: 0;
|
||||||
|
blocks_count: 0;
|
||||||
|
playable_range:{
|
||||||
|
min: 0;
|
||||||
|
max: 2;
|
||||||
|
};
|
||||||
|
layers:{
|
||||||
|
};
|
||||||
|
blocks:{
|
||||||
|
};
|
|
@ -8,7 +8,14 @@
|
||||||
internal pixel
|
internal pixel
|
||||||
LedBlend_Overwrite(pixel PixelA, pixel PixelB, u8* UserData)
|
LedBlend_Overwrite(pixel PixelA, pixel PixelB, u8* UserData)
|
||||||
{
|
{
|
||||||
return PixelB;
|
pixel Result = PixelB;
|
||||||
|
if (PixelB.R == 0 &&
|
||||||
|
PixelB.G == 0 &&
|
||||||
|
PixelB.G == 0)
|
||||||
|
{
|
||||||
|
Result = PixelA;
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal pixel
|
internal pixel
|
||||||
|
|
|
@ -7,6 +7,12 @@
|
||||||
|
|
||||||
#define FLOWER_COLORS_COUNT 12
|
#define FLOWER_COLORS_COUNT 12
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_None(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
|
{
|
||||||
|
// just here so you can fade in from black
|
||||||
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_AltBloomMask(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_AltBloomMask(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
|
@ -171,17 +177,8 @@ Pattern_BasicFlowers(led_buffer* Leds, led_buffer_range Range, assembly Assembly
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_Wavy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_WavyOptions(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData, r32 Granularity, v4 C0, v4 C1, v4 C2)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
|
||||||
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
|
||||||
Time = Time * BLState->PatternSpeed;
|
|
||||||
|
|
||||||
phrase_hue Hue = BlumenLumen_GetCurrentHue(BLState, Assembly);
|
|
||||||
v4 C0 = RGBFromPhraseHue(Hue.Hue0);
|
|
||||||
v4 C1 = RGBFromPhraseHue(Hue.Hue1);
|
|
||||||
v4 C2 = RGBFromPhraseHue(Hue.Hue2);
|
|
||||||
|
|
||||||
r32 Top = 120 + (SinR32(Time) * 10);
|
r32 Top = 120 + (SinR32(Time) * 10);
|
||||||
r32 Mid = 70 + (CosR32(Time * 2.13) * 20);
|
r32 Mid = 70 + (CosR32(Time * 2.13) * 20);
|
||||||
r32 Bot = 0;
|
r32 Bot = 0;
|
||||||
|
@ -233,7 +230,7 @@ Pattern_Wavy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Ti
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_Patchy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_Wavy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
||||||
|
@ -244,6 +241,18 @@ Pattern_Patchy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32
|
||||||
v4 C1 = RGBFromPhraseHue(Hue.Hue1);
|
v4 C1 = RGBFromPhraseHue(Hue.Hue1);
|
||||||
v4 C2 = RGBFromPhraseHue(Hue.Hue2);
|
v4 C2 = RGBFromPhraseHue(Hue.Hue2);
|
||||||
|
|
||||||
|
Pattern_WavyOptions(Leds, Range, Assembly, Time, Transient, UserData, 1, C0, C1, C2);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_PatchyOptions(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData, r32 Granularity, v4 C0, v4 C1, v4 C2)
|
||||||
|
{
|
||||||
|
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
||||||
|
|
||||||
|
r32 BaseGA = 50.000f * (1 / Granularity);
|
||||||
|
r32 BaseGB = 135.20f * (1 / Granularity);
|
||||||
|
r32 BaseGC = 260.74f * (1 / Granularity);
|
||||||
|
|
||||||
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
{
|
{
|
||||||
v4 P = Leds->Positions[LedIndex];
|
v4 P = Leds->Positions[LedIndex];
|
||||||
|
@ -251,22 +260,41 @@ Pattern_Patchy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32
|
||||||
r32 ScaleFactor = 1.0f / LedRange;
|
r32 ScaleFactor = 1.0f / LedRange;
|
||||||
v3 Pp = P.xyz + v3{150, 100, 0};
|
v3 Pp = P.xyz + v3{150, 100, 0};
|
||||||
|
|
||||||
r32 NoiseA = Noise3D((Pp / 38) + v3{0, 0, Time});
|
r32 NoiseA = Noise3D((Pp / BaseGA) + v3{0, 0, Time});
|
||||||
NoiseA = PowR32(NoiseA, 3);
|
NoiseA = PowR32(NoiseA, 3);
|
||||||
NoiseA = Smoothstep(NoiseA);
|
NoiseA = Smoothstep(NoiseA);
|
||||||
v4 CA = C0 * NoiseA;
|
|
||||||
|
|
||||||
r32 NoiseB = Noise3D((Pp / 75) + v3{Time * 0.5f, 0, 0});
|
r32 NoiseB = Noise3D((Pp / BaseGB) + v3{Time * 0.5f, 0, 0});
|
||||||
NoiseB = PowR32(NoiseB, 3);
|
NoiseB = PowR32(NoiseB, 3);
|
||||||
NoiseB = Smoothstep(NoiseB);
|
NoiseB = Smoothstep(NoiseB);
|
||||||
v4 CB = C1 * NoiseB;
|
|
||||||
|
|
||||||
v4 C = (C0 * NoiseA) + (C1 * NoiseB);
|
#if 1
|
||||||
C /= (NoiseA + NoiseB);
|
r32 NoiseC = Noise3D((Pp / BaseGC) + v3{Time * 0.5f, 0, 0});
|
||||||
|
NoiseC = PowR32(NoiseC, 3);
|
||||||
|
NoiseC = Smoothstep(NoiseC);
|
||||||
|
#else
|
||||||
|
r32 NoiseC = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
v4 C = (C0 * NoiseA) + (C1 * NoiseB) + (C2 * NoiseC);
|
||||||
|
C /= (NoiseA + NoiseB + NoiseC);
|
||||||
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_Patchy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
||||||
|
phrase_hue Hue = BlumenLumen_GetCurrentHue(BLState, Assembly);
|
||||||
|
v4 C0 = RGBFromPhraseHue(Hue.Hue0);
|
||||||
|
v4 C1 = RGBFromPhraseHue(Hue.Hue1);
|
||||||
|
v4 C2 = RGBFromPhraseHue(Hue.Hue2);
|
||||||
|
Time = Time * BLState->PatternSpeed;
|
||||||
|
Pattern_PatchyOptions(Leds, Range, Assembly, Time, Transient, UserData, 5, C0, C1, C2);
|
||||||
|
}
|
||||||
|
|
||||||
internal r32
|
internal r32
|
||||||
Leafy_BandSDF(v3 P, gs_random_series* Random, r32 Time)
|
Leafy_BandSDF(v3 P, gs_random_series* Random, r32 Time)
|
||||||
{
|
{
|
||||||
|
@ -412,33 +440,35 @@ Pattern_VerticalLines(led_buffer* Leds, led_buffer_range Range, assembly Assembl
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_Rotary(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_RotaryOptions(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData, r32 Granularity, v4 BGColor, v4 FGColor)
|
||||||
{
|
{
|
||||||
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
DEBUG_TRACK_FUNCTION;
|
||||||
Time = Time * BLState->PatternSpeed;
|
|
||||||
|
|
||||||
gs_random_series Random = InitRandomSeries(24601);
|
gs_random_series Random = InitRandomSeries((u32)(24601 * (Assembly.Center.x + 1.032f)));
|
||||||
|
|
||||||
#define SphereCount 32
|
#define SphereCount 32
|
||||||
v3 SphereCenter[SphereCount];
|
v3 SphereCenter[SphereCount];
|
||||||
|
|
||||||
r32 MaxHeightOffset = 150;
|
r32 G = RemapR32(Granularity, 1, 5, .75f, 2);
|
||||||
|
r32 MaxHeightOffset = 250;
|
||||||
r32 MaxSpeed = 10;
|
r32 MaxSpeed = 10;
|
||||||
r32 SphereRadius = 2.0f;
|
r32 SphereRotationRadius = 3.0f;
|
||||||
|
r32 SphereRadius = 2.0f / G;
|
||||||
for (u32 i = 0; i < SphereCount; i++)
|
for (u32 i = 0; i < SphereCount; i++)
|
||||||
{
|
{
|
||||||
r32 SphereSeedA = NextRandomBilateral(&Random);
|
r32 SphereSeedA = NextRandomUnilateral(&Random);
|
||||||
|
SphereSeedA = PowR32(SphereSeedA, 2);
|
||||||
r32 SphereSeedB = NextRandomBilateral(&Random);
|
r32 SphereSeedB = NextRandomBilateral(&Random);
|
||||||
r32 SphereSpeed = NextRandomUnilateral(&Random) * MaxSpeed;
|
r32 SphereSpeed = NextRandomUnilateral(&Random) * MaxSpeed;
|
||||||
|
|
||||||
r32 SphereTime = Time + SphereSpeed;
|
r32 SphereTime = Time + SphereSpeed;
|
||||||
r32 HeightOffset = SphereTime + (SphereSeedA * MaxHeightOffset);
|
r32 HeightOffset = 150 - (SphereSeedA * MaxHeightOffset);
|
||||||
r32 RotationOffset = SphereTime + SphereSeedB * TauR32;
|
r32 RotationOffset = SphereTime + SphereSeedB * TauR32;
|
||||||
r32 SphereRotationDir = NextRandomBilateral(&Random) < 0 ? -1 : 1;
|
r32 SphereRotationDir = NextRandomBilateral(&Random) < 0 ? -1 : 1;
|
||||||
v3 SpherePosOffset = v3{
|
v3 SpherePosOffset = v3{
|
||||||
SinR32(RotationOffset * SphereRotationDir) * (SphereRadius * 2),
|
SinR32(RotationOffset * SphereRotationDir) * (SphereRotationRadius * 2),
|
||||||
HeightOffset,
|
HeightOffset,
|
||||||
CosR32(RotationOffset * SphereRotationDir) * (SphereRadius * 2)
|
CosR32(RotationOffset * SphereRotationDir) * (SphereRotationRadius * 2)
|
||||||
};
|
};
|
||||||
SphereCenter[i] = Assembly.Center + SpherePosOffset;
|
SphereCenter[i] = Assembly.Center + SpherePosOffset;
|
||||||
}
|
}
|
||||||
|
@ -455,17 +485,27 @@ Pattern_Rotary(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32
|
||||||
Dist = Min(Dist, SphereSDF);
|
Dist = Min(Dist, SphereSDF);
|
||||||
}
|
}
|
||||||
|
|
||||||
v4 C = BlackV4;
|
v4 C = BGColor;
|
||||||
if (Dist <= 1)
|
if (Dist <= 1)
|
||||||
{
|
{
|
||||||
r32 Brightness = Clamp01(SphereRadius - Dist);
|
r32 Brightness = Clamp01(SphereRadius - Dist);
|
||||||
C = WhiteV4 * Brightness;
|
C = V4Lerp(Brightness, BGColor, FGColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_Rotary(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
|
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
||||||
|
Time = Time * BLState->PatternSpeed;
|
||||||
|
Pattern_RotaryOptions(Leds, Range, Assembly, Time, Transient, UserData, 2, BlackV4, WhiteV4);
|
||||||
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_AllOnMask(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_AllOnMask(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
|
@ -480,6 +520,8 @@ Pattern_AllOnMask(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r
|
||||||
internal void
|
internal void
|
||||||
Pattern_BulbMask(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_BulbMask(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
||||||
Time = Time * BLState->PatternSpeed;
|
Time = Time * BLState->PatternSpeed;
|
||||||
|
|
||||||
|
@ -571,26 +613,47 @@ GenVerticalLeaves(v3 P, r32 Time, v4 C0, v4 C1, v4 C2)
|
||||||
return R;
|
return R;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal r32
|
internal void
|
||||||
GenLiquidBands(v3 P, r32 Offset, r32 Time)
|
AddIn_WavesPattern(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData, r32 Granularity, v4 C0, v4 C1, v4 C2)
|
||||||
{
|
{
|
||||||
r32 Width = 30;
|
DEBUG_TRACK_FUNCTION;
|
||||||
r32 VAcc = 0;
|
|
||||||
for (u32 i = 1; i < 3; i++)
|
v4 C2P = C2 * 255;
|
||||||
|
|
||||||
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
{
|
{
|
||||||
v3 P0 = v3{P.x + (23.124f * i), 0, P.z - (-12.34f * i)};
|
v3 P = Leds->Positions[LedIndex].xyz;
|
||||||
|
|
||||||
r32 Y = (P.y - Offset);
|
v4 C = v4{
|
||||||
r32 S = Fbm3D(P0 * .005f, Time) * 250;
|
(r32)Leds->Colors[LedIndex].R,
|
||||||
S += ModR32((Time * 100) - (150 * i), 400);
|
(r32)Leds->Colors[LedIndex].G,
|
||||||
|
(r32)Leds->Colors[LedIndex].B,
|
||||||
|
1
|
||||||
|
};
|
||||||
|
|
||||||
r32 V = (Width - Abs(Y - S)) / Width;
|
r32 Offset = -250;
|
||||||
V = Clamp01(V);
|
r32 Width = 30;
|
||||||
|
r32 Bands = 0;
|
||||||
|
for (u32 i = 1; i <= 1; i++)
|
||||||
|
{
|
||||||
|
P.x = FloorR32(P.x);
|
||||||
|
P.z = FloorR32(P.z);
|
||||||
|
|
||||||
VAcc += V;
|
v3 P0 = v3{P.x + (23.124f * i), 0, P.z - (-12.34f * i) + Time};
|
||||||
|
r32 S = Fbm3D(P0 * .005f, Time) * 250;
|
||||||
|
S += ModR32((Time * 100) - (150 * i), 400);
|
||||||
|
|
||||||
|
r32 Y = (P.y - Offset);
|
||||||
|
r32 V = (Width - Abs(Y - S)) / Width;
|
||||||
|
V = Clamp01(V);
|
||||||
|
|
||||||
|
Bands += V;
|
||||||
|
}
|
||||||
|
|
||||||
|
C = V4Lerp(Bands, C * .5f, C2P);
|
||||||
|
|
||||||
|
Leds->Colors[LedIndex] = pixel{(u8)C.r, (u8)C.g, (u8)C.b};
|
||||||
}
|
}
|
||||||
|
|
||||||
return VAcc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal r32
|
internal r32
|
||||||
|
@ -618,40 +681,70 @@ GenDotBands(v3 P, r32 Time)
|
||||||
internal void
|
internal void
|
||||||
Pattern_VoicePattern(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_VoicePattern(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
DEBUG_TRACK_FUNCTION;
|
||||||
Time = Time * BLState->PatternSpeed;
|
|
||||||
|
|
||||||
|
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
||||||
phrase_hue Hue = BlumenLumen_GetCurrentHue(BLState, Assembly);
|
phrase_hue Hue = BlumenLumen_GetCurrentHue(BLState, Assembly);
|
||||||
v4 C0 = RGBFromPhraseHue(Hue.Hue0);
|
v4 C0 = RGBFromPhraseHue(Hue.Hue0);
|
||||||
v4 C1 = RGBFromPhraseHue(Hue.Hue1);
|
v4 C1 = RGBFromPhraseHue(Hue.Hue1);
|
||||||
v4 C2 = RGBFromPhraseHue(Hue.Hue2);
|
v4 C2 = RGBFromPhraseHue(Hue.Hue2);
|
||||||
|
|
||||||
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
Time = Time * BLState->PatternSpeed * Hue.Speed;;
|
||||||
|
|
||||||
|
switch (Hue.Pattern)
|
||||||
{
|
{
|
||||||
v3 P = Leds->Positions[LedIndex].xyz;
|
case HuePattern_Wavy:
|
||||||
|
{
|
||||||
|
Pattern_WavyOptions(Leds, Range, Assembly, Time, Transient, UserData, Hue.Granularity, C0, C1, C0);
|
||||||
|
}break;
|
||||||
|
|
||||||
v4 C = {};
|
default:
|
||||||
C += GenPatchyColor(P, Time, C0, C2, {});
|
{
|
||||||
//C = GenVerticalLeaves((P - Assembly.Center) + v3{0, 150, 0}, Time, C0, C1, C2);
|
Pattern_PatchyOptions(Leds, Range, Assembly, Time, Transient, UserData, Hue.Granularity, C0, C1, C2);
|
||||||
//r32 Bands = GenLiquidBands(P, -250, Time);
|
}break;
|
||||||
//C = V4Lerp(Bands, C * .5f, C1);
|
}
|
||||||
|
|
||||||
//C = WhiteV4 * GenDotBands(P - Assembly.Center, Time);
|
|
||||||
|
|
||||||
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_VoiceAddIns(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
|
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
||||||
|
phrase_hue Hue = BlumenLumen_GetCurrentHue(BLState, Assembly);
|
||||||
|
v4 C0 = RGBFromPhraseHue(Hue.Hue0);
|
||||||
|
v4 C1 = RGBFromPhraseHue(Hue.Hue1);
|
||||||
|
v4 C2 = RGBFromPhraseHue(Hue.Hue2);
|
||||||
|
|
||||||
|
Time = Time * BLState->PatternSpeed * Hue.Speed;;
|
||||||
|
|
||||||
|
switch (Hue.AddIn)
|
||||||
|
{
|
||||||
|
case AddIn_Rotary:
|
||||||
|
{
|
||||||
|
Pattern_RotaryOptions(Leds, Range, Assembly, Time, Transient, UserData, Hue.Granularity, BlackV4, C2);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case AddIn_Waves:
|
||||||
|
{
|
||||||
|
AddIn_WavesPattern(Leds, Range, Assembly, Time, Transient, UserData, Hue.Granularity, C0, C1, C2);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case AddIn_None:
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
}break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_StemSolid(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_StemSolid(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
DEBUG_TRACK_FUNCTION;
|
||||||
Time = Time * BLState->PatternSpeed;
|
|
||||||
|
|
||||||
phrase_hue Hue = BlumenLumen_GetCurrentHue(BLState, Assembly);
|
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
||||||
v4 C0 = RGBFromPhraseHue(Hue.Hue0);
|
|
||||||
v4 C1 = RGBFromPhraseHue(Hue.Hue1);
|
|
||||||
v4 C2 = RGBFromPhraseHue(Hue.Hue2);
|
|
||||||
|
|
||||||
pixel WhiteMask = V4ToRGBPixel(WhiteV4);
|
pixel WhiteMask = V4ToRGBPixel(WhiteV4);
|
||||||
|
|
||||||
|
@ -662,8 +755,8 @@ Pattern_StemSolid(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r
|
||||||
v2_strip Strip = Assembly.Strips[StripIndex];
|
v2_strip Strip = Assembly.Strips[StripIndex];
|
||||||
for (u32 i = 0; i < Strip.LedCount; i++)
|
for (u32 i = 0; i < Strip.LedCount; i++)
|
||||||
{
|
{
|
||||||
v4 P = Leds->Positions[i];
|
u32 LedIndex = Strip.LedLUT[i];
|
||||||
Leds->Colors[i] = WhiteMask;
|
Leds->Colors[LedIndex] = WhiteMask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -671,6 +764,8 @@ Pattern_StemSolid(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r
|
||||||
internal void
|
internal void
|
||||||
Pattern_PrimaryHue(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_PrimaryHue(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
||||||
Time = Time * BLState->PatternSpeed;
|
Time = Time * BLState->PatternSpeed;
|
||||||
|
|
||||||
|
@ -686,5 +781,89 @@ Pattern_PrimaryHue(led_buffer* Leds, led_buffer_range Range, assembly Assembly,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_GrowFadeMask(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
|
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
||||||
|
Time = Time * BLState->PatternSpeed;
|
||||||
|
|
||||||
|
r32 Period = 10.0f; // seconds
|
||||||
|
r32 ElapsedPct = FractR32(Time / Period);
|
||||||
|
|
||||||
|
r32 ElapsedPctGrow = PowR32(ElapsedPct * 2, 2);
|
||||||
|
r32 ElapsedPctFade = Clamp01((ElapsedPct * 2) - 1);
|
||||||
|
|
||||||
|
r32 Radius = 300 * ElapsedPctGrow;
|
||||||
|
|
||||||
|
v3 Origin = Assembly.Center - v3{0, 150, 0};
|
||||||
|
|
||||||
|
r32 Brightness = Smoothstep(1.0f - ElapsedPctFade);
|
||||||
|
|
||||||
|
pixel COutside = V4ToRGBPixel(BlackV4);
|
||||||
|
pixel CInside = V4ToRGBPixel(WhiteV4 * Brightness);
|
||||||
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
|
{
|
||||||
|
v3 P = Leds->Positions[LedIndex].xyz;
|
||||||
|
r32 Dist = V3Mag(P - Origin);
|
||||||
|
if (Dist < Radius)
|
||||||
|
{
|
||||||
|
Leds->Colors[LedIndex] = CInside;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Leds->Colors[LedIndex] = COutside;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_RainbowLoadingBar(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
|
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
||||||
|
Time = Time * BLState->PatternSpeed;
|
||||||
|
|
||||||
|
// constants
|
||||||
|
r32 Period = 5.0f; // seconds
|
||||||
|
r32 CSpeed = 16.0f;
|
||||||
|
r32 HIncrement = CSpeed * Period;
|
||||||
|
r32 HOffset = CSpeed * Period;
|
||||||
|
r32 MaxSphereRadius = 300;
|
||||||
|
|
||||||
|
// sphere
|
||||||
|
r32 ElapsedPct = FractR32(Time / Period);
|
||||||
|
r32 ElapsedPctGrow = PowR32(ElapsedPct, 2);
|
||||||
|
r32 Radius = MaxSphereRadius * ElapsedPctGrow;
|
||||||
|
v3 Origin = Assembly.Center - v3{0, 150, 0};
|
||||||
|
|
||||||
|
// colors
|
||||||
|
r32 T = Time * CSpeed;
|
||||||
|
r32 TimeStep0 = T;
|
||||||
|
r32 TimeStep1 = T + HOffset;
|
||||||
|
r32 Hue0 = FloorR32(TimeStep0 / HIncrement) * HIncrement;
|
||||||
|
r32 Hue1 = FloorR32(TimeStep1 / HIncrement) * HIncrement;
|
||||||
|
v4 H0 = v4{ModR32(Hue0, 360), 1, 1, 1};
|
||||||
|
v4 H1 = v4{ModR32(Hue1, 360), 1, 1, 1};
|
||||||
|
pixel C0 = V4ToRGBPixel(HSVToRGB(H0));
|
||||||
|
pixel C1 = V4ToRGBPixel(HSVToRGB(H1));
|
||||||
|
|
||||||
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
|
{
|
||||||
|
v3 P = Leds->Positions[LedIndex].xyz;
|
||||||
|
r32 Dist = V3Mag(P - Origin);
|
||||||
|
if (Dist < Radius)
|
||||||
|
{
|
||||||
|
Leds->Colors[LedIndex] = C1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Leds->Colors[LedIndex] = C0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define BLUMEN_PATTERNS_H
|
#define BLUMEN_PATTERNS_H
|
||||||
#endif // BLUMEN_PATTERNS_H
|
#endif // BLUMEN_PATTERNS_H
|
|
@ -201,6 +201,7 @@ BlumenLumen_LoadPatterns(app_state* State)
|
||||||
}
|
}
|
||||||
|
|
||||||
Patterns->Count = 0;
|
Patterns->Count = 0;
|
||||||
|
Patterns_PushPattern(Patterns, Pattern_None, PATTERN_SINGLETHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_HueShift, PATTERN_MULTITHREADED);
|
Patterns_PushPattern(Patterns, Pattern_HueShift, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_Rainbow, PATTERN_MULTITHREADED);
|
Patterns_PushPattern(Patterns, Pattern_Rainbow, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_BasicFlowers, PATTERN_MULTITHREADED);
|
Patterns_PushPattern(Patterns, Pattern_BasicFlowers, PATTERN_MULTITHREADED);
|
||||||
|
@ -214,9 +215,13 @@ BlumenLumen_LoadPatterns(app_state* State)
|
||||||
Patterns_PushPattern(Patterns, Pattern_AllOnMask, PATTERN_MULTITHREADED);
|
Patterns_PushPattern(Patterns, Pattern_AllOnMask, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_BulbMask, PATTERN_MULTITHREADED);
|
Patterns_PushPattern(Patterns, Pattern_BulbMask, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_VoicePattern, PATTERN_MULTITHREADED);
|
Patterns_PushPattern(Patterns, Pattern_VoicePattern, PATTERN_MULTITHREADED);
|
||||||
|
Patterns_PushPattern(Patterns, Pattern_VoiceAddIns, PATTERN_MULTITHREADED);
|
||||||
|
|
||||||
Patterns_PushPattern(Patterns, Pattern_StemSolid, PATTERN_MULTITHREADED);
|
Patterns_PushPattern(Patterns, Pattern_StemSolid, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_PrimaryHue, PATTERN_MULTITHREADED);
|
Patterns_PushPattern(Patterns, Pattern_PrimaryHue, PATTERN_MULTITHREADED);
|
||||||
|
|
||||||
|
Patterns_PushPattern(Patterns, Pattern_GrowFadeMask, PATTERN_MULTITHREADED);
|
||||||
|
Patterns_PushPattern(Patterns, Pattern_RainbowLoadingBar, PATTERN_MULTITHREADED);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
@ -303,6 +308,7 @@ BlumenLumen_UpdateLog(app_state* State, blumen_lumen_state* BLState, context Con
|
||||||
{
|
{
|
||||||
case BlumenPattern_Standard: { PatternMode = "Standard"; } break;
|
case BlumenPattern_Standard: { PatternMode = "Standard"; } break;
|
||||||
case BlumenPattern_VoiceCommand: { PatternMode = "Voice Command"; } break;
|
case BlumenPattern_VoiceCommand: { PatternMode = "Voice Command"; } break;
|
||||||
|
case BlumenPattern_NoControl: { PatternMode = "No Control: Someone's doing the Awaken sequence!"; } break;
|
||||||
}
|
}
|
||||||
AppendPrintF(&FileStr, "Pattern Mode: %s\n", PatternMode);
|
AppendPrintF(&FileStr, "Pattern Mode: %s\n", PatternMode);
|
||||||
|
|
||||||
|
@ -390,12 +396,25 @@ BlumenLumen_CustomInit(app_state* State, context Context)
|
||||||
AnimationSystem_LoadAnimationFromFile(&State->AnimationSystem, State->Patterns, Context, ConstString("data/blumen_animations/anim_demo.foldanim"));
|
AnimationSystem_LoadAnimationFromFile(&State->AnimationSystem, State->Patterns, Context, ConstString("data/blumen_animations/anim_demo.foldanim"));
|
||||||
|
|
||||||
BlumenLumen_SetPatternMode(BlumenPattern_Standard, GlobalAnimTransitionSpeed, &State->AnimationSystem, BLState);
|
BlumenLumen_SetPatternMode(BlumenPattern_Standard, GlobalAnimTransitionSpeed, &State->AnimationSystem, BLState);
|
||||||
|
|
||||||
|
BLState->AwakenHandle = AnimationSystem_LoadAnimationFromFile(&State->AnimationSystem,
|
||||||
|
State->Patterns,
|
||||||
|
Context,
|
||||||
|
ConstString("data/blumen_animations/awaken.foldanim"));
|
||||||
|
BLState->OffAnimHandle = AnimationSystem_LoadAnimationFromFile(&State->AnimationSystem,
|
||||||
|
State->Patterns,
|
||||||
|
Context,
|
||||||
|
ConstString("data/blumen_animations/off_anim.foldanim"));
|
||||||
#endif
|
#endif
|
||||||
State->AnimationSystem.TimelineShouldAdvance = true;
|
State->AnimationSystem.TimelineShouldAdvance = true;
|
||||||
|
|
||||||
BLState->StandardPatternHues.Hue0.Flags = Hue_Value;
|
BLState->StandardPatternHues.Hue0.Flags = Hue_Value;
|
||||||
BLState->StandardPatternHues.Hue1.Flags = Hue_Value;
|
BLState->StandardPatternHues.Hue1.Flags = Hue_Value;
|
||||||
BLState->StandardPatternHues.Hue2.Flags = Hue_Value;
|
BLState->StandardPatternHues.Hue2.Flags = Hue_Value;
|
||||||
|
BLState->StandardPatternHues.Granularity = 1;
|
||||||
|
BLState->StandardPatternHues.Speed = 1;
|
||||||
|
BLState->StandardPatternHues.AddIn = AddIn_Rotary;
|
||||||
|
BLState->StandardPatternHues.Pattern = HuePattern_Wavy;
|
||||||
|
|
||||||
BlumenLumen_AppendBootupLog(State, BLState, Context);
|
BlumenLumen_AppendBootupLog(State, BLState, Context);
|
||||||
return Result;
|
return Result;
|
||||||
|
@ -420,6 +439,38 @@ BlumenLumen_UpdateMotorState(blumen_lumen_state* BLState, motor_status_packet Mo
|
||||||
BLState->ShouldUpdateLog = true;
|
BLState->ShouldUpdateLog = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
BlumenLumen_ApplyNextHotHue(blumen_lumen_state* BLState, context Context, gs_string* DebugStr, app_state* State)
|
||||||
|
{
|
||||||
|
// if we are in standard color mode, shift all flowers to the new color
|
||||||
|
// otherwise, only shift the next flower in the sequence to the new color
|
||||||
|
phrase_hue NewHue = BLState->NextHotHue;
|
||||||
|
|
||||||
|
PrintF(DebugStr, "Switching To: %S\n", NewHue.Phrase);
|
||||||
|
NullTerminate(DebugStr);
|
||||||
|
OutputDebugString(DebugStr->Str);
|
||||||
|
|
||||||
|
|
||||||
|
if (BLState->PatternMode == BlumenPattern_Standard)
|
||||||
|
{
|
||||||
|
BlumenLumen_SetNextHue(BLState, 0, NewHue);
|
||||||
|
BlumenLumen_SetNextHue(BLState, 1, NewHue);
|
||||||
|
BlumenLumen_SetNextHue(BLState, 2, NewHue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u32 AssemblyIdx = BLState->LastAssemblyColorSet;
|
||||||
|
BlumenLumen_SetNextHue(BLState, AssemblyIdx, NewHue);
|
||||||
|
BLState->LastAssemblyColorSet = (BLState->LastAssemblyColorSet + 1) % 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlumenLumen_SetPatternMode(BlumenPattern_VoiceCommand, GlobalAnimTransitionSpeed, &State->AnimationSystem, BLState);
|
||||||
|
BLState->TimeLastSetToVoiceMode = Context.SystemTime_Current;
|
||||||
|
BLState->LastHuePhrase = NewHue;
|
||||||
|
BLState->ShouldUpdateLog = true;
|
||||||
|
BLState->InPhraseReceptionMode = false;
|
||||||
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
||||||
{
|
{
|
||||||
|
@ -444,7 +495,7 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
||||||
u64 NameHash = HashDJB2ToU32(Mic.AnimationFileName);
|
u64 NameHash = HashDJB2ToU32(Mic.AnimationFileName);
|
||||||
u32 NameLen = CStringLength(Mic.AnimationFileName);
|
u32 NameLen = CStringLength(Mic.AnimationFileName);
|
||||||
|
|
||||||
phrase_hue NewHue = PhraseHueMap_Get(BLState->PhraseHueMap, NameHash);
|
phrase_hue NewHue = PhraseHueMap_Find(BLState->PhraseHueMap, NameHash);
|
||||||
if (NewHue.Phrase.Length > 0)
|
if (NewHue.Phrase.Length > 0)
|
||||||
{
|
{
|
||||||
bool IsLonger = (BLState->NextHotHue.Phrase.Length < NewHue.Phrase.Length);
|
bool IsLonger = (BLState->NextHotHue.Phrase.Length < NewHue.Phrase.Length);
|
||||||
|
@ -507,36 +558,12 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
||||||
r32 SecondsSincePhraseBegan = SecondsElapsed(BLState->TimePhraseReceptionBegan, Context->SystemTime_Current);
|
r32 SecondsSincePhraseBegan = SecondsElapsed(BLState->TimePhraseReceptionBegan, Context->SystemTime_Current);
|
||||||
if (SecondsSincePhraseBegan > PhrasePriorityMessageGroupingTime)
|
if (SecondsSincePhraseBegan > PhrasePriorityMessageGroupingTime)
|
||||||
{
|
{
|
||||||
// if we are in standard color mode, shift all flowers to the new color
|
BlumenLumen_ApplyNextHotHue(BLState, *Context, &DebugStr, State);
|
||||||
// otherwise, only shift the next flower in the sequence to the new color
|
|
||||||
phrase_hue NewHue = BLState->NextHotHue;
|
|
||||||
|
|
||||||
PrintF(&DebugStr, "Switching To: %S\n", NewHue.Phrase);
|
|
||||||
NullTerminate(&DebugStr);
|
|
||||||
OutputDebugString(DebugStr.Str);
|
|
||||||
|
|
||||||
|
|
||||||
if (BLState->PatternMode == BlumenPattern_Standard)
|
|
||||||
{
|
|
||||||
BLState->AssemblyColors[0] = NewHue;
|
|
||||||
BLState->AssemblyColors[1] = NewHue;
|
|
||||||
BLState->AssemblyColors[2] = NewHue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
u32 AssemblyIdx = BLState->LastAssemblyColorSet;
|
|
||||||
BLState->AssemblyColors[AssemblyIdx] = NewHue;
|
|
||||||
BLState->LastAssemblyColorSet = (BLState->LastAssemblyColorSet + 1) % 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
BlumenLumen_SetPatternMode(BlumenPattern_VoiceCommand, GlobalAnimTransitionSpeed, &State->AnimationSystem, BLState);
|
|
||||||
BLState->TimeLastSetToVoiceMode = Context->SystemTime_Current;
|
|
||||||
BLState->LastHuePhrase = NewHue;
|
|
||||||
BLState->ShouldUpdateLog = true;
|
|
||||||
BLState->InPhraseReceptionMode = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BlumenLumen_AdvanceHueFade(BLState, *Context);
|
||||||
|
|
||||||
// Update next frames Hues
|
// Update next frames Hues
|
||||||
r32 AnimTime = AnimationSystem_GetCurrentTime(State->AnimationSystem);
|
r32 AnimTime = AnimationSystem_GetCurrentTime(State->AnimationSystem);
|
||||||
AnimTime = (r32)Context->TotalTime;
|
AnimTime = (r32)Context->TotalTime;
|
||||||
|
@ -571,7 +598,8 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open / Close the Motor
|
// Open / Close the Motor
|
||||||
if (MessageQueue_CanWrite(BLState->OutgoingMsgQueue))
|
if (MessageQueue_CanWrite(BLState->OutgoingMsgQueue) &&
|
||||||
|
!BLState->IgnoreTimeOfDay_MotorState)
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < MotorOpenTimesCount; i++)
|
for (u32 i = 0; i < MotorOpenTimesCount; i++)
|
||||||
{
|
{
|
||||||
|
@ -677,6 +705,27 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!BLState->IgnoreTimeOfDay_LedDimming)
|
||||||
|
{
|
||||||
|
bool TimelineShouldAdvance = false;
|
||||||
|
r32 OverrideBrightness = 0.0f;
|
||||||
|
for (u32 i = 0; i < LedOnTimesCount; i++)
|
||||||
|
{
|
||||||
|
time_range Range = LedOnTimes[i];
|
||||||
|
bool CurrTimeInRange = SystemTimeIsInTimeRange(Context->SystemTime_Current, Range);
|
||||||
|
if (CurrTimeInRange)
|
||||||
|
{
|
||||||
|
// If we're in one of the specified time ranges,
|
||||||
|
// play animations and set brightness
|
||||||
|
OverrideBrightness = BLState->BrightnessPercent;
|
||||||
|
TimelineShouldAdvance = State->AnimationSystem.TimelineShouldAdvance;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
State->AnimationSystem.TimelineShouldAdvance = TimelineShouldAdvance;
|
||||||
|
BLState->BrightnessPercent = OverrideBrightness;
|
||||||
|
}
|
||||||
|
|
||||||
// Dim the leds based on temp data
|
// Dim the leds based on temp data
|
||||||
if (!BLState->DEBUG_IgnoreWeatherDimmingLeds)
|
if (!BLState->DEBUG_IgnoreWeatherDimmingLeds)
|
||||||
{
|
{
|
||||||
|
@ -734,109 +783,213 @@ US_CUSTOM_DEBUG_UI(BlumenLumen_DebugUI)
|
||||||
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData.Memory;
|
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData.Memory;
|
||||||
ui_interface* I = &State->Interface;
|
ui_interface* I = &State->Interface;
|
||||||
|
|
||||||
// NOTE(PS): Motors
|
ui_BeginRow(I, BlumenDebug_Count);
|
||||||
|
for (u32 i = 0; i < BlumenDebug_Count; i++)
|
||||||
{
|
{
|
||||||
motor_packet PendingPacket = BLState->DEBUG_PendingMotorPacket;
|
if (ui_Button(I, MakeString(BlDebugUiModeStrings[i])))
|
||||||
|
|
||||||
for (u32 MotorIndex = 0; MotorIndex < BL_FLOWER_COUNT; MotorIndex++)
|
|
||||||
{
|
{
|
||||||
gs_string Label = PushStringF(State->Transient, 32, "Motor %d", MotorIndex);
|
BLState->DebugMode = (bl_debug_ui_mode)i;
|
||||||
ui_BeginRow(I, 5);
|
|
||||||
{
|
|
||||||
ui_Label(I, Label);
|
|
||||||
|
|
||||||
bool IsClosed = PendingPacket.FlowerPositions[MotorIndex] == MotorState_Closed;
|
|
||||||
if (ui_ToggleText(I, MakeString("Closed (1)"), IsClosed))
|
|
||||||
{
|
|
||||||
PendingPacket.FlowerPositions[MotorIndex] = MotorState_Closed;
|
|
||||||
}
|
|
||||||
bool IsHOpen = PendingPacket.FlowerPositions[MotorIndex] == MotorState_HalfOpen;
|
|
||||||
if (ui_ToggleText(I, MakeString("Half Open (3)"), IsHOpen))
|
|
||||||
{
|
|
||||||
PendingPacket.FlowerPositions[MotorIndex] = MotorState_HalfOpen;
|
|
||||||
}
|
|
||||||
bool IsMOpen = PendingPacket.FlowerPositions[MotorIndex] == MotorState_MostlyOpen;
|
|
||||||
if (ui_ToggleText(I, MakeString("Mostly Open (4)"), IsMOpen))
|
|
||||||
{
|
|
||||||
PendingPacket.FlowerPositions[MotorIndex] = MotorState_MostlyOpen;
|
|
||||||
}
|
|
||||||
bool IsOpen = PendingPacket.FlowerPositions[MotorIndex] == MotorState_Open;
|
|
||||||
if (ui_ToggleText(I, MakeString("Open (2)"), IsOpen))
|
|
||||||
{
|
|
||||||
PendingPacket.FlowerPositions[MotorIndex] = MotorState_Open;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ui_EndRow(I);
|
|
||||||
}
|
}
|
||||||
BLState->DEBUG_PendingMotorPacket = PendingPacket;
|
}
|
||||||
|
ui_EndRow(I);
|
||||||
|
|
||||||
if (ui_Button(I, MakeString("Send Motor Packet")))
|
switch (BLState->DebugMode)
|
||||||
|
{
|
||||||
|
case BlumenDebug_Motors:
|
||||||
{
|
{
|
||||||
blumen_packet Packet = {};
|
motor_packet PendingPacket = BLState->DEBUG_PendingMotorPacket;
|
||||||
Packet.Type = PacketType_MotorState;
|
|
||||||
Packet.MotorPacket = BLState->DEBUG_PendingMotorPacket;
|
|
||||||
gs_data Msg = StructToData(&Packet, blumen_packet);
|
|
||||||
MessageQueue_Write(&BLState->OutgoingMsgQueue, Msg);
|
|
||||||
|
|
||||||
DEBUG_SentMotorCommand(Packet.MotorPacket, Context.ThreadContext);
|
BLState->IgnoreTimeOfDay_MotorState = ui_ToggleText(I, MakeString("Motors Ignore Time Limit"), BLState->IgnoreTimeOfDay_MotorState);
|
||||||
}
|
|
||||||
|
|
||||||
motor_packet MotorPos = BLState->LastKnownMotorState;
|
for (u32 MotorIndex = 0; MotorIndex < BL_FLOWER_COUNT; MotorIndex++)
|
||||||
ui_Label(I, MakeString("Current Motor Positions"));
|
|
||||||
{
|
|
||||||
for (u32 i = 0; i < BL_FLOWER_COUNT; i++)
|
|
||||||
{
|
{
|
||||||
ui_BeginRow(I, 2);
|
gs_string Label = PushStringF(State->Transient, 32, "Motor %d", MotorIndex);
|
||||||
gs_string MotorStr = PushStringF(State->Transient, 32,
|
ui_BeginRow(I, 5);
|
||||||
"Motor %d",
|
|
||||||
i);
|
|
||||||
ui_Label(I, MotorStr);
|
|
||||||
|
|
||||||
gs_string StateStr = {};
|
|
||||||
switch (MotorPos.FlowerPositions[i])
|
|
||||||
{
|
{
|
||||||
case MotorState_Closed: {
|
ui_Label(I, Label);
|
||||||
StateStr = MakeString("Closed");
|
|
||||||
} break;
|
|
||||||
case MotorState_HalfOpen: {
|
|
||||||
StateStr = MakeString("Half Open");
|
|
||||||
} break;
|
|
||||||
case MotorState_MostlyOpen: {
|
|
||||||
StateStr = MakeString("Mostly Open");
|
|
||||||
} break;
|
|
||||||
case MotorState_Open: {
|
|
||||||
StateStr = MakeString("Open");
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ui_Label(I, StateStr);
|
bool IsClosed = PendingPacket.FlowerPositions[MotorIndex] == MotorState_Closed;
|
||||||
|
if (ui_ToggleText(I, MakeString("Closed (1)"), IsClosed))
|
||||||
|
{
|
||||||
|
PendingPacket.FlowerPositions[MotorIndex] = MotorState_Closed;
|
||||||
|
}
|
||||||
|
bool IsHOpen = PendingPacket.FlowerPositions[MotorIndex] == MotorState_HalfOpen;
|
||||||
|
if (ui_ToggleText(I, MakeString("Half Open (3)"), IsHOpen))
|
||||||
|
{
|
||||||
|
PendingPacket.FlowerPositions[MotorIndex] = MotorState_HalfOpen;
|
||||||
|
}
|
||||||
|
bool IsMOpen = PendingPacket.FlowerPositions[MotorIndex] == MotorState_MostlyOpen;
|
||||||
|
if (ui_ToggleText(I, MakeString("Mostly Open (4)"), IsMOpen))
|
||||||
|
{
|
||||||
|
PendingPacket.FlowerPositions[MotorIndex] = MotorState_MostlyOpen;
|
||||||
|
}
|
||||||
|
bool IsOpen = PendingPacket.FlowerPositions[MotorIndex] == MotorState_Open;
|
||||||
|
if (ui_ToggleText(I, MakeString("Open (2)"), IsOpen))
|
||||||
|
{
|
||||||
|
PendingPacket.FlowerPositions[MotorIndex] = MotorState_Open;
|
||||||
|
}
|
||||||
|
}
|
||||||
ui_EndRow(I);
|
ui_EndRow(I);
|
||||||
}
|
}
|
||||||
}
|
BLState->DEBUG_PendingMotorPacket = PendingPacket;
|
||||||
|
|
||||||
BLState->DEBUG_IgnoreWeatherDimmingLeds = ui_LabeledToggle(I, MakeString("Ignore Weather Dimming Leds"), BLState->DEBUG_IgnoreWeatherDimmingLeds);
|
if (ui_Button(I, MakeString("Send Motor Packet")))
|
||||||
|
{
|
||||||
|
blumen_packet Packet = {};
|
||||||
|
Packet.Type = PacketType_MotorState;
|
||||||
|
Packet.MotorPacket = BLState->DEBUG_PendingMotorPacket;
|
||||||
|
gs_data Msg = StructToData(&Packet, blumen_packet);
|
||||||
|
MessageQueue_Write(&BLState->OutgoingMsgQueue, Msg);
|
||||||
|
DEBUG_SentMotorCommand(Packet.MotorPacket, Context.ThreadContext);
|
||||||
|
|
||||||
ui_Label(I, MakeString("Set Internal Motor State:"));
|
}
|
||||||
if (ui_Button(I, MakeString("Closed")))
|
|
||||||
|
motor_packet MotorPos = BLState->LastKnownMotorState;
|
||||||
|
ui_Label(I, MakeString("Current Motor Positions"));
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < BL_FLOWER_COUNT; i++)
|
||||||
|
{
|
||||||
|
ui_BeginRow(I, 2);
|
||||||
|
gs_string MotorStr = PushStringF(State->Transient, 32,
|
||||||
|
"Motor %d",
|
||||||
|
i);
|
||||||
|
ui_Label(I, MotorStr);
|
||||||
|
|
||||||
|
gs_string StateStr = {};
|
||||||
|
switch (MotorPos.FlowerPositions[i])
|
||||||
|
{
|
||||||
|
case MotorState_Closed: {
|
||||||
|
StateStr = MakeString("Closed");
|
||||||
|
} break;
|
||||||
|
case MotorState_HalfOpen: {
|
||||||
|
StateStr = MakeString("Half Open");
|
||||||
|
} break;
|
||||||
|
case MotorState_MostlyOpen: {
|
||||||
|
StateStr = MakeString("Mostly Open");
|
||||||
|
} break;
|
||||||
|
case MotorState_Open: {
|
||||||
|
StateStr = MakeString("Open");
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_Label(I, StateStr);
|
||||||
|
ui_EndRow(I);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_Label(I, MakeString("Set Internal Motor State:"));
|
||||||
|
if (ui_Button(I, MakeString("Closed")))
|
||||||
|
{
|
||||||
|
motor_status_packet Motor = {};
|
||||||
|
Motor.Pos.FlowerPositions[0] = MotorState_Closed;
|
||||||
|
Motor.Pos.FlowerPositions[1] = MotorState_Closed;
|
||||||
|
Motor.Pos.FlowerPositions[2] = MotorState_Closed;
|
||||||
|
Motor.Temperature = 16;
|
||||||
|
|
||||||
|
BlumenLumen_UpdateMotorState(BLState, Motor, Context);
|
||||||
|
}
|
||||||
|
if (ui_Button(I, MakeString("Open")))
|
||||||
|
{
|
||||||
|
motor_status_packet Motor = {};
|
||||||
|
Motor.Pos.FlowerPositions[0] = MotorState_Open;
|
||||||
|
Motor.Pos.FlowerPositions[1] = MotorState_Open;
|
||||||
|
Motor.Pos.FlowerPositions[2] = MotorState_Open;
|
||||||
|
Motor.Temperature = 16;
|
||||||
|
|
||||||
|
BlumenLumen_UpdateMotorState(BLState, Motor, Context);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case BlumenDebug_Leds:
|
||||||
{
|
{
|
||||||
motor_status_packet Motor = {};
|
BLState->DEBUG_IgnoreWeatherDimmingLeds = ui_LabeledToggle(I, MakeString("Ignore Weather Dimming Leds"), BLState->DEBUG_IgnoreWeatherDimmingLeds);
|
||||||
Motor.Pos.FlowerPositions[0] = MotorState_Closed;
|
|
||||||
Motor.Pos.FlowerPositions[1] = MotorState_Closed;
|
|
||||||
Motor.Pos.FlowerPositions[2] = MotorState_Closed;
|
|
||||||
Motor.Temperature = 16;
|
|
||||||
|
|
||||||
BlumenLumen_UpdateMotorState(BLState, Motor, Context);
|
BLState->IgnoreTimeOfDay_LedDimming = ui_ToggleText(I, MakeString("Leds Ignore Time Limit"), BLState->IgnoreTimeOfDay_LedDimming);
|
||||||
}
|
|
||||||
if (ui_Button(I, MakeString("Open")))
|
if (ui_BeginLabeledDropdown(I, MakeString("Phrase"), MakeString(BLState->PendingPhrase.Phrase)))
|
||||||
|
{
|
||||||
|
u32 ListCount = BLState->PhraseHueMap.Count;
|
||||||
|
ui_BeginList(I, MakeString("Phrase List"), 5, ListCount);
|
||||||
|
for (u32 i = 0; i < ListCount; i++)
|
||||||
|
{
|
||||||
|
gs_string Str = MakeString(BLState->PhraseHueMap.Phrases[i]);
|
||||||
|
if (ui_Button(I, Str))
|
||||||
|
{
|
||||||
|
BLState->PendingPhrase = PhraseHueMap_Get(BLState->PhraseHueMap, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ui_EndList(I);
|
||||||
|
}
|
||||||
|
ui_EndLabeledDropdown(I);
|
||||||
|
if (ui_Button(I, MakeString("Say Phrase")))
|
||||||
|
{
|
||||||
|
gs_string DebugStr = PushString(State->Transient, 256);
|
||||||
|
BLState->NextHotHue = BLState->PendingPhrase;
|
||||||
|
BlumenLumen_ApplyNextHotHue(BLState, Context, &DebugStr, State);
|
||||||
|
}
|
||||||
|
|
||||||
|
InterfaceAssert(I->PerFrameMemory);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case BlumenDebug_Awaken:
|
||||||
{
|
{
|
||||||
motor_status_packet Motor = {};
|
ui_Label(I, MakeString("Step 1:"));
|
||||||
Motor.Pos.FlowerPositions[0] = MotorState_Open;
|
ui_Label(I, MakeString("Leds off, flowers closed"));
|
||||||
Motor.Pos.FlowerPositions[1] = MotorState_Open;
|
if (ui_Button(I, MakeString("Prepare")))
|
||||||
Motor.Pos.FlowerPositions[2] = MotorState_Open;
|
{
|
||||||
Motor.Temperature = 16;
|
// motors closed
|
||||||
|
blumen_packet M = {};
|
||||||
|
M.Type = PacketType_MotorState;
|
||||||
|
M.MotorPacket.FlowerPositions[0] = MotorState_Closed;
|
||||||
|
M.MotorPacket.FlowerPositions[1] = MotorState_Closed;
|
||||||
|
M.MotorPacket.FlowerPositions[2] = MotorState_Closed;
|
||||||
|
gs_data D = StructToData(&M, blumen_packet);
|
||||||
|
MessageQueue_Write(&BLState->OutgoingMsgQueue, D);
|
||||||
|
|
||||||
BlumenLumen_UpdateMotorState(BLState, Motor, Context);
|
// animation
|
||||||
}
|
State->AnimationSystem.RepeatMode = AnimationRepeat_Single;
|
||||||
|
AnimationFadeGroup_FadeTo(&State->AnimationSystem.ActiveFadeGroup,
|
||||||
|
BLState->OffAnimHandle,
|
||||||
|
VoiceCommandFadeDuration);
|
||||||
|
|
||||||
|
BLState->PatternMode = BlumenPattern_NoControl;
|
||||||
|
BLState->IgnoreTimeOfDay_LedDimming = true;
|
||||||
|
BLState->IgnoreTimeOfDay_MotorState = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_Label(I, MakeString("Step 2:"));
|
||||||
|
if (ui_Button(I, MakeString("Begin Light Show")))
|
||||||
|
{
|
||||||
|
AnimationFadeGroup_FadeTo(&State->AnimationSystem.ActiveFadeGroup,
|
||||||
|
BLState->AwakenHandle,
|
||||||
|
VoiceCommandFadeDuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_Label(I, MakeString("Step 3:"));
|
||||||
|
if (ui_Button(I, MakeString("Open Flowers")))
|
||||||
|
{
|
||||||
|
// motors closed
|
||||||
|
blumen_packet M = {};
|
||||||
|
M.Type = PacketType_MotorState;
|
||||||
|
M.MotorPacket.FlowerPositions[0] = MotorState_Open;
|
||||||
|
M.MotorPacket.FlowerPositions[1] = MotorState_Open;
|
||||||
|
M.MotorPacket.FlowerPositions[2] = MotorState_Open;
|
||||||
|
gs_data D = StructToData(&M, blumen_packet);
|
||||||
|
MessageQueue_Write(&BLState->OutgoingMsgQueue, D);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_Label(I, MakeString("Step 4:"));
|
||||||
|
ui_Label(I, MakeString("Resets Lumenarium"));
|
||||||
|
if (ui_Button(I, MakeString("Complete")))
|
||||||
|
{
|
||||||
|
BLState->IgnoreTimeOfDay_LedDimming = false;
|
||||||
|
BLState->IgnoreTimeOfDay_MotorState = false;
|
||||||
|
BlumenLumen_SetPatternMode(BlumenPattern_Standard, GlobalAnimTransitionSpeed, &State->AnimationSystem,
|
||||||
|
BLState);
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
InvalidDefaultCase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,10 +7,26 @@
|
||||||
|
|
||||||
#include "message_queue.h"
|
#include "message_queue.h"
|
||||||
|
|
||||||
|
enum bl_debug_ui_mode
|
||||||
|
{
|
||||||
|
BlumenDebug_Motors,
|
||||||
|
BlumenDebug_Leds,
|
||||||
|
BlumenDebug_Awaken,
|
||||||
|
|
||||||
|
BlumenDebug_Count,
|
||||||
|
};
|
||||||
|
|
||||||
|
char* BlDebugUiModeStrings[] = {
|
||||||
|
"Motors",
|
||||||
|
"Leds",
|
||||||
|
"Awaken",
|
||||||
|
};
|
||||||
|
|
||||||
enum bl_pattern_mode
|
enum bl_pattern_mode
|
||||||
{
|
{
|
||||||
BlumenPattern_Standard,
|
BlumenPattern_Standard,
|
||||||
BlumenPattern_VoiceCommand,
|
BlumenPattern_VoiceCommand,
|
||||||
|
BlumenPattern_NoControl,
|
||||||
|
|
||||||
BlumenPattern_Count,
|
BlumenPattern_Count,
|
||||||
};
|
};
|
||||||
|
@ -157,6 +173,8 @@ struct blumen_lumen_state
|
||||||
system_time LastSendTime;
|
system_time LastSendTime;
|
||||||
|
|
||||||
phrase_hue StandardPatternHues;
|
phrase_hue StandardPatternHues;
|
||||||
|
r32 AssemblyColorsTransitionTimeLeft[BL_FLOWER_COUNT];
|
||||||
|
phrase_hue NextAssemblyColors[BL_FLOWER_COUNT];
|
||||||
phrase_hue AssemblyColors[BL_FLOWER_COUNT];
|
phrase_hue AssemblyColors[BL_FLOWER_COUNT];
|
||||||
u32 LastAssemblyColorSet;
|
u32 LastAssemblyColorSet;
|
||||||
|
|
||||||
|
@ -170,6 +188,8 @@ struct blumen_lumen_state
|
||||||
|
|
||||||
bl_pattern_mode PatternMode;
|
bl_pattern_mode PatternMode;
|
||||||
animation_handle_array ModeAnimations[BlumenPattern_Count];
|
animation_handle_array ModeAnimations[BlumenPattern_Count];
|
||||||
|
animation_handle OffAnimHandle;
|
||||||
|
animation_handle AwakenHandle;
|
||||||
|
|
||||||
phrase_hue_map PhraseHueMap;
|
phrase_hue_map PhraseHueMap;
|
||||||
|
|
||||||
|
@ -184,14 +204,49 @@ struct blumen_lumen_state
|
||||||
r32 PatternSpeed;
|
r32 PatternSpeed;
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
|
bl_debug_ui_mode DebugMode;
|
||||||
|
|
||||||
motor_packet DEBUG_PendingMotorPacket;
|
motor_packet DEBUG_PendingMotorPacket;
|
||||||
bool DEBUG_IgnoreWeatherDimmingLeds;
|
bool DEBUG_IgnoreWeatherDimmingLeds;
|
||||||
|
|
||||||
bool ShouldUpdateLog;
|
bool ShouldUpdateLog;
|
||||||
|
bool IgnoreTimeOfDay_LedDimming;
|
||||||
|
bool IgnoreTimeOfDay_MotorState;
|
||||||
|
|
||||||
|
phrase_hue PendingPhrase;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "message_queue.cpp"
|
#include "message_queue.cpp"
|
||||||
|
|
||||||
|
internal void
|
||||||
|
BlumenLumen_SetNextHue(blumen_lumen_state* BLState, u32 AssemblyIndex, phrase_hue Hue)
|
||||||
|
{
|
||||||
|
#if 1
|
||||||
|
BLState->NextAssemblyColors[AssemblyIndex] = Hue;
|
||||||
|
BLState->AssemblyColorsTransitionTimeLeft[AssemblyIndex] = PhraseHueFadeInDuration;
|
||||||
|
#else
|
||||||
|
BLState->AssemblyColors[AssemblyIndex] = Hue;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
BlumenLumen_AdvanceHueFade(blumen_lumen_state* BLState, context Context)
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < BL_FLOWER_COUNT; i++)
|
||||||
|
{
|
||||||
|
r32 T = BLState->AssemblyColorsTransitionTimeLeft[i];
|
||||||
|
if (T > 0)
|
||||||
|
{
|
||||||
|
T -= Context.DeltaTime;
|
||||||
|
if (T <= 0)
|
||||||
|
{
|
||||||
|
BLState->AssemblyColors[i] = BLState->NextAssemblyColors[i];
|
||||||
|
}
|
||||||
|
BLState->AssemblyColorsTransitionTimeLeft[i] = T;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal phrase_hue
|
internal phrase_hue
|
||||||
BlumenLumen_GetCurrentHue(blumen_lumen_state* BLState, assembly Assembly)
|
BlumenLumen_GetCurrentHue(blumen_lumen_state* BLState, assembly Assembly)
|
||||||
{
|
{
|
||||||
|
@ -206,7 +261,15 @@ BlumenLumen_GetCurrentHue(blumen_lumen_state* BLState, assembly Assembly)
|
||||||
|
|
||||||
case BlumenPattern_VoiceCommand:
|
case BlumenPattern_VoiceCommand:
|
||||||
{
|
{
|
||||||
Result = BLState->AssemblyColors[Assembly.AssemblyIndex % 3];
|
u32 i = Assembly.AssemblyIndex % 3;
|
||||||
|
r32 T = BLState->AssemblyColorsTransitionTimeLeft[i];
|
||||||
|
if (T > 0)
|
||||||
|
{
|
||||||
|
T = Clamp(T / PhraseHueFadeInDuration, 0, 1);
|
||||||
|
Result = LerpPhraseHue(T, BLState->NextAssemblyColors[i], BLState->AssemblyColors[i]);
|
||||||
|
} else {
|
||||||
|
Result = BLState->AssemblyColors[i];
|
||||||
|
}
|
||||||
}break;
|
}break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,17 +27,27 @@ gs_const_string AmbientPatternFolder = ConstString("data/blumen_animations/ambie
|
||||||
gs_const_string VoicePatternFolder = ConstString("data/blumen_animations/audio_responses/*.foldanim");
|
gs_const_string VoicePatternFolder = ConstString("data/blumen_animations/audio_responses/*.foldanim");
|
||||||
|
|
||||||
// The times of day when the motors should be open.
|
// The times of day when the motors should be open.
|
||||||
|
//
|
||||||
|
// @TimeFormat: documentation follows
|
||||||
// these are in the format { Start_Hour, Start_Minute, End_Hour, End_Minute }
|
// these are in the format { Start_Hour, Start_Minute, End_Hour, End_Minute }
|
||||||
// Hours are in the range 0-23 inclusive
|
// Hours are in the range 0-23 inclusive
|
||||||
// Minutes are in the range 0-59 inclusive
|
// Minutes are in the range 0-59 inclusive
|
||||||
|
//
|
||||||
// NOTE: There is no need to modify the MotorOpenTimesCount variable -
|
// NOTE: There is no need to modify the MotorOpenTimesCount variable -
|
||||||
// it is a compile time constant that gets calculated automatically
|
// it is a compile time constant that gets calculated automatically
|
||||||
global time_range MotorOpenTimes[] = {
|
global time_range MotorOpenTimes[] = {
|
||||||
{ 12, 45, 17, 45 },
|
{ 12, 45, 17, 45 }, // 12:45pm to 5:45pm
|
||||||
{ 19, 00, 23, 00 },
|
{ 19, 00, 23, 00 }, // 7:00pm to 11:00pm
|
||||||
};
|
};
|
||||||
global u32 MotorOpenTimesCount = CArrayLength(MotorOpenTimes); // do not edit
|
global u32 MotorOpenTimesCount = CArrayLength(MotorOpenTimes); // do not edit
|
||||||
|
|
||||||
|
// The times of day when the leds should be on
|
||||||
|
// Search for @TimeFormat to find documentation
|
||||||
|
global time_range LedOnTimes[] = {
|
||||||
|
{ 00, 00, 23, 59 }, // literally always
|
||||||
|
};
|
||||||
|
global u32 LedOnTimesCount = CArrayLength(LedOnTimes); // do not edit
|
||||||
|
|
||||||
// How long it takes to fade from the default pattern to the
|
// How long it takes to fade from the default pattern to the
|
||||||
// voice activated pattern
|
// voice activated pattern
|
||||||
r32 VoiceCommandFadeDuration = 1.0f; // in seconds
|
r32 VoiceCommandFadeDuration = 1.0f; // in seconds
|
||||||
|
@ -105,6 +115,9 @@ r32 GlobalAnimSpeed = 1.0f;
|
||||||
// activated mode
|
// activated mode
|
||||||
r32 GlobalAnimTransitionSpeed = 0.1f;
|
r32 GlobalAnimTransitionSpeed = 0.1f;
|
||||||
|
|
||||||
|
// how long it takes to fade from the old voice hue to the new one
|
||||||
|
r32 PhraseHueFadeInDuration = 2.0f; // seconds
|
||||||
|
|
||||||
r64 PhrasePriorityMessageGroupingTime = 1.0f;
|
r64 PhrasePriorityMessageGroupingTime = 1.0f;
|
||||||
|
|
||||||
// How often should Lumenarium send its status to the python server?
|
// How often should Lumenarium send its status to the python server?
|
||||||
|
|
|
@ -281,13 +281,14 @@ Fbm3D(v3 P, r32 T)
|
||||||
r32 F = 0.0;
|
r32 F = 0.0;
|
||||||
|
|
||||||
F += 0.500000f * Noise3D(Pp + Tt); Pp = Pp * 2.02;
|
F += 0.500000f * Noise3D(Pp + Tt); Pp = Pp * 2.02;
|
||||||
F += 0.031250f * Noise3D(Pp); Pp = Pp * 2.01;
|
//F += 0.031250f * Noise3D(Pp); Pp = Pp * 2.01;
|
||||||
F += 0.250000f * Noise3D(Pp - Tt); Pp = Pp * 2.03;
|
F += 0.300000f * Noise3D(Pp - Tt); Pp = Pp * 2.03;
|
||||||
F += 0.125000f * Noise3D(Pp); Pp = Pp * 2.01;
|
F += 0.125000f * Noise3D(Pp); Pp = Pp * 2.01;
|
||||||
F += 0.062500f * Noise3D(Pp + Tt); Pp = Pp * 2.04;
|
F += 0.062500f * Noise3D(Pp + Tt); Pp = Pp * 2.04;
|
||||||
F += 0.015625f * Noise3D(Pp + Tv);
|
//F += 0.015625f * Noise3D(Pp + Tv);
|
||||||
|
r32 D = 0.9875f;
|
||||||
|
|
||||||
F = F / 0.984375f;
|
F = F / D;
|
||||||
return F;
|
return F;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,19 @@ enum p_hue_flag
|
||||||
Hue_Black = 2,
|
Hue_Black = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum p_hue_pattern
|
||||||
|
{
|
||||||
|
HuePattern_Patchy,
|
||||||
|
HuePattern_Wavy,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum p_hue_add_in
|
||||||
|
{
|
||||||
|
AddIn_None,
|
||||||
|
AddIn_Waves,
|
||||||
|
AddIn_Rotary,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct p_hue
|
typedef struct p_hue
|
||||||
{
|
{
|
||||||
r64 Hue;
|
r64 Hue;
|
||||||
|
@ -25,6 +38,10 @@ typedef struct phrase_hue_map
|
||||||
p_hue* Hue0;
|
p_hue* Hue0;
|
||||||
p_hue* Hue1;
|
p_hue* Hue1;
|
||||||
p_hue* Hue2;
|
p_hue* Hue2;
|
||||||
|
u32* Gran; // granularity
|
||||||
|
r32* Speed;
|
||||||
|
u8* Pattern;
|
||||||
|
u8* AddIn;
|
||||||
} phrase_hue_map;
|
} phrase_hue_map;
|
||||||
|
|
||||||
typedef struct phrase_hue
|
typedef struct phrase_hue
|
||||||
|
@ -34,8 +51,62 @@ typedef struct phrase_hue
|
||||||
p_hue Hue0;
|
p_hue Hue0;
|
||||||
p_hue Hue1;
|
p_hue Hue1;
|
||||||
p_hue Hue2;
|
p_hue Hue2;
|
||||||
|
u32 Granularity;
|
||||||
|
r32 Speed;
|
||||||
|
u8 Pattern;
|
||||||
|
u8 AddIn;
|
||||||
} phrase_hue;
|
} phrase_hue;
|
||||||
|
|
||||||
|
internal p_hue
|
||||||
|
LerpPHue(r32 T, p_hue A, p_hue B)
|
||||||
|
{
|
||||||
|
p_hue Result = {};
|
||||||
|
|
||||||
|
if (Abs(A.Hue - B.Hue) < 180.0f)
|
||||||
|
{
|
||||||
|
Result.Hue = LerpR64(T, A.Hue, B.Hue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Result.Hue = LerpR64(T, A.Hue + 360.0f, B.Hue);
|
||||||
|
Result.Hue = ModR32(Result.Hue, 360.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (T < 0.5f)
|
||||||
|
{
|
||||||
|
Result.Flags = A.Flags;
|
||||||
|
} else {
|
||||||
|
Result.Flags = B.Flags;
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal phrase_hue
|
||||||
|
LerpPhraseHue(r32 T, phrase_hue A, phrase_hue B)
|
||||||
|
{
|
||||||
|
phrase_hue Result = {};
|
||||||
|
Result.Hue0 = LerpPHue(T, A.Hue0, B.Hue0);
|
||||||
|
Result.Hue1 = LerpPHue(T, A.Hue1, B.Hue1);
|
||||||
|
Result.Hue2 = LerpPHue(T, A.Hue2, B.Hue2);
|
||||||
|
Result.Granularity = (u32)LerpR32(T, (r32)A.Granularity, (r32)B.Granularity);
|
||||||
|
Result.Speed = LerpR32(T, A.Speed, B.Speed);
|
||||||
|
|
||||||
|
if (T < .5f) {
|
||||||
|
Result.Phrase = A.Phrase;
|
||||||
|
Result.PhraseHash = A.PhraseHash;
|
||||||
|
Result.Pattern = A.Pattern;
|
||||||
|
Result.AddIn = A.AddIn;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Result.Phrase = B.Phrase;
|
||||||
|
Result.PhraseHash = B.PhraseHash;
|
||||||
|
Result.Pattern = B.Pattern;
|
||||||
|
Result.AddIn = B.AddIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
internal p_hue
|
internal p_hue
|
||||||
CreateHueFromString(gs_const_string Str)
|
CreateHueFromString(gs_const_string Str)
|
||||||
{
|
{
|
||||||
|
@ -46,7 +117,13 @@ CreateHueFromString(gs_const_string Str)
|
||||||
Result.Flags = Hue_White;
|
Result.Flags = Hue_White;
|
||||||
} else {
|
} else {
|
||||||
Result.Flags = Hue_Value;
|
Result.Flags = Hue_Value;
|
||||||
Result.Hue = (r64)ParseFloat(Str);
|
parse_float_result Parsed = ValidateAndParseFloat(Str);
|
||||||
|
if (!Parsed.Success)
|
||||||
|
{
|
||||||
|
OutputDebugString("Failed to Parse CSV Float\n");
|
||||||
|
Parsed.Value = 0.0;
|
||||||
|
}
|
||||||
|
Result.Hue = Parsed.Value;
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
@ -73,9 +150,13 @@ PhraseHueMap_GenFromCSV(gscsv_sheet Sheet, gs_memory_arena* Arena)
|
||||||
Result.CountMax = Sheet.RowCount - 1; // we don't include the header row
|
Result.CountMax = Sheet.RowCount - 1; // we don't include the header row
|
||||||
Result.Phrases = PushArray(Arena, gs_const_string, Result.CountMax);
|
Result.Phrases = PushArray(Arena, gs_const_string, Result.CountMax);
|
||||||
Result.PhraseHashes = PushArray(Arena, u64, Result.CountMax);
|
Result.PhraseHashes = PushArray(Arena, u64, Result.CountMax);
|
||||||
Result.Hue0 = PushArray(Arena, p_hue, Result.CountMax);
|
Result.Hue0 = PushArray(Arena, p_hue, Result.CountMax);
|
||||||
Result.Hue1 = PushArray(Arena, p_hue, Result.CountMax);
|
Result.Hue1 = PushArray(Arena, p_hue, Result.CountMax);
|
||||||
Result.Hue2 = PushArray(Arena, p_hue, Result.CountMax);
|
Result.Hue2 = PushArray(Arena, p_hue, Result.CountMax);
|
||||||
|
Result.Gran = PushArray(Arena, u32, Result.CountMax);
|
||||||
|
Result.Pattern = PushArray(Arena, u8, Result.CountMax);
|
||||||
|
Result.Speed = PushArray(Arena, r32, Result.CountMax);
|
||||||
|
Result.AddIn = PushArray(Arena, u8, Result.CountMax);
|
||||||
|
|
||||||
s32 DestOffset = 0;
|
s32 DestOffset = 0;
|
||||||
for (u32 Row = 1; Row < Sheet.RowCount; Row++)
|
for (u32 Row = 1; Row < Sheet.RowCount; Row++)
|
||||||
|
@ -86,10 +167,15 @@ PhraseHueMap_GenFromCSV(gscsv_sheet Sheet, gs_memory_arena* Arena)
|
||||||
gs_const_string Phrase = CSVSheet_GetCell(Sheet,
|
gs_const_string Phrase = CSVSheet_GetCell(Sheet,
|
||||||
0, Row);
|
0, Row);
|
||||||
|
|
||||||
gs_const_string Hue0Str = CSVSheet_GetCell(Sheet, 1, Row);
|
gs_const_string Hue0Str = CSVSheet_GetCell(Sheet, 1, Row);
|
||||||
gs_const_string Hue1Str = CSVSheet_GetCell(Sheet, 2, Row);
|
gs_const_string Hue1Str = CSVSheet_GetCell(Sheet, 2, Row);
|
||||||
gs_const_string Hue2Str = CSVSheet_GetCell(Sheet, 3, Row);
|
gs_const_string Hue2Str = CSVSheet_GetCell(Sheet, 3, Row);
|
||||||
gs_const_string Homonyms = CSVSheet_GetCell(Sheet, 4, Row);
|
gs_const_string Homonyms = CSVSheet_GetCell(Sheet, 4, Row);
|
||||||
|
gs_const_string Granularity = CSVSheet_GetCell(Sheet, 5, Row);
|
||||||
|
gs_const_string Speed = CSVSheet_GetCell(Sheet, 6, Row);
|
||||||
|
gs_const_string Pattern = CSVSheet_GetCell(Sheet, 7, Row);
|
||||||
|
gs_const_string AddIn = CSVSheet_GetCell(Sheet, 8, Row);
|
||||||
|
|
||||||
if (Phrase.Length == 0 ||
|
if (Phrase.Length == 0 ||
|
||||||
Hue0Str.Length == 0 ||
|
Hue0Str.Length == 0 ||
|
||||||
Hue1Str.Length == 0 ||
|
Hue1Str.Length == 0 ||
|
||||||
|
@ -115,6 +201,36 @@ PhraseHueMap_GenFromCSV(gscsv_sheet Sheet, gs_memory_arena* Arena)
|
||||||
Result.Hue0[Index] = CreateHueFromString(Hue0Str);
|
Result.Hue0[Index] = CreateHueFromString(Hue0Str);
|
||||||
Result.Hue1[Index] = CreateHueFromString(Hue1Str);
|
Result.Hue1[Index] = CreateHueFromString(Hue1Str);
|
||||||
Result.Hue2[Index] = CreateHueFromString(Hue2Str);
|
Result.Hue2[Index] = CreateHueFromString(Hue2Str);
|
||||||
|
|
||||||
|
parse_float_result ParsedSpeed = ValidateAndParseFloat(Speed);
|
||||||
|
if (!ParsedSpeed.Success)
|
||||||
|
{
|
||||||
|
ParsedSpeed.Value = 1.0;
|
||||||
|
}
|
||||||
|
Result.Speed[Index] = ParsedSpeed.Value;
|
||||||
|
|
||||||
|
if (StringsEqual(Pattern, ConstString("wavy")))
|
||||||
|
{
|
||||||
|
Result.Pattern[Index] = HuePattern_Wavy;
|
||||||
|
} else {
|
||||||
|
Result.Pattern[Index] = HuePattern_Patchy;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringsEqual(AddIn, ConstString("waves")))
|
||||||
|
{
|
||||||
|
Result.AddIn[Index] = AddIn_Waves;
|
||||||
|
} else if (StringsEqual(AddIn, ConstString("rotary"))) {
|
||||||
|
Result.AddIn[Index] = AddIn_Rotary;
|
||||||
|
} else {
|
||||||
|
Result.AddIn[Index] = AddIn_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_uint_result ParsedGranularity = ValidateAndParseUInt(Granularity);
|
||||||
|
if (!ParsedGranularity.Success)
|
||||||
|
{
|
||||||
|
ParsedGranularity.Value = 1;
|
||||||
|
}
|
||||||
|
Result.Gran[Index] = ParsedGranularity.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result.Count = Result.CountMax + DestOffset;
|
Result.Count = Result.CountMax + DestOffset;
|
||||||
|
@ -123,24 +239,34 @@ PhraseHueMap_GenFromCSV(gscsv_sheet Sheet, gs_memory_arena* Arena)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal phrase_hue
|
internal phrase_hue
|
||||||
PhraseHueMap_Get(phrase_hue_map Map, u64 PhraseHash)
|
PhraseHueMap_Get(phrase_hue_map Map, u32 Index)
|
||||||
|
{
|
||||||
|
Assert(Index < Map.Count);
|
||||||
|
phrase_hue Result = {};
|
||||||
|
Result.Phrase = Map.Phrases[Index];
|
||||||
|
Result.PhraseHash = Map.PhraseHashes[Index];
|
||||||
|
Result.Hue0 = Map.Hue0[Index];
|
||||||
|
Result.Hue1 = Map.Hue1[Index];
|
||||||
|
Result.Hue2 = Map.Hue2[Index];
|
||||||
|
Result.Granularity = Map.Gran[Index];
|
||||||
|
Result.Speed = Map.Speed[Index];
|
||||||
|
Result.AddIn = Map.AddIn[Index];
|
||||||
|
Result.Pattern = Map.Pattern[Index];
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal phrase_hue
|
||||||
|
PhraseHueMap_Find(phrase_hue_map Map, u64 PhraseHash)
|
||||||
{
|
{
|
||||||
phrase_hue Result = {};
|
phrase_hue Result = {};
|
||||||
|
|
||||||
for (u32 i = 0; i < Map.Count; i++)
|
for (u32 i = 0; i < Map.Count; i++)
|
||||||
{
|
{
|
||||||
if (Map.PhraseHashes[i] == PhraseHash)
|
if (Map.PhraseHashes[i] == PhraseHash)
|
||||||
{
|
{
|
||||||
Result.Phrase = Map.Phrases[i];
|
Result = PhraseHueMap_Get(Map, i);
|
||||||
Result.PhraseHash = Map.PhraseHashes[i];
|
|
||||||
Result.Hue0 = Map.Hue0[i];
|
|
||||||
Result.Hue1 = Map.Hue1[i];
|
|
||||||
Result.Hue2 = Map.Hue2[i];
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue