diff --git a/src/app/editor/panels/foldhaus_panel_animation_timeline.h b/src/app/editor/panels/foldhaus_panel_animation_timeline.h index d319a0e..ca30811 100644 --- a/src/app/editor/panels/foldhaus_panel_animation_timeline.h +++ b/src/app/editor/panels/foldhaus_panel_animation_timeline.h @@ -924,12 +924,12 @@ AnimationTimeline_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* animation* ActiveAnim = 0; animation_handle Handle = State->AnimationSystem.ActiveFadeGroup.From; + TimelineState->NextActiveAnim = Handle; if (IsValid(Handle)) { animation_array Animations = State->AnimationSystem.Animations; ActiveAnim = AnimationArray_GetSafe(Animations, Handle); TimelineState->EditingAnimationHandle = Handle; - TimelineState->NextActiveAnim = Handle; } ui_FillRect(&State->Interface, PanelBounds, v4{.1f,.1f,.1f,1.f}); diff --git a/src/app/engine/animation/foldhaus_animation.h b/src/app/engine/animation/foldhaus_animation.h index 64ef95c..a9a327d 100644 --- a/src/app/engine/animation/foldhaus_animation.h +++ b/src/app/engine/animation/foldhaus_animation.h @@ -89,6 +89,13 @@ struct animation_handle s32 Index; }; +struct animation_handle_array +{ + u32 Count; + animation_handle* Handles; +}; + +internal animation_handle InvalidAnimHandle () { return { -1 }; } internal bool IsValid (animation_handle H) { return H.Index >= 0; } internal void Clear (animation_handle* H) { H->Index = -1; } internal bool AnimHandlesAreEqual (animation_handle A, animation_handle B) diff --git a/src/app/engine/animation/foldhaus_animation_serializer.cpp b/src/app/engine/animation/foldhaus_animation_serializer.cpp index 9227328..577e84b 100644 --- a/src/app/engine/animation/foldhaus_animation_serializer.cpp +++ b/src/app/engine/animation/foldhaus_animation_serializer.cpp @@ -194,10 +194,14 @@ AnimParser_Parse(gs_data File, gs_memory_arena* Arena, animation_pattern_array A internal animation_handle AnimationSystem_LoadAnimationFromFile(animation_system* System, animation_pattern_array AnimPatterns, context Context, gs_const_string FilePath) { + animation_handle NewAnimHandle = InvalidAnimHandle(); gs_file AnimFile = ReadEntireFile(Context.ThreadContext.FileHandler, FilePath); - animation NewAnim = AnimParser_Parse(AnimFile.Data, System->Storage, AnimPatterns); - NewAnim.FileInfo = AnimFile.FileInfo; - animation_handle NewAnimHandle = AnimationArray_Push(&System->Animations, NewAnim); + if (AnimFile.Size > 0) + { + animation NewAnim = AnimParser_Parse(AnimFile.Data, System->Storage, AnimPatterns); + NewAnim.FileInfo = AnimFile.FileInfo; + NewAnimHandle = AnimationArray_Push(&System->Animations, NewAnim); + } return NewAnimHandle; } #define FOLDHAUS_ANIMATION_SERIALIZER_CPP diff --git a/src/app/ss_blumen_lumen/blumen_lumen.cpp b/src/app/ss_blumen_lumen/blumen_lumen.cpp index 803d86d..d596bfc 100644 --- a/src/app/ss_blumen_lumen/blumen_lumen.cpp +++ b/src/app/ss_blumen_lumen/blumen_lumen.cpp @@ -5,6 +5,29 @@ // #ifndef BLUMEN_LUMEN_CPP +internal animation_handle_array +LoadAllAnimationsInDir(gs_const_string Path, blumen_lumen_state* BLState, app_state* State, context Context) +{ + animation_handle_array Result = {}; + + gs_thread_context Ctx = Context.ThreadContext; + gs_file_info_array FilesInDir = EnumerateDirectory(Ctx.FileHandler, State->Transient, Path, 0); + + Result.Count = FilesInDir.Count; + Result.Handles = PushArray(&State->Permanent, animation_handle, Result.Count); + + for (u32 i = 0; i < FilesInDir.Count; i++) + { + gs_file_info File = FilesInDir.Values[i]; + Result.Handles[i] = AnimationSystem_LoadAnimationFromFile(&State->AnimationSystem, + State->Patterns, + Context, + File.Path); + } + + return Result; +} + internal s32 GetCCIndex (assembly Assembly, blumen_lumen_state* BLState) { @@ -265,13 +288,17 @@ BlumenLumen_CustomInit(app_state* State, context Context) State->AnimationSystem.ActiveFadeGroup.From = BLState->AnimHandles[2]; } // End Animation Playground -#else +#elif 0 animation_handle DemoPatternsAnim = AnimationSystem_LoadAnimationFromFile(&State->AnimationSystem, State->Patterns, Context, ConstString("data/demo_patterns.foldanim")); - State->AnimationSystem.ActiveFadeGroup.From = DemoPatternsAnim; +#else + BLState->ModeAnimations[BlumenPattern_Standard] = LoadAllAnimationsInDir(AmbientPatternFolder, BLState, State, Context); + BLState->ModeAnimations[BlumenPattern_VoiceCommand] = LoadAllAnimationsInDir(VoicePatternFolder, BLState, State, Context); + + State->AnimationSystem.ActiveFadeGroup.From = BLState->ModeAnimations[BlumenPattern_Standard].Handles[0]; #endif State->AnimationSystem.TimelineShouldAdvance = true; @@ -301,8 +328,26 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) phrase_hue NewHue = PhraseHueMap_Get(BLState->PhraseHueMap, NameHash); if (NewHue.PhraseHash != 0) { - u32 AssemblyIdx = BLState->LastAssemblyColorSet; - BLState->AssemblyColors[AssemblyIdx] = NewHue; + if (BLState->PatternMode == BlumenPattern_Standard) + { + BLState->AssemblyColors[0] = NewHue; + BLState->AssemblyColors[1] = NewHue; + BLState->AssemblyColors[2] = NewHue; + + animation_handle NewAnim = BLState->ModeAnimations[BlumenPattern_VoiceCommand].Handles[0]; + AnimationFadeGroup_FadeTo(&State->AnimationSystem.ActiveFadeGroup, + NewAnim, + VoiceCommandFadeDuration); + } + else + { + u32 AssemblyIdx = BLState->LastAssemblyColorSet; + BLState->AssemblyColors[AssemblyIdx] = NewHue; + } + + BLState->PatternMode = BlumenPattern_VoiceCommand; + // TODO(PS): get current time so we can fade back after + // a while } }break; @@ -457,9 +502,12 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) Packet.StatusPacket.NextEventTime = 0; animation* ActiveAnim = AnimationSystem_GetActiveAnimation(&State->AnimationSystem); - CopyMemoryTo(ActiveAnim->Name.Str, Packet.StatusPacket.AnimFileName, - Min(ActiveAnim->Name.Length, 32)); - Packet.StatusPacket.AnimFileName[ActiveAnim->Name.Length] = 0; + if (ActiveAnim) + { + CopyMemoryTo(ActiveAnim->Name.Str, Packet.StatusPacket.AnimFileName, + Min(ActiveAnim->Name.Length, 32)); + Packet.StatusPacket.AnimFileName[ActiveAnim->Name.Length] = 0; + } gs_data Msg = StructToData(&Packet, blumen_packet); MessageQueue_Write(&BLState->OutgoingMsgQueue, Msg); diff --git a/src/app/ss_blumen_lumen/blumen_lumen.h b/src/app/ss_blumen_lumen/blumen_lumen.h index 57666dd..1624a75 100644 --- a/src/app/ss_blumen_lumen/blumen_lumen.h +++ b/src/app/ss_blumen_lumen/blumen_lumen.h @@ -7,6 +7,14 @@ #include "message_queue.h" +enum bl_pattern_mode +{ + BlumenPattern_Standard, + BlumenPattern_VoiceCommand, + + BlumenPattern_Count, +}; + enum bl_python_packet_type { PacketType_Invalid = 0, @@ -122,24 +130,6 @@ SystemTimeIsInTimeRange(system_time SysTime, time_range Range) return Result; } - -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]); - #include "blumen_lumen_settings.h" struct blumen_lumen_state @@ -179,6 +169,10 @@ struct blumen_lumen_state u32 AssemblyNameToClearCoreMapCount; u64* AssemblyNameToClearCore_Names; + bl_pattern_mode PatternMode; + animation_handle_array ModeAnimations[BlumenPattern_Count]; + u32 CurrentAnimation; + phrase_hue_map PhraseHueMap; // Debug diff --git a/src/app/ss_blumen_lumen/blumen_lumen_settings.h b/src/app/ss_blumen_lumen/blumen_lumen_settings.h index 4657663..c254555 100644 --- a/src/app/ss_blumen_lumen/blumen_lumen_settings.h +++ b/src/app/ss_blumen_lumen/blumen_lumen_settings.h @@ -10,6 +10,9 @@ gs_const_string Flower2AssemblyPath = ConstString("data/ss_blumen_three.fold"); gs_const_string PhraseMapCSVPath = ConstString("data/flower_codes.csv"); char PhraseMapCSVSeparator = ','; +gs_const_string AmbientPatternFolder = ConstString("data/blumen_animations/ambient_patterns/*.foldanim"); +gs_const_string VoicePatternFolder = ConstString("data/blumen_animations/audio_responses/*.foldanim"); + global time_range MotorOpenTimes[] = { { 00, 30, 00, 40 }, { 00, 50, 01, 00 }, @@ -58,4 +61,6 @@ global time_range MotorOpenTimes[] = { }; global u32 MotorOpenTimesCount = CArrayLength(MotorOpenTimes); +r32 VoiceCommandFadeDuration = 1.0f; // in seconds + #endif //BLUMEN_LUMEN_SETTINGS_H