From d1d83025487720ba9fd5b9d0f15d2868032407f1 Mon Sep 17 00:00:00 2001 From: Rodrigo Braz Monteiro Date: Sat, 7 Jul 2007 06:41:14 +0000 Subject: [PATCH] Line and bicubic curve appending implemented to vector clip. Originally committed to SVN as r1387. --- aegisub/spline.cpp | 11 +++ aegisub/spline_curve.cpp | 16 +++++ aegisub/spline_curve.h | 2 + aegisub/visual_tool_vector_clip.cpp | 105 ++++++++++++++++++++++------ 4 files changed, 114 insertions(+), 20 deletions(-) diff --git a/aegisub/spline.cpp b/aegisub/spline.cpp index 994783bca..3b53b71b6 100644 --- a/aegisub/spline.cpp +++ b/aegisub/spline.cpp @@ -99,6 +99,7 @@ void Spline::DecodeFromASS(wxString str) { char lastCommand = 'm'; int x = 0; int y = 0; + bool coordsSet = false; // Tokenize the string wxStringTokenizer tkn(str,_T(" ")); @@ -115,6 +116,7 @@ void Spline::DecodeFromASS(wxString str) { if (stack.size() == 2 && lastCommand == 'm') { x = stack[0]; y = stack[1]; + coordsSet = true; stack.clear(); } @@ -166,6 +168,15 @@ void Spline::DecodeFromASS(wxString str) { else if (token == _T("c")) lastCommand = 'c'; } } + + // Got coordinates, but list is empty + if (curves.size() == 0 && coordsSet) { + SplineCurve curve; + curve.p1.x = x; + curve.p1.y = y; + curve.type = CURVE_POINT; + AppendCurve(curve); + } } diff --git a/aegisub/spline_curve.cpp b/aegisub/spline_curve.cpp index 616880b17..3763ee043 100644 --- a/aegisub/spline_curve.cpp +++ b/aegisub/spline_curve.cpp @@ -93,6 +93,7 @@ void SplineCurve::Split(SplineCurve &c1,SplineCurve &c2,float t) { void SplineCurve::Smooth(Vector2D P0,Vector2D P3,float smooth) { // Validate if (type != CURVE_LINE) return; + if (p1 == p2) return; smooth = MID(0.0f,smooth,1.0f); // Get points @@ -117,3 +118,18 @@ void SplineCurve::Smooth(Vector2D P0,Vector2D P3,float smooth) { p3 = m2+(c2-m2)*smooth + P2 - m2; type = CURVE_BICUBIC; } + + +/////////////////////// +// Get start/end point +Vector2D SplineCurve::GetStartPoint() { + return p1; +} +Vector2D SplineCurve::GetEndPoint() { + switch (type) { + case CURVE_POINT: return p1; + case CURVE_LINE: return p2; + case CURVE_BICUBIC: return p4; + default: return p1; + } +} diff --git a/aegisub/spline_curve.h b/aegisub/spline_curve.h index f2566e1cb..abf335475 100644 --- a/aegisub/spline_curve.h +++ b/aegisub/spline_curve.h @@ -62,4 +62,6 @@ public: SplineCurve(); void Split(SplineCurve &c1,SplineCurve &c2,float t=0.5); void Smooth(Vector2D prev,Vector2D next,float smooth=1.0f); + Vector2D GetStartPoint(); + Vector2D GetEndPoint(); }; diff --git a/aegisub/visual_tool_vector_clip.cpp b/aegisub/visual_tool_vector_clip.cpp index 5fbf83034..32e2412fd 100644 --- a/aegisub/visual_tool_vector_clip.cpp +++ b/aegisub/visual_tool_vector_clip.cpp @@ -157,6 +157,16 @@ void VisualToolVectorClip::Draw() { DrawDashedLine(cur->p3.x,cur->p3.y,cur->p4.x,cur->p4.y,6); } } + + // Draw preview of inserted line + if (mode == 1 || mode == 2) { + if (spline.curves.size()) { + SplineCurve *c0 = &spline.curves.front(); + SplineCurve *c1 = &spline.curves.back(); + DrawDashedLine(mx,my,c0->p1.x,c0->p1.y,6); + DrawDashedLine(mx,my,c1->GetEndPoint().x,c1->GetEndPoint().y,6); + } + } } @@ -225,7 +235,7 @@ void VisualToolVectorClip::PopulateFeatureList() { ///////////// // Can drag? bool VisualToolVectorClip::DragEnabled() { - return mode == 0; + return mode <= 2; } @@ -252,38 +262,93 @@ void VisualToolVectorClip::ClickedFeature(VisualDraggableFeature &feature) { ///////////// // Can hold? bool VisualToolVectorClip::HoldEnabled() { - return mode == 6 || mode == 7; + return mode == 1 || mode == 2 || mode == 6 || mode == 7; } /////////////////// // Initialize hold void VisualToolVectorClip::InitializeHold() { - spline.curves.clear(); - lastX = -100000; - lastY = -100000; + // Insert line/bicubic + if (mode == 1 || mode == 2) { + SplineCurve curve; + + // Set start position + if (spline.curves.size()) { + curve.p1 = spline.curves.back().GetEndPoint(); + if (mode == 1) curve.type = CURVE_LINE; + else curve.type = CURVE_BICUBIC; + + // Remove point if that's all there is + if (spline.curves.size()==1 && spline.curves.front().type == CURVE_POINT) spline.curves.clear(); + } + + // First point + else { + curve.p1 = Vector2D(mx,my); + curve.type = CURVE_POINT; + } + + // Insert + spline.AppendCurve(curve); + } + + // Freehand + if (mode == 6 || mode == 7) { + spline.curves.clear(); + lastX = -100000; + lastY = -100000; + } } /////////////// // Update hold void VisualToolVectorClip::UpdateHold() { - if (lastX != -100000 && lastY != -100000) { - // See if distance is enough - Vector2D delta(lastX-mx,lastY-my); - int len = (int)delta.Len(); - if (mode == 6 && len < 30) return; - if (mode == 7 && len < 60) return; - - // Generate curve and add it - SplineCurve curve; - curve.type = CURVE_LINE; - curve.p1 = Vector2D(lastX,lastY); - curve.p2 = Vector2D(mx,my); - spline.AppendCurve(curve); + // Insert line + if (mode == 1) { + spline.curves.back().p2 = Vector2D(mx,my); + } + + // Insert bicubic + if (mode == 2) { + SplineCurve &curve = spline.curves.back(); + curve.p4 = Vector2D(mx,my); + + // Control points + if (spline.curves.size() > 1) { + std::list::reverse_iterator iter = spline.curves.rbegin(); + iter++; + SplineCurve &c0 = *iter; + Vector2D prevVector; + float len = (curve.p4-curve.p1).Len(); + if (c0.type == CURVE_LINE) prevVector = c0.p2-c0.p1; + else prevVector = c0.p4-c0.p3; + curve.p2 = prevVector.Unit() * (0.25f*len) + curve.p1; + } + else curve.p2 = curve.p1 * 0.75 + curve.p4 * 0.25; + curve.p3 = curve.p1 * 0.25 + curve.p4 * 0.75; + } + + // Freehand + if (mode == 6 || mode == 7) { + if (lastX != -100000 && lastY != -100000) { + // See if distance is enough + Vector2D delta(lastX-mx,lastY-my); + int len = (int)delta.Len(); + if (mode == 6 && len < 30) return; + if (mode == 7 && len < 60) return; + + // Generate curve and add it + SplineCurve curve; + curve.type = CURVE_LINE; + curve.p1 = Vector2D(lastX,lastY); + curve.p2 = Vector2D(mx,my); + spline.AppendCurve(curve); + } + lastX = mx; + lastY = my; } - lastX = mx; - lastY = my; }