summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFox Caminiti <fox@foxcam.net>2022-11-10 22:34:17 -0500
committerFox Caminiti <fox@foxcam.net>2022-11-10 22:34:17 -0500
commit38bf0102300c97335d8e78b4683cb9b9476dcde0 (patch)
treeb92d8225ba860cde7f23be96c7da3a3563272e8c
parent0a6e95f855afad36481baa9ed72b39ba6e297df6 (diff)
graph implementation
-rw-r--r--createcalls.cpp150
-rw-r--r--defines.h2
-rw-r--r--functions.h8
-rw-r--r--main.cpp141
-rw-r--r--main.h6
-rw-r--r--memory.cpp41
-rw-r--r--my_imgui_widgets.cpp463
-rw-r--r--prenderer.cpp149
8 files changed, 691 insertions, 269 deletions
diff --git a/createcalls.cpp b/createcalls.cpp
index c018eaa..176fc2f 100644
--- a/createcalls.cpp
+++ b/createcalls.cpp
@@ -74,6 +74,32 @@ Bezier_Lookup(memory *Memory, property_channel *Property, uint16 Index)
return &Bezier->Point[Index];
}
+static void
+Bezier_Add(memory *Memory, property_channel *Property, bezier_point PointData)
+{
+ if (!Property->Block_Bezier_Count) {
+ Property->Block_Bezier_Index[0] = Memory_Block_AllocateNew(Memory, F_Bezier);
+ block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Property->Block_Bezier_Index[0]);
+ Bezier->Occupied = true;
+ // NOTE(fox): Effects will change this!
+ History_Action_Swap(Memory, F_Layers, sizeof(Property->Block_Bezier_Count), &Property->Block_Bezier_Count);
+ Property->Block_Bezier_Count++;
+ }
+ int k = 0;
+ for (;;) {
+ bezier_point *Point = Bezier_Lookup(Memory, Property, k);
+ if (!Point->Occupied) {
+ History_Action_Swap(Memory, F_Bezier, sizeof(*Point), Point);
+ *Point = PointData;
+ History_Action_Swap(Memory, F_Layers, sizeof(Property->Keyframe_Count), &Property->Keyframe_Count);
+ Property->Keyframe_Count++;
+ return;
+ }
+ k++;
+ }
+}
+
+
static property_channel
Property_InitFloat(char *Name, real32 Val, real32 ScrubVal, real32 MinVal = PROPERTY_REAL_MIN, real32 MaxVal = PROPERTY_REAL_MAX) { property_channel Property = {};
Property.Name = Name;
@@ -84,18 +110,20 @@ Property_InitFloat(char *Name, real32 Val, real32 ScrubVal, real32 MinVal = PROP
return Property;
}
+// static property_info
+// Property_Sort(memory *Memory, property_channel *Property)
+// {
+// }
+
static property_info
Property_GetInfo(memory *Memory, property_channel *Property)
{
property_info PropertyInfo = {};
- int k = 0;
- for (;;) {
- bezier_point *Point = Bezier_Lookup(Memory, Property, k);
- if (!Point->Occupied)
- break;
+ int h = 0, c = 0, i = 0;
+ while (Block_Loop(Memory, Property, Property->Keyframe_Count, &h, &c, &i)) {
+ bezier_point *Point = Bezier_Lookup(Memory, Property, i);
PropertyInfo.MinVal = (Point->Pos[0].y < PropertyInfo.MinVal) ? Point->Pos[0].y : PropertyInfo.MinVal;
PropertyInfo.MaxVal = (Point->Pos[0].y > PropertyInfo.MaxVal) ? Point->Pos[0].y : PropertyInfo.MaxVal;
- k++;
}
return PropertyInfo;
}
@@ -124,10 +152,11 @@ Graph_GetInfo(project_data *File, memory *Memory)
static void
Keyframe_Interact_Evaluate(memory *Memory, project_state *State, uint8 IsSelected, v2 Pos_Initial[3], v2 Pos_New[3])
{
+ /*
Assert(Pos_New[0].y == Pos_Initial[0].y);
- v2 Offset = V2(State->Interact_Offset[0], State->Interact_Offset[1]);
if (State->Interact_Active == interact_type_keyframe_move) {
- Pos_New[0] = Pos_New[0] + Offset;
+ Pos_New[0].x = Pos_New[0].x + Offset.x;
+ Pos_New[0].y = Pos_New[0].y + Offset.y;
} else if (State->Interact_Active == interact_type_keyframe_scale) {
Pos_New[1].x += (IsSelected - 1 == 0 || IsSelected - 1 == 1) ? Offset.x : 0;
Pos_New[2].x -= (IsSelected - 1 == 0 || IsSelected - 1 == 2) ? Offset.x : 0;
@@ -138,37 +167,45 @@ Keyframe_Interact_Evaluate(memory *Memory, project_state *State, uint8 IsSelecte
Pos_New[2].x += XAxis.x + XAxis.y;
Pos_New[2].y += YAxis.x + YAxis.y;
}
+ */
+}
+
+static block_composition *
+Precomp_Init(project_data *File, memory *Memory)
+{
+ if (File->Comp_Count + 1 > MAX_COMPS) {
+ Assert(0);
+ }
+ block_composition *Comp = (block_composition *)Memory_Block_AllocateAddress(Memory, F_Precomps);
+ History_Action_Block_Swap(Memory, F_Precomps, Comp);
+
+ *Comp = {};
+ Comp->Occupied = 1;
+
+ Comp->Name_String_Index = Memory_Block_AllocateNew(Memory, F_Strings);
+ block_string *String = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, Comp->Name_String_Index);
+ sprintf(String->Char, "Comp %i", File->Comp_Count);
+ String->Occupied = 1;
+
+ History_Action_Swap(Memory, F_File, sizeof(File->Comp_Count), &File->Comp_Count);
+ File->Comp_Count++;
+ return Comp;
+}
+
+static layer_transforms
+Layer_GetTransforms(block_layer *Layer) {
+ return { Layer->x.CurrentValue, Layer->y.CurrentValue, Layer->ax.CurrentValue, Layer->ay.CurrentValue, Layer->rotation.CurrentValue, Layer->scale.CurrentValue };
}
-/*
static void
Layer_Interact_Evaluate(memory *Memory, project_state *State, uint16 Layer_Index_Physical, sorted_comp_info SortedCompInfo, sorted_layer *SortedLayerInfo,
- int32 *Frame_Start, int32 *Frame_End, real32 *Vertical_Offset)
+ int32 *Frame_Start, int32 *Frame_End)
{
if (State->Interact_Active == interact_type_layer_move) {
*Frame_Start += (int32)(State->Interact_Offset[0] + 0);
*Frame_End += (int32)(State->Interact_Offset[0] + 0);
-
- real32 DesiredOffset = *Vertical_Offset + (int32)State->Interact_Offset[1];
- bool32 Direction = ((int32)State->Interact_Offset[1] > 0) ? 1 : -1;
- int i = (Direction > 0) ? SortedCompInfo.LayerCount - 1 : 0;
- bool32 Case = 1;
- while (Case) {
- sorted_layer SortEntry = SortedLayerInfo[i];
- uint32 Index_Physical = SortEntry.Block_Layer_Index;
- block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
- bool32 Test = (Direction > 0) ?
- ((Layer->Vertical_Offset <= DesiredOffset) && (Layer->Vertical_Offset > *Vertical_Offset)) :
- ((Layer->Vertical_Offset >= DesiredOffset) && (Layer->Vertical_Offset < *Vertical_Offset));
- if (!Layer->IsSelected && Test) {
- DesiredOffset += Direction;
- }
- i -= Direction;
- Case = (Direction > 0) ? (i >= 0) : (i < SortedCompInfo.LayerCount);
- }
- *Vertical_Offset = DesiredOffset;
}
- else if (State->Interact_Active == interact_type_layer_timeadjust) {
+ if (State->Interact_Active == interact_type_layer_timeadjust) {
int Side[2] = {0};
Assert(State->Interact_Offset[1] == 0 || State->Interact_Offset[1] == 1);
Side[(int)State->Interact_Offset[1]] = 1;
@@ -178,17 +215,8 @@ Layer_Interact_Evaluate(memory *Memory, project_state *State, uint16 Layer_Index
*Frame_End += (int32)(State->Interact_Offset[0] * Side[1]);
if (*Frame_End <= *Frame_Start)
*Frame_End = *Frame_Start + 1;
- } else if (State->Interact_Active == interact_type_viewport_transform) {
- int i = SortedCompInfo.LayerCount - 1;
- while (i >= 0) {
- sorted_layer SortEntry = SortedLayerInfo[i];
- uint32 Index_Physical = SortEntry.Block_Layer_Index;
- block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
- i--;
- }
}
}
-*/
static void
Layer_Select(memory *Memory, project_state *State, int32 i)
@@ -292,6 +320,38 @@ void Layer_Sort_CheckPrev(memory *Memory, int i, int Direction, sorted_layer *So
}
}
+// TODO(fox): This _could_ be generalized with the layer sorting code...
+
+/*
+Bezier_SortAll()
+{
+ 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_comp_info *SortedCompInfo = &CompStart[Layer->Block_Composition_Index];
+ sorted_layer *SortedLayerInfo = Layer_GetSortedArray(LayerArrayStart, CompStart, Layer->Block_Composition_Index);
+ uint32 SortedIndex_Playhead = 0;
+ while (SortedIndex_Playhead < CurrentSortIndex) {
+ sorted_layer LayerEntry = SortedLayerInfo[SortedIndex_Playhead];
+ block_layer *TestLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, LayerEntry.Block_Layer_Index);
+ if (-Layer->Vertical_Offset < -TestLayer->Vertical_Offset) {
+ break;
+ } else {
+ SortedIndex_Playhead++;
+ }
+ }
+ if (SortedIndex_Playhead != CurrentSortIndex) {
+ uint8 *Address_Start = (uint8 *)(SortedLayerInfo + SortedIndex_Playhead);
+ uint8 *Address_End = (uint8 *)(SortedLayerInfo + CurrentSortIndex) - 1;
+ Assert(CurrentSortIndex != SortedCompInfo->LayerCount);
+ Arbitrary_ShiftData(Address_Start, Address_End, sizeof(sorted_layer), 1);
+ }
+ sorted_layer *LayerEntry = SortedLayerInfo + SortedIndex_Playhead;
+ LayerEntry->Block_Layer_Index = i;
+ LayerEntry->SortedOffset = Layer->Vertical_Offset;
+ CurrentSortIndex++;
+ }
+}
+*/
void Layer_SortAll(project_data *File, project_state *State, memory *Memory, sorted_layer *LayerArrayStart, sorted_comp_info *CompStart, uint32 LayerCount, uint32 CompCount)
{
@@ -300,15 +360,15 @@ void Layer_SortAll(project_data *File, project_state *State, memory *Memory, sor
block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
Assert(Layer->Block_Composition_Index < CompCount);
CompStart[Layer->Block_Composition_Index].LayerCount++;
-
}
h = 0, c = 0, i = 0;
+ uint32 CurrentSortIndex = 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);
sorted_comp_info *SortedCompInfo = &CompStart[Layer->Block_Composition_Index];
sorted_layer *SortedLayerInfo = Layer_GetSortedArray(LayerArrayStart, CompStart, Layer->Block_Composition_Index);
uint32 SortedIndex_Playhead = 0;
- while (SortedIndex_Playhead < SortedCompInfo->CurrentSortIndex) {
+ while (SortedIndex_Playhead < CurrentSortIndex) {
sorted_layer LayerEntry = SortedLayerInfo[SortedIndex_Playhead];
block_layer *TestLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, LayerEntry.Block_Layer_Index);
if (-Layer->Vertical_Offset < -TestLayer->Vertical_Offset) {
@@ -317,16 +377,16 @@ void Layer_SortAll(project_data *File, project_state *State, memory *Memory, sor
SortedIndex_Playhead++;
}
}
- if (SortedIndex_Playhead != SortedCompInfo->CurrentSortIndex) {
+ if (SortedIndex_Playhead != CurrentSortIndex) {
uint8 *Address_Start = (uint8 *)(SortedLayerInfo + SortedIndex_Playhead);
- uint8 *Address_End = (uint8 *)(SortedLayerInfo + SortedCompInfo->CurrentSortIndex) - 1;
- Assert(SortedCompInfo->CurrentSortIndex != SortedCompInfo->LayerCount);
+ uint8 *Address_End = (uint8 *)(SortedLayerInfo + CurrentSortIndex) - 1;
+ Assert(CurrentSortIndex != SortedCompInfo->LayerCount);
Arbitrary_ShiftData(Address_Start, Address_End, sizeof(sorted_layer), 1);
}
sorted_layer *LayerEntry = SortedLayerInfo + SortedIndex_Playhead;
LayerEntry->Block_Layer_Index = i;
LayerEntry->SortedOffset = Layer->Vertical_Offset;
- SortedCompInfo->CurrentSortIndex++;
+ CurrentSortIndex++;
}
if (State->Interact_Active == interact_type_layer_move) {
int32 Offset = (int32)State->Interact_Offset[1];
diff --git a/defines.h b/defines.h
index f2d58f2..fd63c30 100644
--- a/defines.h
+++ b/defines.h
@@ -31,11 +31,11 @@ typedef uint64 ptrsize; // is there a compiler variable for 32 vs 64 bit like
#define MAX_LAYERS 2048
#define MAX_EFFECTS 32
#define MAX_SOURCES 1024
+#define MAX_COMPS 1024
#define MAX_MASKS 8
#define MAX_PROPERTIES_PER_EFFECT 16
#define MAX_KEYFRAME_BLOCKS 64
#define MAX_KEYFRAMES_PER_BLOCK 32 // max keyframes on a single channel is 2048
-#define MAX_BITMAP_CHUNKS 64 // Up to 2048x2048-size textures
#define MAX_SELECTED_PROPERTIES 16
diff --git a/functions.h b/functions.h
index d4a4cfa..eff7435 100644
--- a/functions.h
+++ b/functions.h
@@ -7,10 +7,14 @@ static void Arbitrary_ShiftData(uint8 *Address_Start, uint8 *Address_End, uint64
static v2 T_CompUVToLayerUV(layer_transforms T, uint32 FileWidth, uint32 FileHeight, uint32 SourceWidth, uint32 SourceHeight, v2 CompUV);
-static void Interact_Transform_Begin(project_data *File, memory *Memory, project_state *State, ImVec2 OGPos);
+static void Interact_Transform_Begin(project_data *File, memory *Memory, project_state *State, ImVec2 OGPos, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray);
static v2 Transform_ScreenSpaceToLocal(layer_transforms T, uint32 FileWidth, uint32 FileHeight, uint32 SourceWidth, uint32 SourceHeight, ui UI, ImVec2 ViewportMin, ImVec2 Point);
-static ImVec2 Layer_LocalToScreenSpace(project_state *State, block_layer *Layer, ui *UI, real32 SourceWidth, real32 SourceHeight, real32 CompWidth, real32 CompHeight, v2 Point);
+static ImVec2 Layer_LocalToScreenSpace(project_state *State, memory *Memory, block_layer *Layer, ui *UI, uint32 PrincipalCompIndex, v2 Point);
+
+static v2 TransformPoint(layer_transforms T, real32 Width, real32 Height, v2 Point);
+
+static bezier_point * Bezier_Lookup(memory *Memory, property_channel *Property, uint16 Index);
static void Transform_ApplyInteractive(interact_transform Interact, real32 *OutputX, real32 *OutputY, real32 *OutputRotation, real32 *OutputScale);
diff --git a/main.cpp b/main.cpp
index 0a5e9ed..50f9cc5 100644
--- a/main.cpp
+++ b/main.cpp
@@ -125,6 +125,8 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, ui *UI,
UI->Warp_WantSetPos = false;
}
+ // NOTE(fox): The only requirement for something that needs to happen before the sort is anything that creates/deletes layers.
+ // The requirement for something after the sort is things that depend on the sort. (obvious)
if (!io.WantCaptureKeyboard)
ImGui_ProcessInputs(File, State, UI, Memory, io);
@@ -135,6 +137,11 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, ui *UI,
sorted_layer *SortedLayerArray = (sorted_layer *)((uint8 *)SortedArray + (sizeof(sorted_comp_info) * File->Comp_Count));
Layer_SortAll(File, State, Memory, SortedLayerArray, SortedCompArray, File->Layer_Count, File->Comp_Count);
+
+ if (ImGui::IsKeyPressed(ImGuiKey_T)) {
+ Interact_Transform_Begin(File, Memory, State, io.MousePos, SortedCompArray, SortedLayerArray);
+ }
+
ImGui::DockSpaceOverViewport();
if (Debug.ToggleWindow) {
@@ -143,8 +150,45 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, ui *UI,
ImGui_DebugUndoTree(Memory, State);
}
- // if (State->Initializing == 3)
- // Source_UICreateButton(File, State, Memory, SortedCompArray, SortedLayerArray);
+ if (State->Initializing == 3) {
+ Source_UICreateButton(File, State, Memory, SortedCompArray, SortedLayerArray);
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, 0);
+ History_Entry_Commit(Memory, "Add keyframe");
+ property_channel *Property = &Layer->x;
+ {
+ bezier_point Point = { 1, {0, 300, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 };
+ Bezier_Add(Memory, Property, Point);
+ }
+ {
+ bezier_point Point = { 1, {20, 800, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 };
+ Bezier_Add(Memory, Property, Point);
+ }
+ History_Entry_End(Memory);
+
+ bezier_point *Point2 = Bezier_Lookup(Memory, Property, 0);
+
+ History_Entry_Commit(Memory, "Add keyframe");
+ Property = &Layer->y;
+ {
+ bezier_point Point = { 1, {0, 400, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 };
+ Bezier_Add(Memory, Property, Point);
+ }
+ {
+ bezier_point Point = { 1, {20, -500, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 };
+ Bezier_Add(Memory, Property, Point);
+ }
+ Property = &Layer->opacity;
+ {
+ bezier_point Point = { 1, {0, 0, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 };
+ Bezier_Add(Memory, Property, Point);
+ }
+ {
+ bezier_point Point = { 1, {20, 1, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 };
+ Bezier_Add(Memory, Property, Point);
+ }
+
+ History_Entry_End(Memory);
+ }
ImGui_Viewport(File, State, UI, Memory, io, textureID, SortedCompArray, SortedLayerArray);
@@ -162,11 +206,6 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, ui *UI,
ImGui::EndFrame();
}
-static layer_transforms
-Layer_GetTransforms(block_layer *Layer) {
- return { Layer->x.CurrentValue, Layer->y.CurrentValue, Layer->ax.CurrentValue, Layer->ay.CurrentValue, Layer->rotation.CurrentValue, Layer->scale.CurrentValue };
-}
-
static void *
Render_Comp(project_data *File, project_state *State, memory *Memory, ImGuiIO io, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray, uint32 CompIndex)
{
@@ -189,7 +228,7 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, ImGuiIO io
uint32 Index_Physical = SortEntry.Block_Layer_Index;
block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
if (Layer->Frame_Start <= State->Frame_Current &&
- Layer->Frame_End >= State->Frame_Current && Layer->IsVisible)
+ Layer->Frame_End > State->Frame_Current && Layer->IsVisible)
{
layer_bitmap_state *BitmapState = &State->Render.Bitmap[Index_Physical];
void *BitmapAddress = NULL;
@@ -225,13 +264,11 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, ImGuiIO io
} else {
block_composition *Precomp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, Layer->Block_Source_Index);
cache_entry *Entry = Memory_Cache_Search(State, Memory, cache_entry_type_comp, Layer->Block_Source_Index, State->Frame_Current);
- if (!Entry->IsCached) {
- uint64 Src_TimeStart = GetTime();
- Render_Comp(File, State, Memory, io, SortedCompArray, SortedLayerArray, Layer->Block_Source_Index);
- Layer->x.CurrentValue = (Layer->Block_Source_Index == 0) ? 200 : Comp->Width/2;
- Layer->y.CurrentValue = Comp->Height/2;
- Entry->CycleTime = GetTime() - Src_TimeStart;
- }
+ // if (!Entry->IsCached) {
+ uint64 Src_TimeStart = GetTime();
+ Render_Comp(File, State, Memory, io, SortedCompArray, SortedLayerArray, Layer->Block_Source_Index);
+ Entry->CycleTime = GetTime() - Src_TimeStart;
+ // }
BitmapAddress = Memory_Block_Bitmap_AddressAtIndex(Memory, Entry->Block_StartIndex);
}
Assert(BitmapAddress);
@@ -241,37 +278,38 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, ImGuiIO io
// for (int a = 0; a < Layer->Block_Effect_Count; a++) {
// }
- property_channel *Property = &Layer->x;
-
- if (Property->Block_Bezier_Count) {
- bezier_point *FirstPoint = Bezier_Lookup(Memory, Property, 0);
- int k = 0;
- for (;;) {
- bezier_point *Point = Bezier_Lookup(Memory, Property, k);
- if (!Point->Occupied)
- break;
- k++;
- }
- bezier_point *LastPoint = Bezier_Lookup(Memory, Property, k - 1);
- if (FirstPoint->Pos[0].x >= State->Frame_Current) {
- Property->CurrentValue = FirstPoint->Pos[0].y;
- } else if (LastPoint->Pos[0].x <= State->Frame_Current) {
- Property->CurrentValue = LastPoint->Pos[0].y;
- } else {
- int KeyframeIndex = 0;
+ for (int h = 0; h < AmountOf(Layer->Property); h++) {
+ property_channel *Property = &Layer->Property[h];
+ if (Property->Block_Bezier_Count) {
+ bezier_point *FirstPoint = Bezier_Lookup(Memory, Property, 0);
+ int k = 0;
for (;;) {
- bezier_point *Point = Bezier_Lookup(Memory, Property, KeyframeIndex + 1);
- if (Point->Pos[0].x >= State->Frame_Current)
+ bezier_point *Point = Bezier_Lookup(Memory, Property, k);
+ if (!Point->Occupied)
break;
- KeyframeIndex++;
+ k++;
+ }
+ bezier_point *LastPoint = Bezier_Lookup(Memory, Property, k - 1);
+ if (FirstPoint->Pos[0].x >= State->Frame_Current) {
+ Property->CurrentValue = FirstPoint->Pos[0].y;
+ } else if (LastPoint->Pos[0].x <= State->Frame_Current) {
+ Property->CurrentValue = LastPoint->Pos[0].y;
+ } else {
+ int KeyframeIndex = 0;
+ for (;;) {
+ bezier_point *Point = Bezier_Lookup(Memory, Property, KeyframeIndex + 1);
+ if (Point->Pos[0].x >= State->Frame_Current)
+ break;
+ KeyframeIndex++;
+ }
+ bezier_point *Point = Bezier_Lookup(Memory, Property, KeyframeIndex);
+ bezier_point *NextPoint = Bezier_Lookup(Memory, Property, KeyframeIndex + 1);
+ v2 Pos_New[3] = { Point->Pos[0], Point->Pos[1], Point->Pos[2] };
+ v2 NextPos_New[3] = { NextPoint->Pos[0], NextPoint->Pos[1], NextPoint->Pos[2] };
+ Keyframe_Interact_Evaluate(Memory, State, Point->IsSelected, Point->Pos, Pos_New);
+ Keyframe_Interact_Evaluate(Memory, State, NextPoint->IsSelected, NextPoint->Pos, NextPos_New);
+ Property->CurrentValue = Bezier_SolveYForX(Pos_New[0], Pos_New[0] + Pos_New[2], NextPos_New[0] + NextPos_New[1], NextPos_New[0], State->Frame_Current);
}
- bezier_point *Point = Bezier_Lookup(Memory, Property, KeyframeIndex);
- bezier_point *NextPoint = Bezier_Lookup(Memory, Property, KeyframeIndex + 1);
- v2 Pos_New[3] = { Point->Pos[0], Point->Pos[1], Point->Pos[2] };
- v2 NextPos_New[3] = { NextPoint->Pos[0], NextPoint->Pos[1], NextPoint->Pos[2] };
- Keyframe_Interact_Evaluate(Memory, State, Point->IsSelected, Point->Pos, Pos_New);
- Keyframe_Interact_Evaluate(Memory, State, NextPoint->IsSelected, NextPoint->Pos, NextPos_New);
- Property->CurrentValue = Bezier_SolveYForX(Pos_New[0], Pos_New[0] + Pos_New[2], NextPos_New[0] + NextPos_New[1], NextPos_New[0], State->Frame_Current);
}
}
@@ -361,11 +399,12 @@ int main(int argc, char *argv[]) {
Memory_InitTable(&GlobalMemory, &Memory, 40 * 1024 * 1024, P_MiscCache, "Misc persistent");
Memory_InitTable(&GlobalMemory, &Memory, sizeof(project_data), F_File, "File", sizeof(project_data));
- Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Precomps, "Precomps", sizeof(block_composition));
- Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Layers, "Layers", sizeof(block_layer));
- Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Sources, "Sources", sizeof(block_source));
- Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Bezier, "Bezier paths (keyframes, masks)", sizeof(block_bezier));
- Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Strings, "Strings", sizeof(block_string));
+ Memory_InitTable(&GlobalMemory, &Memory, 1 * 1024 * 1024, F_Precomps, "Precomps", sizeof(block_composition));
+ Memory_InitTable(&GlobalMemory, &Memory, 2 * 1024 * 1024, F_Layers, "Layers", sizeof(block_layer));
+ Memory_InitTable(&GlobalMemory, &Memory, 1 * 1024 * 1024, F_Sources, "Sources", sizeof(block_source));
+ Memory_InitTable(&GlobalMemory, &Memory, 2 * 1024 * 1024, F_Properties, "Properties", sizeof(property_channel));
+ Memory_InitTable(&GlobalMemory, &Memory, 4 * 1024 * 1024, F_Bezier, "Bezier paths (keyframes, masks)", sizeof(block_bezier));
+ Memory_InitTable(&GlobalMemory, &Memory, 4 * 1024 * 1024, F_Strings, "Strings", sizeof(block_string));
Memory_InitTable(&GlobalMemory, &Memory, (uint64)50 * 1024 * 1024, F_PrincipalBitmaps, "Principal bitmap data", BitmapBlockSize);
Memory_InitTable(&GlobalMemory, &Memory, (uint64)64 * 1024 * 1024, B_ScratchSpace, "Scratch");
@@ -428,8 +467,6 @@ int main(int argc, char *argv[]) {
Comp2->Name_String_Index = String_AddToFile(&Memory, "Another comp");
*/
- File->Comp_Count = 1;
-
{
uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/a.jpg");
block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, 0);
@@ -528,7 +565,7 @@ int main(int argc, char *argv[]) {
{
uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/b.jpg");
block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, 1);
- Source->IsSelected = true;
+ // Source->IsSelected = true;
/*
{
Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End);
@@ -585,7 +622,7 @@ int main(int argc, char *argv[]) {
{
uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/c.jpg");
block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, 2);
- Source->IsSelected = true;
+ // Source->IsSelected = true;
/*
{
Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End);
diff --git a/main.h b/main.h
index 1b386ce..096107a 100644
--- a/main.h
+++ b/main.h
@@ -119,7 +119,6 @@ enum focused_window
struct sorted_comp_info
{
uint32 LayerCount;
- uint32 CurrentSortIndex;
};
struct sorted_layer
@@ -145,6 +144,9 @@ struct ui
ImVec2 TimelinePercentZoomed;
ImVec2 TimelinePercentOffset;
+ ImVec2 GraphZoomSize;
+ ImVec2 GraphMoveSize;
+
uint32 InteractTransformMode; // Whether a drag on the Shift+T UI is scale (1), rotation (2), or position (3).
timeline_mode TimelineMode;
@@ -374,9 +376,11 @@ struct property_info
};
struct property_channel {
+ uint8 Occupied;
char *Name;
uint16 Block_Bezier_Index[MAX_KEYFRAME_BLOCKS];
uint16 Block_Bezier_Count;
+ uint16 Keyframe_Count;
real32 CurrentValue;
real32 MaxVal;
diff --git a/memory.cpp b/memory.cpp
index 6e70055..3b3c64f 100644
--- a/memory.cpp
+++ b/memory.cpp
@@ -34,6 +34,13 @@ Memory_Block_AddressAtIndex(memory *Memory, memory_table_list TableName, uint32
return (void *)Address;
}
+static uint16
+Memory_Block_IndexAtAddress(memory *Memory, memory_table_list TableName, void *Address)
+{
+ memory_table *Table = &Memory->Slot[TableName];
+ return ((uint8 *)Address - (uint8 *)Table->Address) / Table->Block_ElementSize;
+}
+
static void *
Memory_Block_AllocateAddress(memory *Memory, memory_table_list TableName)
{
@@ -43,7 +50,37 @@ Memory_Block_AllocateAddress(memory *Memory, memory_table_list TableName)
// IMPORTANT(fox): All block data has to start with a uint8 Occupied variable!
static bool32
-Block_Loop(memory *Memory, memory_table_list TableName, uint32 TotalCount, int *HasIncremented, int *CurrentCount, int *Index)
+Block_Loop(memory *Memory, memory_table_list TableName, uint32 TotalCount, int *HasIncremented, int *CurrentCount, int *Index, void *Extra = NULL)
+{
+ for (;;) {
+ if (*CurrentCount == TotalCount) {
+ return 0;
+ }
+ if (*HasIncremented) {
+ *HasIncremented = 0;
+ (*Index)++;
+ }
+ uint8 *Occupied;
+ if (!Extra) {
+ Occupied = (uint8 *)Memory_Block_AddressAtIndex(Memory, TableName, *Index);
+ } else {
+ Occupied = (uint8 *)Bezier_Lookup(Memory, (property_channel *)Extra, *Index);
+ }
+ if (*Occupied) {
+ *HasIncremented = 1;
+ (*CurrentCount)++;
+ return 1;
+ }
+ (*Index)++;
+ Assert(*CurrentCount <= TotalCount);
+ Assert(*Index <= TotalCount*100); // This can get triggered normally if 100+ items are added and the first 99 in memory are deleted.
+ }
+ Assert(0);
+ return 0;
+}
+
+static bool32
+Block_Loop(memory *Memory, property_channel *Property, uint32 TotalCount, int *HasIncremented, int *CurrentCount, int *Index)
{
for (;;) {
if (*CurrentCount == TotalCount) {
@@ -53,7 +90,7 @@ Block_Loop(memory *Memory, memory_table_list TableName, uint32 TotalCount, int *
*HasIncremented = 0;
(*Index)++;
}
- uint8 *Occupied = (uint8 *)Memory_Block_AddressAtIndex(Memory, TableName, *Index);
+ uint8 *Occupied = (uint8 *)Bezier_Lookup(Memory, Property, *Index);
if (*Occupied) {
*HasIncremented = 1;
(*CurrentCount)++;
diff --git a/my_imgui_widgets.cpp b/my_imgui_widgets.cpp
index e1e9ffc..722ce1e 100644
--- a/my_imgui_widgets.cpp
+++ b/my_imgui_widgets.cpp
@@ -138,9 +138,7 @@ ImGui_File(project_data *File, project_state *State, memory *Memory, ImGuiIO io,
ImGui::Begin("Files");
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
- if (!ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows))
- Source_DeselectAll(File, Memory);
- else if (ImGui::IsKeyPressed(ImGuiKey_Backspace)) {
+ if (ImGui::IsKeyPressed(ImGuiKey_Backspace)) {
/*
uint64 SortSize = (sizeof(uint16) * File->Comp_Count);
@@ -214,6 +212,9 @@ ImGui_File(project_data *File, project_state *State, memory *Memory, ImGuiIO io,
ImGui::EndPopup();
}
+ // if (!ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows))
+ // Source_DeselectAll(File, Memory);
+
#if DEBUG
for (int i = 0; i < Debug.Temp.WatchedProperties; i++) {
@@ -603,6 +604,7 @@ ImGui_TransformUI(project_data *File, project_state *State, memory *Memory, ui *
}
if (ImGui::IsKeyPressed(ImGuiKey_Escape)) {
+ State->Interact_Active = interact_type_none;
State->UpdateFrame = true;
}
@@ -632,6 +634,106 @@ ImGui_TransformUI(project_data *File, project_state *State, memory *Memory, ui *
}
static void
+ImGui_LayerViewportUI(project_state *State, memory *Memory, ui *UI, ImDrawList *draw_list, block_composition *MainComp, uint32 CompIndex, block_layer *ParentLayer[4], uint32 Recursions,
+ sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray)
+{
+ sorted_comp_info *SortedCompInfo = &SortedCompArray[CompIndex];
+ sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, CompIndex);
+ ImU32 wcol = ImGui::GetColorU32(ImGuiCol_Text);
+ for (int i = 0; i < SortedCompInfo->LayerCount; i++)
+ {
+ sorted_layer SortEntry = SortedLayerInfo[i];
+ uint32 Index_Physical = SortEntry.Block_Layer_Index;
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
+ if (Layer->IsPrecomp) {
+ ParentLayer[Recursions] = Layer;
+ ImGui_LayerViewportUI(State, Memory, UI, draw_list, MainComp, Layer->Block_Source_Index, ParentLayer, Recursions + 1, SortedCompArray, SortedLayerArray);
+ }
+ if (Layer->IsSelected) {
+ uint32 Width = 0, Height = 0;
+ if (!Layer->IsPrecomp) {
+ block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index);
+ Width = Source->Width;
+ Height = Source->Height;
+ } else {
+ block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, Layer->Block_Source_Index);
+ Width = Comp->Width;
+ Height = Comp->Height;
+ }
+
+ v2 Point[5] = { V2(Width*Layer->ax.CurrentValue, Height*Layer->ay.CurrentValue), V2(0, 0), V2(Width, 0), V2(0, Height), V2(Width, Height) };
+
+ layer_transforms T = Layer_GetTransforms(Layer);
+
+ if (State->Interact_Active == interact_type_viewport_transform && Layer->IsSelected) {
+ Transform_ApplyInteractive(*(interact_transform *)&State->Interact_Offset[0], &T.x, &T.y, &T.rotation, &T.scale);
+ }
+
+ v2 NewPos[5];
+ for (int i = 0; i < 5; i++) {
+ NewPos[i] = TransformPoint(T, Width, Height, Point[i]);
+ }
+
+ int i = 0;
+ while (i < Recursions) {
+ T = Layer_GetTransforms(ParentLayer[i]);
+ block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, ParentLayer[i]->Block_Source_Index);
+ Width = Comp->Width;
+ Height = Comp->Height;
+ for (int i = 0; i < 5; i++) {
+ NewPos[i] = TransformPoint(T, Width, Height, NewPos[i]);
+ }
+ i++;
+ }
+
+ ImVec2 ScreenPoint[5];
+ for (int i = 0; i < 5; i++) {
+ v2 CompUV = NewPos[i] / V2(MainComp->Width, MainComp->Height);
+
+ ScreenPoint[i] = ImVec2(UI->CompPos.x + CompUV.x * UI->CompZoom.x,
+ UI->CompPos.y + CompUV.y * UI->CompZoom.y);
+
+ }
+ draw_list->AddNgon(ScreenPoint[0], 20, wcol, 8, 10.0f);
+ draw_list->AddLine(ScreenPoint[1], ScreenPoint[2], wcol, 2.0f);
+ draw_list->AddLine(ScreenPoint[2], ScreenPoint[4], wcol, 2.0f);
+ draw_list->AddLine(ScreenPoint[1], ScreenPoint[3], wcol, 2.0f);
+ draw_list->AddLine(ScreenPoint[3], ScreenPoint[4], wcol, 2.0f);
+ }
+ /*
+ if (Layer->IsSelected) {
+ uint32 Width = 0, Height = 0;
+ if (!Layer->IsPrecomp) {
+ block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index);
+ Width = Source->Width;
+ Height = Source->Height;
+ } else {
+ block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, Layer->Block_Source_Index);
+ Width = Comp->Width;
+ Height = Comp->Height;
+ }
+ // Anchor point UI
+ v2 CenterPoint = V2(Width*Layer->ax.CurrentValue, Height*Layer->ay.CurrentValue);
+ ImVec2 ScreenAP = Layer_LocalToScreenSpace(State, Memory, Layer, UI, File->PrincipalCompIndex, CenterPoint);
+ draw_list->AddNgon(ScreenAP, 20, wcol, 8, 10.0f);
+
+ // Bounding box UI
+ ImVec2 P1 = Layer_LocalToScreenSpace(State, Memory, Layer, UI, File->PrincipalCompIndex, V2(0, 0));
+ ImVec2 P2 = Layer_LocalToScreenSpace(State, Memory, Layer, UI, File->PrincipalCompIndex, V2(Width, 0));
+ ImVec2 P3 = Layer_LocalToScreenSpace(State, Memory, Layer, UI, File->PrincipalCompIndex, V2(0, Height));
+ ImVec2 P4 = Layer_LocalToScreenSpace(State, Memory, Layer, UI, File->PrincipalCompIndex, V2(Width, Height));
+ draw_list->AddLine(P1, P2, wcol, 2.0f);
+ draw_list->AddLine(P2, P4, wcol, 2.0f);
+ draw_list->AddLine(P1, P3, wcol, 2.0f);
+ draw_list->AddLine(P3, P4, wcol, 2.0f);
+
+ }
+ */
+
+ }
+}
+
+static void
ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io, GLuint textureID,
sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray)
{
@@ -668,35 +770,11 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
draw_list->AddImage((void *)(intptr_t)textureID, CompPosMin, CompPosMax);
draw_list->PopClipRect();
- ImU32 wcol = ImGui::GetColorU32(ImGuiCol_Text);
// UI+interaction for layer
if (State->MostRecentlySelectedLayer > -1)
{
- 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) {
- block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index);
-
- // Anchor point UI
- v2 CenterPoint = V2(Source->Width*Layer->ax.CurrentValue, Source->Height*Layer->ay.CurrentValue);
- ImVec2 ScreenAP = Layer_LocalToScreenSpace(State, Layer, UI, Source->Width, Source->Height, MainComp->Width, MainComp->Height, CenterPoint);
- draw_list->AddNgon(ScreenAP, 20, wcol, 8, 10.0f);
-
- // Bounding box UI
- ImVec2 P1 = Layer_LocalToScreenSpace(State, Layer, UI, Source->Width, Source->Height, MainComp->Width, MainComp->Height, V2(0, 0));
- ImVec2 P2 = Layer_LocalToScreenSpace(State, Layer, UI, Source->Width, Source->Height, MainComp->Width, MainComp->Height, V2(Source->Width, 0));
- ImVec2 P3 = Layer_LocalToScreenSpace(State, Layer, UI, Source->Width, Source->Height, MainComp->Width, MainComp->Height, V2(0, Source->Height));
- ImVec2 P4 = Layer_LocalToScreenSpace(State, Layer, UI, Source->Width, Source->Height, MainComp->Width, MainComp->Height, V2(Source->Width, Source->Height));
- draw_list->AddLine(P1, P2, wcol, 2.0f);
- draw_list->AddLine(P2, P4, wcol, 2.0f);
- draw_list->AddLine(P1, P3, wcol, 2.0f);
- draw_list->AddLine(P3, P4, wcol, 2.0f);
-
- }
- }
-
+ block_layer *ParentLayer[4];
+ ImGui_LayerViewportUI(State, Memory, UI, draw_list, MainComp, File->PrincipalCompIndex, ParentLayer, 0, SortedCompArray, SortedLayerArray);
if (State->Interact_Active == interact_type_viewport_transform) {
ImGui_TransformUI(File, State, Memory, UI, draw_list, io, (interact_transform *)&State->Interact_Offset[0], ViewportMin, MainComp->Width, MainComp->Height);
}
@@ -916,6 +994,9 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor
{
UI->Test.Split(draw_list, 2);
+ TimelineMoveSize.y = TimelineMoveSize.y + (TimelineZoomSize.y * (0.25 / 2));
+ TimelineZoomSize.y = TimelineZoomSize.y * 0.75;
+
int h = 0, c = 0, i = 0;
while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i))
{
@@ -924,16 +1005,8 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor
continue;
int32 Frame_Start = Layer->Frame_Start;
- int32 Frame_End = Layer->Frame_End;
- real32 Vertical_Offset = GraphInfo.LowestOffset; // Layer->Vertical_Offset;
- ImVec2 Layer_LocalPos = ImVec2(Frame_Start, Vertical_Offset);
- ImVec2 Layer_LocalSize = ImVec2(Frame_End - Frame_Start, Layer->Vertical_Height);
- ImVec2 Layer_LocalPos_Ratio = (Layer_LocalPos * Increment);
- ImVec2 Layer_LocalSize_Ratio = Layer_LocalSize * Increment;
- ImVec2 Layer_ScreenPos_Min = TimelineAbsolutePos + TimelineMoveSize + (Layer_LocalPos_Ratio * TimelineZoomSize);
- ImVec2 Layer_ScreenPos_Max = TimelineAbsolutePos + TimelineMoveSize + ((Layer_LocalPos_Ratio + Layer_LocalSize_Ratio) * TimelineZoomSize);
- ImVec2 Layer_ScreenSize = Layer_ScreenPos_Max - Layer_ScreenPos_Min;
+ ImVec2 Layer_ScreenPos_Min = TimelineAbsolutePos + TimelineMoveSize; // (* TimelineZoomSize);
ImGui::PushID(i);
@@ -941,8 +1014,12 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor
if (State->Interact_Active == interact_type_keyframe_move) {
ImVec2 DragDelta = io.MousePos - ImVec2(State->Interact_Offset[2], State->Interact_Offset[3]);
- State->Interact_Offset[0] = (DragDelta.x / TimelineSizeWithBorder.x * UI->TimelinePercentZoomed.x) / Increment.x;
- State->Interact_Offset[1] = -1 * (DragDelta.y / TimelineSizeWithBorder.y * UI->TimelinePercentZoomed.y) * ((GraphInfo.MaxVal - GraphInfo.MinVal));
+ // State->Interact_Offset[0] = (DragDelta.x / TimelineSizeWithBorder.x * UI->TimelinePercentZoomed.x) / Increment.x;
+ // State->Interact_Offset[1] = -1 * (DragDelta.y / TimelineSizeWithBorder.y * UI->TimelinePercentZoomed.y) * ((GraphInfo.MaxVal - GraphInfo.MinVal));
+ State->Interact_Offset[0] = DragDelta.x;
+ State->Interact_Offset[1] = DragDelta.y;
+ DebugWatchVar("DeltaX: ", &DragDelta.x, d_float);
+ DebugWatchVar("Deltay: ", &DragDelta.y, d_float);
} else if (State->Interact_Active == interact_type_keyframe_scale) {
ImVec2 DragDelta = io.MousePos - ImVec2(State->Interact_Offset[2], State->Interact_Offset[3]);
State->Interact_Offset[0] = (DragDelta.x / TimelineSizeWithBorder.x * UI->TimelinePercentZoomed.x) / Increment.x;
@@ -954,7 +1031,6 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor
State->Interact_Active == interact_type_keyframe_rotate ||
State->Interact_Active == interact_type_keyframe_scale))
{
- Assert(0);
// Memory_Cache_Invalidate(State, Memory, cache_entry_type_comp, Lay
}
@@ -980,6 +1056,7 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor
v2 Keyframe_LocalPos_[3] = { Point->Pos[0], Point->Pos[1], Point->Pos[2] };
if (Point->IsSelected) {
+ /*
if (State->Interact_Active == interact_type_keyframe_rotate) {
ImVec2 Keyframe_LocalPos_Ratio = (V2(Keyframe_LocalPos_[0]) - ImVec2(0, GraphInfo.MinVal)) * ImVec2(Increment.x, Y_Increment);
ImVec2 Keyframe_ScreenPos = Layer_ScreenPos_Min + ((ImVec2(1, -1) * Keyframe_LocalPos_Ratio + ImVec2(0, 0.5)) * TimelineZoomSize) + ImVec2(0, Layer_ScreenSize.y/2);
@@ -988,14 +1065,21 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor
State->Interact_Offset[0] = atan((Slope_Old - Slope_New) / (1 + Slope_Old * Slope_New));
DebugWatchVar("Rotation: ", &State->Interact_Offset[0], d_float);
}
- Keyframe_Interact_Evaluate(Memory, State, Point->IsSelected, Point->Pos, Keyframe_LocalPos_);
+ */
+ v2 Offset = V2(State->Interact_Offset[0], State->Interact_Offset[1]);
+ if (State->Interact_Active == interact_type_keyframe_move) {
+ Keyframe_LocalPos_[0].x += (Offset.x / TimelineZoomSize.x) / Increment.x;
+ Keyframe_LocalPos_[0].y -= ((Offset.y / TimelineZoomSize.y)) * (GraphInfo.MaxVal - GraphInfo.MinVal);
+ }
+ // Keyframe_Interact_Evaluate(Memory, State, Point->IsSelected, Point->Pos, Keyframe_LocalPos_);
}
ImVec2 Keyframe_LocalPos[3] = { V2(Keyframe_LocalPos_[0]), V2(Keyframe_LocalPos_[0] + Keyframe_LocalPos_[1]), V2(Keyframe_LocalPos_[0] + Keyframe_LocalPos_[2]) };
ImVec2 Keyframe_LocalPos_Ratio[3];
for (int b = 0; b < 3; b++) {
Keyframe_LocalPos_Ratio[b] = (Keyframe_LocalPos[b] - ImVec2(0, GraphInfo.MinVal)) * ImVec2(Increment.x, Y_Increment);
- Keyframe_ScreenPos[NewIdx + b] = Layer_ScreenPos_Min + ((ImVec2(1, -1) * Keyframe_LocalPos_Ratio[b] + ImVec2(0, 0.5)) * TimelineZoomSize) + ImVec2(0, Layer_ScreenSize.y/2);
+ // Keyframe_ScreenPos[NewIdx + b] = Layer_ScreenPos_Min + ((ImVec2(1, -1) * Keyframe_LocalPos_Ratio[b] + ImVec2(0, 0.5)) * TimelineZoomSize) + ImVec2(0, Layer_ScreenSize.y/2);
+ Keyframe_ScreenPos[NewIdx + b] = TimelineAbsolutePos + TimelineMoveSize + ((ImVec2(1, -1) * Keyframe_LocalPos_Ratio[b] + ImVec2(0, 1)) * TimelineZoomSize);
}
if (UI->BoxSelect) {
@@ -1098,8 +1182,8 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
int32 Frame_Start = Layer->Frame_Start;
int32 Frame_End = Layer->Frame_End;
real32 Vertical_Offset = SortEntry.SortedOffset;
- // if (Layer->IsSelected)
- // Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End, &Vertical_Offset);
+ if (Layer->IsSelected)
+ Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End);
ImVec2 Layer_LocalPos = ImVec2(Frame_Start, Vertical_Offset);
ImVec2 Layer_LocalSize = ImVec2(Frame_End - Frame_Start, Layer->Vertical_Height);
@@ -1118,6 +1202,11 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
else
Test = (Layer_ScreenPos_Max.y <= io.MouseClickedPos[0].y && Layer_ScreenPos_Max.y >= io.MousePos.y);
+ if (io.MouseClickedPos[0].x < io.MousePos.x)
+ Test &= (Layer_ScreenPos_Max.x >= io.MouseClickedPos[0].x && Layer_ScreenPos_Min.x <= io.MousePos.x);
+ else
+ Test &= (Layer_ScreenPos_Min.x <= io.MouseClickedPos[0].x && Layer_ScreenPos_Max.x >= io.MousePos.x);
+
if (Test) {
if (!Layer->IsSelected) {
Layer->IsSelected = true;
@@ -1146,6 +1235,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
}
if (ImGui::IsItemActive()) {
if (ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) {
+ Assert(Layer->IsSelected);
State->Interact_Active = interact_type_layer_timeadjust;
ImVec2 DragDelta = ImGui::GetMouseDragDelta();
DragDelta = DragDelta + (ImVec2(UI->Warp_X, UI->Warp_Y) * TimelineSize);
@@ -1157,19 +1247,21 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
}
if (ImGui::IsItemDeactivated()) {
if (State->Interact_Active == interact_type_layer_timeadjust) {
- Assert(0);
- /*
+ History_Entry_Commit(Memory, "Adjust layer timing");
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_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Layer->Frame_Start, &Layer->Frame_End, &Layer->Vertical_Offset);
- // }
+ if (Layer->IsSelected) {
+ // NOTE(fox): Some data on the tree could be saved here.
+ History_Action_Swap(Memory, F_File, sizeof(Layer->Frame_Start), &Layer->Frame_Start);
+ History_Action_Swap(Memory, F_File, sizeof(Layer->Frame_End), &Layer->Frame_End);
+ Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Layer->Frame_Start, &Layer->Frame_End);
+ }
}
+ History_Entry_End(Memory);
State->Interact_Active = interact_type_none;
State->Interact_Offset[0] = 0;
State->Interact_Offset[1] = 0;
- */
}
}
@@ -1186,6 +1278,70 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
}
}
+ ImGui::OpenPopupOnItemClick("layerpopup", ImGuiPopupFlags_MouseButtonRight);
+ if (ImGui::BeginPopup("layerpopup")) {
+ if (ImGui::MenuItem("Pre-compose layer")) {
+ History_Entry_Commit(Memory, "Pre-compose layer");
+ block_composition *NewComp = Precomp_Init(File, Memory);
+ NewComp->Width = Comp->Width;
+ NewComp->Height = Comp->Height;
+ NewComp->FPS = Comp->FPS;
+ NewComp->BytesPerPixel = Comp->BytesPerPixel;
+ NewComp->Frame_Count = Comp->Frame_Count;
+ NewComp->Frame_Start = Comp->Frame_Start;
+ NewComp->Frame_End = Comp->Frame_End;
+ int32 TopOffset = 0;
+ for (int i = SortedCompInfo.LayerCount - 1; i >= 0; i--)
+ {
+ sorted_layer SortEntry = SortedLayerInfo[i];
+ uint32 Index_Physical = SortEntry.Block_Layer_Index;
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
+ if (Layer->IsSelected) {
+ TopOffset = Layer->Vertical_Offset;
+ break;
+ }
+ }
+ for (int i = SortedCompInfo.LayerCount - 1; i >= 0; i--)
+ {
+ sorted_layer SortEntry = SortedLayerInfo[i];
+ uint32 Index_Physical = SortEntry.Block_Layer_Index;
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
+ if (Layer->IsSelected) {
+ History_Action_Swap(Memory, F_File, sizeof(Layer->Block_Composition_Index), &Layer->Block_Composition_Index);
+ Layer->Block_Composition_Index = 1;
+ }
+ }
+ block_layer *PrecompLayer = Layer_Init(File, Memory);
+ PrecompLayer->IsPrecomp = true;
+ PrecompLayer->Block_Source_Index = 1;
+ PrecompLayer->Block_Composition_Index = 0;
+ PrecompLayer->Vertical_Offset = TopOffset;
+ PrecompLayer->Frame_End = NewComp->Frame_End;
+ PrecompLayer->ColIndex = 3;
+ PrecompLayer->x.CurrentValue = Comp->Width/2;
+ PrecompLayer->y.CurrentValue = Comp->Height/2;
+ History_Entry_End(Memory);
+ State->UpdateFrame = true;
+ }
+ if (ImGui::BeginMenu("Layer color"))
+ {
+ ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
+ for (int c = 0; c < AmountOf(UI->LayerColors); c++) {
+ ImGui::PushID(c);
+ ImGui::PushStyleColor(ImGuiCol_Button, UI->LayerColors[c]);
+ real32 Size = ImGui::GetFontSize() * 2;
+ ImVec2 ColSize(Size, Size);
+ ImGui::Button("##test", ColSize);
+ if ((c+1) % 4) { ImGui::SameLine(); }
+ ImGui::PopStyleColor();
+ ImGui::PopID();
+ }
+ ImGui::PopStyleVar();
+ ImGui::EndMenu();
+ }
+ ImGui::EndPopup();
+ }
+
if (ImGui::IsItemActive()) {
if (ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) {
if (State->Interact_Active == interact_type_none) {
@@ -1218,8 +1374,12 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
uint32 Index_Physical = SortEntry.Block_Layer_Index;
block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
if (Layer->IsSelected) {
+ // NOTE(fox): Some data on the tree could be saved here.
History_Action_Swap(Memory, F_File, sizeof(Layer->Vertical_Offset), &Layer->Vertical_Offset);
+ History_Action_Swap(Memory, F_File, sizeof(Layer->Frame_Start), &Layer->Frame_Start);
+ History_Action_Swap(Memory, F_File, sizeof(Layer->Frame_End), &Layer->Frame_End);
Layer->Vertical_Offset = SortEntry.SortedOffset;
+ Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Layer->Frame_Start, &Layer->Frame_End);
}
}
State->Interact_Active = interact_type_none;
@@ -1243,8 +1403,8 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
int32 Frame_Start = Layer->Frame_Start;
int32 Frame_End = Layer->Frame_End;
real32 Vertical_Offset = SortEntry.SortedOffset;
- // if (Layer->IsSelected)
- // Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End, &Vertical_Offset);
+ if (Layer->IsSelected)
+ Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End);
ImVec2 Layer_LocalPos = ImVec2(Frame_Start, Vertical_Offset);
ImVec2 Layer_LocalSize = ImVec2(Frame_End - Frame_Start, Layer->Vertical_Height);
@@ -1298,8 +1458,8 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
int32 Frame_Start = Layer->Frame_Start;
int32 Frame_End = Layer->Frame_End;
real32 Vertical_Offset = SortEntry.SortedOffset;
- // if (Layer->IsSelected)
- // Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End, &Vertical_Offset);
+ if (Layer->IsSelected)
+ Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End);
ImVec2 Layer_LocalPos = ImVec2(Frame_Start, Vertical_Offset);
ImVec2 Layer_LocalSize = ImVec2(Frame_End - Frame_Start, Layer->Vertical_Height);
@@ -1311,6 +1471,9 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
ImU32 LayerColor = 0;
ImU32 BorderColor = 0;
+ LayerColor = ImColor(UI->LayerColors[Layer->ColIndex]);
+ BorderColor = ImColor(0.2, 0.2, 0.2, 1.0f);
+ /*
if (UI->TimelineMode == timeline_mode_graph) {
LayerColor = ImColor(UI->LayerColors[Layer->ColIndex]);
BorderColor = ImColor(0.3, 0.3, 0.3, 1.0f);
@@ -1318,11 +1481,14 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
LayerColor = ImColor(UI->LayerColors[Layer->ColIndex]);
BorderColor = ImColor(0.2, 0.2, 0.2, 1.0f);
}
+ */
draw_list->AddRectFilled(Layer_ScreenPos_Min, Layer_ScreenPos_Max, LayerColor);
draw_list->AddRect(Layer_ScreenPos_Min, Layer_ScreenPos_Max, BorderColor, 2);
// block_string *String = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, Layer->Block_String_Index);
- // draw_list->AddText(Layer_ScreenPos_Min, 0xFFFFFFFF, String->Char);
+ char buf[21];
+ sprintf(buf, "%.2f, %.2f", Layer->Vertical_Offset, SortEntry.SortedOffset);
+ draw_list->AddText(Layer_ScreenPos_Min, 0xFFFFFFFF, buf);
if (Layer->IsSelected) {
draw_list->AddRectFilled(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(0.25f, 0.25f, 0.25f, 0.5f), 2);
@@ -1392,32 +1558,54 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
ImVec2 Val_Min(0, 0);
ImVec2 Val_Max(40, LayerIncrement);
- if (UI->TimelinePercentZoomed.x == 0) {
- UI->TimelinePercentZoomed = ImVec2(1, 1);
+ // ImVec2 *ActivePercentZoomed = (UI->TimelineMode != timeline_mode_graph) ? &UI->TimelinePercentZoomed : &UI->GraphPercentZoomed;
+ // ImVec2 *ActivePercentOffset = (UI->TimelineMode != timeline_mode_graph) ? &UI->TimelinePercentOffset : &UI->GraphPercentOffset;
+ ImVec2 *ActivePercentZoomed = &UI->TimelinePercentZoomed;
+ ImVec2 *ActivePercentOffset = &UI->TimelinePercentOffset;
+
+ if (ActivePercentZoomed->x == 0) {
+ *ActivePercentZoomed = ImVec2(1, 1);
}
+ ImVec2 ActiveZoomSize = TimelineSizeWithBorder / *ActivePercentZoomed;
+ ImVec2 ActiveMoveSize = TimelineSizeWithBorder * *ActivePercentOffset / *ActivePercentZoomed;
+
ImVec2 TimelineZoomSize = TimelineSizeWithBorder / UI->TimelinePercentZoomed;
ImVec2 TimelineMoveSize = TimelineSizeWithBorder * UI->TimelinePercentOffset / UI->TimelinePercentZoomed;
+ DebugWatchVar("TimelineY: ", &TimelineMoveSize.y, d_float);
+
ImGui_TimelineHorizontalIncrementDraw(State, UI, draw_list, TimelineSizeWithBorder, TimelineAbsolutePos, *MainComp, TimelineZoomSize, TimelineMoveSize);
ImVec2 Increment = ImVec2((real32)1 / MainComp->Frame_Count, (real32)1 / LayerIncrement);
-
ImGui_Timeline_DrawPrecomp(File, State, Memory, UI, io, draw_list, File->PrincipalCompIndex,
Increment, TimelineAbsolutePos, TimelineMoveSize, TimelineZoomSize,
TimelineSize, TimelineSizeWithBorder, LayerIncrement,
SortedCompArray, SortedLayerArray);
if (UI->TimelineMode == timeline_mode_graph) {
- // uint64 Keyframe_SortSize = (sizeof(sorted_comp_info) * File->Comp_Count) + (sizeof(sorted_layer) * File->Layer_Count);
- // void *SortedArray = Memory_PushScratch(Memory, Keyframe_SortSize);
- // Arbitrary_Zero((uint8 *)SortedArray, SortSize);
+
+ if (UI->GraphMoveSize.y == 0) {
+ UI->GraphZoomSize = ImVec2(1, UI->TimelinePercentZoomed.y );
+ UI->GraphMoveSize = ImVec2(0, -UI->TimelinePercentOffset.y );
+ }
+
+ ImVec2 ZoomDifference = (UI->TimelinePercentZoomed / UI->GraphZoomSize);
+ ImVec2 MoveDifference = (UI->TimelinePercentOffset + (UI->GraphMoveSize));
+ DebugWatchVar("zoomdif: ", &ZoomDifference.y, d_float);
+ DebugWatchVar("movedif: ", &MoveDifference.y, d_float);
+ ImVec2 GraphZoomSize = TimelineSizeWithBorder / ZoomDifference;
+ ImVec2 GraphMoveSize = TimelineSizeWithBorder * (MoveDifference) / UI->TimelinePercentZoomed;
+ DebugWatchVar("zoomsize: ", &GraphZoomSize.y, d_float);
+ DebugWatchVar("movesize: ", &GraphMoveSize.y, d_float);
+
+ draw_list->AddRectFilled(WindowMinAbs, WindowMaxAbs,
+ IM_COL32(50, 50, 50, 150));
graph_info GraphInfo = Graph_GetInfo(File, Memory);
ImGui_Timeline_DrawGraph(File, State, Memory, UI, io, draw_list, GraphInfo,
- Increment, TimelineAbsolutePos, TimelineMoveSize, TimelineZoomSize,
+ Increment, TimelineAbsolutePos, GraphMoveSize, GraphZoomSize,
TimelineSize, TimelineSizeWithBorder, LayerIncrement);
- // Memory_PopScratch(Memory, Keyframe_SortSize);
}
ImVec2 MouseDelta = io.MouseDelta / TimelineSize;
@@ -1426,8 +1614,8 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
real32 BarThickness = 50;
real32 BarMinZoom = 0.01;
- real32 BarH_Pos = -TimelineSizeWithBorder.x * UI->TimelinePercentOffset.x;
- real32 BarH_Size = TimelineSizeWithBorder.x / (1 / UI->TimelinePercentZoomed.x);
+ real32 BarH_Pos = -TimelineSizeWithBorder.x * ActivePercentOffset->x;
+ real32 BarH_Size = TimelineSizeWithBorder.x / (1 / ActivePercentZoomed->x);
// I use "UI" to denote the size/position after clipping the bar so that it
// doesn't go out of bounds and the handles are always selectable at the edges.
@@ -1454,9 +1642,9 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
if ((ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)))
{
- if ((UI->TimelinePercentZoomed.x - MouseDelta.x) > BarMinZoom) {
- UI->TimelinePercentZoomed.x -= MouseDelta.x;
- UI->TimelinePercentOffset.x -= MouseDelta.x;
+ if ((ActivePercentZoomed->x - MouseDelta.x) > BarMinZoom) {
+ ActivePercentZoomed->x -= MouseDelta.x;
+ ActivePercentOffset->x -= MouseDelta.x;
}
BarHeld = true;
}
@@ -1466,7 +1654,7 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
if (ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1))
{
- UI->TimelinePercentOffset.x -= MouseDelta.x;
+ ActivePercentOffset->x -= MouseDelta.x;
BarHeld = true;
}
@@ -1475,8 +1663,8 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
if ((ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)))
{
- if ((UI->TimelinePercentZoomed.x + MouseDelta.x) > BarMinZoom) {
- UI->TimelinePercentZoomed.x += MouseDelta.x;
+ if ((ActivePercentZoomed->x + MouseDelta.x) > BarMinZoom) {
+ ActivePercentZoomed->x += MouseDelta.x;
}
BarHeld = true;
}
@@ -1485,11 +1673,11 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
ImGui_WarpMouse(UI, io.MousePos, TimelineAbsolutePos, TimelineAbsolutePos + TimelineSizeWithBorder, 1);
}
- Assert(UI->TimelinePercentZoomed.x > BarMinZoom);
+ Assert(ActivePercentZoomed->x > BarMinZoom);
real32 BarV_MaxSize = TimelineSizeWithBorder.y - BarThickness/2;
- real32 BarV_Pos = -BarV_MaxSize * UI->TimelinePercentOffset.y;
- real32 BarV_Size = BarV_MaxSize / (1 / UI->TimelinePercentZoomed.y);
+ real32 BarV_Pos = -BarV_MaxSize * ActivePercentOffset->y;
+ real32 BarV_Size = BarV_MaxSize / (1 / ActivePercentZoomed->y);
BarV_Size = Max(BarV_Size, FontHeight*4);
real32 BarV_Offset = Max(BarV_Pos, 0);
@@ -1514,8 +1702,8 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
if ((ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)))
{
- UI->TimelinePercentZoomed.y -= MouseDelta.y;
- UI->TimelinePercentOffset.y -= MouseDelta.y;
+ ActivePercentZoomed->y -= MouseDelta.y;
+ ActivePercentOffset->y -= MouseDelta.y;
BarHeld = true;
}
@@ -1524,12 +1712,12 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
if (ImGui::IsItemHovered() && io.MouseWheel)
{
- UI->TimelinePercentOffset.y -= io.MouseWheel/10;
+ ActivePercentOffset->y -= io.MouseWheel/10;
}
if (ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1))
{
- UI->TimelinePercentOffset.y -= MouseDelta.y;
+ ActivePercentOffset->y -= MouseDelta.y;
BarHeld = true;
}
@@ -1538,11 +1726,11 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
if ((ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)))
{
- UI->TimelinePercentZoomed.y += MouseDelta.y;
+ ActivePercentZoomed->y += MouseDelta.y;
BarHeld = true;
}
- UI->TimelinePercentZoomed.y = Max(UI->TimelinePercentZoomed.y, 0.01);
+ ActivePercentZoomed->y = Max(ActivePercentZoomed->y, 0.01);
if (BarHeld) {
ImGui_WarpMouse(UI, io.MousePos, TimelineAbsolutePos, TimelineAbsolutePos + TimelineSizeWithBorder, 2);
@@ -1558,91 +1746,74 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
bool32 LeftClick = ImGui::IsMouseDown(ImGuiMouseButton_Left);
bool32 RightClick = ImGui::IsMouseDown(ImGuiMouseButton_Right);
- ImGui::OpenPopupOnItemClick("layercolor", ImGuiPopupFlags_MouseButtonRight);
- if (ImGui::BeginPopup("layercolor")) {
- ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
- for (int c = 0; c < AmountOf(UI->LayerColors); c++) {
- ImGui::PushID(c);
- ImGui::PushStyleColor(ImGuiCol_Button, UI->LayerColors[c]);
- real32 Size = ImGui::GetFontSize() * 2;
- ImVec2 ColSize(Size, Size);
- ImGui::Button("##test", ColSize);
- if ((c+1) % 4) { ImGui::SameLine(); }
- ImGui::PopStyleColor();
- ImGui::PopID();
- }
- ImGui::PopStyleVar();
- ImGui::EndPopup();
- }
-
if (IsHovered && io.MouseWheel) {
real32 Increment = 0.1;
bool32 Direction = (io.MouseWheel > 0) ? 1 : -1;
- ImVec2 Offset = (io.MousePos - (TimelineAbsolutePos + TimelineMoveSize)) / TimelineZoomSize;
+ ImVec2 Offset = (io.MousePos - (TimelineAbsolutePos + ActiveMoveSize)) / ActiveZoomSize;
if (io.KeyShift) {
- UI->TimelinePercentOffset.y += Increment*Direction;
+ ActivePercentOffset->y += Increment*Direction;
} else if (io.KeyCtrl) {
- UI->TimelinePercentOffset.x += Increment*Direction*0.3;
+ ActivePercentOffset->x += Increment*Direction*0.3;
} else {
if (Direction == 1) {
- UI->TimelinePercentZoomed = UI->TimelinePercentZoomed - (UI->TimelinePercentZoomed * Increment);
- UI->TimelinePercentOffset = UI->TimelinePercentOffset - ((UI->TimelinePercentOffset * Increment) + Offset*Increment);
+ *ActivePercentZoomed = *ActivePercentZoomed - (*ActivePercentZoomed * Increment);
+ *ActivePercentOffset = *ActivePercentOffset - ((*ActivePercentOffset * Increment) + Offset*Increment);
} else {
- UI->TimelinePercentOffset = ((UI->TimelinePercentOffset + Offset*Increment) / (1.0f - Increment));
- UI->TimelinePercentZoomed = (UI->TimelinePercentZoomed / (1.0f - Increment));
+ *ActivePercentOffset = ((*ActivePercentOffset + Offset*Increment) / (1.0f - Increment));
+ *ActivePercentZoomed = (*ActivePercentZoomed / (1.0f - Increment));
}
}
}
- if (IsItemActivated) {
- if (!io.KeyShift && UI->TimelineMode == timeline_mode_default) Layer_DeselectAll(Memory, File->Layer_Count);
- if (State->Interact_Active == interact_type_keyframe_move ||
- State->Interact_Active == interact_type_keyframe_rotate ||
- State->Interact_Active == interact_type_keyframe_scale) {
- 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)
- continue;
- for (int h = 0; h < AmountOf(Layer->Property); h++) {
- property_channel *Property = &Layer->Property[h];
- if (Property->Block_Bezier_Count) {
- int k = 0;
- for (;;) {
- bezier_point *Point = Bezier_Lookup(Memory, Property, k);
- if (!Point->Occupied)
- break;
- if (Point->IsSelected) {
- Keyframe_Interact_Evaluate(Memory, State, Point->IsSelected, Point->Pos, Point->Pos);
+ if (LeftClick) {
+ if (IsItemActivated) {
+ if (!io.KeyShift && UI->TimelineMode == timeline_mode_default) Layer_DeselectAll(Memory, File->Layer_Count);
+ if (State->Interact_Active == interact_type_keyframe_move ||
+ State->Interact_Active == interact_type_keyframe_rotate ||
+ State->Interact_Active == interact_type_keyframe_scale) {
+ 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)
+ continue;
+ for (int h = 0; h < AmountOf(Layer->Property); h++) {
+ property_channel *Property = &Layer->Property[h];
+ if (Property->Block_Bezier_Count) {
+ int k = 0;
+ for (;;) {
+ bezier_point *Point = Bezier_Lookup(Memory, Property, k);
+ if (!Point->Occupied)
+ break;
+ if (Point->IsSelected) {
+ Keyframe_Interact_Evaluate(Memory, State, Point->IsSelected, Point->Pos, Point->Pos);
+ }
+ k++;
}
- k++;
}
}
}
+ State->Interact_Offset[0] = 0;
+ State->Interact_Offset[1] = 0;
+ State->Interact_Offset[2] = 0;
+ State->Interact_Offset[3] = 0;
+ State->Interact_Active = interact_type_none;
}
- State->Interact_Offset[0] = 0;
- State->Interact_Offset[1] = 0;
- State->Interact_Offset[2] = 0;
- State->Interact_Offset[3] = 0;
- State->Interact_Active = interact_type_none;
+ UI->BoxSelect = true;
}
- UI->BoxSelect = true;
- }
- if (IsItemActive) {
- Assert(UI->BoxSelect);
- draw_list->AddRectFilled(io.MouseClickedPos[0], io.MousePos,
- IM_COL32(0, 0, 200, 50));
+ if (IsItemActive) {
+ Assert(UI->BoxSelect);
+ draw_list->AddRectFilled(io.MouseClickedPos[0], io.MousePos,
+ IM_COL32(0, 0, 200, 50));
+ }
+ } else {
+ UI->Warp_X = 0;
+ UI->Warp_Y = 0;
}
if (IsItemDeactivated) {
UI->BoxSelect = false;
}
- if (!ImGui::IsMouseDown(ImGuiMouseButton_Left)) {
- UI->Warp_X = 0;
- UI->Warp_Y = 0;
- }
-
draw_list->PopClipRect();
ImGui::PopClipRect();
@@ -1684,8 +1855,10 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me
if (ImGui::IsKeyPressed(ImGuiKey_B)) {
State->Tool = tool_brush;
}
- if (ImGui::IsKeyPressed(ImGuiKey_T)) {
- Interact_Transform_Begin(File, Memory, State, io.MousePos);
+ if (ImGui::IsKeyPressed(ImGuiKey_Tab)) {
+ UI->TimelineMode = (UI->TimelineMode == timeline_mode_default) ? timeline_mode_graph : timeline_mode_default;
+ UI->GraphZoomSize = ImVec2(0, 0);
+ UI->GraphMoveSize = ImVec2(0, 0);
}
if (UI->TimelineMode == timeline_mode_graph) {
if (ImGui::IsKeyPressed(ImGuiKey_G)) {
@@ -1716,7 +1889,7 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me
if (ImGui::IsKeyPressed(ImGuiKey_Space)) {
State->IsPlaying ^= 1;
}
- if (ImGui::IsKeyPressed(ImGuiKey_T)) {
+ if (ImGui::IsKeyPressed(ImGuiKey_2)) {
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);
diff --git a/prenderer.cpp b/prenderer.cpp
index dcb4577..58e1b22 100644
--- a/prenderer.cpp
+++ b/prenderer.cpp
@@ -63,13 +63,13 @@ Transform_ApplyInteractive(interact_transform Interact, real32 *OutputX, real32
}
static void
-Transform_IterateOuterBounds(block_layer *Layer, block_source *Source, real32 *MinX, real32 *MinY, real32 *MaxX, real32 *MaxY)
+Transform_IterateOuterBounds(block_layer *Layer, uint32 Width, uint32 Height, real32 *MinX, real32 *MinY, real32 *MaxX, real32 *MaxY)
{
real32 Rad = (Layer->rotation.CurrentValue * (PI / 180));
real32 s = Layer->scale.CurrentValue;
- v2 XAxis = (Source->Width * s)*V2(cos(Rad), sin(Rad));
- v2 YAxis = (Source->Height * -s)*V2(sin(Rad), -cos(Rad));
+ v2 XAxis = (Width * s)*V2(cos(Rad), sin(Rad));
+ v2 YAxis = (Height * -s)*V2(sin(Rad), -cos(Rad));
real32 AnchorX = Layer->ax.CurrentValue;
real32 AnchorY = Layer->ay.CurrentValue;
@@ -89,23 +89,109 @@ Transform_IterateOuterBounds(block_layer *Layer, block_source *Source, real32 *M
}
}
+static void
+Transform_Recurse(project_state *State, memory *Memory, block_composition *MainComp, uint32 CompIndex, block_layer *ParentLayer[4], uint32 Recursions,
+ sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray,
+ real32 *MinX, real32 *MinY, real32 *MaxX, real32 *MaxY)
+{
+ sorted_comp_info *SortedCompInfo = &SortedCompArray[CompIndex];
+ sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, CompIndex);
+ for (int i = 0; i < SortedCompInfo->LayerCount; i++)
+ {
+ sorted_layer SortEntry = SortedLayerInfo[i];
+ uint32 Index_Physical = SortEntry.Block_Layer_Index;
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
+ if (Layer->IsPrecomp) {
+ ParentLayer[Recursions] = Layer;
+ Transform_Recurse(State, Memory, MainComp, Layer->Block_Source_Index, ParentLayer, Recursions + 1, SortedCompArray, SortedLayerArray,
+ MinX, MinY, MaxX, MaxY);
+ }
+ if (Layer->IsSelected) {
+ uint32 Width = 0, Height = 0;
+ if (!Layer->IsPrecomp) {
+ block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index);
+ Width = Source->Width;
+ Height = Source->Height;
+ } else {
+ block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, Layer->Block_Source_Index);
+ Width = Comp->Width;
+ Height = Comp->Height;
+ }
+
+ v2 Point[5] = { V2(Width*Layer->ax.CurrentValue, Height*Layer->ay.CurrentValue), V2(0, 0), V2(Width, 0), V2(0, Height), V2(Width, Height) };
+
+ layer_transforms T = Layer_GetTransforms(Layer);
+
+ v2 NewPos[5];
+ for (int i = 0; i < 5; i++) {
+ NewPos[i] = TransformPoint(T, Width, Height, Point[i]);
+ }
+
+ int i = 0;
+ while (i < Recursions) {
+ T = Layer_GetTransforms(ParentLayer[i]);
+ block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, ParentLayer[i]->Block_Source_Index);
+ Width = Comp->Width;
+ Height = Comp->Height;
+ for (int i = 0; i < 5; i++) {
+ NewPos[i] = TransformPoint(T, Width, Height, NewPos[i]);
+ }
+ i++;
+ }
+
+ for (int i = 0; i < 4; i++) {
+ if (NewPos[i+1].x < *MinX) { *MinX = NewPos[i+1].x; }
+ if (NewPos[i+1].y < *MinY) { *MinY = NewPos[i+1].y; }
+ if (NewPos[i+1].x > *MaxX) { *MaxX = NewPos[i+1].x; }
+ if (NewPos[i+1].y > *MaxY) { *MaxY = NewPos[i+1].y; }
+ }
+ }
+ }
+}
+
// IMPORTANT(fox): The selection state and ordering of layers cannot change
// until this action is exited/committed!
static void
-Interact_Transform_Begin(project_data *File, memory *Memory, project_state *State, ImVec2 OGPos)
+Interact_Transform_Begin(project_data *File, memory *Memory, project_state *State, ImVec2 OGPos,
+ sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray)
{
real32 MinX = 100000;
real32 MinY = 100000;
real32 MaxX = -100000;
real32 MaxY = -100000;
+ block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex);
+ block_layer *ParentLayer[4];
+ Transform_Recurse(State, Memory, MainComp, File->PrincipalCompIndex, ParentLayer, 0,
+ SortedCompArray, SortedLayerArray,
+ &MinX, &MinY, &MaxX, &MaxY);
+ if (MinX != 100000) {
+ State->Interact_Active = interact_type_viewport_transform;
+ interact_transform *Interact = (interact_transform *)&State->Interact_Offset[0];
+ Interact->Min = V2(MinX, MinY);
+ Interact->Max = V2(MaxX, MaxY);
+ Interact->Position = V2(0);
+ Interact->Radians = 0;
+ Interact->Scale = 1.0f;
+ Interact->OGPos = OGPos;
+ }
+ /*
bool32 Activate = false;
// Find the max dimensions of all the selected layers.
for (int i = 0; i < File->Layer_Count; i++) {
block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
if (!Layer->IsSelected)
continue;
- block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index);
- Transform_IterateOuterBounds(Layer, Source, &MinX, &MinY, &MaxX, &MaxY);
+ uint32 Width = 0, Height = 0;
+ if (!Layer->IsPrecomp) {
+ block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index);
+ Width = Source->Width;
+ Height = Source->Height;
+ } else {
+ block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, Layer->Block_Source_Index);
+ Width = Comp->Width;
+ Height = Comp->Height;
+ }
+ Transform_IterateOuterBounds(Layer, Width, Height, &MinX, &MinY, &MaxX, &MaxY);
Activate = true;
}
if (Activate) {
@@ -118,30 +204,51 @@ Interact_Transform_Begin(project_data *File, memory *Memory, project_state *Stat
Interact->Scale = 1.0f;
Interact->OGPos = OGPos;
}
+ */
+}
+
+static v2
+TransformPoint(layer_transforms T, real32 Width, real32 Height, v2 Point)
+{
+ real32 Rad = (T.rotation * (PI / 180));
+ v2 XAxis = (Point.x - T.ax*Width) * T.scale * V2(cos(Rad), sin(Rad));
+ v2 YAxis = (Point.y - T.ay*Height) * -T.scale * V2(sin(Rad), -cos(Rad));
+ v2 LocalPoint = XAxis + YAxis;
+ return V2(T.x + LocalPoint.x, T.y + LocalPoint.y);
}
+
static ImVec2
-Layer_LocalToScreenSpace(project_state *State, block_layer *Layer, ui *UI,
- real32 SourceWidth, real32 SourceHeight, real32 CompWidth, real32 CompHeight, v2 Point)
+Layer_LocalToScreenSpace(project_state *State, memory *Memory, block_layer *Layer, ui *UI, uint32 PrincipalCompIndex, v2 Point)
{
- real32 Rotation = Layer->rotation.CurrentValue;
- real32 s = Layer->scale.CurrentValue;
- real32 X = Layer->x.CurrentValue;
- real32 Y = Layer->y.CurrentValue;
+ block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, PrincipalCompIndex);
+
+ uint32 Width = 0, Height = 0;
+ if (!Layer->IsPrecomp) {
+ block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index);
+ Width = Source->Width;
+ Height = Source->Height;
+ } else {
+ block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, Layer->Block_Source_Index);
+ Width = Comp->Width;
+ Height = Comp->Height;
+ }
+
+ layer_transforms T = Layer_GetTransforms(Layer);
if (State->Interact_Active == interact_type_viewport_transform && Layer->IsSelected) {
- Transform_ApplyInteractive(*(interact_transform *)&State->Interact_Offset[0], &X, &Y, &Rotation, &s);
+ Transform_ApplyInteractive(*(interact_transform *)&State->Interact_Offset[0], &T.x, &T.y, &T.rotation, &T.scale);
}
- real32 Rad = (Rotation * (PI / 180));
- real32 AX = Layer->ax.CurrentValue;
- real32 AY = Layer->ay.CurrentValue;
+ v2 NewPos = TransformPoint(T, Width, Height, Point);
+
+ if (Layer->Block_Composition_Index != PrincipalCompIndex) {
+ layer_transforms T = Layer_GetTransforms(Layer);
+ NewPos = TransformPoint(T, Width, Height, NewPos);
+ }
+
+ v2 CompUV = NewPos / V2(MainComp->Width, MainComp->Height);
- v2 XAxis = (Point.x - AX*SourceWidth) * s * V2(cos(Rad), sin(Rad));
- v2 YAxis = (Point.y - AY*SourceHeight) * -s * V2(sin(Rad), -cos(Rad));
- v2 LocalPoint = XAxis + YAxis;
- v2 CompUV = V2((X + LocalPoint.x) / CompWidth,
- (Y + LocalPoint.y) / CompHeight);
v2 ScreenPoint = V2(UI->CompPos.x + CompUV.x * UI->CompZoom.x,
UI->CompPos.y + CompUV.y * UI->CompZoom.y);