diff options
Diffstat (limited to 'src/imgui_ui_viewport.cpp')
-rw-r--r-- | src/imgui_ui_viewport.cpp | 447 |
1 files changed, 151 insertions, 296 deletions
diff --git a/src/imgui_ui_viewport.cpp b/src/imgui_ui_viewport.cpp index 601b0f4..c846c7e 100644 --- a/src/imgui_ui_viewport.cpp +++ b/src/imgui_ui_viewport.cpp @@ -222,172 +222,6 @@ ImGui_Viewport_BrushUI(project_state *State, memory *Memory, ImVec2 ViewportMin, } } -#if 0 -static void -ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO &io, ImDrawList *draw_list, - v2 Min, v2 Max, ImVec2 ViewportMin, uint32 CompWidth, uint32 CompHeight, uint16 *SortedKeyframeArray) -{ - interact_transform *Interact = (interact_transform *)&State->Interact_Offset[0]; - - v2 InteractMin = Min; - v2 InteractMax = Max; - real32 Rad = 0; - real32 Scale = 1; - - - if (State->Interact_Active == interact_type_viewport_transform_gizmo) { - InteractMin = Interact->Min + Interact->Position; - InteractMax = Interact->Max + Interact->Position; - Rad = Interact->Radians; - Scale = Interact->Scale; - } - - v2 BoxLength = InteractMax - InteractMin; - v2 Center = InteractMax - (BoxLength/2); - - real32 Point0X = Center.x - InteractMin.x; - real32 Point0Y = Center.y - InteractMin.y; - - v2 XAxis = (Point0X * Scale)*V2(cos(Rad), sin(Rad)); - v2 YAxis = (Point0Y * -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; - - if (State->Interact_Active == interact_type_viewport_transform_gizmo) { - 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)(Rad / (PI / 180)), 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; - - bool32 OtherActions = ImGui::IsKeyDown(ImGuiKey_Z); - real32 FontSize = ImGui::GetFontSize() * 3; - real32 Delta = io.MouseDelta.x + io.MouseDelta.y; - - ImVec2 Screen_Center = IV2(Center)*CompScale + UI->CompPos; - - char *Buttons[] = { "##position", "##rotation", "##scale" }; - for (int i = 0; i < 3; i++) { - ImGui::SetCursorScreenPos(Screen_Center + ImVec2(i*FontSize, i*FontSize)); - ImGui::Button(Buttons[i], ImVec2(FontSize, FontSize)); - bool32 IsActivated = ImGui::IsItemActivated(); - bool32 IsActive = ImGui::IsItemActive(); - bool32 IsDeactivated = ImGui::IsItemDeactivated(); - if (IsActivated) { - State->Interact_Active = interact_type_viewport_transform_gizmo; - *Interact = {}; - Interact->Min = Min; - Interact->Max = Max; - } - if (IsActive && Delta != 0.0f) { - v2 Increase = V2(io.MousePos - io.MouseClickedPos[0]); - if (i == 0) { - Interact->Position = Increase; - } else if (i == 1) { - 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); - v2 SlopeDot = V2(BoxLength.x, BoxLength.y); - - real32 Slope_Mouse = LocalY/LocalX; - - real32 Slope_Corner = BoxLength.y / BoxLength.x; - real32 Slope_Flipped = -BoxLength.x / BoxLength.y; - real32 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; - } - } - } else if (i == 2) { - real32 StartX = (io.MouseClickedPos[0].x - UI->CompPos.x)/CompScale.x - InteractMin.x - (BoxLength.x/2); - real32 StartY = (io.MouseClickedPos[0].y - UI->CompPos.y)/CompScale.y - InteractMin.y - (BoxLength.y/2); - 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 Normalized = LocalX / StartX; - if (Normalized < 0.0f) - Normalized = 0.0f; - Interact->Scale = Normalized; - // printf("Local X: %.2f\n", Normalized); - } else { - Assert(0); - } - } - if (IsDeactivated) { - Assert(State->Interact_Active == interact_type_viewport_transform_gizmo); - int h = 0, c = 0, i = 0; - History_Entry_Commit(Memory, "Transform layers"); - while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - if (Layer->IsSelected == 1) { - 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(*(interact_transform *)&State->Interact_Offset[0], &Layer->x.CurrentValue, &Layer->y.CurrentValue, &Layer->rotation.CurrentValue, &Layer->scale.CurrentValue); - } - } - History_Entry_End(Memory); - State->Interact_Active = interact_type_none; - *Interact = {}; - State->UpdateFrame = true; - } - } -} -#endif - static real32 T_AreaAtAngle(int PointCount, v2 *PointData, v2 Center, real32 Rotation, v2 *CurrentMin, v2 *CurrentMax) { @@ -448,7 +282,8 @@ T_FindBestFit(int PointCount, v2 *PointData, v2 *Center, v2 *NewCenter, v2 *Best static void ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO &io, ImDrawList *draw_list, - int *PointCount, v2 *PointData, ImVec2 ViewportMin, uint32 CompWidth, uint32 CompHeight, uint16 *SortedKeyframeArray) + int *PointCount, v2 *PointData, ImVec2 ViewportMin, uint32 CompWidth, uint32 CompHeight, + sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 *SortedKeyframeArray) { interact_transform *Interact = &State->Interact_Transform; @@ -458,7 +293,6 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me real32 Rad2 = 0; real32 Scale = 1; - aaa += 0.02; if (Interact->Min.x == 0.0f) { T_FindBestFit(*PointCount, PointData, &Interact->OGCenter, &Interact->NewCenter, &Interact->Min, &Interact->Max, &Interact->RadianOffset); // Interact->RadianOffset += @@ -466,52 +300,62 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me } if (Interact->Min.x != 0.0f) { - InteractMin = Interact->Min + Interact->Position; - InteractMax = Interact->Max + Interact->Position; + InteractMin = Interact->Min; + InteractMax = Interact->Max; Rad = Interact->RadianOffset; Rad2 = Interact->Radians; Scale = Interact->Scale; } real32 Angle = Interact->RadianOffset / (PI / 180); - DebugWatchVar("Rad", &Interact->Radians, d_float); - DebugWatchVar("bestangle", &Angle, d_float); + // DebugWatchVar("Rad", &Interact->Radians, d_float); + // DebugWatchVar("bestangle", &Angle, d_float); v2 BoxLength = InteractMax - InteractMin; v2 Center = Interact->OGCenter; - v2 PosL[4] = {}; - v2 PosS[4] = { InteractMin, V2(InteractMax.x, InteractMin.y), InteractMax, V2(InteractMin.x, InteractMax.y) }; + v2 PosL[8] = {}; + v2 PosS[8] = { InteractMin, V2(InteractMax.x, InteractMin.y), + InteractMax, V2(InteractMin.x, InteractMax.y), + InteractMin + V2(BoxLength.x * 0.5, 0), InteractMin + V2(0, BoxLength.y * 0.5), + InteractMax - V2(BoxLength.x * 0.5, 0), InteractMax - V2(0, BoxLength.y * 0.5) }; v2 LocalCenter = InteractMax - (BoxLength/2); + + // NOTE(fox): There's two transformations we need to do: the best-fit + // bounding box transformed from the center of the 0 degree bounding box, + // and then the Interactive rotation based on the center of the best-fit + // bounding box _at its new position_. v2 NewCenter = {}; { real32 Point0X = LocalCenter.x - Center.x; real32 Point0Y = LocalCenter.y - Center.y; - v2 XAxis = (Point0X * Scale)*V2(cos(Rad), sin(Rad)); - v2 YAxis = (Point0Y * Scale)*V2(sin(Rad), -cos(Rad)); + v2 XAxis = (Point0X * 1.0f)*V2(cos(Rad), sin(Rad)); + v2 YAxis = (Point0Y * 1.0f)*V2(sin(Rad), -cos(Rad)); v2 Pos = XAxis + YAxis; NewCenter.x = Center.x + Pos.x; NewCenter.y = Center.y + Pos.y; } - for (int i = 0; i < 4; i++) { + for (int i = 0; i < 8; i++) { real32 Point0X = PosS[i].x - Center.x; real32 Point0Y = PosS[i].y - Center.y; - v2 XAxis = (Point0X * Scale)*V2(cos(Rad), sin(Rad)); - v2 YAxis = (Point0Y * Scale)*V2(sin(Rad), -cos(Rad)); + v2 XAxis = (Point0X * 1.0f)*V2(cos(Rad), sin(Rad)); + v2 YAxis = (Point0Y * 1.0f)*V2(sin(Rad), -cos(Rad)); v2 Pos = XAxis + YAxis; PosL[i].x = Center.x + Pos.x; PosL[i].y = Center.y + Pos.y; { Point0X = PosL[i].x - NewCenter.x; Point0Y = PosL[i].y - NewCenter.y; - XAxis = (Point0X * Scale)*V2(cos(Rad2), sin(Rad2)); + XAxis = (Point0X * Scale)*V2(cos(Rad2), sin(Rad2)); YAxis = (Point0Y * -Scale)*V2(sin(Rad2), -cos(Rad2)); v2 NewPos = XAxis + YAxis; PosL[i].x = NewCenter.x + NewPos.x; PosL[i].y = NewCenter.y + NewPos.y; + PosL[i].x += Interact->Position.x; + PosL[i].y += Interact->Position.y; } } @@ -523,6 +367,13 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me P[2] = IV2(PosL[2])*CompScale + UI->CompPos; P[3] = IV2(PosL[3])*CompScale + UI->CompPos; + ImVec2 Mid_P[4]; + + Mid_P[0] = IV2(PosL[4])*CompScale + UI->CompPos; + Mid_P[1] = IV2(PosL[5])*CompScale + UI->CompPos; + Mid_P[2] = IV2(PosL[6])*CompScale + UI->CompPos; + Mid_P[3] = IV2(PosL[7])*CompScale + UI->CompPos; + ImU32 wcol = IM_COL32(0, 0, 255, 255); draw_list->AddLine(P[0], P[1], wcol, 2.0f); draw_list->AddLine(P[1], P[2], wcol, 2.0f); @@ -532,76 +383,24 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me draw_list->AddLine(P[0], P[2], wcol, 1.0f); draw_list->AddLine(P[1], P[3], wcol, 1.0f); -#if 0 - { - ImU32 wcol = IM_COL32(0, 0, 255, 255); - v2 Min = V2(10000, 10000), Max = V2(-10000, -10000); - for (int i = 0; i < *PointCount; i++) { - v2 Pos = PointData[i]; - if (Pos.x < Min.x) { Min.x = Pos.x; } - if (Pos.y < Min.y) { Min.y = Pos.y; } - if (Pos.x > Max.x) { Max.x = Pos.x; } - if (Pos.y > Max.y) { Max.y = Pos.y; } - } - v2 Dimensions = Max - Min; - v2 Center = Min + Dimensions/2; - ImVec2 P[4] = { IV2(Min), ImVec2(Max.x, Min.y), IV2(Max), ImVec2(Min.x, Max.y) }; - P[0] = P[0]*CompScale + UI->CompPos; - P[1] = P[1]*CompScale + UI->CompPos; - P[2] = P[2]*CompScale + UI->CompPos; - P[3] = P[3]*CompScale + UI->CompPos; - ImVec2 C = IV2(Center)*CompScale + UI->CompPos; - draw_list->AddNgon(C, 10, wcol, 8, 9.0f); - /* - for (int i = 0; i < *PointCount; i++) { - v2 Pos = PointData[i]; - v2 XAxis = (Pos.x - Center.x) * V2(cos(Rad), sin(Rad)); - v2 YAxis = (Pos.y - Center.y) * V2(sin(Rad), -cos(Rad)); - Pos = XAxis + YAxis; - ImVec2 PosS = IV2(Pos)*CompScale + UI->CompPos; - draw_list->AddNgon(PosS, 10, wcol, 8, 9.0f); - }*/ - 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); - } - { - ImU32 wcol = IM_COL32(255, 0, 255, 255); - v2 Min = Interact->Min, Max = Interact->Max; - ImVec2 P[4] = { IV2(Min), ImVec2(Max.x, Min.y), IV2(Max), ImVec2(Min.x, Max.y) }; - P[0] = P[0]*CompScale + UI->CompPos; - P[1] = P[1]*CompScale + UI->CompPos; - P[2] = P[2]*CompScale + UI->CompPos; - P[3] = P[3]*CompScale + UI->CompPos; - ImVec2 C = IV2(Center)*CompScale + UI->CompPos; - draw_list->AddNgon(C, 10, wcol, 8, 9.0f); - 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); - } -#endif - - v2 XAxis2 = (BoxLength*CompScale.x)*V2(cos(Rad), sin(Rad)); - v2 YAxis2 = (BoxLength*CompScale.y)*V2(sin(Rad), -cos(Rad)); + layer_transforms BoxTransforms = { NewCenter.x, NewCenter.y, 0.5, 0.5, (real32)(Rad / (PI / 180)), Scale }; + v2 LayerPoint = Transform_ScreenSpaceToLocal(BoxTransforms, CompWidth, CompHeight, BoxLength.x, BoxLength.y, UI->CompPos, UI->CompZoom, ViewportMin, io.MousePos); - // 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)(Rad / (PI / 180)), Scale }; - v2 LayerPoint = Transform_ScreenSpaceToLocal(BoxTransforms, CompWidth, CompHeight, BoxLength.x, BoxLength.y, UI->CompPos, UI->CompZoom, ViewportMin, io.MousePos); + // for (int i = 0; i < 4; i++) { + // v2 Anchor = TransformPoint(BoxTransforms, BoxLength.x, BoxLength.y, BoxLength * Mid_Local[i]); + // Mid_P[i] = IV2(Anchor)*CompScale + UI->CompPos; + // } real32 U = LayerPoint.x / BoxLength.x; real32 V = LayerPoint.y / BoxLength.y; + DebugWatchVar("U", &U, d_float); + DebugWatchVar("V", &V, d_float); 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); @@ -612,29 +411,49 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me ImGui::PopStyleColor(); if (ImGui::IsItemActivated() && !OtherActions) { + State->Interact_Active = interact_type_viewport_transform_gizmo; 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; + v2 Dir = {}; + if (i == 0) { + Dir = V2(-1, 1); + } else if (i == 1) { + Dir = V2(1, 1); + } else if (i == 2) { + Dir = V2(1, -1); + } else if (i == 3) { + Dir = V2(-1, -1); + } else { + Assert(0); } + + ImVec2 LengthVec = (io.MousePos - io.MouseClickedPos[0]) / CompScale; + real32 NegRad = -Rad; + v2 UnrotatedLengthVec = {}; + { + v2 XAxis = (LengthVec.x * 1.0f)*V2(cos(NegRad), sin(NegRad)); + v2 YAxis = (LengthVec.y * -1.0f)*V2(sin(NegRad), -cos(NegRad)); + v2 UnrotatedLengthVec = XAxis + YAxis; + } + + real32 Length = UnrotatedLengthVec.x * Dir.x; + DebugWatchVar("Len", &Length, d_float); + real32 BoxAxis = BoxLength.x; + Interact->Scale = 1.0f + Length / BoxAxis; + v2 MovePos = V2((Length / 2), -(Length / 2) * (BoxLength.y / BoxLength.x)); + v2 XAxis = (MovePos.x * Dir.x)*V2(cos(Rad), sin(Rad)); + v2 YAxis = (MovePos.y * Dir.y)*V2(sin(Rad), -cos(Rad)); + v2 Pos = XAxis + YAxis; + Interact->Position.x = Pos.x; + Interact->Position.y = Pos.y; } + 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. @@ -644,43 +463,67 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me InBounds = true; } + uint32 Col[4] = { IM_COL32(255, 0, 0, 255), IM_COL32(0, 255, 0, 255), IM_COL32(0, 0, 255, 255), IM_COL32(255, 255, 255, 255) }; for (int i = 0; i < 4; i++) { ImGui::SetCursorScreenPos(P[i] - ScaleHandleSize/2); ImGui::PushID(i); ImGui::Button("##ScaleRotateCorners", ScaleHandleSize); if (ImGui::IsItemActivated() && !OtherActions) { - State->InteractTransformMode = 2; - // if (InBounds) - // State->InteractTransformMode = 1; - // else - // State->InteractTransformMode = 2; + if (InBounds) + State->InteractTransformMode = 1; + else + State->InteractTransformMode = 2; State->Interact_Active = interact_type_viewport_transform_gizmo; } // 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; + ImVec2 LengthVec = (io.MousePos - io.MouseClickedPos[0]) / CompScale; + real32 NegRad = -Rad; + v2 XAxis = (LengthVec.x * 1.0f)*V2(cos(NegRad), sin(NegRad)); + v2 YAxis = (LengthVec.y * -1.0f)*V2(sin(NegRad), -cos(NegRad)); + v2 UnrotatedLengthVec = XAxis + YAxis; + + v2 Dir = {}; + if (i == 0) { + Dir = V2(-1, 1); + } else if (i == 1) { + Dir = V2(1, 1); + } else if (i == 2) { + Dir = V2(1, -1); + } else if (i == 3) { + Dir = V2(-1, -1); + } else { + Assert(0); + } + + v2 Vector0 = V2(BoxLength.x, BoxLength.y); + real32 Dot = Inner(V2(-Vector0.y * Dir.x, Vector0.x * Dir.y), UnrotatedLengthVec); + bool32 Test = (Dot < 0.0f) ? 0 : 1; + + if (!Test) { + real32 Length = UnrotatedLengthVec.x * Dir.x; + real32 BoxAxis = BoxLength.x; + Interact->Scale = 1.0f + Length / BoxAxis; + v2 MovePos = V2((Length / 2), -(Length / 2) * (BoxLength.y / BoxLength.x)); + v2 XAxis = (MovePos.x * Dir.x)*V2(cos(Rad), sin(Rad)); + v2 YAxis = (MovePos.y * Dir.y)*V2(sin(Rad), -cos(Rad)); + v2 Pos = XAxis + YAxis; + Interact->Position.x = Pos.x; + Interact->Position.y = Pos.y; + } else { + real32 Mult = (i == 1 || i == 3) ? -1 : 1; + real32 Length = UnrotatedLengthVec.y * Mult * Dir.x; + real32 BoxAxis = BoxLength.y; + Interact->Scale = 1.0f + -Length / BoxAxis; + v2 MovePos = V2(-(Length / 2) * (BoxLength.x / BoxLength.y), (Length / 2)); + v2 XAxis = (MovePos.x * Dir.x)*V2(cos(Rad), sin(Rad)); + v2 YAxis = (MovePos.y * Dir.y)*V2(sin(Rad), -cos(Rad)); + v2 Pos = XAxis + YAxis; + Interact->Position.x = Pos.x; + Interact->Position.y = Pos.y; } } @@ -706,13 +549,16 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me ImGui::PopID(); } - - if (InBounds && !io.KeyAlt) { - ImGui::SetCursorScreenPos(io.MousePos - ScaleHandleSize/2); - ImGui::Button("##mover", ScaleHandleSize); - if (!State->InteractTransformMode && ImGui::IsItemActivated() && !OtherActions) { - State->Interact_Active = interact_type_viewport_transform_gizmo; - State->InteractTransformMode = 3; + 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); + if (LayerHovered) { + ImGui::SetCursorScreenPos(io.MousePos - ScaleHandleSize/2); + ImGui::Button("##mover", ScaleHandleSize); + if (!State->InteractTransformMode && ImGui::IsItemActivated() && !OtherActions) { + State->Interact_Active = interact_type_viewport_transform_gizmo; + State->InteractTransformMode = 3; + } } } @@ -1246,7 +1092,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, 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, 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); } @@ -1318,8 +1164,16 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, BoxMax.y > BoxMin.y) BoxMax.y = (MousePos.y > ClickedPos.y) ? MousePos.y : ClickedPos.y; if (io.MouseDelta.x || io.MouseDelta.y) { - if (State->Tool == tool_default && State->Interact_Active == interact_type_none) - State->Interact_Active = interact_type_viewport_selection; + if (State->Tool == tool_default && State->Interact_Active == interact_type_none) { + int32 Selection = Layer_TestSelection(Memory, State, UI, SortedCompArray, SortedLayerArray, File->PrincipalCompIndex); + if (!State->InteractTransformMode && Selection != -1) { + Layer_Select(Memory, State, Selection); + State->Interact_Active = interact_type_viewport_transform_gizmo; + State->InteractTransformMode = 3; + } else { + State->Interact_Active = interact_type_viewport_selection; + } + } if (State->Interact_Active == interact_type_viewport_selection) { Layer_DeselectAll(File, State, Memory); @@ -1341,14 +1195,14 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, (IsHovered && IsDeactivated && !io.KeyCtrl && !io.KeyAlt)) && !ImGui::IsMouseDown(ImGuiMouseButton_Right) && !ImGui::IsKeyDown(ImGuiKey_Z)) { - // Layer selection - if (State->Tool == tool_default && State->Interact_Active == interact_type_none) { - int32 Selection = Layer_TestSelection(Memory, State, UI, SortedCompArray, SortedLayerArray, File->PrincipalCompIndex); - if (!io.KeyShift && State->Interact_Active == interact_type_none) - Layer_DeselectAll(File, State, Memory); - if (Selection != -1) - Layer_Select(Memory, State, Selection); - } + // Layer selection + if (State->Tool == tool_default && State->Interact_Active == interact_type_none) { + int32 Selection = Layer_TestSelection(Memory, State, UI, SortedCompArray, SortedLayerArray, File->PrincipalCompIndex); + if (!io.KeyShift && State->Interact_Active == interact_type_none) + Layer_DeselectAll(File, State, Memory); + if (Selection != -1) + Layer_Select(Memory, State, Selection); + } } if (IsDeactivated && State->Interact_Active == interact_type_viewport_selection) { @@ -1518,6 +1372,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, State->Interact_Dup_Previous[1] = State->Interact_Offset[1]; State->Interact_Offset[0] = 0; State->Interact_Offset[1] = 0; + State->Interact_Transform = {}; History_Entry_End(Memory); } else { Assert(IsActive); |