summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFox Caminiti <fox@foxcam.net>2023-02-10 17:44:36 -0500
committerFox Caminiti <fox@foxcam.net>2023-02-10 17:44:36 -0500
commit52c6ad3f2686cb66a8954ca5dac7f3eba4676cc3 (patch)
tree8a1d505378f5b23ad95e1b59396b04fe4852f0fc
parent3d2e5b594b1872f866a698014c97ee4e98de6259 (diff)
ellipse and dumb cursor
-rw-r--r--dependencies/src/imgui/imgui_impl_sdl.cpp6
-rw-r--r--src/createcalls.cpp31
-rw-r--r--src/gl_calls.cpp3
-rw-r--r--src/imgui_ui.cpp26
-rw-r--r--src/imgui_ui_viewport.cpp354
-rw-r--r--src/include/all.h8
-rw-r--r--src/include/main.h4
-rw-r--r--src/layer.cpp22
-rw-r--r--src/main.cpp51
-rw-r--r--src/nanovg.cpp25
-rw-r--r--src/prenderer.cpp100
11 files changed, 194 insertions, 436 deletions
diff --git a/dependencies/src/imgui/imgui_impl_sdl.cpp b/dependencies/src/imgui/imgui_impl_sdl.cpp
index 9a68de7..3e54363 100644
--- a/dependencies/src/imgui/imgui_impl_sdl.cpp
+++ b/dependencies/src/imgui/imgui_impl_sdl.cpp
@@ -461,7 +461,7 @@ static SDL_Cursor *cursor_test(const char *image[])
int i, row, col;
Uint8 data[4*32];
Uint8 mask[4*32];
- int hot_x, hot_y;
+ // int hot_x, hot_y;
i = -1;
for (row=0; row<32; ++row) {
@@ -486,8 +486,8 @@ static SDL_Cursor *cursor_test(const char *image[])
}
}
}
- sscanf(image[4+row], "%d,%d", &hot_x, &hot_y);
- return SDL_CreateCursor(data, mask, 32, 32, hot_x, hot_y);
+ // sscanf(image[4+row], "%d,%d", &hot_x, &hot_y);
+ return SDL_CreateCursor(data, mask, 32, 32, 0, 0);
}
static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void* sdl_gl_context)
diff --git a/src/createcalls.cpp b/src/createcalls.cpp
index 09bcea5..fc50b6e 100644
--- a/src/createcalls.cpp
+++ b/src/createcalls.cpp
@@ -35,6 +35,9 @@ File_Open(project_data *File, project_state *State, memory *Memory, char *Filena
}
}
String_Copy(State->Filename, State->DummyName, 512);
+
+ File->UI.Shape = {};
+
State->Initializing = 4;
Memory->History.NumberOfEntries = 0;
Memory->History.EntryPlayhead = 0;
@@ -489,7 +492,7 @@ void Slide_Test(project_data *File, project_state *State, memory *Memory, sorted
v2 LayerPos = V2(Layer->x.CurrentValue, Layer->y.CurrentValue);
int Width, Height;
Layer_GetDimensions(Memory, Layer, &Width, &Height);
- v2 Difference = V2(abs(CompPos.x - LayerPos.x), abs(CompPos.y - LayerPos.y));
+ v2 Difference = V2(fabs(CompPos.x - LayerPos.x), fabs(CompPos.y - LayerPos.y));
printf("Diff: %.1f, %.1f\n", Difference.x, Difference.y);
if (Difference.x < Threshold &&
Difference.y < Threshold)
@@ -849,7 +852,7 @@ Project_ShapeLayer_New(project_data *File, project_state *State, memory *Memory)
// SortedCompArray, SortedLayerArray, SelectionCount, SelectedLayerIndex, SelectedPrecompIndex)
}
// Rect mode
- if (State->Interact_Modifier == 1) {
+ if (State->ShapeMode == 0) {
v2 *CompPoint = (v2 *)&State->Interact_Offset[0];
for (int i = 0; i < 4; i++) {
bezier_point PointData = { 1, { CompPoint[i], V2(0, 0), V2(0, 0) }, interpolation_type_linear, 0 };
@@ -857,7 +860,23 @@ Project_ShapeLayer_New(project_data *File, project_state *State, memory *Memory)
CompPoint[i] = {0};
}
Shape->IsClosed = true;
- State->Interact_Modifier = 0;
+ } else if (State->ShapeMode == 1) {
+ v2 Radius = *((v2 *)&State->Interact_Offset + 0);
+ v2 Center = *((v2 *)&State->Interact_Offset + 1);
+ real32 cx = Center.x;
+ real32 cy = Center.y;
+ real32 rx = Radius.x;
+ real32 ry = Radius.y;
+ v2 Points[12] = { V2(cx-rx, cy), V2(0, ry*KAPPA), V2(0, -ry*KAPPA),
+ V2(cx, cy+ry), V2(+rx*KAPPA, 0), V2(-rx*KAPPA, 0),
+ V2(cx+rx, cy), V2(0, -ry*KAPPA), V2(0, ry*KAPPA),
+ V2(cx, cy-ry), V2(-rx*KAPPA, 0), V2(+rx*KAPPA, 0) };
+ for (int i = 0; i < 4; i++) {
+ bezier_point PointData = { 1, { Points[i*3+0], Points[i*3+1], Points[i*3+2] }, interpolation_type_bezier, 0 };
+ Bezier_Add(Memory, F_File, Shape->Block_Bezier_Index, &Shape->Block_Bezier_Count, &Shape->Point_Count, PointData);
+ }
+
+ // Shape->IsClosed = true;
}
shape_options ShapeOpt = File->UI.ShapeOpt;
@@ -866,14 +885,16 @@ Project_ShapeLayer_New(project_data *File, project_state *State, memory *Memory)
v2 Min = {}, Max = {};
void *Data = Memory_PushScratch(Memory, sizeof(nvg_point) * 128);
layer_transforms T = {};
- NVG_FlattenPath(Memory, Shape, ShapeOpt, (nvg_point *)Data, State, T, 0, 0, 0, 0, 0, &Min, &Max);
+ bool32 IsConvex = 0;
+ NVG_FlattenPath(Memory, Shape, ShapeOpt, (nvg_point *)Data, State, T, 0, 0, 0, 0, 0, &Min, &Max, &IsConvex);
Memory_PopScratch(Memory, sizeof(nvg_point) * 128);
Shape->Width = Max.x - Min.x;
Shape->Height = Max.y - Min.y;
for (int i = 0; i < Shape->Point_Count; i++) {
bezier_point *Point = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, i, 1);
for (int a = 0; a < 3; a++) {
- Point->Pos[a] = (Point->Pos[a] - Min) / V2(Shape->Width, Shape->Height);
+ v2 Sub = (a == 0) ? Min : V2(0, 0);
+ Point->Pos[a] = (Point->Pos[a] - Sub) / V2(Shape->Width, Shape->Height);
}
}
diff --git a/src/gl_calls.cpp b/src/gl_calls.cpp
index 1203c2f..8d5ef8c 100644
--- a/src/gl_calls.cpp
+++ b/src/gl_calls.cpp
@@ -358,7 +358,8 @@ GL_RasterizeShape2(gl_effect_layer *TestM, void *StrokeData, void *FillData, uin
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
- glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_INT, 0);
+ // glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_INT, 0);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, FillCount);
}
else {
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
diff --git a/src/imgui_ui.cpp b/src/imgui_ui.cpp
index 5d0f65d..5d8b319 100644
--- a/src/imgui_ui.cpp
+++ b/src/imgui_ui.cpp
@@ -140,6 +140,15 @@ ImGui_ColorPanel(project_data *File, project_state *State, ui *UI, memory *Memor
}
}
+ if (State->Tool == tool_rectangle) {
+ if (ImGui::MenuItem("Rect", NULL, (State->ShapeMode == 0))) {
+ State->ShapeMode = 0;
+ }
+ if (ImGui::MenuItem("Ellipse", NULL, (State->ShapeMode == 1))) {
+ State->ShapeMode = 1;
+ }
+ }
+
if (State->Tool == tool_brush) {
real32 BrushSizeMin = 0;
real32 BrushSizeMax = 1024;
@@ -449,6 +458,9 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me
State->Interact_Modifier = 0;
}
}
+ if (ImGui::IsKeyPressed(ImGuiKey_A)) {
+ State->Tool = tool_default_pointmove;
+ }
if (ImGui::IsKeyPressed(ImGuiKey_V)) {
State->Tool = tool_default;
}
@@ -518,9 +530,17 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me
}
}
} else if (State->FocusedWindow == focus_viewport) {
- if (ImGui::IsKeyPressed(ImGuiKey_T)) {
- Interact_Transform_Begin(File, Memory, State, io.MousePos, Sorted.CompArray, Sorted.LayerArray);
- State->Tool = tool_default;
+ if (ImGui::IsKeyPressed(ImGuiKey_S)) {
+ State->Interact_Offset[1] = SDL_GetPerformanceCounter();
+ State->Interact_Offset[2] = io.MousePos.x;
+ State->Interact_Offset[3] = io.MousePos.y;
+ State->Interact_Active = interact_type_viewport_transform;
+ }
+ if (ImGui::IsKeyPressed(ImGuiKey_R)) {
+ State->Interact_Offset[1] = SDL_GetPerformanceCounter();
+ State->Interact_Offset[2] = io.MousePos.x;
+ State->Interact_Offset[3] = io.MousePos.y;
+ State->Interact_Active = interact_type_viewport_transform;
}
}
}
diff --git a/src/imgui_ui_viewport.cpp b/src/imgui_ui_viewport.cpp
index dc37225..103d325 100644
--- a/src/imgui_ui_viewport.cpp
+++ b/src/imgui_ui_viewport.cpp
@@ -61,6 +61,7 @@ ImGui_Viewport_ShapeUI(project_state *State, memory *Memory, ui *UI, ImGuiIO &io
ImVec2 Point = (i == 0) ? IV2(Point_0->Pos[0]) : IV2(Point_0->Pos[0] + Point_0->Pos[i]);
if (Layer != NULL) {
layer_transforms T = Layer_GetTransforms(Layer);
+ Point = Point * ImVec2(Shape->Width, Shape->Height);
Point = IV2(TransformPoint(T, Width, Height, *(v2 *)&Point));
}
if (State->Interact_Active == interact_type_keyframe_move && Point_0->IsSelected) {
@@ -74,6 +75,7 @@ ImGui_Viewport_ShapeUI(project_state *State, memory *Memory, ui *UI, ImGuiIO &io
ImVec2 Point = (i == 0) ? IV2(Point_1->Pos[0]) : IV2(Point_1->Pos[0] + Point_1->Pos[i]);
if (Layer != NULL) {
layer_transforms T = Layer_GetTransforms(Layer);
+ Point = Point * ImVec2(Shape->Width, Shape->Height);
Point = IV2(TransformPoint(T, Width, Height, *(v2 *)&Point));
}
if (State->Interact_Active == interact_type_keyframe_move && Point_1->IsSelected) {
@@ -145,8 +147,8 @@ ImGui_Viewport_ShapeUI(project_state *State, memory *Memory, ui *UI, ImGuiIO &io
v2 *Pos = &Point->Pos[Point->IsSelected-1];
History_Action_Swap(Memory, F_Bezier, sizeof(*Pos), Pos);
*Pos = TransformPoint(T, Shape->Width, Shape->Height, *Pos);
- Pos->x += State->Interact_Offset[0];
- Pos->y += State->Interact_Offset[1];
+ Pos->x += State->Interact_Offset[0] / Shape->Width;
+ Pos->y += State->Interact_Offset[1] / Shape->Height;
*Pos = T_CompPosToLayerPos(T, MainComp->Width, MainComp->Height, Shape->Width, Shape->Height, Pos->x, Pos->y);
}
}
@@ -157,6 +159,7 @@ ImGui_Viewport_ShapeUI(project_state *State, memory *Memory, ui *UI, ImGuiIO &io
}
}
draw_list->AddNgon(ScreenPoint_1[a], 4, PointCol, 8, 5.0f);
+ draw_list->AddNgon(ScreenPoint_1[a], 4, 0xFFFFFFFF, 8, 8.0f);
ImGui::PopID();
}
ImGui::PopID();
@@ -607,14 +610,16 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me
}
if (InBounds && !io.KeyAlt && !ImGui::IsKeyDown(ImGuiKey_Z) && !ImGui::IsKeyDown(ImGuiKey_ModShift)) {
- v2 MouseLocalUV = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, io.MousePos);
- bool32 LayerHovered = Layer_TestForPoint(Memory, State, UI, SortedCompArray, SortedLayerArray, File->PrincipalCompIndex, MouseLocalUV);
+ v2 MouseLocalPos = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, io.MousePos) * V2(CompWidth, CompHeight);
+ layer_transforms T = {};
+ T.scale = 1.0f;
+ bool32 LayerHovered = Layer_TestForPoint(Memory, State, UI, SortedCompArray, SortedLayerArray, File->PrincipalCompIndex, MouseLocalPos, T);
if (LayerHovered) {
if (ImGui::GetMouseCursor() == ImGuiMouseCursor_None) {
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
}
ImGui::SetCursorScreenPos(io.MousePos - ScaleHandleSize/2);
- ImGui::InvisibleButton("##mover", ScaleHandleSize);
+ ImGui::Button("##mover", ScaleHandleSize);
if (!State->InteractTransformMode && ImGui::IsItemActivated() && !OtherActions) {
State->Interact_Active = interact_type_viewport_transform_gizmo;
State->InteractTransformMode = 3;
@@ -691,286 +696,6 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me
}
}
-
-static void
-ImGui_Viewport_TransformUI(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO &io, ImDrawList *draw_list,
- interact_transform *Interact, ImVec2 ViewportMin, uint32 CompWidth, uint32 CompHeight, uint16 *SortedKeyframeArray)
-{
- v2 InteractMin = Interact->Min + Interact->Position;
- v2 InteractMax = Interact->Max + Interact->Position;
-
- v2 BoxLength = InteractMax - InteractMin;
- v2 Center = InteractMax - (BoxLength/2);
-
- real32 Point0X = Center.x - InteractMin.x;
- real32 Point0Y = Center.y - InteractMin.y;
-
- real32 Rad = Interact->Radians;
-
- v2 XAxis = (Point0X * Interact->Scale)*V2(cos(Rad), sin(Rad));
- v2 YAxis = (Point0Y * -Interact->Scale)*V2(sin(Rad), -cos(Rad));
-
- // Points are clockwise starting from the top left.
- real32 X0 = -XAxis.x - YAxis.x + Center.x;
- real32 Y0 = -XAxis.y - YAxis.y + Center.y;
- real32 X1 = X0 + XAxis.x*2;
- real32 Y1 = Y0 + XAxis.y*2;
- real32 X2 = X1 + YAxis.x*2;
- real32 Y2 = Y1 + YAxis.y*2;
- real32 X3 = X2 - XAxis.x*2;
- real32 Y3 = Y2 - XAxis.y*2;
-
- // Midway points.
- real32 Mid_X0 = X0 + XAxis.x;
- real32 Mid_Y0 = Y0 + XAxis.y;
- real32 Mid_X1 = X1 + YAxis.x;
- real32 Mid_Y1 = Y1 + YAxis.y;
- real32 Mid_X2 = X2 - XAxis.x;
- real32 Mid_Y2 = Y2 - XAxis.y;
- real32 Mid_X3 = X3 - YAxis.x;
- real32 Mid_Y3 = Y3 - YAxis.y;
-
- ImVec2 CompScale = UI->CompZoom / ImVec2(CompWidth, CompHeight);
-
- ImVec2 P[4];
- P[0] = ImVec2(X0, Y0)*CompScale + UI->CompPos;
- P[1] = ImVec2(X1, Y1)*CompScale + UI->CompPos;
- P[2] = ImVec2(X2, Y2)*CompScale + UI->CompPos;
- P[3] = ImVec2(X3, Y3)*CompScale + UI->CompPos;
-
- ImVec2 Mid_P[4];
- Mid_P[0] = ImVec2(Mid_X0, Mid_Y0)*CompScale + UI->CompPos;
- Mid_P[1] = ImVec2(Mid_X1, Mid_Y1)*CompScale + UI->CompPos;
- Mid_P[2] = ImVec2(Mid_X2, Mid_Y2)*CompScale + UI->CompPos;
- Mid_P[3] = ImVec2(Mid_X3, Mid_Y3)*CompScale + UI->CompPos;
-
- ImU32 wcol = ImGui::GetColorU32(ImGuiCol_Text);
- draw_list->AddLine(P[0], P[1], wcol, 2.0f);
- draw_list->AddLine(P[1], P[2], wcol, 2.0f);
- draw_list->AddLine(P[2], P[3], wcol, 2.0f);
- draw_list->AddLine(P[3], P[0], wcol, 2.0f);
-
- v2 XAxis2 = (BoxLength*CompScale.x)*V2(cos(Rad), sin(Rad));
- v2 YAxis2 = (BoxLength*CompScale.y)*V2(sin(Rad), -cos(Rad));
-
- v2 XAxisPerp = (1.0f / LengthSq(XAxis))*XAxis;
- v2 YAxisPerp = (1.0f / LengthSq(YAxis))*YAxis;
-
- // real32 LocalX = ((io.MousePos.x - UI->CompPos.x) - Center.x) ;
- // real32 LocalY = ((io.MousePos.y - UI->CompPos.y) - Center.y) ;
- layer_transforms BoxTransforms = { Center.x, Center.y, 0.5, 0.5, (real32)(Interact->Radians / (PI / 180)), Interact->Scale };
- v2 LayerPoint = Transform_ScreenSpaceToLocal(BoxTransforms, CompWidth, CompHeight, BoxLength.x, BoxLength.y, UI->CompPos, UI->CompZoom, ViewportMin, io.MousePos);
-
- real32 U = LayerPoint.x / BoxLength.x;
- real32 V = LayerPoint.y / BoxLength.y;
-
- ImVec2 ScaleHandleSize(50, 50);
-
- bool32 OtherActions = ImGui::IsKeyDown(ImGuiKey_Z);
-
- // First do the halfway scale points, since they don't need UVs considered:
- for (int i = 0; i < 4; i++) {
- ImGui::SetCursorScreenPos(Mid_P[i] - ScaleHandleSize/2);
- ImGui::PushID(i);
-
- ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::ColorConvertFloat4ToU32(ImVec4(0.6f, 0.0f, 0.3f, 1.0f)));
- ImGui::Button("##ScaleMids", ScaleHandleSize);
- ImGui::PopStyleColor();
-
- if (ImGui::IsItemActivated() && !OtherActions) {
- State->InteractTransformMode = 1;
- }
-
- if (State->InteractTransformMode == 1 && ImGui::IsItemActive())
- {
- uint32 side = i;
- if (side == 0) {
- Interact->Scale -= io.MouseDelta.y / BoxLength.y;
- Interact->Position.y += io.MouseDelta.y / 2;
- } else if (side == 1) {
- Interact->Scale += io.MouseDelta.x / BoxLength.x;
- Interact->Position.x += io.MouseDelta.x / 2;
- } else if (side == 2) {
- Interact->Scale += io.MouseDelta.y / BoxLength.y;
- Interact->Position.y += io.MouseDelta.y / 2;
- } else if (side == 3) {
- Interact->Scale -= io.MouseDelta.x / BoxLength.x;
- Interact->Position.x += io.MouseDelta.x / 2;
- }
- }
- ImGui::PopID();
- }
-
- bool32 InBounds = false;
- // Scale if cursor is on button within the UV, rotate if outside UV, and position if a non-button is dragged.
- if (U >= 0.0f && U <= 1.0f && V >= 0.0f && V <= 1.0f)
- {
- ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::ColorConvertFloat4ToU32(ImVec4(0.6f, 0.0f, 0.3f, 1.0f)));
- InBounds = true;
- }
-
- for (int i = 0; i < 4; i++) {
- ImGui::SetCursorScreenPos(P[i] - ScaleHandleSize/2);
- ImGui::PushID(i);
- ImGui::Button("##ScaleRotateCorners", ScaleHandleSize);
-
- if (ImGui::IsItemActivated() && !OtherActions) {
- if (InBounds)
- State->InteractTransformMode = 1;
- else
- State->InteractTransformMode = 2;
- }
-
- // Scale part
- if (State->InteractTransformMode == 1 && ImGui::IsItemActive())
- {
- // TODO(fox): Corner dragging scale only works in the X
- // axis. Mostly feels right when dragged how you expect,
- // but I'll fix it if someone complains.
- uint32 side = i;
- if (side == 0) {
- Interact->Scale -= io.MouseDelta.x / BoxLength.x;
- Interact->Position.x += io.MouseDelta.x / 2;
- Interact->Position.y += io.MouseDelta.x*(BoxLength.y/BoxLength.x) / 2;
- } else if (side == 1) {
- Interact->Scale += io.MouseDelta.x / BoxLength.x;
- Interact->Position.x += io.MouseDelta.x / 2;
- Interact->Position.y -= io.MouseDelta.x*(BoxLength.y/BoxLength.x) / 2;
- } else if (side == 2) {
- Interact->Scale += io.MouseDelta.x / BoxLength.x;
- Interact->Position.x += io.MouseDelta.x / 2;
- Interact->Position.y += io.MouseDelta.x*(BoxLength.y/BoxLength.x) / 2;
- } else if (side == 3) {
- Interact->Scale -= io.MouseDelta.x / BoxLength.x;
- Interact->Position.x += io.MouseDelta.x / 2;
- Interact->Position.y -= io.MouseDelta.x*(BoxLength.y/BoxLength.x) / 2;
- }
- }
-
- // Rotation part
- if (State->InteractTransformMode == 2 && ImGui::IsItemActive())
- {
- real32 LocalX = (io.MousePos.x - UI->CompPos.x)/CompScale.x - InteractMin.x - (BoxLength.x/2);
- real32 LocalY = (io.MousePos.y - UI->CompPos.y)/CompScale.y - InteractMin.y - (BoxLength.y/2);
-
- real32 Slope_Mouse = LocalY/LocalX;
- real32 Slope_Corner = 0;
- real32 Slope_Flipped = 0;
- real32 Dot = 0;
-
- // TODO(fox) learn basic geometry to do this properly
-
- // We find the angle between the direction of whichever corner the
- // mouse is grabbing (Slope_Corner) and the mouse's current
- // position (Slope_Mouse) to get ExtraRadians. The calculation only
- // works between -90 and 90, so I take the dot product of the
- // opposite edge of the corner and add the extra degrees when it's negative.
-
- v2 SlopeDot = V2(BoxLength.x, BoxLength.y);
- // top left clockwise
- uint32 side = i;
- if (side == 0) {
- Slope_Corner = BoxLength.y / BoxLength.x;
- Slope_Flipped = -BoxLength.x / BoxLength.y;
- Dot = LocalX * -SlopeDot.x + LocalY * -SlopeDot.y;
- } else if (side == 1) {
- Slope_Corner = -BoxLength.y / BoxLength.x;
- Slope_Flipped = BoxLength.x / BoxLength.y;
- Dot = LocalX * SlopeDot.x + LocalY * -SlopeDot.y;
- } else if (side == 2) {
- Slope_Corner = BoxLength.y / BoxLength.x;
- Slope_Flipped = -BoxLength.x / BoxLength.y;
- Dot = LocalX * SlopeDot.x + LocalY * SlopeDot.y;
- } else if (side == 3) {
- Slope_Corner = -BoxLength.y / BoxLength.x;
- Slope_Flipped = BoxLength.x / BoxLength.y;
- Dot = LocalX * -SlopeDot.x + LocalY * SlopeDot.y;
- }
-
- Interact->Radians = atan((Slope_Mouse - Slope_Corner) / (1 + Slope_Mouse * Slope_Corner));
- real32 ExtraRadians2 = atan((Slope_Mouse - Slope_Flipped) / (1 + Slope_Mouse * Slope_Flipped));
-
- if (Dot < 0) {
- if (Interact->Radians < 0) {
- Interact->Radians = (90 * (PI / 180)) + ExtraRadians2;
- } else {
- Interact->Radians = (-90 * (PI / 180)) + ExtraRadians2;
- }
- }
- }
-
- ImGui::PopID();
- }
-
- if (!State->InteractTransformMode && ImGui::IsMouseClicked(ImGuiMouseButton_Left) && InBounds && !OtherActions)
- State->InteractTransformMode = 3;
-
- if (State->InteractTransformMode == 3) {
- Interact->Position.x += (real32)io.MouseDelta.x/CompScale.x;
- Interact->Position.y += (real32)io.MouseDelta.y/CompScale.y;
- }
-
- if (State->InteractTransformMode)
- {
- if (io.MouseDelta.x || io.MouseDelta.y)
- State->UpdateFrame = true;
- if (!ImGui::IsMouseDown(ImGuiMouseButton_Left))
- State->InteractTransformMode = 0;
- }
-
- if (ImGui::IsKeyPressed(ImGuiKey_Escape)) {
- State->Interact_Active = interact_type_none;
- State->Interact_Modifier = 0;
- State->UpdateFrame = true;
- Memory->PurgeCache = true;
- }
-
- // Second condition so you don't have to reach for Enter.
- if (ImGui::IsKeyPressed(ImGuiKey_Enter) || (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && io.KeyCtrl)) {
- int h = 0, c = 0, i = 0;
- // if (!io.KeyCtrl)
- History_Entry_Commit(Memory, "Transform layers");
- while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) {
- block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
- if (Layer->IsSelected & 0x01) {
- // if (io.KeyCtrl) {
- // layer_transforms T = Layer_GetTransforms(Layer);
- // Transform_ApplyInteractive(*(interact_transform *)&State->Interact_Offset[0], &T.x, &T.y, &T.rotation, &T.scale);
- // property_channel *Property[4] = { &Layer->x, &Layer->y, &Layer->rotation, &Layer->scale };
- // real32 Val[4] = { T.x, T.y, T.rotation, T.scale };
- // for (int a = 0; a < 4; a++) {
- // if (Property[a]->CurrentValue != Val[a]) {
- // History_Entry_Commit(Memory, "Add keyframe");
- // bezier_point Point = { 1, {(real32)State->Frame_Current, Val[a], -1, 0, 1, 0}, interpolation_type_linear, 0, {0, 0, 0}, 0 };
- // uint16 *ArrayLocation = Property_GetSortedArray(SortedKeyframeArray, State->MostRecentlySelectedLayer, h);
- // Bezier_Add(Memory, F_Layers, Property[a], Point, ArrayLocation);
- // History_Entry_End(Memory);
- // }
- // }
- // } else {
- {
- History_Action_Swap(Memory, F_Layers, sizeof(Layer->x.CurrentValue), &Layer->x.CurrentValue);
- History_Action_Swap(Memory, F_Layers, sizeof(Layer->y.CurrentValue), &Layer->y.CurrentValue);
- History_Action_Swap(Memory, F_Layers, sizeof(Layer->scale.CurrentValue), &Layer->scale.CurrentValue);
- History_Action_Swap(Memory, F_Layers, sizeof(Layer->rotation.CurrentValue), &Layer->rotation.CurrentValue);
- Transform_ApplyInteractive(State->Interact_Transform, &Layer->x.CurrentValue, &Layer->y.CurrentValue, &Layer->rotation.CurrentValue, &Layer->scale.CurrentValue);
- }
- }
- }
- // if (!io.KeyCtrl)
- History_Entry_End(Memory);
- State->Interact_Active = interact_type_none;
- State->Interact_Modifier = 0;
- State->UncommitedKeyframe = 1;
- State->UpdateFrame = true;
- }
-
- if (InBounds == true) {
- ImGui::PopStyleColor();
- }
-
-}
-
static void
ImGui_Viewport_SelectedLayerUI(project_state *State, memory *Memory, ui *UI, ImGuiIO &io, ImDrawList *draw_list, block_composition *MainComp, uint32 CompIndex, layer_transforms ExtraT, int *PointCount, v2 *PointData,
sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray)
@@ -1034,7 +759,7 @@ ImGui_Viewport_SelectedLayerUI(project_state *State, memory *Memory, ui *UI, ImG
}
- if (Layer->IsShapeLayer && State->Tool == tool_default_pointmove && State->Interact_Active == interact_type_none ) {
+ if (Layer->IsShapeLayer && State->Tool == tool_default_pointmove && (State->Interact_Active == interact_type_none || State->Interact_Active == interact_type_keyframe_move) ) {
ImGui_Viewport_ShapeUI(State, Memory, UI, io, Layer, Width, Height, &Layer->Shape, MainComp, draw_list);
// point visualization
@@ -1108,7 +833,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
bool open = true;
ImGui::Begin("Viewport", &open, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
- DebugWatchVar("Count: ", &State->PreviousSelectionCount, d_int);
+ // DebugWatchVar("Count: ", &State->PreviousSelectionCount, d_int);
if (ImGui::IsWindowHovered(ImGuiFocusedFlags_ChildWindows)) {
State->FocusedWindow = focus_viewport;
@@ -1190,11 +915,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
int PointCount = 0;
layer_transforms T = {};
ImGui_Viewport_SelectedLayerUI(State, Memory, UI, io, draw_list, MainComp, File->PrincipalCompIndex, T, &PointCount, PointData, SortedCompArray, SortedLayerArray);
- if (State->Interact_Active == interact_type_viewport_transform) {
- ImGui_Viewport_TransformUI(File, State, Memory, UI, io, draw_list, &State->Interact_Transform, ViewportMin, MainComp->Width, MainComp->Height, SortedKeyframeArray);
- } else {
- ImGui_Viewport_TransformUI2(File, State, Memory, UI, io, draw_list, &PointCount, PointData, ViewportMin, MainComp->Width, MainComp->Height, SortedCompArray, SortedLayerArray, SortedKeyframeArray);
- }
+ ImGui_Viewport_TransformUI2(File, State, Memory, UI, io, draw_list, &PointCount, PointData, ViewportMin, MainComp->Width, MainComp->Height, SortedCompArray, SortedLayerArray, SortedKeyframeArray);
Memory_PopScratch(Memory, sizeof(v2) * 512);
}
@@ -1340,15 +1061,13 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
State->Interact_Active = interact_type_none;
}
- /*
if (State->Interact_Active == interact_type_viewport_transform) {
- interact_transform *Interact = (interact_transform *)&State->Interact_Offset[0];
- ImVec2 DragDelta = io.MousePos - Interact->OGPos;
- Interact->Position = V2(DragDelta.x, DragDelta.y);
- if (io.MouseDelta.x || io.MouseDelta.y)
- State->UpdateFrame = true;
+ if (io.MouseDelta.x || io.MouseDelta.y)
+ {
+ State->Interact_Offset[4] = io.MousePos.x;
+ State->Interact_Offset[5] = io.MousePos.y;
+ }
}
- */
if (IsActive && ImGui::IsMouseDragging(ImGuiMouseButton_Right, -1.0f))
{
@@ -1385,6 +1104,9 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
}
}
+ if (IsActive)
+ int a = 0;
+
if (State->Tool == tool_pen && State->Interact_Active == interact_type_none && State->MostRecentlySelectedLayer == -1) {
v2 CompUV = State->LastClickedPoint;
ImVec2 ScreenPoint = ImVec2(UI->CompPos.x + CompUV.x * UI->CompZoom.x,
@@ -1453,17 +1175,39 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
MousePos = ScreenPointStart + ImVec2(Vector.x, Vector.x);
}
if (IsActive && !OtherActions) {
- draw_list->AddRect(ScreenPointStart, MousePos, wcol, 2.0f);
+ if (State->ShapeMode == 0) {
+ draw_list->AddRect(ScreenPointStart, MousePos, wcol, 2.0f);
+ } else if (State->ShapeMode == 1) {
+ ImVec2 Radius = (MousePos - ScreenPointStart) / 2;
+ ImVec2 Center = ScreenPointStart + Radius;
+ real32 cx = Center.x;
+ real32 cy = Center.y;
+ real32 rx = Radius.x;
+ real32 ry = Radius.y;
+ draw_list->AddBezierCubic(ImVec2(cx-rx, cy), ImVec2(cx-rx, cy+ry*KAPPA), ImVec2(cx-rx*KAPPA, cy+ry), ImVec2(cx, cy+ry), wcol, 1.0f);
+ draw_list->AddBezierCubic(ImVec2(cx, cy+ry), ImVec2(cx+rx*KAPPA, cy+ry), ImVec2(cx+rx, cy+ry*KAPPA), ImVec2(cx+rx, cy), wcol, 1.0f);
+ draw_list->AddBezierCubic(ImVec2(cx+rx, cy), ImVec2(cx+rx, cy-ry*KAPPA), ImVec2(cx+rx*KAPPA, cy-ry), ImVec2(cx, cy-ry), wcol, 1.0f);
+ draw_list->AddBezierCubic(ImVec2(cx, cy-ry), ImVec2(cx-rx*KAPPA, cy-ry), ImVec2(cx-rx, cy-ry*KAPPA), ImVec2(cx-rx, cy), wcol, 1.0f);
+
+ }
}
if (Shape->Point_Count == 0 && IsDeactivated && !OtherActions && !ImGui::IsMouseReleased(ImGuiMouseButton_Right)) {
ImVec2 ScreenPoint[4] = { ScreenPointStart, ImVec2(ScreenPointStart.x, MousePos.y), MousePos, ImVec2(MousePos.x, ScreenPointStart.y) };
- v2 *CompPoint = (v2 *)&State->Interact_Offset[0];
- for (int i = 0; i < 4; i++) {
- CompPoint[i] = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, ScreenPoint[i]);
- CompPoint[i] = CompPoint[i] * V2(MainComp->Width, MainComp->Height);
+ if (State->ShapeMode == 0) {
+ v2 *CompPoint = (v2 *)&State->Interact_Offset[0];
+ for (int i = 0; i < 4; i++) {
+ CompPoint[i] = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, ScreenPoint[i]);
+ CompPoint[i] = CompPoint[i] * V2(MainComp->Width, MainComp->Height);
+ }
+ } else if (State->ShapeMode == 1) {
+ v2 CompMin = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, ScreenPointStart) * V2(MainComp->Width, MainComp->Height);
+ v2 CompMax = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, io.MousePos) * V2(MainComp->Width, MainComp->Height);
+ v2 Radius = (CompMax - CompMin) / 2;
+ v2 Center = CompMin + Radius;
+ *((v2 *)&State->Interact_Offset + 0) = Radius;
+ *((v2 *)&State->Interact_Offset + 1) = Center;
}
State->HotkeyInput = hotkey_newlayer_shape;
- State->Interact_Modifier = 1;
}
}
diff --git a/src/include/all.h b/src/include/all.h
index b5b1d77..8117437 100644
--- a/src/include/all.h
+++ b/src/include/all.h
@@ -374,10 +374,6 @@ static bool32
Transform_TestBox(block_layer *Layer, uint32 Width, uint32 Height, v2 Min, v2 Max);
static void
-Interact_Transform_Begin(project_data *File, memory *Memory, project_state *State, ImVec2 OGPos,
- sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray);
-
-static void
Layer_RecursiveDeselect(memory *Memory, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 TargetIndex, uint16 PrincipalIndex);
static bool32
@@ -472,7 +468,7 @@ Data_Decompress(memory *Memory, void *CompressedLocation, uint64 CompressedSize,
static uint32
NVG_FlattenPath(memory *Memory, shape_layer *Shape, shape_options ShapeOpt, nvg_point *PointData,
project_state *State, layer_transforms T, int Width, int Height,
- int CompWidth, int CompHeight, bool32 Interact, v2 *Min, v2 *Max);
+ int CompWidth, int CompHeight, bool32 Interact, v2 *Min, v2 *Max, bool32 IsConcave);
static real32 *
NVG_Point(real32 *StrokeData, real32 x, real32 y, real32 u, real32 v);
@@ -532,7 +528,7 @@ inline void
ImGui_DrawCenteredRect(ImDrawList *draw_list, ImVec2 Point, real32 Width, uint32 col);
static bool32
-Layer_TestForPoint(memory *Memory, project_state *State, ui *UI, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 PrincipalIndex, v2 CompUV);
+Layer_TestForPoint(memory *Memory, project_state *State, ui *UI, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 CompIndex, v2 CompPos, layer_transforms ExtraT);
static v2
TransformPoint(layer_transforms T, real32 Width, real32 Height, v2 Point);
diff --git a/src/include/main.h b/src/include/main.h
index 3b4843e..da037dc 100644
--- a/src/include/main.h
+++ b/src/include/main.h
@@ -478,6 +478,8 @@ struct project_state
bool32 UpdateScreen = 1; // refreshes entire UI; influenced by raw key/mouse input
bool32 DebugDisableCache = 1;
+ bool32 ShapeMode = 0;
+
bool32 ViewportEnabled = 0;
bool32 SelectionMode = 1;
@@ -625,7 +627,7 @@ struct ui
0xff8b1f1f,
0xffc25909,
0xff57c20a,
- 0xff8ee6da,
+ 0xff203d6a,
0xffa48fb7,
0xffd14061,
0xff38b683,
diff --git a/src/layer.cpp b/src/layer.cpp
index 0b278e5..570c7fc 100644
--- a/src/layer.cpp
+++ b/src/layer.cpp
@@ -117,10 +117,11 @@ Layer_UpdateMasksEffects(project_state *State, block_layer *Layer, memory *Memor
Arbitrary_Zero((uint8 *)Data, sizeof(nvg_point) * 128);
layer_transforms T = Layer_GetTransforms(Layer);
v2 Min = {}, Max = {};
+ bool32 IsConvex = 0;
uint32 NumberOfVerts = NVG_FlattenPath(Memory, Shape, ShapeOpt, (nvg_point *)Data,
- State, T, Shape->Width, Shape->Height, Width, Height, 1, &Min, &Max);
+ State, T, Shape->Width, Shape->Height, Width, Height, 1, &Min, &Max, &IsConvex);
void *Data_Stroke = Memory_PushScratch(Memory, sizeof(real32) * 4 * 256);
- uint32 StrokeCount = NVG_ExpandStroke(Memory, NumberOfVerts, ShapeOpt.StrokeWidth, ShapeOpt.LineCapType, ShapeOpt.LineJoinType, Shape->IsClosed, (nvg_point *)Data, (real32 *)Data_Stroke);
+ uint32 StrokeCount = NVG_ExpandStroke(Memory, NumberOfVerts, ShapeOpt.StrokeWidth, ShapeOpt.LineCapType, ShapeOpt.LineJoinType, Shape->IsClosed, (nvg_point *)Data, (real32 *)Data_Stroke, &IsConvex);
void *Data_Fill = Memory_PushScratch(Memory, sizeof(real32) * 4 * NumberOfVerts);
NVG_ExpandFill(Memory, NumberOfVerts, (nvg_point *)Data, (real32 *)Data_Fill);
@@ -421,9 +422,8 @@ Layer_TraverseForPoint(project_data *File, project_state *State, memory *Memory,
return PointUV * V2(InnerWidth, InnerHeight);
}
-// TODO(fox): Precomps?
static bool32
-Layer_TestForPoint(memory *Memory, project_state *State, ui *UI, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 CompIndex, v2 CompUV)
+Layer_TestForPoint(memory *Memory, project_state *State, ui *UI, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 CompIndex, v2 CompPos, layer_transforms ExtraT)
{
block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, CompIndex);
sorted_comp_array SortedCompStart = SortedCompArray[CompIndex];
@@ -435,7 +435,16 @@ Layer_TestForPoint(memory *Memory, project_state *State, ui *UI, sorted_comp_arr
int Width, Height;
Layer_GetDimensions(Memory, Layer, &Width, &Height);
layer_transforms T = Layer_GetTransforms(Layer);
- v2 UV = T_CompUVToLayerUV(T, Comp->Width, Comp->Height, Width, Height, CompUV);
+ v2 NewPos = T_CompPosToLayerPos(T, Comp->Width, Comp->Height, Width, Height, CompPos.x, CompPos.y);
+ if (Layer->IsPrecomp) {
+ // only like 20% sure how this works...
+ layer_transforms NewExtraT = T;
+ NewExtraT.rotation = ExtraT.rotation - NewExtraT.rotation;
+ NewExtraT.scale = ExtraT.scale / NewExtraT.scale;
+ if (Layer_TestForPoint(Memory, State, UI, SortedCompArray, SortedLayerArray, Layer->Block_Source_Index, NewPos, NewExtraT))
+ return 1;
+ }
+ v2 UV = NewPos / V2(Width, Height);
if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && ((Layer->IsSelected & 0x01) || Layer->IsPrecomp) && !Layer->IsLocked)
{
return 1;
@@ -645,8 +654,9 @@ Layer_TestBoxSelect(memory *Memory, project_state *State, ui *UI, sorted_comp_ar
nvg_point *NVGPointData = (nvg_point *)Memory_PushScratch(Memory, sizeof(nvg_point) * 1024);
v2 ShapeMin = {}, ShapeMax = {};
+ bool32 IsConvex = 0;
uint32 NumberOfVerts = NVG_FlattenPath(Memory, Shape, Layer->ShapeOpt, NVGPointData,
- State, T, Shape->Width, Shape->Height, Comp->Width, Comp->Height, 1, &ShapeMin, &ShapeMax);
+ State, T, Shape->Width, Shape->Height, Comp->Width, Comp->Height, 1, &ShapeMin, &ShapeMax, &IsConvex);
v2 Box[4] = { MinPos, V2(MinPos.x, MaxPos.y), MaxPos, V2(MaxPos.x, MinPos.y) };
if (Shape_TestBoxSelect(T, Comp->Width, Comp->Height, Shape->Width, Shape->Height, Box, NVGPointData, NumberOfVerts)) {
Layer_Select(Memory, State, Index_Physical);
diff --git a/src/main.cpp b/src/main.cpp
index f5ffbea..0b57e99 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -174,7 +174,7 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, sorted_
test = 0;
uint64 InputTime = SDL_GetPerformanceCounter() - InputStart;
- printf("OURUI: %.2lu\n", InputTime);
+ // printf("OURUI: %.2lu\n", InputTime);
return test;
}
@@ -371,7 +371,7 @@ GL_Test(const ImDrawList* parent_list, const ImDrawCmd* cmd)
GL_DeleteHWBuffer(&MSBuffer);
uint64 PerfEnd = SDL_GetPerformanceCounter() - PerfStart;
- printf("OPENGL: %.2lu\n", PerfEnd);
+ // printf("OPENGL: %.2lu\n", PerfEnd);
}
// TODO(fox): We have five functions that essentially do this same precomp loop
@@ -454,7 +454,7 @@ LayerIterate_SelectionStatus(project_state *State, memory *Memory, uint32 CompIn
Position = XAxis + YAxis;
layer_transforms T = Layer_GetTransforms(Layer);
v2 UV = T_CompUVToLayerUV(T, Comp->Width, Comp->Height, Width, Height, Center / V2(Comp->Width, Comp->Height));
- if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && (Layer->IsSelected & 0x03) && !Layer->IsLocked)
+ if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && (Layer->IsSelected & 0x01) && !Layer->IsLocked)
{
*SelectionCount += 1;
*SelectedLayerIndex = i;
@@ -623,18 +623,37 @@ Render_UI(project_data *File, project_state *State, memory *Memory, ui *UI, ImDr
void *Data = PointBuffer;
shape_layer *Shape = &Layer->Shape;
shape_options ShapeOpt = Layer->ShapeOpt;
- if (ShapeOpt.Visibility == 1 && ShapeOpt.StrokeWidth <= 0.0f)
- continue;
+ if (ShapeOpt.StrokeWidth == 0.0f) {
+ if (ShapeOpt.Visibility == 0)
+ ShapeOpt.Visibility = 2;
+ if (ShapeOpt.Visibility == 1)
+ continue;
+ }
+ bool32 IsConvex = 0;
v2 Min = {}, Max = {};
uint32 NumberOfVerts = NVG_FlattenPath(Memory, Shape, ShapeOpt, (nvg_point *)Data,
- State, T, Shape->Width, Shape->Height, Comp->Width, Comp->Height, 1, &Min, &Max);
+ State, T, Shape->Width, Shape->Height, Comp->Width, Comp->Height, 1, &Min, &Max, &IsConvex);
PointBuffer += NumberOfVerts * sizeof(nvg_point);
void *Data_Stroke = PointBuffer;
- uint32 StrokeCount = NVG_ExpandStroke(Memory, NumberOfVerts, ShapeOpt.StrokeWidth, ShapeOpt.LineCapType, ShapeOpt.LineJoinType, Shape->IsClosed, (nvg_point *)Data, (real32 *)Data_Stroke);
- PointBuffer += StrokeCount * sizeof(real32) * 4;
void *Data_Fill = PointBuffer;
- NVG_ExpandFill(Memory, NumberOfVerts, (nvg_point *)Data, (real32 *)Data_Fill);
- PointBuffer += NumberOfVerts * sizeof(real32) * 4;
+ uint32 StrokeCount = 0;
+
+ int RenderFlags = 0;
+ if (ShapeOpt.Visibility == 1 || ShapeOpt.Visibility == 2) {
+ RenderFlags |= gl_renderflag_stroke;
+ StrokeCount = NVG_ExpandStroke(Memory, NumberOfVerts, ShapeOpt.StrokeWidth, ShapeOpt.LineCapType, ShapeOpt.LineJoinType, Shape->IsClosed, (nvg_point *)Data, (real32 *)Data_Stroke, &IsConvex);
+ PointBuffer += StrokeCount * sizeof(real32) * 4;
+ Data_Fill = PointBuffer;
+ }
+
+ if (ShapeOpt.Visibility == 0 || ShapeOpt.Visibility == 2) {
+ RenderFlags |= gl_renderflag_fill;
+ NVG_ExpandFill(Memory, NumberOfVerts, (nvg_point *)Data, (real32 *)Data_Fill);
+ PointBuffer += NumberOfVerts * sizeof(real32) * 4;
+ }
+
+ if (!IsConvex)
+ RenderFlags |= gl_renderflag_concave;
// zero to set the framebuffer to main
gl_effect_layer TestL = {};
@@ -644,19 +663,13 @@ Render_UI(project_data *File, project_state *State, memory *Memory, ui *UI, ImDr
RenderData->LayerCount++;
PointBuffer += sizeof(gl_data);
- int RenderFlags = 0;
- int Visibility = ShapeOpt.Visibility;
- if (Visibility == 0 || Visibility == 2)
- RenderFlags |= gl_renderflag_fill;
- if (Visibility == 1 || Visibility == 2)
- RenderFlags |= gl_renderflag_stroke;
-
*GL_Data = { 0, Data_Stroke, StrokeCount, ShapeOpt.StrokeCol,
Data_Fill, NumberOfVerts, ShapeOpt.FillCol,
T, Shape->Width, Shape->Height, RenderFlags };
} else if (Layer->IsPrecomp) {
layer_transforms NewExtraT = Layer_GetTransforms(Layer);
+ // TODO(fox): Add center point for proper scaling!
NewExtraT = Transform_TestInteracts(State, Layer, SortEntry, NewExtraT);
if (ExtraT.scale != 0) {
NewExtraT = Transform_Add(NewExtraT, ExtraT, Comp->Width, Comp->Height);
@@ -1203,9 +1216,7 @@ int main(int argc, char *argv[]) {
sprintf(State->DummyName, "test");
if (File_Open(File, State, &Memory, State->DummyName)) {
State->UpdateFrame = true;
- State->MostRecentlySelectedLayer = 0;
}
- File->UI.LayerColors[3] = 0xff203d6a;
// File->PrincipalCompIndex = 1;
#else
// uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/yu.webm");
@@ -1492,7 +1503,7 @@ int main(int argc, char *argv[]) {
if (TargetMS > FrameMS)
SDL_Delay((uint64)(TargetMS - FrameMS));
}
- printf("TOTAL: %.2lu, (%.2f ms) - INPUTS: %.2lu - RENDERING: %.2lu\n", PerfTime, FrameMS, InputTime, RenderTime);
+ // printf("TOTAL: %.2lu, (%.2f ms) - INPUTS: %.2lu - RENDERING: %.2lu\n", PerfTime, FrameMS, InputTime, RenderTime);
// printf("TOTAL: %.2lu, (%.2f ms) - RENDERING: %.2lu\n", PerfTime, FrameMS, PerfTime);
}
diff --git a/src/nanovg.cpp b/src/nanovg.cpp
index f1d1702..95bba7d 100644
--- a/src/nanovg.cpp
+++ b/src/nanovg.cpp
@@ -179,7 +179,7 @@ static real32 * NVG_ButtCap(nvg_point *Point, real32 *StrokeData,
static uint32
NVG_FlattenPath(memory *Memory, shape_layer *Shape, shape_options ShapeOpt, nvg_point *PointData,
project_state *State, layer_transforms T, int Width, int Height,
- int CompWidth, int CompHeight, bool32 Interact, v2 *Min, v2 *Max)
+ int CompWidth, int CompHeight, bool32 Interact, v2 *Min, v2 *Max, bool32 *IsConvex)
{
nvg_point *PointPlayhead = PointData;
bezier_point *BezierPointData = (bezier_point *)Memory_PushScratch(Memory, sizeof(bezier_point) * 128);
@@ -226,13 +226,29 @@ NVG_FlattenPath(memory *Memory, shape_layer *Shape, shape_options ShapeOpt, nvg_
Min->y = Point->y;
Point = NextPoint++;
}
+ // Tell whether we need concave filling or not. ExpandStroke also does this.
+ if (ShapeOpt.Visibility == 2) {
+ Point = &PointData[NumberOfVerts - 1];
+ NextPoint = PointData;
+ int LeftCount = 0;
+ for (int i = 0; i < NumberOfVerts; i++) {
+ real32 cross = NextPoint->dx * Point->dy - Point->dx * NextPoint->dy;
+ if (cross > 0.0f) {
+ LeftCount++;
+ }
+ Point = NextPoint++;
+ }
+ if (LeftCount == NumberOfVerts)
+ *IsConvex = true;
+ }
+
return NumberOfVerts;
}
real32 MiterLimit = 2.4f;
static uint32
-NVG_ExpandStroke(void *Memory, int NumberOfVerts, real32 StartWidth, nvg_line_cap LineCap, nvg_line_cap LineJoin, bool32 IsClosed, nvg_point *PointData, real32 *StrokeData)
+NVG_ExpandStroke(void *Memory, int NumberOfVerts, real32 StartWidth, nvg_line_cap LineCap, nvg_line_cap LineJoin, bool32 IsClosed, nvg_point *PointData, real32 *StrokeData, bool32 *IsConvex)
{
real32 Width = StartWidth * 0.5;
int ncap = 12;
@@ -254,6 +270,7 @@ NVG_ExpandStroke(void *Memory, int NumberOfVerts, real32 StartWidth, nvg_line_ca
StrokeData = NVG_ButtCap(Point, StrokeData, Point->dx, Point->dy, Width, Width-1, 0.5, 0.5, 0);
}
}
+ int LeftCount = 0;
for (int i = Start; i < LoopAmount; i++) {
@@ -282,6 +299,7 @@ NVG_ExpandStroke(void *Memory, int NumberOfVerts, real32 StartWidth, nvg_line_ca
// Keep track of left turns.
cross = NextPoint->dx * Point->dy - Point->dx * NextPoint->dy;
if (cross > 0.0f) {
+ LeftCount++;
NextPoint->Flags |= NVG_PT_LEFT;
}
@@ -309,6 +327,8 @@ NVG_ExpandStroke(void *Memory, int NumberOfVerts, real32 StartWidth, nvg_line_ca
Point = NextPoint++;
}
+ if (LeftCount == LoopAmount)
+ *IsConvex = true;
if (!IsClosed) {
if (LineCap == NVG_ROUND) {
@@ -321,6 +341,7 @@ NVG_ExpandStroke(void *Memory, int NumberOfVerts, real32 StartWidth, nvg_line_ca
StrokeData = NVG_Point(StrokeData, StartingStrokeData[4], StartingStrokeData[5], 0, 0);
}
+
int GL_PointCount = (StrokeData - StartingStrokeData) / 4;
return GL_PointCount;
diff --git a/src/prenderer.cpp b/src/prenderer.cpp
index 5119d55..7cac63e 100644
--- a/src/prenderer.cpp
+++ b/src/prenderer.cpp
@@ -191,89 +191,6 @@ Transform_Recurse(project_state *State, memory *Memory, block_composition *MainC
}
}
-// 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,
- sorted_comp_array *SortedCompArray, sorted_layer_array *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 = &State->Interact_Transform;
- 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;
- 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) {
- State->Interact_Active = interact_type_viewport_transform;
- interact_transform *Interact = &State->Interact_Transform;
- Interact->Min = V2(MinX, MinY);
- Interact->Max = V2(MaxX, MaxY);
- Interact->Position = V2(0);
- Interact->Radians = 0;
- Interact->Scale = 1.0f;
- Interact->OGPos = OGPos;
- }
- */
-}
-
-static void
-Interact_Transform2_Begin(project_data *File, memory *Memory, project_state *State, ImVec2 OGPos,
- sorted_comp_array *SortedCompArray, sorted_layer_array *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 = &State->Interact_Transform;
- Interact->Min = V2(MinX, MinY);
- Interact->Max = V2(MaxX, MaxY);
- Interact->Position = V2(0);
- Interact->Radians = 0;
- Interact->Scale = 1.0f;
- Interact->OGPos = OGPos;
- }
-}
-
static v2
TransformPoint(layer_transforms T, real32 Width, real32 Height, v2 Point)
{
@@ -300,7 +217,9 @@ static layer_transforms
Transform_TestInteracts(project_state *State, block_layer *Layer, sorted_layer_array SortEntry, layer_transforms T)
{
if (State->Interact_Active == interact_type_viewport_transform && Layer->IsSelected & 0x01) {
- Transform_ApplyInteractive(State->Interact_Transform, &T.x, &T.y, &T.rotation, &T.scale);
+ T.x += State->Interact_Offset[0];
+ T.y += State->Interact_Offset[1];
+ real32 Rand = State->Interact_Offset[3];
}
if (State->Interact_Active == interact_type_viewport_transform_gizmo && Layer->IsSelected & 0x01) {
Transform_ApplyInteractive(State->Interact_Transform, &T.x, &T.y, &T.rotation, &T.scale);
@@ -330,6 +249,19 @@ Transform_Add(layer_transforms T, layer_transforms ExtraT, real32 Width, real32
return T;
}
+static layer_transforms
+Transform_Add2(layer_transforms T, layer_transforms ExtraT, real32 Width, real32 Height)
+{
+ v2 NewPos = TransformPoint(ExtraT, Width, Height, V2(T.x, T.y));
+ T.x = NewPos.x;
+ T.y = NewPos.y;
+ T.ax = T.ax;
+ T.ay = T.ay;
+ T.rotation = T.rotation + ExtraT.rotation;
+ T.scale = T.scale / ExtraT.scale;
+ return T;
+}
+
static ImVec2
Layer_LocalToScreenSpace(project_state *State, memory *Memory, block_layer *Layer, ui *UI, uint32 PrincipalCompIndex, v2 Point)
{