From b9d111d0136f32d1c43b12eb6e5595fcead9c025 Mon Sep 17 00:00:00 2001 From: Fox Caminiti Date: Tue, 7 Feb 2023 17:48:15 -0500 Subject: viewport improvements --- src/createcalls.cpp | 89 +++++++++++++++++++++++++++++++-------- src/imgui_ui.cpp | 6 +-- src/imgui_ui_stable_diffusion.cpp | 2 +- src/imgui_ui_timeline.cpp | 39 ++++++++--------- src/imgui_ui_viewport.cpp | 44 +++++++++++++------ src/include/all.h | 8 ++-- src/include/layer.h | 2 +- src/include/main.h | 5 +++ src/layer.cpp | 68 ++++++++++++++++++++++++------ src/main.cpp | 59 +++++++++++++++++++------- src/prenderer.cpp | 14 +++--- src/sorted.cpp | 6 +-- 12 files changed, 245 insertions(+), 97 deletions(-) diff --git a/src/createcalls.cpp b/src/createcalls.cpp index 4761a94..bf9eea2 100644 --- a/src/createcalls.cpp +++ b/src/createcalls.cpp @@ -207,7 +207,7 @@ Property_InitFloat(real32 Val, real32 ScrubVal, real32 MinVal, real32 MaxVal, bo } static block_composition * -Precomp_Init(project_data *File, memory *Memory) +Precomp_Init(project_data *File, memory *Memory, block_composition *DupeComp) { if (File->Comp_Count + 1 > MAX_COMPS) { Assert(0); @@ -215,7 +215,11 @@ Precomp_Init(project_data *File, memory *Memory) block_composition *Comp = (block_composition *)Memory_Block_AllocateAddress(Memory, F_Precomps); History_Action_Block_Swap(Memory, F_Precomps, Comp); - *Comp = {}; + if (DupeComp) { + *Comp = *DupeComp; + } else { + *Comp = {}; + } Comp->Occupied = 1; Comp->Name_String_Index = Memory_Block_AllocateNew(Memory, F_Strings); @@ -262,7 +266,7 @@ Effect_Add(project_data *File, project_state *State, memory *Memory, uint32 Effe while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - if (Layer->IsSelected) { + if (Layer->IsSelected & 0x01) { Layer->Block_Effect_Index[Layer->Block_Effect_Count] = Effect_Init(State, Memory, EffectEntryIndex, Layer->Block_Effect_Count); History_Action_Swap(Memory, F_Layers, sizeof(Layer->Block_Effect_Count), &Layer->Block_Effect_Count); Layer->Block_Effect_Count++; @@ -293,7 +297,7 @@ Keyframe_Commit(project_data *File, project_state *State, memory *Memory, while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); sorted_layer_array *SortedLayerStart = Sorted_GetLayerStart(SortedLayerArray, SortedCompArray, Layer->Block_Composition_Index); - if ((State->TimelineMode == timeline_mode_graph) && !Layer->IsSelected) + if ((State->TimelineMode == timeline_mode_graph) && !(Layer->IsSelected & 0x01)) continue; sorted_property_array *InfoLocation = SortedPropertyStart + SortedLayerStart->SortedPropertyStart; uint16 *ArrayLocation = SortedKeyframeArray + SortedLayerStart->SortedKeyframeStart; @@ -360,7 +364,7 @@ void Clipboard_Paste(project_data *File, project_state *State, memory *Memory, s sorted_layer_array SortEntry = SortedLayerStart[i]; uint32 Index_Physical = SortEntry.Block_Layer_Index; block_layer *TestLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - if (TestLayer->IsSelected) { + if (TestLayer->IsSelected & 0x01) { Layer = TestLayer; break; } @@ -414,7 +418,7 @@ void Clipboard_Store(project_data *File, project_state *State, memory *Memory, s block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); for (int h = 0; h < AmountOf(Layer->Property); h++) { property_channel *Property = &Layer->Property[h]; - if (Property->IsToggled || Layer->IsSelected) { + if (Property->IsToggled || (Layer->IsSelected & 0x01)) { sorted_property_array *InfoLocation = Property_GetSortedInfo(SortedPropertyStart, i, h); uint16 *ArrayLocation = Property_GetSortedArray(SortedKeyframeArray, i, h); clipboard_channel *Channel = &Contents->Channel[Contents->ChannelCount]; @@ -459,7 +463,7 @@ void Slide_Init(project_data *File, project_state *State, memory *Memory) int h = 0, c = 0, i = 0; while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - if (Layer->IsSelected) { + if (Layer->IsSelected & 0x01) { interact_slide_layer *Interact_Layer = (interact_slide_layer *)InteractBuffer; *Interact_Layer = {0}; Interact_Layer->Index = i; @@ -591,7 +595,7 @@ Layer_Nudge(project_data *File, project_state *State, memory *Memory, // NOTE(fox): Some data on the tree could be saved here. History_Action_Swap(Memory, F_Layers, sizeof(Layer->Vertical_Offset), &Layer->Vertical_Offset); Layer->Vertical_Offset = SortEntry.SortedOffset; - if (Layer->IsSelected) { + if (Layer->IsSelected & 0x01) { History_Action_Swap(Memory, F_Layers, sizeof(Layer->Frame_Offset), &Layer->Frame_Offset); Interact_Evaluate_Layer(Memory, State, Index_Physical, SortedCompStart, SortedLayerStart, &Layer->Frame_Start, &Layer->Frame_End, &Layer->Frame_Offset); } @@ -628,7 +632,7 @@ void File_DeselectAllKeyframes(project_data *File, project_state *State, memory int h = 0, c = 0, i = 0; while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - if (!Layer->IsSelected) + if (!(Layer->IsSelected & 0x01)) continue; sorted_layer_array *SortedLayerStart = Sorted_GetLayerStart(SortedLayerArray, SortedCompArray, Layer->Block_Composition_Index); sorted_property_array *InfoLocation = SortedPropertyStart + SortedLayerStart->SortedPropertyStart; @@ -656,7 +660,7 @@ Project_Layer_Delete(project_data *File, project_state *State, memory *Memory) int LayerCount = File->Layer_Count; while (Block_Loop(Memory, F_Layers, LayerCount, &h, &c, &i)) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - if (Layer->IsSelected == 1) { + if (Layer->IsSelected & 0x01) { if (!CommitAction) { History_Entry_Commit(Memory, "Delete layer"); CommitAction = 1; @@ -707,6 +711,55 @@ SortUnionTest(memory *Memory, sorted_layer_array *SortedLayerStart, block_layer } } +// NOTE(fox): PrecompLayer is assumed to be untouched from the layer it was duplicated from! +static uint16 +Layer_Precomp_CopyContents(project_data *File, project_state *State, memory *Memory, block_layer *PrecompLayer, + sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray) +{ + Assert(PrecompLayer->IsPrecomp); + int CompIndex = PrecompLayer->Block_Source_Index; + sorted_comp_array SortedCompStart = SortedCompArray[CompIndex]; + sorted_layer_array *SortedLayerStart = Sorted_GetLayerStart(SortedLayerArray, SortedCompArray, CompIndex); + int LayerCount = SortedCompStart.LayerCount; + Assert(SortedCompStart.FakeLayerCount == 0); + + block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, CompIndex); + block_composition *NewPrecomp = Precomp_Init(File, Memory, Comp); + uint16 NewCompIndex = Memory_Block_LazyIndexAtAddress(Memory, F_Precomps, NewPrecomp); + + for (int i = 0; i < LayerCount; i++) + { + sorted_layer_array SortEntry = SortedLayerStart[i]; + uint32 Index_Physical = SortEntry.Block_Layer_Index; + block_layer *NewLayer = NULL; + { + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); + Assert(!(Layer->IsSelected & 0x01)); + NewLayer = (block_layer *)Memory_Block_AllocateAddress(Memory, F_Layers); + History_Action_Block_Swap(Memory, F_Layers, NewLayer); + *NewLayer = *Layer; + } + + NewLayer->Block_Composition_Index = NewCompIndex; + + // TODO(fox): Effect duplication + Assert(NewLayer->Block_Effect_Count == 0); + + block_string *OldString = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, NewLayer->Block_String_Index); + + NewLayer->Block_String_Index = Memory_Block_AllocateNew(Memory, F_Strings); + block_string *String = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, NewLayer->Block_String_Index, 0); + sprintf(String->Char, "%s", OldString->Char); + History_Action_Swap(Memory, F_Strings, sizeof(String->Occupied), &String->Occupied); + String->Occupied = 1; + + History_Action_Swap(Memory, F_File, sizeof(File->Layer_Count), &File->Layer_Count); + File->Layer_Count++; + } + + return NewCompIndex; +} + static void Project_Layer_Duplicate(project_data *File, project_state *State, memory *Memory, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, v2 Offset, bool32 FakeOnly, bool32 NewPrecomp) @@ -720,19 +773,20 @@ Project_Layer_Duplicate(project_data *File, project_state *State, memory *Memory sorted_layer_array SortEntry = SortedLayerStart[i]; uint32 Index_Physical = SortEntry.Block_Layer_Index; block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); - if ((FakeOnly && SortEntry.IsFake) || (!FakeOnly && Layer->IsSelected == 1)) + if ((FakeOnly && SortEntry.IsFake) || (!FakeOnly && (Layer->IsSelected & 0x01))) { if (!FakeOnly) - Layer->IsSelected = false; + Layer->IsSelected = 0x00; block_layer *NewLayer = (block_layer *)Memory_Block_AllocateAddress(Memory, F_Layers); History_Action_Block_Swap(Memory, F_Layers, NewLayer); *NewLayer = *Layer; if (NewPrecomp && Layer->IsPrecomp) { - NewLayer->Block_Source_Index = Layer_Precomp_CopyContents(); + NewLayer->Block_Source_Index = Layer_Precomp_CopyContents(File, State, Memory, NewLayer, SortedCompArray, SortedLayerArray); } + // TODO(fox): Effect duplication Assert(Layer->Block_Effect_Count == 0); Layer_Select(Memory, State, Memory_Block_LazyIndexAtAddress(Memory, F_Layers, NewLayer)); @@ -755,7 +809,7 @@ Project_Layer_Duplicate(project_data *File, project_state *State, memory *Memory File->Layer_Count++; } else { - Layer->IsSelected = false; + Layer->IsSelected = 0x00; } } } @@ -790,6 +844,7 @@ Project_ShapeLayer_New(project_data *File, project_state *State, memory *Memory) if (State->MostRecentlySelectedLayer == -1) { Layer->Block_Composition_Index = File->PrincipalCompIndex; } else { + // TODO(fox): Allow shapes to be drawn inside selected precomps? // LayerIterate_DeepestPrecomp(State, Memory, CompIndex, ExtraT, Center, // SortedCompArray, SortedLayerArray, SelectionCount, SelectedLayerIndex, SelectedPrecompIndex) } @@ -932,7 +987,7 @@ void Precomp_UIDelete(project_data *File, project_state *State, memory *Memory, sorted_layer_array SortEntry = SortedLayerStart[i]; uint32 Index_Physical = SortEntry.Block_Layer_Index; Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); - if (Layer->IsSelected) { + if (Layer->IsSelected & 0x01) { } } } @@ -956,7 +1011,7 @@ void Precomp_UICreateButton(project_data *File, project_state *State, memory *Me sorted_layer_array SortEntry = SortedLayerStart[i]; uint32 Index_Physical = SortEntry.Block_Layer_Index; block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); - if (Layer->IsSelected) { + if (Layer->IsSelected & 0x01) { TopOffset = Layer->Vertical_Offset; break; } @@ -966,7 +1021,7 @@ void Precomp_UICreateButton(project_data *File, project_state *State, memory *Me sorted_layer_array SortEntry = SortedLayerStart[i]; uint32 Index_Physical = SortEntry.Block_Layer_Index; block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); - if (Layer->IsSelected) { + if (Layer->IsSelected & 0x01) { History_Action_Swap(Memory, F_Layers, sizeof(Layer->Block_Composition_Index), &Layer->Block_Composition_Index); Layer->Block_Composition_Index = File->Comp_Count - 1; } diff --git a/src/imgui_ui.cpp b/src/imgui_ui.cpp index a07854e..84e2b91 100644 --- a/src/imgui_ui.cpp +++ b/src/imgui_ui.cpp @@ -385,7 +385,7 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me int h = 0, c = 0, i = 0; while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - if (Layer->IsSelected) { + if (Layer->IsSelected & 0x01) { Layer_ToggleAllChannels(State, Memory, Layer, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyStart, Sorted.PropertyArray); } } @@ -407,7 +407,7 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me int h = 0, c = 0, i = 0; while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - if (Layer->IsSelected && Layer->IsShapeLayer) { + if ((Layer->IsSelected & 0x01) && Layer->IsShapeLayer) { if (!CommitAction) { History_Entry_Commit(Memory, "Swap shape colors"); CommitAction = 1; @@ -551,7 +551,7 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me int h = 0, c = 0, i = 0; while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - if ((Layer->IsSelected == 1) && Layer->IsPrecomp) { + if ((Layer->IsSelected & 0x01) && Layer->IsPrecomp) { Layer->Precomp_Toggled ^= 1; } } diff --git a/src/imgui_ui_stable_diffusion.cpp b/src/imgui_ui_stable_diffusion.cpp index 9f2963a..6febdf3 100644 --- a/src/imgui_ui_stable_diffusion.cpp +++ b/src/imgui_ui_stable_diffusion.cpp @@ -98,7 +98,7 @@ ImGui_SD_Prompt(project_data *File, project_state *State, ui *UI, memory *Memory sorted_layer_array SortEntry = SortedLayerStart[i]; uint32 Index_Physical = SortEntry.Block_Layer_Index; block_layer *TestLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); - if (TestLayer->IsSelected) { + if (TestLayer->IsSelected & 0x01) { Layer = TestLayer; break; } diff --git a/src/imgui_ui_timeline.cpp b/src/imgui_ui_timeline.cpp index f8c5258..aa4d0cd 100644 --- a/src/imgui_ui_timeline.cpp +++ b/src/imgui_ui_timeline.cpp @@ -114,7 +114,7 @@ ImGui_Timeline_GraphInfo(project_data *File, project_state *State, memory *Memor while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - if (!Layer->IsSelected) + if (!(Layer->IsSelected & 0x01)) continue; block_string *String = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, Layer->Block_String_Index); @@ -243,7 +243,7 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor for (int i = 0; i < SortedCompStart.LayerCount; i++) { sorted_layer_array *SortedLayer = &SortedLayerStart[i]; block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, SortedLayer->Block_Layer_Index); - if (!Layer->IsSelected) + if (!(Layer->IsSelected & 0x01)) continue; int32 Frame_Offset = Layer->Frame_Offset; @@ -442,7 +442,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem int32 Frame_Offset = Layer->Frame_Offset; real32 Vertical_Offset = SortEntry.SortedOffset + SortEntry.DisplayOffset; - if (Layer->IsSelected) + if (Layer->IsSelected & 0x01) Interact_Evaluate_Layer(Memory, State, Index_Physical, SortedCompStart, SortedLayerStart, &Frame_Start, &Frame_End, &Frame_Offset); ImVec2 Layer_LocalPos = ImVec2(Frame_Start + Frame_Offset, Vertical_Offset); @@ -483,10 +483,10 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem draw_list->AddText(ImVec2(TextX, Layer_ScreenPos_Min.y), 0xFFFFFFFF, buf); } - if (Layer->IsSelected == 1) { + if (Layer->IsSelected & 0x01) { draw_list->AddRectFilled(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(0.25f, 0.25f, 0.25f, 0.5f), 2); draw_list->AddRect(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(1.0f, 1.0f, 1.0f, 0.5f), 2); - } else if (Layer->IsSelected == 2) { + } else if (Layer->IsSelected & 0x02) { // draw_list->AddRectFilled(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(0.25f, 0.25f, 0.25f, 0.5f), 2); draw_list->AddRect(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(0.0f, 0.9f, 0.0f, 0.9f), 4); } @@ -511,11 +511,11 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem Test &= (Layer_ScreenPos_Min.x <= io.MouseClickedPos[0].x && Layer_ScreenPos_Max.x >= io.MousePos.x); if (Test) { - if (!Layer->IsSelected && !Layer->IsLocked) { + if (!(Layer->IsSelected & 0x01) && !(Layer->IsSelected & 0x02) && !Layer->IsLocked) { Layer_Select(Memory, State, Index_Physical); } } else if (!io.KeyShift) { - Layer->IsSelected = false; + Layer->IsSelected = 0x00; } } @@ -535,14 +535,14 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem } } if (ImGui::IsItemActivated()) { - if (!Layer->IsSelected && !Layer->IsLocked) { + if (!(Layer->IsSelected & 0x01) && !Layer->IsLocked) { if (!io.KeyShift) Layer_DeselectAll(File, State, Memory); Layer_Select(Memory, State, Index_Physical); } } if (ImGui::IsItemActive()) { if (ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) { - Assert(Layer->IsSelected); + Assert(Layer->IsSelected & 0x01); State->Interact_Active = interact_type_layer_timeadjust; ImVec2 DragDelta = ImGui::GetMouseDragDelta(); DragDelta = DragDelta + (ImVec2(State->Warp_X, State->Warp_Y) * TimelineSize); @@ -557,7 +557,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem int h = 0, c = 0, i = 0; while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - if (Layer->IsSelected) { + if (Layer->IsSelected & 0x01) { // NOTE(fox): Some data on the tree could be saved here. History_Action_Swap(Memory, F_Layers, sizeof(Layer->Frame_Start), &Layer->Frame_Start); History_Action_Swap(Memory, F_Layers, sizeof(Layer->Frame_End), &Layer->Frame_End); @@ -585,7 +585,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem } if (ImGui::IsItemActivated()) { - if (!Layer->IsSelected && !Layer->IsLocked) { + if (!(Layer->IsSelected & 0x01) && !Layer->IsLocked) { if (!io.KeyShift) Layer_DeselectAll(File, State, Memory); Layer_Select(Memory, State, Index_Physical); Layer_Select_RecurseUp(Memory, State, Index_Physical, RecursionIdx, Recursions); @@ -599,7 +599,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem int h = 0, z = 0, i = 0; while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &z, &i)) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - if (Layer->IsSelected) { + if (Layer->IsSelected & 0x01) { if (!Commit) { History_Entry_Commit(Memory, "Toggle visibility"); Commit = true; @@ -617,14 +617,14 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem bool32 Commit = false; int h = 0, z = 0, i = 0; while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &z, &i)) { - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - if (Layer->IsSelected == 1 || Layer->IsLocked) { + block_layer *CurLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); + if ((CurLayer->IsSelected & 0x01) || (Layer == CurLayer)) { if (!Commit) { History_Entry_Commit(Memory, "Toggle lock"); Commit = true; } - History_Action_Swap(Memory, F_Layers, sizeof(Layer->IsLocked), &Layer->IsLocked); - Layer->IsLocked ^= 1; + History_Action_Swap(Memory, F_Layers, sizeof(CurLayer->IsLocked), &CurLayer->IsLocked); + CurLayer->IsLocked ^= 1; } } if (Commit) { @@ -655,7 +655,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem int h = 0, z = 0, i = 0; while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &z, &i)) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - if (Layer->IsSelected == 1) { + if (Layer->IsSelected & 0x01) { Layer->ColIndex = c; } } @@ -726,7 +726,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem // NOTE(fox): Some data on the tree could be saved here. History_Action_Swap(Memory, F_Layers, sizeof(Layer->Vertical_Offset), &Layer->Vertical_Offset); Layer->Vertical_Offset = SortEntry.SortedOffset; - if (Layer->IsSelected) { + if (Layer->IsSelected & 0x01) { History_Action_Swap(Memory, F_Layers, sizeof(Layer->Frame_Offset), &Layer->Frame_Offset); Interact_Evaluate_Layer(Memory, State, Index_Physical, SortedCompStart, SortedLayerStart, &Layer->Frame_Start, &Layer->Frame_End, &Layer->Frame_Offset); } @@ -1087,7 +1087,8 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, if (LeftClick) { if (IsItemActivated) { - if (!io.KeyShift && State->TimelineMode == timeline_mode_default) Layer_DeselectAll(File, State, Memory); + if (!io.KeyShift && State->TimelineMode == timeline_mode_default) + Layer_DeselectAll(File, State, Memory); if (State->Interact_Active == interact_type_keyframe_move || State->Interact_Active == interact_type_keyframe_rotate || State->Interact_Active == interact_type_keyframe_scale) { diff --git a/src/imgui_ui_viewport.cpp b/src/imgui_ui_viewport.cpp index 2489cd5..ed26ce7 100644 --- a/src/imgui_ui_viewport.cpp +++ b/src/imgui_ui_viewport.cpp @@ -394,7 +394,11 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me real32 U = LayerPoint.x / BoxLength.x; real32 V = LayerPoint.y / BoxLength.y; + ImVec2 BoxScreenDimensions = IV2(BoxLength)*CompScale; + real32 HandleSize = ImGui::GetFontSize() * 2; + if (BoxScreenDimensions.x < (HandleSize*2) || BoxScreenDimensions.y < (HandleSize*2)) + HandleSize *= 0.5; ImVec2 ScaleHandleSize(HandleSize, HandleSize); bool32 OtherActions = ImGui::IsKeyDown(ImGuiKey_Z); @@ -669,7 +673,7 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me Assert(State->Tool == tool_default); if (!io.KeyShift) { - Layer_DeselectAll(File, State, Memory); + Layer_DeselectAll(File, State, Memory, 1); State->Interact_Transform = {}; } if (Selection != -1) @@ -928,7 +932,7 @@ ImGui_Viewport_TransformUI(project_data *File, project_state *State, memory *Mem History_Entry_Commit(Memory, "Transform layers"); while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - if (Layer->IsSelected == 1) { + if (Layer->IsSelected & 0x01) { // if (io.KeyCtrl) { // layer_transforms T = Layer_GetTransforms(Layer); // Transform_ApplyInteractive(*(interact_transform *)&State->Interact_Offset[0], &T.x, &T.y, &T.rotation, &T.scale); @@ -987,7 +991,7 @@ ImGui_Viewport_SelectedLayerUI(project_state *State, memory *Memory, ui *UI, ImG } ImGui_Viewport_SelectedLayerUI(State, Memory, UI, io, draw_list, MainComp, Layer->Block_Source_Index, NewExtraT, PointCount, PointData, SortedCompArray, SortedLayerArray); } - if (Layer->IsSelected == 1) { + if (Layer->IsSelected & 0x01) { uint32 Width = 0, Height = 0; void *Data; uint32 NumberOfVerts; @@ -1017,11 +1021,11 @@ ImGui_Viewport_SelectedLayerUI(project_state *State, memory *Memory, ui *UI, ImG layer_transforms T = Layer_GetTransforms(Layer); if ((State->Interact_Active == interact_type_viewport_transform || - State->Interact_Active == interact_type_viewport_transform_gizmo) && Layer->IsSelected == 1) { + State->Interact_Active == interact_type_viewport_transform_gizmo) && Layer->IsSelected & 0x01) { Transform_ApplyInteractive(State->Interact_Transform, &T.x, &T.y, &T.rotation, &T.scale); } if (State->Interact_Active == interact_type_viewport_duplicate && SortEntry.IsFake) { - Assert(Layer->IsSelected); + Assert(Layer->IsSelected & 0x01); T.x += State->Interact_Offset[0]; T.y += State->Interact_Offset[1]; } @@ -1226,7 +1230,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); if (!Layer->IsPrecomp) { block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index); - if (Layer->IsSelected && Source->Type == source_type_principal) { + if ((Layer->IsSelected & 0x01) && Source->Type == source_type_principal) { Assert(Source->BytesPerPixel == 4); Arbitrary_Zero((uint8 *)State->Brush.TransientBitmap, 2048*2048*4); State->Interact_Active = interact_type_brush; @@ -1263,7 +1267,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, if (BoxMax.x - BoxMin.x > 0.1f && BoxMax.y - BoxMin.y > 0.1f) { Assert(BoxMax.x > BoxMin.x && BoxMax.y > BoxMin.y) - BoxMax.y = (MousePos.y > ClickedPos.y) ? MousePos.y : ClickedPos.y; + if (io.MouseDelta.x || io.MouseDelta.y) { if (State->Tool == tool_default && State->Interact_Active == interact_type_none) { layer_transforms T = {}; @@ -1271,22 +1275,26 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, v2 CompPoint = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, io.MousePos) * V2(MainComp->Width, MainComp->Height); int32 Selection = LayerIterate_TestSelection(State, Memory, File->PrincipalCompIndex, T, CompPoint, SortedCompArray, SortedLayerArray, io.KeyShift); - if (!State->InteractTransformMode && Selection != -1) { - if (!io.KeyShift) - Layer_DeselectAll(File, State, Memory); + if (!io.KeyShift && !State->InteractTransformMode && Selection != -1) { + Layer_DeselectAll(File, State, Memory); Layer_Select(Memory, State, Selection); State->Interact_Active = interact_type_viewport_transform_gizmo; State->Interact_OutOfDrag = true; State->InteractTransformMode = 3; } else { State->Interact_Active = interact_type_viewport_selection; + if (io.KeyShift) { + Interact_BoxSelect_Start(File, State, Memory); + } } } if (State->Interact_Active == interact_type_viewport_selection) { - Layer_DeselectAll(File, State, Memory); + Layer_DeselectAll(File, State, Memory, 1); v2 MinPos_Comp = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, BoxMin) * V2(MainComp->Width, MainComp->Height); v2 MaxPos_Comp = ImGui_ScreenPointToCompUV(ViewportMax, UI->CompPos, UI->CompZoom, BoxMax) * V2(MainComp->Width, MainComp->Height); - Layer_TestBoxSelect(Memory, State, UI, SortedCompArray, SortedLayerArray, File->PrincipalCompIndex, MinPos_Comp, MaxPos_Comp); + layer_transforms T = {}; + T.scale = 1.0f; + Layer_TestBoxSelect(Memory, State, UI, SortedCompArray, SortedLayerArray, File->PrincipalCompIndex, T, MinPos_Comp, MaxPos_Comp); } } if (State->Interact_Active == interact_type_viewport_selection) { @@ -1326,6 +1334,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, } if (IsDeactivated && State->Interact_Active == interact_type_viewport_selection) { + Interact_BoxSelect_End(File, State, Memory); State->Interact_Active = interact_type_none; } @@ -1465,8 +1474,15 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, real32 Distance = 0; if (IsActive) { - if (ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1.0f)) + if (ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1.0f)) { + real32 MouseVecLength = Length(io.MousePos - io.MouseClickedPos[0]); + real32 MouseMaxLength = ViewportScale.x; Distance = io.MouseDelta.x + io.MouseDelta.y; + real32 Multiplier = -log(1.0f - (MouseVecLength / MouseMaxLength)); + if (isnan(Multiplier)) + Multiplier = 0.0f; + Distance = Distance + (Distance * Multiplier); + } if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) Distance = 200; } @@ -1494,7 +1510,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, State->Interact_Active = interact_type_none; State->Interact_Modifier = 0; v2 Offset = V2(State->Interact_Offset[0], State->Interact_Offset[1]); - Project_Layer_Duplicate(File, State, Memory, SortedCompArray, SortedLayerArray, Offset, 1); + Project_Layer_Duplicate(File, State, Memory, SortedCompArray, SortedLayerArray, Offset, 1, io.KeyCtrl); State->Interact_Dup_Previous[0] = State->Interact_Offset[0]; State->Interact_Dup_Previous[1] = State->Interact_Offset[1]; State->Interact_Offset[0] = 0; diff --git a/src/include/all.h b/src/include/all.h index 82731ff..cdd14a8 100644 --- a/src/include/all.h +++ b/src/include/all.h @@ -77,7 +77,7 @@ static void Property_AddKeyframe(memory *Memory, memory_table_list TableName, property_channel *Property, int Frame, uint16 *ArrayLocation); static block_composition * -Precomp_Init(project_data *File, memory *Memory); +Precomp_Init(project_data *File, memory *Memory, block_composition *DupeComp = NULL); static uint32 Effect_Init(project_state *State, memory *Memory, uint32 EffectEntryIndex, int EffectCount); @@ -123,7 +123,7 @@ Property_IsGraphSelected(memory *Memory, property_channel *Property, uint16 *Arr static void Project_Layer_Duplicate(project_data *File, project_state *State, memory *Memory, - sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, v2 Offset, bool32 FakeOnly); + sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, v2 Offset, bool32 FakeOnly, bool32 NewPrecomp); static void Project_ShapeLayer_New(project_data *File, project_state *State, memory *Memory); @@ -222,7 +222,7 @@ static bool32 ImGui_TestBoxSelection_Point(ImVec2 Pos, ImGuiIO &io, bool32 *Test static void Layer_TestBoxSelect(memory *Memory, project_state *State, ui *UI, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, - uint16 PrincipalIndex, v2 MinPos, v2 MaxPos); + uint16 PrincipalIndex, layer_transforms ExtraT, v2 MinPos, v2 MaxPos); void AV_IsFileSupported(char *filename, bool32 *IsVideo, bool32 *HasAudio); @@ -376,7 +376,7 @@ Interact_Transform_Begin(project_data *File, memory *Memory, project_state *Stat static void Layer_RecursiveDeselect(memory *Memory, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 TargetIndex, uint16 PrincipalIndex); -static void +static bool32 Main_InputTest(project_data *File, project_state *State, memory *Memory, sorted_file Sorted, ui *UI, SDL_Window *window, GLuint textureID); static void diff --git a/src/include/layer.h b/src/include/layer.h index d354c89..074a274 100644 --- a/src/include/layer.h +++ b/src/include/layer.h @@ -24,7 +24,7 @@ static void Layer_Select_RecurseUp(memory *Memory, project_state *State, int32 i, int16 RecursionIdx[MAX_PRECOMP_RECURSIONS], uint32 Recursions); static void -Layer_DeselectAll(project_data *File, project_state *State, memory *Memory); +Layer_DeselectAll(project_data *File, project_state *State, memory *Memory, bool32 AllowComp = 0); static bool32 Layer_LoopChannels(project_state *State, memory *Memory, sorted_property_array **SortedProperty, uint16 **SortedKeyframe, block_layer *Layer, diff --git a/src/include/main.h b/src/include/main.h index 0ee8511..9c1da89 100644 --- a/src/include/main.h +++ b/src/include/main.h @@ -465,6 +465,7 @@ struct project_state { bool32 UpdateKeyframes = 0; bool32 UpdateFrame = 1; // only refreshes frame; set UpdateKeyframes to update animation + bool32 UpdateScreen = 1; // refreshes entire UI; influenced by raw key/mouse input bool32 DebugDisableCache = 1; // bad @@ -743,6 +744,10 @@ struct block_layer { bool32 IsVisible; bool32 IsLocked; + // Valid values this can be: + // 0x01 - standard select + // 0x02 - precomp layer + // 0x04 - transient box selection state when shift is held bool32 IsSelected; bool32 IsAdjustment; diff --git a/src/layer.cpp b/src/layer.cpp index 4c94987..9a3a0a4 100644 --- a/src/layer.cpp +++ b/src/layer.cpp @@ -182,7 +182,7 @@ Layer_ToggleChannel(project_data *File, memory *Memory, int32 a) while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - if (Layer->IsSelected == 1) + if (Layer->IsSelected & 0x01) Layer->Property[a].IsToggled ^= 1; } } @@ -191,7 +191,8 @@ static void Layer_Select(memory *Memory, project_state *State, int32 i) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - Layer->IsSelected = true; + // Assert(!(Layer->IsSelected & 0x02)); + Layer->IsSelected |= 0x01; State->MostRecentlySelectedLayer = i; State->Interact_Transform = {}; State->RecentSelectionType = selection_type_layer; @@ -202,24 +203,50 @@ Layer_Select_RecurseUp(memory *Memory, project_state *State, int32 i, int16 Recu { for (int a = 1; a <= Recursions; a++) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, RecursionIdx[a]); - Layer->IsSelected = 2; + Layer->IsSelected = 0x02; } } static void -Layer_DeselectAll(project_data *File, project_state *State, memory *Memory) { +Interact_BoxSelect_Start(project_data *File, project_state *State, memory *Memory) { int h = 0, c = 0, i = 0; while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - // stupid way to preserve this - if (Layer->IsSelected == -1) { - Layer->IsSelected = 2; + if (Layer->IsSelected & 0x01) { + Layer->IsSelected |= 0x04; + } + } +} + +static void +Interact_BoxSelect_End(project_data *File, project_state *State, memory *Memory) { + int h = 0, c = 0, i = 0; + while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); + if (Layer->IsSelected & 0x04) { + Layer->IsSelected ^= 0x04; + } + } +} + +static void +Layer_DeselectAll(project_data *File, project_state *State, memory *Memory, bool32 AllowComp) { + int h = 0, c = 0, i = 0; + bool32 ShiftLayers = false; + while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); + if (Layer->IsSelected & 0x04) { + ShiftLayers = 1; } else { - Layer->IsSelected = false; + if (!(AllowComp && Layer->IsSelected & 0x02)) { + Layer->IsSelected = 0x00; + } } } State->Interact_Transform = {}; - State->MostRecentlySelectedLayer = -1; + if (!ShiftLayers) { + State->MostRecentlySelectedLayer = -1; + } } // TODO(fox): This function will be replaced once properties are reworked. @@ -317,7 +344,7 @@ Layer_Select_Traverse(uint16 PrincipalCompIndex, memory *Memory, project_state * sorted_layer_array SortEntry = SortedLayerStart[i]; uint32 Index_Physical = SortEntry.Block_Layer_Index; block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); - if (Layer->IsPrecomp && Layer->IsSelected == 2) { + if (Layer->IsPrecomp && (Layer->IsSelected & 0x02)) { *Recursions = RecursionsCurrent + 1; RecursionIdx[*Recursions] = Index_Physical; Layer_Select_Traverse(PrincipalCompIndex, Memory, State, IndexToFind, SortedCompArray, SortedLayerArray, RecursionIdx, Recursions); @@ -390,7 +417,7 @@ Layer_TestForPoint(memory *Memory, project_state *State, ui *UI, sorted_comp_arr Layer_GetDimensions(Memory, Layer, &Width, &Height); layer_transforms T = Layer_GetTransforms(Layer); v2 UV = T_CompUVToLayerUV(T, Comp->Width, Comp->Height, Width, Height, CompUV); - if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && (Layer->IsSelected || Layer->IsPrecomp) && !Layer->IsLocked) + if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && ((Layer->IsSelected & 0x01) || Layer->IsPrecomp) && !Layer->IsLocked) { return 1; } @@ -512,6 +539,10 @@ Transform_TestBox(block_layer *Layer, uint32 Width, uint32 Height, v2 Min, v2 Ma v2 Pos = {Layer->x.CurrentValue, Layer->y.CurrentValue}; v2 Origin = Pos - (XAxis * AnchorX) - (YAxis * AnchorY); + if (Origin.x > Min.x && Origin.x < Max.x && + Origin.y > Min.y && Origin.y < Max.y) + return true; + real32 XLengthSq = 1.0f / LengthSq(XAxis); real32 YLengthSq = 1.0f / LengthSq(YAxis); @@ -577,7 +608,7 @@ Shape_TestBoxSelect(layer_transforms T, uint32 CompWidth, uint32 CompHeight, uin static void Layer_TestBoxSelect(memory *Memory, project_state *State, ui *UI, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, - uint16 PrincipalIndex, v2 MinPos, v2 MaxPos) + uint16 PrincipalIndex, layer_transforms ExtraT, v2 MinPos, v2 MaxPos) { block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, PrincipalIndex); sorted_comp_array SortedCompStart = SortedCompArray[PrincipalIndex]; @@ -603,6 +634,17 @@ Layer_TestBoxSelect(memory *Memory, project_state *State, ui *UI, sorted_comp_ar } Memory_PopScratch(Memory, sizeof(nvg_point) * 1024); + } else if (Layer->IsPrecomp && (Layer->IsSelected & 0x02)) { + int Width = 0, Height = 0; + Layer_GetDimensions(Memory, Layer, &Width, &Height); + // only like 20% sure how this works... + layer_transforms NewExtraT = Layer_GetTransforms(Layer); + v2 NewMinPos = T_CompPosToLayerPos(NewExtraT, Comp->Width, Comp->Height, Width, Height, MinPos.x, MinPos.y); + v2 NewMaxPos = T_CompPosToLayerPos(NewExtraT, Comp->Width, Comp->Height, Width, Height, MaxPos.x, MaxPos.y); + NewExtraT.rotation = ExtraT.rotation - NewExtraT.rotation; + NewExtraT.scale = ExtraT.scale / NewExtraT.scale; + Layer_TestBoxSelect(Memory, State, UI, SortedCompArray, SortedLayerArray, + Layer->Block_Source_Index, NewExtraT, NewMinPos, NewMaxPos); } else { int Width, Height; Layer_GetDimensions(Memory, Layer, &Width, &Height); @@ -626,7 +668,7 @@ Layer_RecursiveDeselect(memory *Memory, sorted_comp_array *SortedCompArray, sort Layer_RecursiveDeselect(Memory, SortedCompArray, SortedLayerArray, TargetIndex, Layer->Block_Source_Index); } if (Layer->Block_Composition_Index != TargetIndex) { - Layer->IsSelected = false; + Layer->IsSelected = 0x00; } } } diff --git a/src/main.cpp b/src/main.cpp index f8dd546..77a405a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -69,11 +69,14 @@ Main_RenderUI(ImGuiIO io, ImVec4 clear_color, SDL_Window *window) SDL_GL_SwapWindow(window); } -static void +// NOTE(fox): Many state changes require the frame after the input event to be rendered. + +static bool32 Main_InputTest(project_data *File, project_state *State, memory *Memory, sorted_file Sorted, ui *UI, SDL_Window *window, GLuint textureID) { ImGuiIO& io = ImGui::GetIO(); SDL_Event event = {}; + int test = 0; while (SDL_PollEvent(&event)) { ImGui_ImplSDL2_ProcessEvent(&event); @@ -86,8 +89,12 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, sorted_ State->IsRunning = false; if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window)) State->IsRunning = false; + test++; } + if (State->UpdateScreen == 0 && test == 0) + return 0; + if (State->Warp_WantSetPos) { ImGui::GetIO().WantSetMousePos = true; io.MousePos = State->Warp_PositionToSet; @@ -117,7 +124,7 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, sorted_ // we need to delay a bit. if (State->FirstFrame) { ImGui::EndFrame(); - return; + return 2; } #if DEBUG @@ -159,6 +166,12 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, sorted_ Memory_Cache_Purge(File, State, Memory); Memory->PurgeCache = false; } + + if (test) + test += 1; + if (State->UpdateScreen) + test = 0; + return test; } static void @@ -257,7 +270,7 @@ Render_SortKeyframes(project_data *File, project_state *State, memory *Memory, int32 Frame_Start = Layer->Frame_Start; int32 Frame_End = Layer->Frame_End; int32 Frame_Offset = Layer->Frame_Offset; - if (Layer->IsSelected) + if (Layer->IsSelected & 0x01) Interact_Evaluate_Layer(Memory, State, Index_Physical, *SortedCompStart, SortedLayerStart, &Frame_Start, &Frame_End, &Frame_Offset); int32 Frame_Start_Abs = Frame_Start + Frame_Offset; int32 Frame_End_Abs = Frame_End + Frame_Offset; @@ -383,7 +396,7 @@ LayerIterate_DeepestPrecomp(project_state *State, memory *Memory, uint32 CompInd Position = XAxis + YAxis; layer_transforms T = Layer_GetTransforms(Layer); v2 UV = T_CompUVToLayerUV(T, Comp->Width, Comp->Height, Width, Height, Center / V2(Comp->Width, Comp->Height)); - if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && Layer->IsSelected) + if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && (Layer->IsSelected & 0x01)) { *SelectionCount += 1; *SelectedLayerIndex = i; @@ -426,7 +439,7 @@ LayerIterate_SelectionStatus(project_state *State, memory *Memory, uint32 CompIn Position = XAxis + YAxis; layer_transforms T = Layer_GetTransforms(Layer); v2 UV = T_CompUVToLayerUV(T, Comp->Width, Comp->Height, Width, Height, Center / V2(Comp->Width, Comp->Height)); - if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && Layer->IsSelected && !Layer->IsLocked) + if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && (Layer->IsSelected & 0x03) && !Layer->IsLocked) { *SelectionCount += 1; *SelectedLayerIndex = i; @@ -452,7 +465,7 @@ LayerIterate_SelectionAct(project_state *State, memory *Memory, uint32 CompIndex Assert(Layer->Block_Composition_Index == CompIndex); int Width = 0, Height = 0; Layer_GetDimensions(Memory, Layer, &Width, &Height); - if (Layer->IsPrecomp && Layer->IsSelected) { + if (Layer->IsPrecomp && (Layer->IsSelected & 0x03)) { // only like 20% sure how this works... layer_transforms NewExtraT = Layer_GetTransforms(Layer); v2 NewCenter = T_CompPosToLayerPos(NewExtraT, Comp->Width, Comp->Height, Width, Height, Center.x, Center.y); @@ -460,7 +473,7 @@ LayerIterate_SelectionAct(project_state *State, memory *Memory, uint32 CompIndex NewExtraT.scale = ExtraT.scale / NewExtraT.scale; LayerIndex = LayerIterate_SelectionAct(State, Memory, Layer->Block_Source_Index, NewExtraT, NewCenter, SortedCompArray, SortedLayerArray, SelectionCount, SelectedLayerIndex, SelectedPrecompIndex, BelowOnly); if (LayerIndex != -1) { - Layer->IsSelected = -1; + Layer->IsSelected = 0x02; return LayerIndex; } } @@ -471,7 +484,7 @@ LayerIterate_SelectionAct(project_state *State, memory *Memory, uint32 CompIndex Position = XAxis + YAxis; layer_transforms T = Layer_GetTransforms(Layer); v2 UV = T_CompUVToLayerUV(T, Comp->Width, Comp->Height, Width, Height, Center / V2(Comp->Width, Comp->Height)); - if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && !Layer->IsSelected && !Layer->IsLocked) + if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && !(Layer->IsSelected & 0x01) && !Layer->IsLocked) { if (!BelowOnly && SelectionCount == 1) { if (i < SelectedLayerIndex || SelectedPrecompIndex != CompIndex) { @@ -524,7 +537,7 @@ LayerIterate(project_state *State, memory *Memory, uint32 CompIndex, layer_trans NewExtraT.scale = ExtraT.scale / NewExtraT.scale; LayerIterate(State, Memory, Layer->Block_Source_Index, NewExtraT, NewCenter, SortedCompArray, SortedLayerArray); } - if (Layer->IsSelected == 1) { + if (Layer->IsSelected & 0x01) { #if DEBUG if (Layer->IsPrecomp) PostMsg(State, "DEBUG: Precomp transformed!"); @@ -568,7 +581,7 @@ Render_UI(project_data *File, project_state *State, memory *Memory, ui *UI, ImDr int32 Frame_Start = Layer->Frame_Start; int32 Frame_End = Layer->Frame_End; int32 Frame_Offset = Layer->Frame_Offset; - if (Layer->IsSelected) + if (Layer->IsSelected & 0x01) Interact_Evaluate_Layer(Memory, State, Index_Physical, *SortedCompStart, SortedLayerStart, &Frame_Start, &Frame_End, &Frame_Offset); int32 Frame_Start_Abs = Frame_Start + Frame_Offset; int32 Frame_End_Abs = Frame_End + Frame_Offset; @@ -713,7 +726,7 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, sorted_fil int32 Frame_Start = Layer->Frame_Start; int32 Frame_End = Layer->Frame_End; int32 Frame_Offset = Layer->Frame_Offset; - if (Layer->IsSelected) + if (Layer->IsSelected & 0x01) Interact_Evaluate_Layer(Memory, State, Index_Physical, *SortedCompStart, SortedLayerStart, &Frame_Start, &Frame_End, &Frame_Offset); int32 Frame_Start_Abs = Frame_Start + Frame_Offset; int32 Frame_End_Abs = Frame_End + Frame_Offset; @@ -1163,6 +1176,7 @@ int main(int argc, char *argv[]) { State->UpdateFrame = true; State->MostRecentlySelectedLayer = 0; } + File->UI.LayerColors[3] = 0xff203d6a; // File->PrincipalCompIndex = 1; #else // uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/yu.webm"); @@ -1302,7 +1316,13 @@ int main(int argc, char *argv[]) { sorted_file Sorted = File_Sort_Push(File, State, &Memory); - Main_InputTest(File, State, &Memory, Sorted, &File->UI, window, textureID); + if (State->FirstFrame) + State->UpdateScreen = 2; + + // TODO(fox): Do the same thing with the timeline and viewport to + // reduce wasted rendering further; for now I am at least pausing all + // UI when no inputs happen. + State->UpdateScreen += Main_InputTest(File, State, &Memory, Sorted, &File->UI, window, textureID); if (State->IsPlaying) { block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(&Memory, F_Precomps, File->PrincipalCompIndex); @@ -1390,7 +1410,7 @@ int main(int argc, char *argv[]) { } else if (State_ExecuteAtEnd == 2) { History_Entry_Commit(&Memory, "Duplicate layers"); v2 Offset = V2(State->Interact_Dup_Previous[0], State->Interact_Dup_Previous[1]); - Project_Layer_Duplicate(File, State, &Memory, Sorted.CompArray, Sorted.LayerArray, Offset, 0); + Project_Layer_Duplicate(File, State, &Memory, Sorted.CompArray, Sorted.LayerArray, Offset, 0, io.KeyCtrl); State->Interact_Transform = {}; History_Entry_End(&Memory); } @@ -1403,6 +1423,7 @@ int main(int argc, char *argv[]) { // frames, but we'd have to make sure the pop order stays the same in all scenarios. Assert(Debug.ScratchState == 0); + bool32 UpdateScreen = 0; if (State->IsPlaying && State->HotFramePerf > 1 && FullyCached) { uint64 RenderTime = SDL_GetPerformanceCounter() - State->HotFramePerf; real64 FrameMS = (1000.0f * (real64)RenderTime) / (real64)PerfFrequency; @@ -1412,7 +1433,11 @@ int main(int argc, char *argv[]) { Main_RenderUI(io, clear_color, window); State->HotFramePerf = 1; } else { - Main_RenderUI(io, clear_color, window); + if (State->UpdateScreen) { + Main_RenderUI(io, clear_color, window); + State->UpdateScreen--; + UpdateScreen = 1; + } } if (State->HotFramePerf == 1) { @@ -1429,7 +1454,11 @@ int main(int argc, char *argv[]) { uint64 PerfTime = PerfEnd - PerfStart; real64 FrameMS = (1000.0f * (real64)PerfTime) / (real64)PerfFrequency; real64 FPS = PerfFrequency / PerfTime; - // printf("%.02f ms/f, %.02f frames\n", FrameMS, FPS); + if (!UpdateScreen) { + real64 TargetMS = (1000.0f / 60); + if (TargetMS > FrameMS) + SDL_Delay((uint64)(TargetMS - FrameMS)); + } } for (int i = 0; i < 7; i++) { diff --git a/src/prenderer.cpp b/src/prenderer.cpp index 0af9911..5119d55 100644 --- a/src/prenderer.cpp +++ b/src/prenderer.cpp @@ -156,7 +156,7 @@ Transform_Recurse(project_state *State, memory *Memory, block_composition *MainC Transform_Recurse(State, Memory, MainComp, Layer->Block_Source_Index, ParentLayer, Recursions + 1, SortedCompArray, SortedLayerArray, MinX, MinY, MaxX, MaxY); } - if (Layer->IsSelected) { + if (Layer->IsSelected & 0x01) { int Width = 0, Height = 0; Layer_GetDimensions(Memory, Layer, &Width, &Height); @@ -299,18 +299,18 @@ Transform_Inverse(layer_transforms T) static layer_transforms Transform_TestInteracts(project_state *State, block_layer *Layer, sorted_layer_array SortEntry, layer_transforms T) { - if (State->Interact_Active == interact_type_viewport_transform && Layer->IsSelected == 1) { + if (State->Interact_Active == interact_type_viewport_transform && Layer->IsSelected & 0x01) { Transform_ApplyInteractive(State->Interact_Transform, &T.x, &T.y, &T.rotation, &T.scale); } - if (State->Interact_Active == interact_type_viewport_transform_gizmo && Layer->IsSelected == 1) { + if (State->Interact_Active == interact_type_viewport_transform_gizmo && Layer->IsSelected & 0x01) { Transform_ApplyInteractive(State->Interact_Transform, &T.x, &T.y, &T.rotation, &T.scale); } - if (State->Interact_Active == interact_type_viewport_slide && Layer->IsSelected == 1) { + if (State->Interact_Active == interact_type_viewport_slide && Layer->IsSelected & 0x01) { Assert(0); // Transform_ApplySlide((v2 *)&State->Interact_Offset[0], &T); } if (State->Interact_Active == interact_type_viewport_duplicate && SortEntry.IsFake) { - Assert(Layer->IsSelected); + Assert(Layer->IsSelected & 0x01); T.x += State->Interact_Offset[0]; T.y += State->Interact_Offset[1]; } @@ -349,7 +349,7 @@ Layer_LocalToScreenSpace(project_state *State, memory *Memory, block_layer *Laye layer_transforms T = Layer_GetTransforms(Layer); if ((State->Interact_Active == interact_type_viewport_transform || - State->Interact_Active == interact_type_viewport_transform_gizmo) && Layer->IsSelected == 1) { + State->Interact_Active == interact_type_viewport_transform_gizmo) && Layer->IsSelected & 0x01) { Transform_ApplyInteractive(State->Interact_Transform, &T.x, &T.y, &T.rotation, &T.scale); } @@ -451,7 +451,7 @@ Transform_Calculate(project_state *State, memory *Memory, project_data *File, bl blend_mode BlendMode = Layer->BlendMode; if ((State->Interact_Active == interact_type_viewport_transform || - State->Interact_Active == interact_type_viewport_transform_gizmo) && Layer->IsSelected == 1) { + State->Interact_Active == interact_type_viewport_transform_gizmo) && Layer->IsSelected & 0x01) { Transform_ApplyInteractive(State->Interact_Transform, &X, &Y, &Rotation, &s); } diff --git a/src/sorted.cpp b/src/sorted.cpp index 5826e68..1553bf9 100644 --- a/src/sorted.cpp +++ b/src/sorted.cpp @@ -174,7 +174,7 @@ Layer_Sort_Shift(project_state *State, memory *Memory, sorted_layer_array *LayerEntry = &SortedLayerStart[i]; block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, LayerEntry->Block_Layer_Index); Assert(LayerEntry->SortedOffset == Layer->Vertical_Offset); - if (Layer->IsSelected) { + if (Layer->IsSelected & 0x01) { int32 SpacesToMove = Offset * Direction; while (SpacesToMove) { Layer_Sort_CheckPrev(Memory, i, Direction, SortedLayerStart, *SortedCompStart, &EntriesPassed, LayerEntry, 0); @@ -253,7 +253,7 @@ Layer_SortAll(project_state *State, memory *Memory, Assert(Layer->Block_Composition_Index < CompCount); sorted_comp_array *SortedCompStart = &CompArrayStart[Layer->Block_Composition_Index]; SortedCompStart->LayerCount++; - if (State->Interact_Active == interact_type_viewport_duplicate && Layer->IsSelected == 1) { + if (State->Interact_Active == interact_type_viewport_duplicate && Layer->IsSelected & 0x01) { SortedCompStart->FakeLayerCount++; } } @@ -298,7 +298,7 @@ Layer_SortAll(project_state *State, memory *Memory, int Idx = i + FauxIncrement; sorted_layer_array *LayerEntry = &SortedLayerStart[Idx]; block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, LayerEntry->Block_Layer_Index); - if (Layer->IsSelected == 1) { + if (Layer->IsSelected & 0x01) { for (int a = i+1; a < SortedCompStart->LayerCount; a++) { int PrevIdx = a + FauxIncrement - 1; sorted_layer_array *PrevLayerEntry = &SortedLayerStart[PrevIdx]; -- cgit v1.2.3