From bc5375149c0ecb416848a2d3657ea41ae97177b3 Mon Sep 17 00:00:00 2001 From: Fox Caminiti Date: Wed, 10 Aug 2022 21:24:03 -0400 Subject: path rasterization started with opengl --- my_imgui_internal_widgets.cpp | 104 ++++++++++-------------------------------- 1 file changed, 23 insertions(+), 81 deletions(-) (limited to 'my_imgui_internal_widgets.cpp') diff --git a/my_imgui_internal_widgets.cpp b/my_imgui_internal_widgets.cpp index c654e36..705b898 100644 --- a/my_imgui_internal_widgets.cpp +++ b/my_imgui_internal_widgets.cpp @@ -164,95 +164,44 @@ bool ImGui::TestLine(ImVec2 p0, ImVec2 p1) return Toggle; } -// Slightly modified version of the bezier closest point lookup code that -// additionally outputs the ratio of the closest point along the curve for use -// in constructing the handles of new points. +// Currently not used anywhere outside of debug UI. I'll keep it in case +// there's a place where doing this operation in UI space is useful. Note that +// the version of this function in bezier.cpp differs in precision by about +// 0.001. - -// The ratio here is just the dot product divided by the squared length. -ImVec2 ImLineClosestPoint2(const ImVec2& a, const ImVec2& b, const ImVec2& p, float& ratio) +ImVec2 ImGui::RatioToPoint(ImVec2 a, ImVec2 b, float ratio) { - ImVec2 ap = p - a; ImVec2 ab_dir = b - a; - float dot = ap.x * ab_dir.x + ap.y * ab_dir.y; - if (dot < 0.0f) { - ratio = 0.0f; - return a; - } float ab_len_sqr = ab_dir.x * ab_dir.x + ab_dir.y * ab_dir.y; - if (dot > ab_len_sqr) { - ratio = 1.0f; - return b; - } - ratio = dot / ab_len_sqr; + float dot = ratio*ab_len_sqr; return a + ab_dir * dot / ab_len_sqr; } -// Function to convert a ratio back into a point for the bezier handles. -ImVec2 ImGui::RatioToPoint(const ImVec2& a, const ImVec2& b, float ratio) +// Returns true when cursor is close to the curve but not too close to the +// beginning/end points. Basically just a wrapper for that ClosestPoint +// function. +bool ImGui::BezierInteractive(ImVec2 p0, ImVec2 p1, ImVec2 p2, ImVec2 p3) { - ImVec2 ab_dir = b - a; - float ab_len_sqr = ab_dir.x * ab_dir.x + ab_dir.y * ab_dir.y; - float dot = ratio*ab_len_sqr; - return a + ab_dir * dot / ab_len_sqr; -} + bool hovered = false; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; -// Following the algorithm, we take the ratio from the _leftmost_ point in each -// subdivision of the cubic spline until we're within tess_tol, and then we -// interpolate it with the subdivision's rightmost point in the ClosestPoint call. -// The pow(0.5, level) represents the ratio of the next subdivision's leftmost -// point (AKA the rightmost point of the current subdivision). + ImVec2 point = ImBezierCubicClosestPointCasteljau(p0, p1, p2, p3, g.IO.MousePos, GetStyle().CurveTessellationTol); -static void ImBezierCubicClosestPointCasteljauStep2(const ImVec2& p, ImVec2& p_closest, float ratio, float& r_closest, ImVec2& p_last, float& p_closest_dist2, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level) -{ - float dx = x4 - x1; - float dy = y4 - y1; - float d2 = ((x2 - x4) * dy - (y2 - y4) * dx); - float d3 = ((x3 - x4) * dy - (y3 - y4) * dx); - d2 = (d2 >= 0) ? d2 : -d2; - d3 = (d3 >= 0) ? d3 : -d3; - if ((d2 + d3) * (d2 + d3) < tess_tol * (dx * dx + dy * dy)) - { - ImVec2 p_current(x4, y4); - float added_ratio; - ImVec2 p_line = ImLineClosestPoint2(p_last, p_current, p, added_ratio); - float dist2 = ImLengthSqr(p - p_line); - if (dist2 < p_closest_dist2) - { - p_closest = p_line; - p_closest_dist2 = dist2; - r_closest = ratio + pow(0.5, level)*added_ratio; - } - p_last = p_current; - } - else if (level < 10) + if (abs(g.IO.MousePos.x - point.x) < 3 && abs(g.IO.MousePos.y - point.y) < 3 && + abs(p0.x - point.x) > 3 && abs(p0.y - point.y) > 3 && + abs(p1.x - point.x) > 3 && abs(p1.y - point.y) > 3) { - float x12 = (x1 + x2)*0.5f, y12 = (y1 + y2)*0.5f; - float x23 = (x2 + x3)*0.5f, y23 = (y2 + y3)*0.5f; - float x34 = (x3 + x4)*0.5f, y34 = (y3 + y4)*0.5f; - float x123 = (x12 + x23)*0.5f, y123 = (y12 + y23)*0.5f; - float x234 = (x23 + x34)*0.5f, y234 = (y23 + y34)*0.5f; - float x1234 = (x123 + x234)*0.5f, y1234 = (y123 + y234)*0.5f; - ImBezierCubicClosestPointCasteljauStep2(p, p_closest, ratio, r_closest, p_last, p_closest_dist2, x1, y1, x12, y12, x123, y123, x1234, y1234, tess_tol, level + 1); - ImBezierCubicClosestPointCasteljauStep2(p, p_closest, ratio + pow(0.5, level+1), r_closest, p_last, p_closest_dist2, x1234, y1234, x234, y234, x34, y34, x4, y4, tess_tol, level + 1); + hovered = true; } -} -ImVec2 ImBezierCubicClosestPointCasteljau2(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, float& ratio, float tess_tol) -{ - IM_ASSERT(tess_tol > 0.0f); - ImVec2 p_last = p1; - ImVec2 p_closest; - float p_closest_dist2 = FLT_MAX; - float r_closest; - ImBezierCubicClosestPointCasteljauStep2(p, p_closest, 0, r_closest, p_last, p_closest_dist2, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, tess_tol, 0); - ratio = r_closest; - return p_closest; + return hovered; } -// Returns true when cursor is close to the curve but not too close to the beginning/end points. -bool ImGui::BezierInteractive(ImVec2 p0, ImVec2 p1, ImVec2 p2, ImVec2 p3, float& ratio) +bool ImGui::LineInteractive(ImVec2 p0, ImVec2 p1) { bool hovered = false; @@ -261,21 +210,14 @@ bool ImGui::BezierInteractive(ImVec2 p0, ImVec2 p1, ImVec2 p2, ImVec2 p3, float& if (window->SkipItems) return false; - ImDrawList* draw_list = window->DrawList; - ImU32 col = ImGui::GetColorU32(ImGuiCol_ScrollbarGrab); - - ImVec2 point = ImBezierCubicClosestPointCasteljau2(p0, p1, p2, p3, g.IO.MousePos, ratio, GetStyle().CurveTessellationTol); - + ImVec2 point = ImLineClosestPoint(p0, p1, g.IO.MousePos); if (abs(g.IO.MousePos.x - point.x) < 3 && abs(g.IO.MousePos.y - point.y) < 3 && abs(p0.x - point.x) > 3 && abs(p0.y - point.y) > 3 && abs(p1.x - point.x) > 3 && abs(p1.y - point.y) > 3) { - col = GetColorU32(ImGuiCol_Button); hovered = true; } - draw_list->AddBezierCubic(p0, p1, p2, p3, col, 2.0f, 0); - return hovered; } -- cgit v1.2.3