summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFox Caminiti <fox@foxcam.net>2022-11-11 21:55:34 -0500
committerFox Caminiti <fox@foxcam.net>2022-11-11 21:55:34 -0500
commitc27530c79fd135c499a52b222e9cec16aa1951ad (patch)
treef77b7c339a5607b053cef143d659f8f959f6fd63
parent38bf0102300c97335d8e78b4683cb9b9476dcde0 (diff)
graph improvements
-rw-r--r--createcalls.cpp195
-rw-r--r--functions.h3
-rw-r--r--main.cpp100
-rw-r--r--main.h29
-rw-r--r--memory.cpp11
-rw-r--r--my_imgui_widgets.cpp110
6 files changed, 234 insertions, 214 deletions
diff --git a/createcalls.cpp b/createcalls.cpp
index 176fc2f..01f1caa 100644
--- a/createcalls.cpp
+++ b/createcalls.cpp
@@ -67,13 +67,37 @@ Source_Generate(project_data *File, project_state *State, memory *Memory, void *
}
static bezier_point *
-Bezier_Lookup(memory *Memory, property_channel *Property, uint16 Index)
+Bezier_LookupAddress(memory *Memory, property_channel *Property, uint16 Index)
{
Assert(Index < MAX_KEYFRAMES_PER_BLOCK);
block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Property->Block_Bezier_Index[0]);
return &Bezier->Point[Index];
}
+/*
+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);
+ real32 Slope_Old = (Keyframe_ScreenPos.y - State->Interact_Offset[3]) / (Keyframe_ScreenPos.x - State->Interact_Offset[2]);
+ real32 Slope_New = (Keyframe_ScreenPos.y - io.MousePos.y) / (Keyframe_ScreenPos.x - io.MousePos.x);
+ 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_);
+
+
+static void
+Bezier_EvaluateValue(project_state *State, bezier_point *PointAddress, v2 *Pos)
+{
+ Pos[0] = PointAddress->Pos[0];
+ Pos[1] = PointAddress->Pos[1];
+ Pos[2] = PointAddress->Pos[2];
+ if (State->Interact_Active == interact_type_keyframe_move && PointAddress->IsSelected) {
+ Pos[0].x += (int32)State->Interact_Offset[0];
+ }
+}
+
static void
Bezier_Add(memory *Memory, property_channel *Property, bezier_point PointData)
{
@@ -87,7 +111,7 @@ Bezier_Add(memory *Memory, property_channel *Property, bezier_point PointData)
}
int k = 0;
for (;;) {
- bezier_point *Point = Bezier_Lookup(Memory, Property, k);
+ bezier_point *Point = Bezier_LookupAddress(Memory, Property, k);
if (!Point->Occupied) {
History_Action_Swap(Memory, F_Bezier, sizeof(*Point), Point);
*Point = PointData;
@@ -110,45 +134,6 @@ 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 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;
- }
- return PropertyInfo;
-}
-
-static graph_info
-Graph_GetInfo(project_data *File, memory *Memory)
-{
- graph_info GraphInfo = {};
- for (int a = 0; a < File->Layer_Count; a++) {
- block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, a);
- if (!Layer->IsSelected)
- continue;
- for (int h = 0; h < AmountOf(Layer->Property); h++) {
- property_channel *Property = &Layer->Property[h];
- if (Property->Block_Bezier_Count) {
- property_info PropertyInfo = Property_GetInfo(Memory, Property);
- GraphInfo.MinVal = (PropertyInfo.MinVal < GraphInfo.MinVal) ? PropertyInfo.MinVal : GraphInfo.MinVal;
- GraphInfo.MaxVal = (PropertyInfo.MaxVal > GraphInfo.MaxVal) ? PropertyInfo.MaxVal : GraphInfo.MaxVal;
- }
- }
- GraphInfo.LowestOffset = (Layer->Vertical_Offset > GraphInfo.LowestOffset) ? Layer->Vertical_Offset : GraphInfo.LowestOffset;
- }
- return GraphInfo;
-}
-
static void
Keyframe_Interact_Evaluate(memory *Memory, project_state *State, uint8 IsSelected, v2 Pos_Initial[3], v2 Pos_New[3])
{
@@ -303,63 +288,98 @@ void Layer_RecursiveDeselect(memory *Memory, sorted_comp_info *SortedCompArray,
}
}
-void Layer_Sort_CheckPrev(memory *Memory, int i, int Direction, sorted_layer *SortedLayerInfo, sorted_comp_info SortedCompInfo, int *EntriesPassed, sorted_layer *LayerEntry)
+void Property_MinMax(memory *Memory, project_state *State, property_channel *Property, uint16 *ArrayLocation, v2 *Min, v2 *Max)
{
- int PrevOffsetIndex = i + Direction + (*EntriesPassed * Direction);
- bool32 OutOfBounds = (Direction > 0) ? (PrevOffsetIndex > (SortedCompInfo.LayerCount - 1)) : (PrevOffsetIndex < 0);
- if (!OutOfBounds) {
- sorted_layer *PrevLayerEntry = &SortedLayerInfo[PrevOffsetIndex];
- // block_layer *PrevLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, PrevLayerEntry->Block_Layer_Index);
- // real32 PrevOffset = PrevLayer->Vertical_Offset;
- real32 PrevOffset = PrevLayerEntry->SortedOffset;
- if (PrevOffset == (LayerEntry->SortedOffset - Direction)) {
- LayerEntry->SortedOffset -= Direction;
- (*EntriesPassed)++;
- Layer_Sort_CheckPrev(Memory, i, Direction, SortedLayerInfo, SortedCompInfo, EntriesPassed, LayerEntry);
- }
+ v2 FirstPointPos[3];
+ bezier_point *FirstPointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[0]);
+ Bezier_EvaluateValue(State, FirstPointAddress, FirstPointPos);
+ Min->x = FirstPointPos[0].x;
+ v2 LastPointPos[3];
+ bezier_point *LastPointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[Property->Keyframe_Count - 1]);
+ Bezier_EvaluateValue(State, LastPointAddress, LastPointPos);
+ Max->x = LastPointPos[0].x;
+ int32 Offset = (State->Interact_Active == interact_type_keyframe_move) ? (int32)State->Interact_Offset[0] : 0;
+ real32 MinY = FLT_MAX;
+ real32 MaxY = FLT_MIN;
+ for (int p = 0; p < Property->Keyframe_Count; p++) {
+ bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[p]);
+ MinY = (MinY < PointAddress->Pos[0].y) ? MinY : PointAddress->Pos[0].y;
+ MaxY = (MaxY > PointAddress->Pos[0].y) ? MaxY : PointAddress->Pos[0].y;
}
+ Min->y = MinY;
+ Max->y = MaxY;
}
-// TODO(fox): This _could_ be generalized with the layer sorting code...
+// The sorting algorithm is straightforward: read every point, evaluate it if
+// it's currently being interacted with by the user, record index in a sorted
+// list, and repeat, shiftig the list as necessary.
-/*
-Bezier_SortAll()
+void Property_SortAll(memory *Memory, project_state *State, property_channel *Property, uint16 *PropertyArrayStart)
{
- 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);
+ int h = 0, c = 0, i = 0;
+ uint32 CurrentSortIndex = 0;
+ int32 Offset = (State->Interact_Active == interact_type_keyframe_move) ? (int32)State->Interact_Offset[0] : 0;
+ while (Block_Loop(Memory, Property, Property->Keyframe_Count, &h, &c, &i)) {
+ v2 PointPos[3];
+ bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, i);
+ Bezier_EvaluateValue(State, PointAddress, PointPos);
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) {
+ uint16 TestPointEntry = PropertyArrayStart[SortedIndex_Playhead];
+ v2 TestPointPos[3];
+ bezier_point *TestPointAddress = Bezier_LookupAddress(Memory, Property, TestPointEntry);
+ Bezier_EvaluateValue(State, TestPointAddress, TestPointPos);
+ if (PointPos[0].x < TestPointPos[0].x ) {
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);
+ uint8 *Address_Start = (uint8 *)(PropertyArrayStart + SortedIndex_Playhead);
+ uint8 *Address_End = (uint8 *)(PropertyArrayStart + CurrentSortIndex) - 1;
+ Assert(CurrentSortIndex != Property->Keyframe_Count);
+ Arbitrary_ShiftData(Address_Start, Address_End, sizeof(uint16), 1);
}
- sorted_layer *LayerEntry = SortedLayerInfo + SortedIndex_Playhead;
- LayerEntry->Block_Layer_Index = i;
- LayerEntry->SortedOffset = Layer->Vertical_Offset;
+ uint16 *PointEntry = PropertyArrayStart + SortedIndex_Playhead;
+ *PointEntry = i;
CurrentSortIndex++;
}
}
-*/
-void Layer_SortAll(project_data *File, project_state *State, memory *Memory, sorted_layer *LayerArrayStart, sorted_comp_info *CompStart, uint32 LayerCount, uint32 CompCount)
+void Layer_Sort_CheckPrev(memory *Memory, int i, int Direction, sorted_layer *SortedLayerInfo, sorted_comp_info SortedCompInfo, int *EntriesPassed, sorted_layer *LayerEntry)
+{
+ int PrevOffsetIndex = i + Direction + (*EntriesPassed * Direction);
+ bool32 OutOfBounds = (Direction > 0) ? (PrevOffsetIndex > (SortedCompInfo.LayerCount - 1)) : (PrevOffsetIndex < 0);
+ if (!OutOfBounds) {
+ sorted_layer *PrevLayerEntry = &SortedLayerInfo[PrevOffsetIndex];
+ real32 PrevOffset = PrevLayerEntry->SortedOffset;
+ if (PrevOffset == (LayerEntry->SortedOffset - Direction)) {
+ LayerEntry->SortedOffset -= Direction;
+ (*EntriesPassed)++;
+ Layer_Sort_CheckPrev(Memory, i, Direction, SortedLayerInfo, SortedCompInfo, EntriesPassed, LayerEntry);
+ }
+ }
+}
+
+// The first loop is for counting how many layers are in each precomp, the
+// second is for sorting the layers by offset, and the third is for applying
+// interactivity if the user is moving any layers.
+
+void Layer_SortAll(project_data *File, project_state *State, memory *Memory, sorted_layer *LayerArrayStart, sorted_comp_info *CompStart, uint16 *SortedPropertyArray, uint32 LayerCount, uint32 CompCount)
{
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);
Assert(Layer->Block_Composition_Index < CompCount);
CompStart[Layer->Block_Composition_Index].LayerCount++;
+ for (int h = 0; h < AmountOf(Layer->Property); h++) {
+ property_channel *Property = &Layer->Property[h];
+ if (Property->Block_Bezier_Count) {
+ uint16 *ArrayLocation = SortedPropertyArray + (i * 7 * MAX_KEYFRAMES_PER_BLOCK) + (h * MAX_KEYFRAMES_PER_BLOCK);
+ Property_SortAll(Memory, State, Property, ArrayLocation);
+ }
+ }
}
h = 0, c = 0, i = 0;
uint32 CurrentSortIndex = 0;
@@ -427,6 +447,35 @@ void Layer_SortAll(project_data *File, project_state *State, memory *Memory, sor
}
}
+sorted_file File_Sort_Push(project_data *File, project_state *State, memory *Memory)
+{
+ sorted_file Sorted = {0};
+ Sorted.Layer_SortSize = (sizeof(sorted_comp_info) * File->Comp_Count) +
+ (sizeof(sorted_layer) * File->Layer_Count);
+ void *Layer_SortedArray = Memory_PushScratch(Memory, Sorted.Layer_SortSize);
+ Arbitrary_Zero((uint8 *)Layer_SortedArray, Sorted.Layer_SortSize);
+ Sorted.CompArray = (sorted_comp_info *)Layer_SortedArray;
+ Sorted.LayerArray = (sorted_layer *)((uint8 *)Layer_SortedArray + (sizeof(sorted_comp_info) * File->Comp_Count));
+
+ uint64 PropertyArraySize = sizeof(uint16) * 7 * MAX_KEYFRAMES_PER_BLOCK * File->Layer_Count;
+ uint64 PropertyInfoSize = sizeof(sorted_property_info) * 7 * File->Layer_Count;
+ Sorted.Property_SortSize = PropertyArraySize + PropertyInfoSize;
+ void *Property_SortedArray = Memory_PushScratch(Memory, Sorted.Property_SortSize);
+ Arbitrary_Zero((uint8 *)Property_SortedArray, Sorted.Property_SortSize);
+ Sorted.PropertyInfo = (sorted_property_info *)Property_SortedArray;
+ Sorted.PropertyArray = (uint16 *)((uint8 *)Property_SortedArray + PropertyInfoSize);
+
+ Layer_SortAll(File, State, Memory, Sorted.LayerArray, Sorted.CompArray, Sorted.PropertyArray, File->Layer_Count, File->Comp_Count);
+ return Sorted;
+}
+
+void File_Sort_Pop(memory *Memory, uint64 Layer_SortSize, uint64 Property_SortSize)
+{
+ Memory_PopScratch(Memory, Property_SortSize);
+ Memory_PopScratch(Memory, Layer_SortSize);
+}
+
+
static void
Layer_Delete(project_data *File, memory *Memory, uint32 Index)
{
diff --git a/functions.h b/functions.h
index eff7435..a6b608e 100644
--- a/functions.h
+++ b/functions.h
@@ -14,7 +14,8 @@ static ImVec2 Layer_LocalToScreenSpace(project_state *State, memory *Memory, blo
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 bezier_point * Bezier_LookupAddress(memory *Memory, property_channel *Property, uint16 Index);
+static void Bezier_EvaluateValue(project_state *State, bezier_point *PointAddress, v2 *Pos);
static void Transform_ApplyInteractive(interact_transform Interact, real32 *OutputX, real32 *OutputY, real32 *OutputRotation, real32 *OutputScale);
diff --git a/main.cpp b/main.cpp
index 50f9cc5..31572b4 100644
--- a/main.cpp
+++ b/main.cpp
@@ -130,16 +130,10 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, ui *UI,
if (!io.WantCaptureKeyboard)
ImGui_ProcessInputs(File, State, UI, Memory, io);
- uint64 SortSize = (sizeof(sorted_comp_info) * File->Comp_Count) + (sizeof(sorted_layer) * File->Layer_Count);
- void *SortedArray = Memory_PushScratch(Memory, SortSize);
- Arbitrary_Zero((uint8 *)SortedArray, SortSize);
- sorted_comp_info *SortedCompArray = (sorted_comp_info *)SortedArray;
- 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);
-
+ sorted_file Sorted = File_Sort_Push(File, State, Memory);
if (ImGui::IsKeyPressed(ImGuiKey_T)) {
- Interact_Transform_Begin(File, Memory, State, io.MousePos, SortedCompArray, SortedLayerArray);
+ Interact_Transform_Begin(File, Memory, State, io.MousePos, Sorted.CompArray, Sorted.LayerArray);
}
ImGui::DockSpaceOverViewport();
@@ -151,22 +145,29 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, ui *UI,
}
if (State->Initializing == 3) {
- Source_UICreateButton(File, State, Memory, SortedCompArray, SortedLayerArray);
+ Source_UICreateButton(File, State, Memory, Sorted.CompArray, Sorted.LayerArray);
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_point Point = { 1, {0, 800, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 };
+ Bezier_Add(Memory, Property, Point);
+ }
+ {
+ bezier_point Point = { 1, {20, 300, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 };
+ Bezier_Add(Memory, Property, Point);
+ }
+ {
+ bezier_point Point = { 1, {10, 200, -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_point Point = { 1, {15, 200, -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;
{
@@ -174,31 +175,33 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, ui *UI,
Bezier_Add(Memory, Property, Point);
}
{
- bezier_point Point = { 1, {20, -500, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 };
+ bezier_point Point = { 1, {20, 400, -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_point Point = { 1, {0, 1, -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_point Point = { 1, {20, 0, -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);
- ImGui_Timeline(File, State, Memory, UI, io, SortedCompArray, SortedLayerArray);
- ImGui_File(File, State, Memory, io, SortedCompArray, SortedLayerArray);
+ ImGui_Viewport(File, State, UI, Memory, io, textureID, Sorted.CompArray, Sorted.LayerArray);
+ ImGui_Timeline(File, State, Memory, UI, io, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyArray);
+ ImGui_File(File, State, Memory, io, Sorted.CompArray, Sorted.LayerArray);
ImGui_PropertiesPanel(File, State, UI, Memory, io);
ImGui_ColorPanel(File, State, UI, Memory, io);
ImGui_Menu(File, State, UI, Memory, io);
- Memory_PopScratch(Memory, SortSize);
+ File_Sort_Pop(Memory, Sorted.Layer_SortSize, Sorted.Property_SortSize);
+
#if DEBUG
Debug.Temp = {};
#endif
@@ -207,7 +210,7 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, ui *UI,
}
static void *
-Render_Comp(project_data *File, project_state *State, memory *Memory, ImGuiIO io, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray, uint32 CompIndex)
+Render_Comp(project_data *File, project_state *State, memory *Memory, ImGuiIO io, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray, uint16 *SortedPropertyArray, uint32 CompIndex)
{
block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, CompIndex);
cache_entry *Entry_Main = Memory_Cache_Search(State, Memory, cache_entry_type_comp, CompIndex, State->Frame_Current);
@@ -266,7 +269,7 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, ImGuiIO io
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);
+ Render_Comp(File, State, Memory, io, SortedCompArray, SortedLayerArray, SortedPropertyArray, Layer->Block_Source_Index);
Entry->CycleTime = GetTime() - Src_TimeStart;
// }
BitmapAddress = Memory_Block_Bitmap_AddressAtIndex(Memory, Entry->Block_StartIndex);
@@ -278,37 +281,34 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, ImGuiIO io
// for (int a = 0; a < Layer->Block_Effect_Count; a++) {
// }
+ int32 Offset = (State->Interact_Active == interact_type_keyframe_move) ? (int32)State->Interact_Offset[0] : 0;
for (int h = 0; h < AmountOf(Layer->Property); h++) {
property_channel *Property = &Layer->Property[h];
+ uint16 *ArrayLocation = SortedPropertyArray + (i * 7 * MAX_KEYFRAMES_PER_BLOCK) + (h * MAX_KEYFRAMES_PER_BLOCK);
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;
+ v2 Min, Max;
+ Property_MinMax(Memory, State, Property, ArrayLocation, &Min, &Max);
+ if (Min.x >= State->Frame_Current) {
+ Property->CurrentValue = Min.y;
+ } else if (Max.x <= State->Frame_Current) {
+ Property->CurrentValue = Max.y;
} else {
int KeyframeIndex = 0;
for (;;) {
- bezier_point *Point = Bezier_Lookup(Memory, Property, KeyframeIndex + 1);
- if (Point->Pos[0].x >= State->Frame_Current)
+ v2 PointPos[3];
+ bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[KeyframeIndex + 1]);
+ Bezier_EvaluateValue(State, PointAddress, PointPos);
+ if (PointPos[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);
+ v2 PointPos[3];
+ bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[KeyframeIndex]);
+ Bezier_EvaluateValue(State, PointAddress, PointPos);
+ v2 NextPointPos[3];
+ bezier_point *NextPointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[KeyframeIndex + 1]);
+ Bezier_EvaluateValue(State, NextPointAddress, NextPointPos);
+ Property->CurrentValue = Bezier_SolveYForX(PointPos[0], PointPos[0] + PointPos[2], NextPointPos[0] + NextPointPos[1], NextPointPos[0], State->Frame_Current);
}
}
}
@@ -347,17 +347,11 @@ Main_Renderer(project_data *File, project_state *State, memory *Memory, SDL_Wind
block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex);
- // NOTE(fox): All layers are given a slot here
- uint64 SortSize = (sizeof(sorted_comp_info) * File->Comp_Count) + (sizeof(sorted_layer) * File->Layer_Count);
- void *SortedArray = Memory_PushScratch(Memory, SortSize);
- Arbitrary_Zero((uint8 *)SortedArray, SortSize);
- sorted_comp_info *SortedCompArray = (sorted_comp_info *)SortedArray;
- 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);
+ sorted_file Sorted = File_Sort_Push(File, State, Memory);
- void *MainCompBuffer = Render_Comp(File, State, Memory, io, SortedCompArray, SortedLayerArray, File->PrincipalCompIndex);
+ void *MainCompBuffer = Render_Comp(File, State, Memory, io, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyArray, File->PrincipalCompIndex);
- Memory_PopScratch(Memory, SortSize);
+ File_Sort_Pop(Memory, Sorted.Layer_SortSize, Sorted.Property_SortSize);
glBindTexture(GL_TEXTURE_2D, textureID);
diff --git a/main.h b/main.h
index 096107a..26b3666 100644
--- a/main.h
+++ b/main.h
@@ -116,6 +116,12 @@ enum focused_window
focus_timeline
};
+struct sorted_property_info
+{
+ uint32 MinYIndex;
+ uint32 MaxYIndex;
+};
+
struct sorted_comp_info
{
uint32 LayerCount;
@@ -127,6 +133,16 @@ struct sorted_layer
real32 SortedOffset;
};
+struct sorted_file
+{
+ sorted_layer *LayerArray;
+ sorted_comp_info *CompArray;
+ sorted_property_info *PropertyInfo;
+ uint16 *PropertyArray;
+ uint64 Layer_SortSize;
+ uint64 Property_SortSize;
+};
+
enum timeline_mode
{
timeline_mode_default,
@@ -362,19 +378,6 @@ struct property_header
real32 MaxVal;
};
-struct graph_info
-{
- real32 MinVal = FLT_MAX;
- real32 MaxVal = FLT_MIN;
- real32 LowestOffset = FLT_MIN;
-};
-
-struct property_info
-{
- real32 MinVal = FLT_MAX;
- real32 MaxVal = FLT_MIN;
-};
-
struct property_channel {
uint8 Occupied;
char *Name;
diff --git a/memory.cpp b/memory.cpp
index 3b3c64f..53388bf 100644
--- a/memory.cpp
+++ b/memory.cpp
@@ -50,7 +50,7 @@ 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, void *Extra = NULL)
+Block_Loop(memory *Memory, memory_table_list TableName, uint32 TotalCount, int *HasIncremented, int *CurrentCount, int *Index)
{
for (;;) {
if (*CurrentCount == TotalCount) {
@@ -60,12 +60,7 @@ Block_Loop(memory *Memory, memory_table_list TableName, uint32 TotalCount, int *
*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);
- }
+ uint8 *Occupied = (uint8 *)Memory_Block_AddressAtIndex(Memory, TableName, *Index);
if (*Occupied) {
*HasIncremented = 1;
(*CurrentCount)++;
@@ -90,7 +85,7 @@ Block_Loop(memory *Memory, property_channel *Property, uint32 TotalCount, int *H
*HasIncremented = 0;
(*Index)++;
}
- uint8 *Occupied = (uint8 *)Bezier_Lookup(Memory, Property, *Index);
+ uint8 *Occupied = (uint8 *)Bezier_LookupAddress(Memory, Property, *Index);
if (*Occupied) {
*HasIncremented = 1;
(*CurrentCount)++;
diff --git a/my_imgui_widgets.cpp b/my_imgui_widgets.cpp
index 722ce1e..04cedb0 100644
--- a/my_imgui_widgets.cpp
+++ b/my_imgui_widgets.cpp
@@ -988,14 +988,14 @@ ImGui_GraphInfo(project_data *File, project_state *State, memory *Memory, ui *UI
}
static void
-ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, ImDrawList *draw_list, graph_info GraphInfo,
+ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, ImDrawList *draw_list,
ImVec2 Increment, ImVec2 TimelineAbsolutePos, ImVec2 TimelineMoveSize, ImVec2 TimelineZoomSize,
- ImVec2 TimelineSize, ImVec2 TimelineSizeWithBorder, real32 LayerIncrement)
+ ImVec2 TimelineSize, ImVec2 TimelineSizeWithBorder, real32 LayerIncrement, uint16 *SortedPropertyArray)
{
UI->Test.Split(draw_list, 2);
- TimelineMoveSize.y = TimelineMoveSize.y + (TimelineZoomSize.y * (0.25 / 2));
- TimelineZoomSize.y = TimelineZoomSize.y * 0.75;
+ TimelineMoveSize.y = TimelineMoveSize.y + (TimelineZoomSize.y * (0.25 / 4));
+ TimelineZoomSize.y = TimelineZoomSize.y * 0.6;
int h = 0, c = 0, i = 0;
while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i))
@@ -1014,9 +1014,11 @@ 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;
+ // NOTE(fox): I'm setting the X (time) to the transformed value and
+ // the Y (value) to the raw drag delta, because the Y units can be
+ // normalized while the X units are always universal across all the
+ // graphs (and it has to be passed into the sorter).
+ State->Interact_Offset[0] = (DragDelta.x / TimelineZoomSize.x) / Increment.x;
State->Interact_Offset[1] = DragDelta.y;
DebugWatchVar("DeltaX: ", &DragDelta.x, d_float);
DebugWatchVar("Deltay: ", &DragDelta.y, d_float);
@@ -1036,50 +1038,30 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor
for (int h = 0; h < AmountOf(Layer->Property); h++) {
property_channel *Property = &Layer->Property[h];
+ uint16 *ArrayLocation = SortedPropertyArray + (i * 7 * MAX_KEYFRAMES_PER_BLOCK) + (h * MAX_KEYFRAMES_PER_BLOCK);
ImGui::PushID(Property);
if (Property->Block_Bezier_Count) {
- property_info PropertyInfo = Property_GetInfo(Memory, Property);
- real32 Y_Increment = 1 / (GraphInfo.MaxVal - GraphInfo.MinVal);
+ v2 Min, Max;
+ Property_MinMax(Memory, State, Property, ArrayLocation, &Min, &Max);
+ real32 Y_Increment = 1 / (Max.y - Min.y);
bezier_point *PointAddress[2] = {};
ImVec2 Keyframe_ScreenPos[6] = {};
- int k = 0;
- for (;;) {
- int Idx = (k % 2);
+ for (int p = 0; p < Property->Keyframe_Count; p++) {
+ int k = ArrayLocation[p];
+ int Idx = (p % 2);
int NewIdx = Idx * 3;
int OldIdx = (NewIdx == 3) ? 0 : 3;
- PointAddress[Idx] = Bezier_Lookup(Memory, Property, k);
- bezier_point *Point = PointAddress[Idx];
-
- if (!Point->Occupied)
- break;
-
- 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);
- real32 Slope_Old = (Keyframe_ScreenPos.y - State->Interact_Offset[3]) / (Keyframe_ScreenPos.x - State->Interact_Offset[2]);
- real32 Slope_New = (Keyframe_ScreenPos.y - io.MousePos.y) / (Keyframe_ScreenPos.x - io.MousePos.x);
- State->Interact_Offset[0] = atan((Slope_Old - Slope_New) / (1 + Slope_Old * Slope_New));
- DebugWatchVar("Rotation: ", &State->Interact_Offset[0], d_float);
- }
- */
- 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]) };
+ PointAddress[Idx] = Bezier_LookupAddress(Memory, Property, k);
+
+ v2 PointPos[3];
+ Bezier_EvaluateValue(State, PointAddress[Idx], PointPos);
+
+ ImVec2 Keyframe_LocalPos[3] = { V2(PointPos[0]), V2(PointPos[0] + PointPos[1]), V2(PointPos[0] + PointPos[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] = TimelineAbsolutePos + TimelineMoveSize + ((ImVec2(1, -1) * Keyframe_LocalPos_Ratio[b] + ImVec2(0, 1)) * TimelineZoomSize);
+ Keyframe_LocalPos_Ratio[b] = (Keyframe_LocalPos[b] - ImVec2(0, Min.y)) * ImVec2(Increment.x, Y_Increment);
+ Keyframe_ScreenPos[NewIdx + b] = TimelineAbsolutePos + TimelineMoveSize + ((ImVec2(1, 1) * Keyframe_LocalPos_Ratio[b]) * TimelineZoomSize);
}
if (UI->BoxSelect) {
@@ -1091,11 +1073,11 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor
if (Keyframe_ScreenPos[NewIdx].y >= Y_Top && Keyframe_ScreenPos[NewIdx].y <= Y_Bottom &&
Keyframe_ScreenPos[NewIdx].x >= X_Left && Keyframe_ScreenPos[NewIdx].x <= X_Right)
{
- if (!Point->IsSelected) {
- Point->IsSelected = 1;
+ if (!PointAddress[Idx]->IsSelected) {
+ PointAddress[Idx]->IsSelected = 1;
}
} else if (!io.KeyShift) {
- Point->IsSelected = 0;
+ PointAddress[Idx]->IsSelected = 0;
}
}
@@ -1104,10 +1086,10 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor
ImVec2 ButtonSize(16, 16);
ImGui::PushID(k);
- int Max = (Point->IsSelected) ? 2 : 0;
+ int Max = PointAddress[Idx]->IsSelected ? 2 : 0;
for (int b = Max; b >= 0; b--) {
- ImU32 PointCol = ((Point->IsSelected - 1) == b) ? ImColor(0.8f, 0.5f, 0.0f, 1.0f) : ImColor(0.1f, 0.1f, 0.1f, 1.0f);
- ImU32 LineCol = ((Point->IsSelected - 1) == b) ? ImColor(0.8f, 0.5f, 0.5f, 1.0f) : ImColor(0.4f, 0.4f, 0.4f, 1.0f);
+ ImU32 PointCol = ((PointAddress[Idx]->IsSelected - 1) == b) ? ImColor(0.8f, 0.5f, 0.0f, 1.0f) : ImColor(0.1f, 0.1f, 0.1f, 1.0f);
+ ImU32 LineCol = ((PointAddress[Idx]->IsSelected - 1) == b) ? ImColor(0.8f, 0.5f, 0.5f, 1.0f) : ImColor(0.4f, 0.4f, 0.4f, 1.0f);
ImGui::PushID(b);
ImGui::SetCursorScreenPos(Keyframe_ScreenPos[NewIdx + b] - (ButtonSize * 0.5));
ImGui::InvisibleButton("##keyframemover", ButtonSize, ImGuiMouseButton_Left);
@@ -1122,10 +1104,10 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor
PointCol = ImColor(1.0f, 0.8f, 0.8f, 1.0f);
if (IsItemActivated) {
- Point->IsSelected = b+1;
+ PointAddress[Idx]->IsSelected = b+1;
}
- if (b != 0 && Point->IsSelected)
+ if (b != 0 && PointAddress[Idx]->IsSelected)
draw_list->AddLine(Keyframe_ScreenPos[NewIdx], Keyframe_ScreenPos[NewIdx + b], LineCol, 2.0f);
if (b == 0)
@@ -1139,7 +1121,7 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor
UI->Test.SetCurrentChannel(draw_list, 0);
- if (k != 0) {
+ if (p != 0) {
if (PointAddress[0]->Type == interpolation_type_bezier && PointAddress[1]->Type == interpolation_type_bezier) {
draw_list->AddBezierCubic(Keyframe_ScreenPos[OldIdx], Keyframe_ScreenPos[OldIdx + 2],
Keyframe_ScreenPos[NewIdx + 1], Keyframe_ScreenPos[NewIdx], col, 1.0f, 0);
@@ -1147,7 +1129,6 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor
draw_list->AddLine(Keyframe_ScreenPos[0], Keyframe_ScreenPos[3], col, 1.0f);
}
}
- k++;
}
}
ImGui::PopID();
@@ -1500,7 +1481,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
}
static void
-ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray)
+ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray, uint16 *SortedPropertyArray)
{
if (UI->TimelineMode == timeline_mode_graph)
ImGui_GraphInfo(File, State, Memory, UI, io);
@@ -1602,10 +1583,9 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
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,
+ ImGui_Timeline_DrawGraph(File, State, Memory, UI, io, draw_list,
Increment, TimelineAbsolutePos, GraphMoveSize, GraphZoomSize,
- TimelineSize, TimelineSizeWithBorder, LayerIncrement);
+ TimelineSize, TimelineSizeWithBorder, LayerIncrement, SortedPropertyArray);
}
ImVec2 MouseDelta = io.MouseDelta / TimelineSize;
@@ -1777,17 +1757,15 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
if (!Layer->IsSelected)
continue;
for (int h = 0; h < AmountOf(Layer->Property); h++) {
+ uint16 *ArrayLocation = SortedPropertyArray + (i * 7 * MAX_KEYFRAMES_PER_BLOCK) + (h * MAX_KEYFRAMES_PER_BLOCK);
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++;
+ for (int p = 0; p < Property->Keyframe_Count; p++) {
+ int k = ArrayLocation[p];
+ bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, k);
+ if (PointAddress->IsSelected) {
+ v2 NewPos[3];
+ Bezier_EvaluateValue(State, PointAddress, NewPos);
+ PointAddress->Pos[0].x = NewPos[0].x;
}
}
}