forked from mia/Aegisub
Line and bicubic curve appending implemented to vector clip.
Originally committed to SVN as r1387.
This commit is contained in:
parent
1af87b0808
commit
d1d8302548
4 changed files with 114 additions and 20 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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,22 +262,76 @@ 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() {
|
||||
// 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() {
|
||||
// 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<SplineCurve>::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);
|
||||
|
@ -284,6 +348,7 @@ void VisualToolVectorClip::UpdateHold() {
|
|||
}
|
||||
lastX = mx;
|
||||
lastY = my;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue