diff --git a/FexTracker/FexTrackerRel.lib b/FexTracker/FexTrackerRel.lib index a998d6474..b49534a48 100644 Binary files a/FexTracker/FexTrackerRel.lib and b/FexTracker/FexTrackerRel.lib differ diff --git a/FexTracker/FexTrackerRel_Opti.lib b/FexTracker/FexTrackerRel_Opti.lib index c38209731..382cfc32b 100644 Binary files a/FexTracker/FexTrackerRel_Opti.lib and b/FexTracker/FexTrackerRel_Opti.lib differ diff --git a/core/FexTracker.h b/core/FexTracker.h index 2af2f9d57..09902b456 100644 --- a/core/FexTracker.h +++ b/core/FexTracker.h @@ -60,8 +60,13 @@ typedef struct{ float x, y; }vec2; +typedef struct{ + float x, y, z; +}vec3; + class FexImgPyramid; class FexTrackingFeature; +class FexMovement; class FEXTRACKER_API FexTracker { @@ -72,8 +77,13 @@ public: FexTrackerConfig Cfg; //work void ProcessImage( float *Img, bool bFirst=0 ); //we assume grayscale image here - void InfluenceFeatures( int Frame, float x, float y, float off ); + void ProcessingDone(); // call after last call to ProcessImage to clear temporary storage +//point -> movement + void InfluenceFeatures( int Frame, float x, float y, float off ); + FexMovement* GetMovement(); + +//feature access FexTrackingFeature* operator [] ( int i ); inline int GetCount(){ return nFeatures; }; inline int GetFrame(){ return CurFrame; }; diff --git a/core/FexTrackingFeature.h b/core/FexTrackingFeature.h index e0424a00d..f0371274e 100644 --- a/core/FexTrackingFeature.h +++ b/core/FexTrackingFeature.h @@ -18,7 +18,7 @@ public: int Eigenvalue; tenlist Pos; - + int StartTime; float Influence; diff --git a/core/ass_dialogue.cpp b/core/ass_dialogue.cpp index 95de06cb0..8fe96de5d 100644 --- a/core/ass_dialogue.cpp +++ b/core/ass_dialogue.cpp @@ -42,12 +42,15 @@ #include "utils.h" #include #include +#include "FexTracker.h" +#include "FexMovement.h" ////////////////////// AssDialogue ////////////////////// // Constructs AssDialogue AssDialogue::AssDialogue() { Tracker = 0; + Movement = 0; Type = ENTRY_DIALOGUE; group = _T("[Events]"); @@ -70,6 +73,7 @@ AssDialogue::AssDialogue() { AssDialogue::AssDialogue(wxString _data,bool IsSSA) { Tracker = 0; + Movement = 0; Type = ENTRY_DIALOGUE; group = _T("[Events]"); @@ -97,6 +101,17 @@ void AssDialogue::Clear () { delete *cur; } Blocks.clear(); + + if( Tracker ) + { + delete Tracker; + Tracker = 0; + } + if( Movement ) + { + DeleteMovement( Movement ); + Movement = 0; + } } diff --git a/core/ass_dialogue.h b/core/ass_dialogue.h index ff60c6415..2c1d5a00c 100644 --- a/core/ass_dialogue.h +++ b/core/ass_dialogue.h @@ -43,6 +43,7 @@ #include "ass_entry.h" #include "ass_time.h" class FexTracker; +class FexMovement; ////////////// @@ -167,6 +168,7 @@ public: wxString Effect; // Effect name wxString Text; // Raw text data FexTracker *Tracker; // Point tracker + FexMovement *Movement; // Point tracker generated movement bool Parse(bool IsSSA=false); // Parses raw ASS data into everything else void ParseASSTags(); // Parses text to generate block information (doesn't update data) diff --git a/core/bitmaps/button_track_split.bmp b/core/bitmaps/button_track_movement.bmp similarity index 100% rename from core/bitmaps/button_track_split.bmp rename to core/bitmaps/button_track_movement.bmp diff --git a/core/bitmaps/button_track_split_line.bmp b/core/bitmaps/button_track_split_line.bmp new file mode 100644 index 000000000..9bab8e6ff Binary files /dev/null and b/core/bitmaps/button_track_split_line.bmp differ diff --git a/core/fexmovement.h b/core/fexmovement.h new file mode 100644 index 000000000..be657c915 --- /dev/null +++ b/core/fexmovement.h @@ -0,0 +1,36 @@ +// FexMovement.h: interface for the FexMovement class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_FEXMOVEMENT_H__63D8ADD8_4EA1_4C56_8D6F_7B587A1A61A4__INCLUDED_) +#define AFX_FEXMOVEMENT_H__63D8ADD8_4EA1_4C56_8D6F_7B587A1A61A4__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +typedef struct +{ + vec2 Pos; + vec3 Rot; + vec2 Scale; +}FexMovementFrame; + +#include "tenlist.h" +class FexMovement +{ +public: + FexMovement(); + ~FexMovement(); + + void Load( const char* Filename ); + void Save( const char* Filename ); + + const char* GetUniqueName(); + + tenlist Frames; +}; + +void FEXTRACKER_API DeleteMovement( FexMovement* delme ); + +#endif // !defined(AFX_FEXMOVEMENT_H__63D8ADD8_4EA1_4C56_8D6F_7B587A1A61A4__INCLUDED_) diff --git a/core/frame_main.h b/core/frame_main.h index 01715bb1c..794824804 100644 --- a/core/frame_main.h +++ b/core/frame_main.h @@ -105,9 +105,13 @@ private: void OnVideoPlayLine(wxCommandEvent &event); void OnVideoStop(wxCommandEvent &event); void OnVideoToggleScroll(wxCommandEvent &event); + + void OnVideoTrackerMenu(wxCommandEvent &event); void OnVideoTrackPoints(wxCommandEvent &event); void OnVideoTrackPointAdd(wxCommandEvent &event); void OnVideoTrackPointDel(wxCommandEvent &event); + void OnVideoTrackMovement(wxCommandEvent &event); + void OnVideoTrackSplitLine(wxCommandEvent &event); void OnKeyDown(wxKeyEvent &event); @@ -324,9 +328,13 @@ enum { Video_Play_Line, Video_Stop, Video_Auto_Scroll, + + Video_Tracker_Menu, Video_Track_Points, Video_Track_Point_Add, Video_Track_Point_Del, + Video_Track_Movement, + Video_Track_Split_Line, Menu_File_Recent = 2000, Menu_Video_Recent = 2200, diff --git a/core/frame_main_events.cpp b/core/frame_main_events.cpp index 51dfe72c2..afcf9c10b 100644 --- a/core/frame_main_events.cpp +++ b/core/frame_main_events.cpp @@ -74,6 +74,7 @@ #include "dialog_timing_processor.h" #include "FexTracker.h" #include "FexTrackingFeature.h" +#include "FexMovement.h" //////////////////// @@ -86,9 +87,13 @@ BEGIN_EVENT_TABLE(FrameMain, wxFrame) EVT_BUTTON(Video_Play_Line, FrameMain::OnVideoPlayLine) EVT_BUTTON(Video_Stop, FrameMain::OnVideoStop) EVT_TOGGLEBUTTON(Video_Auto_Scroll, FrameMain::OnVideoToggleScroll) - EVT_BUTTON(Video_Track_Points, FrameMain::OnVideoTrackPoints) - EVT_BUTTON(Video_Track_Point_Add, FrameMain::OnVideoTrackPointAdd) - EVT_BUTTON(Video_Track_Point_Del, FrameMain::OnVideoTrackPointDel) + + EVT_BUTTON(Video_Tracker_Menu, FrameMain::OnVideoTrackerMenu) + EVT_MENU(Video_Track_Points, FrameMain::OnVideoTrackPoints) + EVT_MENU(Video_Track_Point_Add, FrameMain::OnVideoTrackPointAdd) + EVT_MENU(Video_Track_Point_Del, FrameMain::OnVideoTrackPointDel) + EVT_MENU(Video_Track_Movement, FrameMain::OnVideoTrackMovement) + EVT_MENU(Video_Track_Split_Line, FrameMain::OnVideoTrackSplitLine) EVT_CLOSE(FrameMain::OnCloseWindow) @@ -1129,6 +1134,21 @@ void FrameMain::OnVideoToggleScroll(wxCommandEvent &event) { } +/////////////////// +// Track current line +void FrameMain::OnVideoTrackerMenu(wxCommandEvent &event) { + wxMenu menu( _("FexTracker") ); + AppendBitmapMenuItem(&menu, Video_Track_Points, _("track points"), _(""), wxBITMAP(button_track_points)); + menu.AppendSeparator(); + AppendBitmapMenuItem(&menu, Video_Track_Point_Add, _("add points to movement"), _(""), wxBITMAP(button_track_point_add)); + AppendBitmapMenuItem(&menu, Video_Track_Point_Del, _("remove points from movement"), _(""), wxBITMAP(button_track_point_del)); + menu.AppendSeparator(); + AppendBitmapMenuItem(&menu, Video_Track_Movement, _("generate movement from points"), _(""), wxBITMAP(button_track_movement)); + AppendBitmapMenuItem(&menu, Video_Track_Split_Line, _("split line for movement"), _(""), wxBITMAP(button_track_split_line)); + PopupMenu(&menu); +} + + /////////////////// // Track current line void FrameMain::OnVideoTrackPoints(wxCommandEvent &event) { @@ -1170,6 +1190,70 @@ void FrameMain::OnVideoTrackPoints(wxCommandEvent &event) { } +/////////////////// +// Track current line +void FrameMain::OnVideoTrackMovement(wxCommandEvent &event) { + videoBox->videoDisplay->Stop(); + + // Get line + AssDialogue *curline = SubsBox->GetDialogue(EditBox->linen); + if (!curline) return; + if( !curline->Tracker ) return; + + // Create Movement + if( curline->Movement ) DeleteMovement( curline->Movement ); + curline->Movement = curline->Tracker->GetMovement(); + + // Remove Tracker + delete curline->Tracker; + curline->Tracker = 0; + + videoBox->videoDisplay->RefreshVideo(); +} + + +/////////////////// +// split current line +void FrameMain::OnVideoTrackSplitLine(wxCommandEvent &event) { + videoBox->videoDisplay->Stop(); + + // Get line + AssDialogue *curline = SubsBox->GetDialogue(EditBox->linen); + if (!curline) return; + if( !curline->Movement ) return; + + // Create split lines + int StartFrame = VFR_Output.CorrectFrameAtTime(curline->Start.GetMS(),true); + int EndFrame = VFR_Output.CorrectFrameAtTime(curline->End.GetMS(),false); + + for( int Frame = StartFrame; Frame < EndFrame; Frame ++ ) + { + int localframe = Frame - StartFrame; + + while( curline->Movement->Frames.size() <= localframe ) localframe--; + FexMovementFrame f = curline->Movement->Frames[localframe]; +// f.Pos.x /= videoBox->videoDisplay->GetW + + AssDialogue *cur = new AssDialogue( curline->data ); + cur->Start.SetMS(VFR_Output.CorrectTimeAtFrame(Frame,true)); + cur->End.SetMS(VFR_Output.CorrectTimeAtFrame(Frame,false)); + cur->Text = wxString::Format( _T("{\\pos(%.0f,%.0f)\\fscx%.2f\\fscy%.2f}"), f.Pos.x, f.Pos.y, f.Scale.x*100, f.Scale.y*100 ) + cur->Text; + cur->UpdateData(); + + SubsBox->InsertLine(cur,EditBox->linen + Frame - StartFrame,true,false); + } + + // Remove Movement + DeleteMovement( curline->Movement ); + curline->Movement = 0; + + // Remove this line + SubsBox->DeleteLines( EditBox->linen, EditBox->linen, false ); + + videoBox->videoDisplay->RefreshVideo(); +} + + /////////////////// // Increase Influence void FrameMain::OnVideoTrackPointAdd(wxCommandEvent &event) { diff --git a/core/res.rc b/core/res.rc index d618c2011..bbf9fc79c 100644 --- a/core/res.rc +++ b/core/res.rc @@ -79,9 +79,12 @@ shift_to_frame_disable BITMAP "bitmaps/shift_to_frame_disable.bmp" button_play BITMAP "bitmaps/button_play.bmp" button_stop BITMAP "bitmaps/button_stop.bmp" + button_track_points BITMAP "bitmaps/button_track_points.bmp" button_track_point_add BITMAP "bitmaps/button_track_point_add.bmp" button_track_point_del BITMAP "bitmaps/button_track_point_del.bmp" +button_track_movement BITMAP "bitmaps/button_track_movement.bmp" +button_track_split_line BITMAP "bitmaps/button_track_split_line.bmp" button_bold BITMAP "bitmaps/button_bold.bmp" button_italics BITMAP "bitmaps/button_italics.bmp" diff --git a/core/video_box.cpp b/core/video_box.cpp index a1ea01200..7f6253aa6 100644 --- a/core/video_box.cpp +++ b/core/video_box.cpp @@ -59,12 +59,9 @@ VideoBox::VideoBox(wxPanel *parent) { AutoScroll = new ToggleBitmap(videoPage,Video_Auto_Scroll,wxBITMAP(toggle_video_autoscroll),wxSize(30,-1)); AutoScroll->SetToolTip(_("Toggle autoscroll of video")); AutoScroll->SetValue(Options.AsBool(_T("Sync video with subs"))); - wxBitmapButton *VideoTrackPointsButton = new wxBitmapButton(videoPage,Video_Track_Points,wxBITMAP(button_track_points),wxDefaultPosition,wxSize(25,-1)); - VideoTrackPointsButton->SetToolTip(_("Track point movements in video")); - wxBitmapButton *VideoTrackPointAddButton = new wxBitmapButton(videoPage,Video_Track_Point_Add,wxBITMAP(button_track_point_add),wxDefaultPosition,wxSize(25,-1)); - VideoTrackPointAddButton->SetToolTip(_("Increase influence of tracking points")); - wxBitmapButton *VideoTrackPointDelButton = new wxBitmapButton(videoPage,Video_Track_Point_Del,wxBITMAP(button_track_point_del),wxDefaultPosition,wxSize(25,-1)); - VideoTrackPointDelButton->SetToolTip(_("Decrease influence of tracking points")); + + wxBitmapButton *VideoTrackerMenuButton = new wxBitmapButton(videoPage,Video_Tracker_Menu,wxBITMAP(button_track_points),wxDefaultPosition,wxSize(25,-1)); + VideoTrackerMenuButton->SetToolTip(_("FexTracker")); // Seek videoSlider = new VideoSlider(videoPage,-1); @@ -99,9 +96,7 @@ VideoBox::VideoBox(wxPanel *parent) { videoBottomSizer->Add(AutoScroll,0,wxTOP|wxBOTTOM|wxALIGN_CENTER|wxEXPAND,2); videoBottomSizer->Add(VideoPosition,1,wxLEFT|wxALIGN_CENTER,5); videoBottomSizer->Add(VideoSubsPos,1,wxALIGN_CENTER,0); - videoBottomSizer->Add(VideoTrackPointsButton,0,wxTOP|wxBOTTOM|wxALIGN_CENTER,2); - videoBottomSizer->Add(VideoTrackPointAddButton,0,wxTOP|wxBOTTOM|wxALIGN_CENTER,2); - videoBottomSizer->Add(VideoTrackPointDelButton,0,wxTOP|wxBOTTOM|wxALIGN_CENTER,2); + videoBottomSizer->Add(VideoTrackerMenuButton,0,wxTOP|wxBOTTOM|wxALIGN_CENTER,2); VideoSizer = new wxBoxSizer(wxVERTICAL); VideoSizer->Add(videoDisplay,0,wxEXPAND,0); VideoSizer->Add(videoSliderSizer,0,wxEXPAND,0); diff --git a/core/video_display.cpp b/core/video_display.cpp index a6b7fc6c2..dae9d34f4 100644 --- a/core/video_display.cpp +++ b/core/video_display.cpp @@ -55,6 +55,7 @@ #include #include "FexTracker.h" #include "FexTrackingFeature.h" +#include "FexMovement.h" /////// @@ -557,7 +558,7 @@ void VideoDisplay::DrawTrackingOverlay( wxDC &dc ) // Get line AssDialogue *curline = grid->GetDialogue(grid->editBox->linen); - if( !curline || !curline->Tracker ) return; + if( !curline ) return; int StartFrame = VFR_Output.CorrectFrameAtTime(curline->Start.GetMS(),true); int EndFrame = VFR_Output.CorrectFrameAtTime(curline->End.GetMS(),false); @@ -565,28 +566,45 @@ void VideoDisplay::DrawTrackingOverlay( wxDC &dc ) if( frame_nEndFrame ) return; int localframe = frame_n - StartFrame; - if( curline->Tracker->GetFrame() <= localframe ) return; - dc.SetLogicalFunction(wxCOPY); - - for( int i=0;iTracker->GetCount();i++ ) + if( curline->Tracker ) { - FexTrackingFeature* f = (*curline->Tracker)[i]; - if( f->StartTime > localframe ) continue; - int llf = localframe - f->StartTime; - if( f->Pos.size() <= llf ) continue; - vec2 pt = f->Pos[llf]; - pt.x *= provider->GetZoom(); - pt.y *= provider->GetZoom(); - pt.x = int(pt.x); - pt.y = int(pt.y); + if( curline->Tracker->GetFrame() <= localframe ) return; - dc.SetPen(wxPen(wxColour(255*(1-f->Influence),255*f->Influence,0),1)); + dc.SetLogicalFunction(wxCOPY); - dc.DrawLine( pt.x-2, pt.y, pt.x, pt.y ); - dc.DrawLine( pt.x, pt.y-2, pt.x, pt.y ); - dc.DrawLine( pt.x+1, pt.y, pt.x+3, pt.y ); - dc.DrawLine( pt.x, pt.y+1, pt.x, pt.y+3 ); + for( int i=0;iTracker->GetCount();i++ ) + { + FexTrackingFeature* f = (*curline->Tracker)[i]; + if( f->StartTime > localframe ) continue; + int llf = localframe - f->StartTime; + if( f->Pos.size() <= llf ) continue; + vec2 pt = f->Pos[llf]; + pt.x *= provider->GetZoom(); + pt.y *= provider->GetZoom(); + pt.x = int(pt.x); + pt.y = int(pt.y); + + dc.SetPen(wxPen(wxColour(255*(1-f->Influence),255*f->Influence,0),1)); + + dc.DrawLine( pt.x-2, pt.y, pt.x, pt.y ); + dc.DrawLine( pt.x, pt.y-2, pt.x, pt.y ); + dc.DrawLine( pt.x+1, pt.y, pt.x+3, pt.y ); + dc.DrawLine( pt.x, pt.y+1, pt.x, pt.y+3 ); + } + } + else if( curline->Movement ) + { + if( curline->Movement->Frames.size() <= localframe ) return; + + dc.SetPen(wxPen(wxColour(255,0,0),2)); + FexMovementFrame f = curline->Movement->Frames.lVal[localframe]; + f.Pos.x *= provider->GetZoom(); + f.Pos.y *= provider->GetZoom(); + f.Scale.x *= 30* provider->GetZoom(); + f.Scale.y *= 30* provider->GetZoom(); + dc.DrawLine( f.Pos.x-f.Scale.x, f.Pos.y, f.Pos.x+f.Scale.x+1, f.Pos.y ); + dc.DrawLine( f.Pos.x, f.Pos.y-f.Scale.y, f.Pos.x, f.Pos.y+f.Scale.y+1 ); } }