From e6042b7a01f83e2ac394b034635bb7579bee8b50 Mon Sep 17 00:00:00 2001 From: Peter Slattery Date: Sat, 20 Mar 2021 21:49:02 -0700 Subject: [PATCH] Patterns --- src/app/engine/animation/foldhaus_animation.h | 3 +- src/app/patterns/blumen_patterns.h | 50 ++++------ src/app/platform_win32/win32_foldhaus.cpp | 6 ++ src/app/ss_blumen_lumen/blumen_lumen.cpp | 97 ++++++++++++------- src/app/ss_blumen_lumen/blumen_lumen.h | 25 ++++- 5 files changed, 116 insertions(+), 65 deletions(-) diff --git a/src/app/engine/animation/foldhaus_animation.h b/src/app/engine/animation/foldhaus_animation.h index 0c33c8b..33d466a 100644 --- a/src/app/engine/animation/foldhaus_animation.h +++ b/src/app/engine/animation/foldhaus_animation.h @@ -157,7 +157,6 @@ struct animation_system // NOTE(Peter): The frame currently being displayed/processed. you // can see which frame you're on by looking at the time slider on the timeline // panel - animation_handle ActiveAnimationHandle_; animation_fade_group ActiveFadeGroup; s32 CurrentFrame; @@ -561,7 +560,9 @@ AnimationFadeGroup_Update(animation_fade_group* Group, r32 DeltaTime) { if (IsValid(Group->To)) { + r32 FadeBefore = Group->FadeElapsed; Group->FadeElapsed += DeltaTime; + if (Group->FadeElapsed >= Group->FadeDuration) { AnimationFadeGroup_Advance(Group); diff --git a/src/app/patterns/blumen_patterns.h b/src/app/patterns/blumen_patterns.h index 4eb7230..18d267e 100644 --- a/src/app/patterns/blumen_patterns.h +++ b/src/app/patterns/blumen_patterns.h @@ -980,7 +980,7 @@ Pattern_Patchy(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* T v3 Pp = P.xyz; - r32 Noise = Fbm3D((Pp / 1000) + (v3{Time, -Time, SinR32(Time)} * 0.1f)); + r32 Noise = Fbm3D((Pp / 1000) + (v3{Time, -Time, Time} * 0.01f)); Noise = RemapR32(Noise, -1, 1, 0, 1); Noise = Smoothstep(Noise, 0, 1); u8 NV = (u8)(Noise * 255); @@ -991,6 +991,7 @@ Pattern_Patchy(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* T v4 C = GetColor(&FlowerAColors[0], FLOWER_COLORS_COUNT, Noise); C = C * BNoise; + //Leds->Colors[LedIndex] = V4ToRGBPixel(v4{Noise, Noise, Noise, 1}); Leds->Colors[LedIndex] = V4ToRGBPixel(C); //Leds->Colors[LedIndex] = pixel{NV, NV, NV}; } @@ -1001,11 +1002,13 @@ Pattern_Leafy(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Tr { v4* Colors = &FlowerBColors[0]; -#if 1 + for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++) { v4 P = Leds->Positions[LedIndex]; - r32 RefPos = P.y; // + Noise2D(v2{P.x, P.z} * 10); + +#if 0 + r32 RefPos = P.y + Noise2D(v2{P.x, P.z} * 10); v4 C = {}; r32 B = 0; @@ -1015,18 +1018,19 @@ Pattern_Leafy(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Tr u32 BandCount = 10; for (u32 Band = 0; Band < BandCount; Band++) { - r32 BandSeed = RemapR32(Hash1((r32)Band), -1, 1, 0, 1); - r32 BandDelay = BandSeed * TransitionPeriod; + r32 BandSeed = Hash1((r32)Band); + r32 BandSeedPos = RemapR32(BandSeed, -1, 1, 0, 1); + r32 BandDelay = BandSeedPos * TransitionPeriod; r32 BandTransitionPeriod = RemapR32(Hash1((r32)Band * 3.413f), -1, 1, 0, 1) * TransitionPeriod; r32 BandOffset = Time + BandDelay; r32 BandPercent = ModR32(BandOffset, BandTransitionPeriod) / BandTransitionPeriod; r32 BandSmoothed = Smoothstep(BandPercent, 0, 1); - r32 BandHeight = 125 - BandPercent * 250; + r32 BandHeight = -125 + BandPercent * 250; - r32 BandDist = Abs(RefPos - (BandHeight + BandSeed * 5)); + r32 BandDist = Abs(RefPos - BandHeight); - B += Max(0, BandWidth - BandDist); + B += Max(0, (BandWidth + BandSeed * 2.5) - BandDist); } B = Clamp(0, B, 1); @@ -1039,31 +1043,17 @@ Pattern_Leafy(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Tr GradientB = Clamp(0, GradientB, 1); C = (GradientC * GradientB) + (BandC * B); +#endif + //v4 C = GetColor(&FlowerBColors[0], FLOWER_COLORS_COUNT, 0); + v4 C = v4{ 255, 100, 3 }; + C /= 255.f; + //r32 B = Fbm3D(P.xyz / 200); //C *= B; - + if (P.y < 75) { + C = v4{ 139 / 255.f, 69 / 255.f, 19 / 255.f, 1.0f} * .25f; + } Leds->Colors[LedIndex] = V4ToRGBPixel(C); } -#else - - r32 FadeTop = 150; - r32 FadeBottom = -50; - - v4 C = GetColor(&FlowerAColors[0], FLOWER_COLORS_COUNT, 0); - - for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++) - { - v4 P = Leds->Positions[LedIndex]; - - r32 Brightness = RemapR32(P.y, 200, 0, 1, 0); - - Brightness = Clamp(Brightness, 0, 1); - u8 B = (u8)(Brightness * 255); - - v4 CB = C * Brightness; - - Leds->Colors[LedIndex] = V4ToRGBPixel(CB); - } -#endif } internal void diff --git a/src/app/platform_win32/win32_foldhaus.cpp b/src/app/platform_win32/win32_foldhaus.cpp index c34f3f4..ab6faac 100644 --- a/src/app/platform_win32/win32_foldhaus.cpp +++ b/src/app/platform_win32/win32_foldhaus.cpp @@ -681,6 +681,12 @@ WinMain ( RenderBuffer.ViewHeight = MainWindow.Height; Context.DeltaTime = LastFrameSecondsElapsed; +#if 0 + gs_string T = PushStringF(Context.ThreadContext.Transient, 256, "%f\n", Context.DeltaTime); + NullTerminate(&T); + OutputDebugStringA(T.Str); +#endif + Context.UpdateAndRender(&Context, InputQueue, &RenderBuffer, &OutputData); bool Multithread = true; diff --git a/src/app/ss_blumen_lumen/blumen_lumen.cpp b/src/app/ss_blumen_lumen/blumen_lumen.cpp index cfc8b54..2d9b842 100644 --- a/src/app/ss_blumen_lumen/blumen_lumen.cpp +++ b/src/app/ss_blumen_lumen/blumen_lumen.cpp @@ -223,9 +223,9 @@ BlumenLumen_CustomInit(app_state* State, context Context) for (u32 i = 0; i < FLOWER_COLORS_COUNT; i++) { - FlowerAColors[i] = TEMP_Saturate(FlowerAColors[i]); - FlowerBColors[i] = TEMP_Saturate(FlowerBColors[i]); - FlowerCColors[i] = TEMP_Saturate(FlowerCColors[i]); + //FlowerAColors[i] = TEMP_Saturate(FlowerAColors[i]); + //FlowerBColors[i] = TEMP_Saturate(FlowerBColors[i]); + //FlowerCColors[i] = TEMP_Saturate(FlowerCColors[i]); } return Result; @@ -236,8 +236,11 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) { blumen_lumen_state* BLState = (blumen_lumen_state*)UserData.Memory; - MotorTimeElapsed += Context->DeltaTime; + bool SendMotorCommand = false; + blumen_packet MotorCommand = {}; + #if 0 + MotorTimeElapsed += Context->DeltaTime; BLState->TimeElapsed += Context->DeltaTime; if (BLState->TimeElapsed > 5) @@ -249,10 +252,6 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) } #endif - gs_string BlueString = MakeString("blue"); - gs_string GreenString = MakeString("green"); - gs_string ILoveYouString = MakeString("i_love_you"); - while (MessageQueue_CanRead(&BLState->IncomingMsgQueue)) { gs_data PacketData = MessageQueue_Read(&BLState->IncomingMsgQueue); @@ -262,27 +261,47 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) case PacketType_PatternCommand: { microphone_packet Mic = Packet.MicPacket; - u32 NameLen = CStringLength(Mic.AnimationFileName); - if (StringEqualsCharArray(BlueString.ConstString, Mic.AnimationFileName, NameLen)) - { - State->AnimationSystem.ActiveFadeGroup.From.Index = 0; - } - else if (StringEqualsCharArray(GreenString.ConstString, Mic.AnimationFileName, NameLen)) - { - State->AnimationSystem.ActiveFadeGroup.From.Index = 1; - } - else if (StringEqualsCharArray(ILoveYouString.ConstString, Mic.AnimationFileName, NameLen)) - { - State->AnimationSystem.ActiveFadeGroup.From.Index = 2; - } - OutputDebugStringA("\nReceived Pattern Packet\n"); + for (u32 i = 0; i < PhraseToAnimMapCount; i++) + { + gs_const_string PhraseStr = ConstString(PhraseToAnimMap[i].Phrase); + u32 PhraseIndex = PhraseToAnimMap[i].PatternIndex; + if (StringEqualsCharArray(PhraseStr, Mic.AnimationFileName, NameLen)) + { + AnimationFadeGroup_FadeTo(&State->AnimationSystem.ActiveFadeGroup, + animation_handle{(s32)PhraseIndex}, + 3.0f); + OutputDebugStringA("\nReceived Pattern Packet\n"); + + { + // DEBUG CODE + u8 MotorState = BLState->LastKnownMotorState.FlowerPositions[0]; + if (MotorState == 2) { + OutputDebugStringA("Sending 1\n"); + MotorState = 1; + } + else + { + OutputDebugStringA("Sending 1\n"); + MotorState = 2; + } + + blumen_packet MPacket = {}; + MPacket.Type = PacketType_MotorState; + MPacket.MotorPacket.FlowerPositions[0] = MotorState; + MPacket.MotorPacket.FlowerPositions[1] = MotorState; + MPacket.MotorPacket.FlowerPositions[2] = MotorState; + MotorCommand = MPacket; + SendMotorCommand = true; + } + } + } }break; case PacketType_MotorState: { - motor_packet Motor = Packet.MotorPacket; + motor_status_packet Motor = Packet.MotorStatusPacket; // NOTE(pjs): Python sends multi-byte integers in little endian // order. Have to unpack @@ -290,12 +309,12 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) Motor.Temperature = (T[0] << 8 | T[1] << 0); - BLState->LastKnownMotorState = Motor; + BLState->LastKnownMotorState = Motor.Pos; gs_string Temp = PushStringF(State->Transient, 256, "\nReceived Motor States: \n\tPos: %d %d %d\n\tErr: %d %d %d\n\tTemp: %d\n\n", - Motor.FlowerPositions[0], - Motor.FlowerPositions[1], - Motor.FlowerPositions[2], + Motor.Pos.FlowerPositions[0], + Motor.Pos.FlowerPositions[1], + Motor.Pos.FlowerPositions[2], Motor.MotorStatus[0], Motor.MotorStatus[1], Motor.MotorStatus[2], @@ -334,6 +353,7 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) if (MessageQueue_CanWrite(BLState->OutgoingMsgQueue)) { +#if 0 for (u32 i = 0; i < MotorOpenTimesCount; i++) { time_range Range = MotorOpenTimes[i]; @@ -347,33 +367,42 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) r64 NanosSinceLastSend = ((r64)Context->SystemTime_Current.NanosSinceEpoch - (r64)BLState->LastSendTime.NanosSinceEpoch); r64 SecondsSinceLastSend = NanosSinceLastSend / PowR32(10, 8); - SendOpen = SecondsSinceLastSend > 2; + //SendOpen = SecondsSinceLastSend > 2; if (SendOpen) { + SendMotorCommand = true; + BLState->LastSendTime = Context->SystemTime_Current; OutputDebugString("Motors: Open\n"); + blumen_packet Packet = {}; Packet.Type = PacketType_MotorState; Packet.MotorPacket.FlowerPositions[0] = 2; Packet.MotorPacket.FlowerPositions[1] = 2; Packet.MotorPacket.FlowerPositions[2] = 2; - gs_data Msg = StructToData(&Packet, blumen_packet); - MessageQueue_Write(&BLState->OutgoingMsgQueue, Msg); + MotorCommand = Packet; } else if (!CurrTimeInRange && LastTimeInRange) { + SendMotorCommand = true; OutputDebugString("Motors: Close\n"); + blumen_packet Packet = {}; Packet.Type = PacketType_MotorState; Packet.MotorPacket.FlowerPositions[0] = 1; Packet.MotorPacket.FlowerPositions[1] = 1; Packet.MotorPacket.FlowerPositions[2] = 1; - gs_data Msg = StructToData(&Packet, blumen_packet); - MessageQueue_Write(&BLState->OutgoingMsgQueue, Msg); + MotorCommand = Packet; } } +#endif + + if (SendMotorCommand) + { + gs_data Msg = StructToData(&MotorCommand, blumen_packet); + MessageQueue_Write(&BLState->OutgoingMsgQueue, Msg); + } } - // Dim the leds based on temp data #if DIM_LED_BRIGHTNESS for (u32 i = 0; i < State->LedSystem.BuffersCount; i++) @@ -387,6 +416,8 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) Color->B = Color->B * BLState->BrightnessPercent; } } + + // TODO(pjs): dim stem to 50% #endif // Send Status Packet diff --git a/src/app/ss_blumen_lumen/blumen_lumen.h b/src/app/ss_blumen_lumen/blumen_lumen.h index b29ea6c..30b975a 100644 --- a/src/app/ss_blumen_lumen/blumen_lumen.h +++ b/src/app/ss_blumen_lumen/blumen_lumen.h @@ -18,6 +18,11 @@ enum bl_python_packet_type typedef struct motor_packet { u8 FlowerPositions[3]; +} motor_packet; + +typedef struct motor_status_packet +{ + motor_packet Pos; /* u8 Motor1Pos; u8 Motor2Pos; @@ -26,7 +31,7 @@ u8 Motor3Pos; u8 MotorStatus[3]; u16 Temperature; -} motor_packet; +} motor_status_packet; typedef struct microphone_packet { @@ -66,6 +71,7 @@ typedef struct blumen_packet union { motor_packet MotorPacket; + motor_status_packet MotorStatusPacket; microphone_packet MicPacket; temp_packet TempPacket; status_packet StatusPacket; @@ -121,6 +127,23 @@ global time_range MotorOpenTimes[] = { }; global u32 MotorOpenTimesCount = 3; +struct phrase_string_to_anim_file +{ + char* Phrase; + u32 PatternIndex; +}; + +phrase_string_to_anim_file PhraseToAnimMap[] = { + { "begonia", 0}, + { "hyacinth", 1 }, + { "tulip", 1 }, + { "calla lilly", 0 }, + { "sunflower", 1 }, + { "salvia", 2 }, + { "freesia", 2 }, +}; +u32 PhraseToAnimMapCount = sizeof(PhraseToAnimMap) / sizeof(PhraseToAnimMap[0]); + struct blumen_lumen_state { bool Running;