merge
This commit is contained in:
commit
00a4cb5e39
|
@ -678,7 +678,7 @@ AnimationSystem_Init(animation_system_desc Desc)
|
||||||
Result.ActiveFadeGroup.FadeElapsed = 0;
|
Result.ActiveFadeGroup.FadeElapsed = 0;
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
Result.Multithreaded = true;
|
Result.Multithreaded = false;
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -413,14 +413,15 @@ BlumenLumen_CustomInit(app_state* State, context Context)
|
||||||
#endif
|
#endif
|
||||||
State->AnimationSystem.TimelineShouldAdvance = true;
|
State->AnimationSystem.TimelineShouldAdvance = true;
|
||||||
|
|
||||||
BLState->StandardPatternHues.Hue0.Flags = Hue_Value;
|
|
||||||
BLState->StandardPatternHues.Hue1.Flags = Hue_Value;
|
|
||||||
BLState->StandardPatternHues.Hue2.Flags = Hue_Value;
|
|
||||||
BLState->StandardPatternHues.Granularity = 1;
|
BLState->StandardPatternHues.Granularity = 1;
|
||||||
BLState->StandardPatternHues.Speed = 1;
|
BLState->StandardPatternHues.Speed = 1;
|
||||||
BLState->StandardPatternHues.AddIn = AddIn_Rotary;
|
BLState->StandardPatternHues.AddIn = AddIn_Rotary;
|
||||||
BLState->StandardPatternHues.Pattern = HuePattern_Wavy;
|
BLState->StandardPatternHues.Pattern = HuePattern_Wavy;
|
||||||
|
|
||||||
|
BLState->DebugHue.Hue0.HSV = v4{0, 1, 1, 1};
|
||||||
|
BLState->DebugHue.Hue1.HSV = v4{0, 1, 1, 1};
|
||||||
|
BLState->DebugHue.Hue2.HSV = v4{0, 1, 1, 1};
|
||||||
|
|
||||||
BlumenLumen_AppendBootupLog(State, BLState, Context);
|
BlumenLumen_AppendBootupLog(State, BLState, Context);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
@ -456,7 +457,8 @@ BlumenLumen_ApplyNextHotHue(blumen_lumen_state* BLState, context Context, gs_str
|
||||||
OutputDebugString(DebugStr->Str);
|
OutputDebugString(DebugStr->Str);
|
||||||
|
|
||||||
|
|
||||||
if (BLState->PatternMode == BlumenPattern_Standard)
|
if (BLState->PatternMode == BlumenPattern_Standard ||
|
||||||
|
NewHue.OverrideAll)
|
||||||
{
|
{
|
||||||
BlumenLumen_SetNextHue(BLState, 0, NewHue);
|
BlumenLumen_SetNextHue(BLState, 0, NewHue);
|
||||||
BlumenLumen_SetNextHue(BLState, 1, NewHue);
|
BlumenLumen_SetNextHue(BLState, 1, NewHue);
|
||||||
|
@ -581,9 +583,15 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
||||||
r32 ColorRelOscSpeed = 1 * ColorSpeed;;
|
r32 ColorRelOscSpeed = 1 * ColorSpeed;;
|
||||||
r32 ColorOscillation = (SinR32(BaseTime * ColorOscSpeed) + 1) / 2;
|
r32 ColorOscillation = (SinR32(BaseTime * ColorOscSpeed) + 1) / 2;
|
||||||
r32 ColorRelationship = 30 + (((1 + SinR32(BaseTime * ColorRelOscSpeed)) / 2) * 300);
|
r32 ColorRelationship = 30 + (((1 + SinR32(BaseTime * ColorRelOscSpeed)) / 2) * 300);
|
||||||
BLState->StandardPatternHues.Hue0.Hue = ModR32(ColorOscillation * 360, 360);
|
|
||||||
BLState->StandardPatternHues.Hue1.Hue = ModR32(BaseTime + ColorRelationship, 360);
|
r32 H0 = ModR32(ColorOscillation * 360, 360);
|
||||||
BLState->StandardPatternHues.Hue2.Hue = LerpR32(.3f, BLState->StandardPatternHues.Hue0.Hue, BLState->StandardPatternHues.Hue1.Hue);
|
r32 H1 = ModR32(BaseTime + ColorRelationship, 360);
|
||||||
|
// TODO(PS): use our new HSV lerp
|
||||||
|
r32 H2 = LerpR32(.3f, H0, H1);
|
||||||
|
|
||||||
|
BLState->StandardPatternHues.Hue0.HSV = v4{ H0, 1, 1, 1 };
|
||||||
|
BLState->StandardPatternHues.Hue1.HSV = v4{ H1, 1, 1, 1 };
|
||||||
|
BLState->StandardPatternHues.Hue2.HSV = v4{ H2, 1, 1, 1 };
|
||||||
|
|
||||||
// Transition back to standard mode after some time
|
// Transition back to standard mode after some time
|
||||||
if (BLState->PatternMode == BlumenPattern_VoiceCommand)
|
if (BLState->PatternMode == BlumenPattern_VoiceCommand)
|
||||||
|
@ -616,6 +624,10 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
||||||
if (MessageQueue_CanWrite(BLState->OutgoingMsgQueue) &&
|
if (MessageQueue_CanWrite(BLState->OutgoingMsgQueue) &&
|
||||||
!BLState->IgnoreTimeOfDay_MotorState)
|
!BLState->IgnoreTimeOfDay_MotorState)
|
||||||
{
|
{
|
||||||
|
u64 NanosSinceLastSend = Context->SystemTime_Current.NanosSinceEpoch - BLState->LastSendTime.NanosSinceEpoch;
|
||||||
|
r32 SecondsSinceLastSend = (r64)NanosSinceLastSend * NanosToSeconds;
|
||||||
|
bool ShouldSendCurrentState = SecondsSinceLastSend >= MotorResendStatePeriod;
|
||||||
|
|
||||||
for (u32 i = 0; i < MotorOpenTimesCount; i++)
|
for (u32 i = 0; i < MotorOpenTimesCount; i++)
|
||||||
{
|
{
|
||||||
time_range Range = MotorOpenTimes[i];
|
time_range Range = MotorOpenTimes[i];
|
||||||
|
@ -626,9 +638,13 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
||||||
|
|
||||||
bool LastTimeInRange = SystemTimeIsInTimeRange(Context->SystemTime_Last, Range);
|
bool LastTimeInRange = SystemTimeIsInTimeRange(Context->SystemTime_Last, Range);
|
||||||
|
|
||||||
|
#if 0
|
||||||
bool SendOpen = CurrTimeInRange && !LastSendTimeInRange;
|
bool SendOpen = CurrTimeInRange && !LastSendTimeInRange;
|
||||||
bool SendClose = !CurrTimeInRange && LastSendTimeInRange;
|
bool SendClose = !CurrTimeInRange && LastSendTimeInRange;
|
||||||
|
#else
|
||||||
|
bool SendOpen = CurrTimeInRange && ShouldSendCurrentState;
|
||||||
|
bool SendClose = !CurrTimeInRange && ShouldSendCurrentState;
|
||||||
|
#endif
|
||||||
//SendOpen = SecondsSinceLastSend > 2;
|
//SendOpen = SecondsSinceLastSend > 2;
|
||||||
if (SendOpen)
|
if (SendOpen)
|
||||||
{
|
{
|
||||||
|
@ -643,6 +659,7 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
||||||
Packet.MotorPacket.FlowerPositions[1] = 2;
|
Packet.MotorPacket.FlowerPositions[1] = 2;
|
||||||
Packet.MotorPacket.FlowerPositions[2] = 2;
|
Packet.MotorPacket.FlowerPositions[2] = 2;
|
||||||
MotorCommand = Packet;
|
MotorCommand = Packet;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (SendClose)
|
else if (SendClose)
|
||||||
{
|
{
|
||||||
|
@ -656,6 +673,7 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
||||||
Packet.MotorPacket.FlowerPositions[1] = 1;
|
Packet.MotorPacket.FlowerPositions[1] = 1;
|
||||||
Packet.MotorPacket.FlowerPositions[2] = 1;
|
Packet.MotorPacket.FlowerPositions[2] = 1;
|
||||||
MotorCommand = Packet;
|
MotorCommand = Packet;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -953,9 +971,9 @@ US_CUSTOM_DEBUG_UI(BlumenLumen_DebugUI)
|
||||||
if (BLState->DebugOverrideHue)
|
if (BLState->DebugOverrideHue)
|
||||||
{
|
{
|
||||||
phrase_hue PHue = BLState->DebugHue;
|
phrase_hue PHue = BLState->DebugHue;
|
||||||
PHue.Hue0.Hue = (r64)ui_LabeledRangeSlider(I, MakeString("Hue0"), (r32)PHue.Hue0.Hue, 0, 360);
|
PHue.Hue0.HSV.x = (r64)ui_LabeledRangeSlider(I, MakeString("Hue0"), (r32)PHue.Hue0.HSV.x, 0, 360);
|
||||||
PHue.Hue1.Hue = (r64)ui_LabeledRangeSlider(I, MakeString("Hue1"), (r32)PHue.Hue1.Hue, 0, 360);
|
PHue.Hue1.HSV.x = (r64)ui_LabeledRangeSlider(I, MakeString("Hue1"), (r32)PHue.Hue1.HSV.x, 0, 360);
|
||||||
PHue.Hue2.Hue = (r64)ui_LabeledRangeSlider(I, MakeString("Hue2"), (r32)PHue.Hue2.Hue, 0, 360);
|
PHue.Hue2.HSV.x = (r64)ui_LabeledRangeSlider(I, MakeString("Hue2"), (r32)PHue.Hue2.HSV.x, 0, 360);
|
||||||
PHue.Granularity = (u32)ui_LabeledRangeSlider(I, MakeString("Granularity"), (r32)PHue.Granularity, 0, 5);
|
PHue.Granularity = (u32)ui_LabeledRangeSlider(I, MakeString("Granularity"), (r32)PHue.Granularity, 0, 5);
|
||||||
PHue.Speed = ui_LabeledRangeSlider(I, MakeString("Speed"), PHue.Speed, 0, 4);
|
PHue.Speed = ui_LabeledRangeSlider(I, MakeString("Speed"), PHue.Speed, 0, 4);
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,11 @@ global time_range MotorOpenTimes[] = {
|
||||||
};
|
};
|
||||||
global u32 MotorOpenTimesCount = CArrayLength(MotorOpenTimes); // do not edit
|
global u32 MotorOpenTimesCount = CArrayLength(MotorOpenTimes); // do not edit
|
||||||
|
|
||||||
|
// Lumenarium repeatedly resends the current motor state to the python
|
||||||
|
// server. This variable determines how much time elapses between each
|
||||||
|
// message.
|
||||||
|
global r32 MotorResendStatePeriod = 90.0f; // seconds
|
||||||
|
|
||||||
// The times of day when the leds should be on
|
// The times of day when the leds should be on
|
||||||
// Search for @TimeFormat to find documentation
|
// Search for @TimeFormat to find documentation
|
||||||
global time_range LedOnTimes[] = {
|
global time_range LedOnTimes[] = {
|
||||||
|
|
|
@ -29,8 +29,7 @@ enum p_hue_add_in
|
||||||
|
|
||||||
typedef struct p_hue
|
typedef struct p_hue
|
||||||
{
|
{
|
||||||
r64 Hue;
|
v4 HSV;
|
||||||
p_hue_flag Flags;
|
|
||||||
} p_hue;
|
} p_hue;
|
||||||
|
|
||||||
typedef struct phrase_hue_map
|
typedef struct phrase_hue_map
|
||||||
|
@ -46,6 +45,7 @@ typedef struct phrase_hue_map
|
||||||
r32* Speed;
|
r32* Speed;
|
||||||
u8* Pattern;
|
u8* Pattern;
|
||||||
u8* AddIn;
|
u8* AddIn;
|
||||||
|
bool* OverrideAll;
|
||||||
} phrase_hue_map;
|
} phrase_hue_map;
|
||||||
|
|
||||||
typedef struct phrase_hue
|
typedef struct phrase_hue
|
||||||
|
@ -59,6 +59,7 @@ typedef struct phrase_hue
|
||||||
r32 Speed;
|
r32 Speed;
|
||||||
u8 Pattern;
|
u8 Pattern;
|
||||||
u8 AddIn;
|
u8 AddIn;
|
||||||
|
bool OverrideAll;
|
||||||
} phrase_hue;
|
} phrase_hue;
|
||||||
|
|
||||||
internal p_hue
|
internal p_hue
|
||||||
|
@ -66,22 +67,25 @@ LerpPHue(r32 T, p_hue A, p_hue B)
|
||||||
{
|
{
|
||||||
p_hue Result = {};
|
p_hue Result = {};
|
||||||
|
|
||||||
if (Abs(A.Hue - B.Hue) < 180.0f)
|
if (Abs(A.HSV.x - B.HSV.x) < 180.0f)
|
||||||
{
|
{
|
||||||
Result.Hue = LerpR64(T, A.Hue, B.Hue);
|
Result.HSV.x = LerpR64(T, A.HSV.x, B.HSV.x);
|
||||||
}
|
}
|
||||||
|
else if (B.HSV.x > A.HSV.x)
|
||||||
|
{
|
||||||
|
Result.HSV.x = LerpR64(T, A.HSV.x, B.HSV.x - 360.0f);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Result.Hue = LerpR64(T, A.Hue + 360.0f, B.Hue);
|
Result.HSV.x = LerpR64(T, A.HSV.x - 360.0f, B.HSV.x);
|
||||||
Result.Hue = ModR32(Result.Hue, 360.0f);
|
|
||||||
}
|
}
|
||||||
|
if (Result.HSV.x < 360) Result.HSV.x += 360;
|
||||||
|
if (Result.HSV.x > 360) Result.HSV.x -= 360;
|
||||||
|
Result.HSV.x = Clamp(0, Result.HSV.x, 360);
|
||||||
|
Result.HSV.y = LerpR32(T, A.HSV.y, B.HSV.y);
|
||||||
|
Result.HSV.z = LerpR32(T, A.HSV.z, B.HSV.z);
|
||||||
|
Result.HSV.w = LerpR32(T, A.HSV.w, B.HSV.w);
|
||||||
|
|
||||||
if (T < 0.5f)
|
|
||||||
{
|
|
||||||
Result.Flags = A.Flags;
|
|
||||||
} else {
|
|
||||||
Result.Flags = B.Flags;
|
|
||||||
}
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,18 +120,18 @@ CreateHueFromString(gs_const_string Str)
|
||||||
{
|
{
|
||||||
p_hue Result = {};
|
p_hue Result = {};
|
||||||
if (Str.Str[0] == 'b') {
|
if (Str.Str[0] == 'b') {
|
||||||
Result.Flags = Hue_Black;
|
Result.HSV = v4{0, 0, 0, 1 };
|
||||||
} else if (Str.Str[0] == 'w') {
|
} else if (Str.Str[0] == 'w') {
|
||||||
Result.Flags = Hue_White;
|
Result.HSV = v4{0, 0, 1, 1 };;
|
||||||
} else {
|
} else {
|
||||||
Result.Flags = Hue_Value;
|
|
||||||
parse_float_result Parsed = ValidateAndParseFloat(Str);
|
parse_float_result Parsed = ValidateAndParseFloat(Str);
|
||||||
if (!Parsed.Success)
|
if (!Parsed.Success)
|
||||||
{
|
{
|
||||||
OutputDebugString("Failed to Parse CSV Float\n");
|
OutputDebugString("Failed to Parse CSV Float\n");
|
||||||
Parsed.Value = 0.0;
|
Parsed.Value = 0.0;
|
||||||
}
|
}
|
||||||
Result.Hue = Parsed.Value;
|
Result.HSV = v4{ (r32)Parsed.Value, 1, 1, 1 };
|
||||||
|
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
@ -135,14 +139,7 @@ CreateHueFromString(gs_const_string Str)
|
||||||
internal v4
|
internal v4
|
||||||
RGBFromPhraseHue (p_hue H)
|
RGBFromPhraseHue (p_hue H)
|
||||||
{
|
{
|
||||||
v4 Result = {};
|
v4 Result = H.HSV;
|
||||||
switch (H.Flags)
|
|
||||||
{
|
|
||||||
case Hue_Black: { Result = v4{1, 0, 0, 1}; } break;
|
|
||||||
case Hue_White: { Result = v4{1, 0, 1, 1}; } break;
|
|
||||||
case Hue_Value: { Result = v4{(r32)H.Hue, 1, 1, 1}; } break;
|
|
||||||
InvalidDefaultCase;
|
|
||||||
}
|
|
||||||
Result = HSVToRGB(Result);
|
Result = HSVToRGB(Result);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
@ -163,6 +160,7 @@ PhraseHueMap_GenFromCSV(gscsv_sheet Sheet, gs_memory_arena* Arena)
|
||||||
Result.Pattern = PushArray(Arena, u8, Result.CountMax);
|
Result.Pattern = PushArray(Arena, u8, Result.CountMax);
|
||||||
Result.Speed = PushArray(Arena, r32, Result.CountMax);
|
Result.Speed = PushArray(Arena, r32, Result.CountMax);
|
||||||
Result.AddIn = PushArray(Arena, u8, Result.CountMax);
|
Result.AddIn = PushArray(Arena, u8, Result.CountMax);
|
||||||
|
Result.OverrideAll = PushArray(Arena, bool, Result.CountMax);
|
||||||
|
|
||||||
// this lets us tightly pack phrase_hues even if there is a
|
// this lets us tightly pack phrase_hues even if there is a
|
||||||
// row in the csv that is empty or invalid
|
// row in the csv that is empty or invalid
|
||||||
|
@ -182,6 +180,7 @@ PhraseHueMap_GenFromCSV(gscsv_sheet Sheet, gs_memory_arena* Arena)
|
||||||
gs_const_string Speed = CSVSheet_GetCell(Sheet, 6, Row);
|
gs_const_string Speed = CSVSheet_GetCell(Sheet, 6, Row);
|
||||||
gs_const_string Pattern = CSVSheet_GetCell(Sheet, 7, Row);
|
gs_const_string Pattern = CSVSheet_GetCell(Sheet, 7, Row);
|
||||||
gs_const_string AddIn = CSVSheet_GetCell(Sheet, 8, Row);
|
gs_const_string AddIn = CSVSheet_GetCell(Sheet, 8, Row);
|
||||||
|
gs_const_string OverrideAll = CSVSheet_GetCell(Sheet, 9, Row);
|
||||||
|
|
||||||
// essential parameters
|
// essential parameters
|
||||||
if (Phrase.Length == 0 ||
|
if (Phrase.Length == 0 ||
|
||||||
|
@ -239,6 +238,8 @@ PhraseHueMap_GenFromCSV(gscsv_sheet Sheet, gs_memory_arena* Arena)
|
||||||
ParsedGranularity.Value = 1;
|
ParsedGranularity.Value = 1;
|
||||||
}
|
}
|
||||||
Result.Gran[Index] = ParsedGranularity.Value;
|
Result.Gran[Index] = ParsedGranularity.Value;
|
||||||
|
|
||||||
|
Result.OverrideAll[Index] = StringsEqualUpToLength(OverrideAll, ConstString("yes"), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result.Count = Result.CountMax + DestOffset;
|
Result.Count = Result.CountMax + DestOffset;
|
||||||
|
@ -260,6 +261,7 @@ PhraseHueMap_Get(phrase_hue_map Map, u32 Index)
|
||||||
Result.Speed = Map.Speed[Index];
|
Result.Speed = Map.Speed[Index];
|
||||||
Result.AddIn = Map.AddIn[Index];
|
Result.AddIn = Map.AddIn[Index];
|
||||||
Result.Pattern = Map.Pattern[Index];
|
Result.Pattern = Map.Pattern[Index];
|
||||||
|
Result.OverrideAll = Map.OverrideAll[Index];
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue