Curve points of tracking curves now can be grabbed to smooth spikes
authorSergey Sharybin <sergey.vfx@gmail.com>
Wed, 18 Jan 2012 16:45:02 +0000 (16:45 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Wed, 18 Jan 2012 16:45:02 +0000 (16:45 +0000)
Curve points of tracks curves now can be selected for X and Y channels
separately and can be moved along Y axis of curve viewer, points currently
can't change frame they belong to. This allows to smooth spikes caused by
unwanted marker jump.

Also fixed some mistakes in cancel transform in cases when locked tracks
were being trying to be moved; fixed incorrect calculation of marker speed
for curve drawing.

source/blender/editors/space_clip/clip_graph_draw.c
source/blender/editors/space_clip/clip_graph_ops.c
source/blender/editors/space_clip/clip_utils.c
source/blender/editors/space_clip/space_clip.c
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_generics.c
source/blender/makesdna/DNA_tracking_types.h

index 9aba6db0c8086fb5cdabdeaaf05392e7c4663efd..e913ae77f05e6b1b53dd95800b79c51cc76223c2 100644 (file)
@@ -155,15 +155,16 @@ void tracking_segment_end_cb(void *UNUSED(userdata))
 }
 
 static void tracking_segment_knot_cb(void *userdata, MovieTrackingTrack *track,
-                       MovieTrackingMarker *marker, int UNUSED(coord), float val)
+                       MovieTrackingMarker *marker, int coord, float val)
 {
        struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } *data = userdata;
-       int sel= 0;
+       int sel= 0, sel_flag;
 
        if(track!=data->act_track)
                return;
 
-       sel= (marker->flag&MARKER_GRAPH_SEL) ? 1 : 0;
+       sel_flag= coord == 0 ? MARKER_GRAPH_SEL_X : MARKER_GRAPH_SEL_Y;
+       sel= (marker->flag & sel_flag) ? 1 : 0;
 
        if(sel == data->sel) {
                if(sel) UI_ThemeColor(TH_HANDLE_VERTEX_SELECT);
index 08d6bcf47bc80ce9c8e8b0d1ef963914c6d15bc3..8be5e520b1fd1eea541146b4193eef3ae92fdf00 100644 (file)
@@ -68,13 +68,13 @@ static void toggle_selection_cb(void *userdata, MovieTrackingMarker *marker)
 
        switch(data->action) {
                case SEL_SELECT:
-                       marker->flag|= MARKER_GRAPH_SEL;
+                       marker->flag|= (MARKER_GRAPH_SEL_X|MARKER_GRAPH_SEL_Y);
                        break;
                case SEL_DESELECT:
-                       marker->flag&= ~MARKER_GRAPH_SEL;
+                       marker->flag&= ~(MARKER_GRAPH_SEL_X|MARKER_GRAPH_SEL_Y);
                        break;
                case SEL_INVERT:
-                       marker->flag^= MARKER_GRAPH_SEL;
+                       marker->flag^= (MARKER_GRAPH_SEL_X|MARKER_GRAPH_SEL_Y);
                        break;
        }
 }
@@ -177,7 +177,10 @@ static int mouse_select_knot(bContext *C, float co[2], int extend)
                                        clip_graph_tracking_iterate(sc, &selectdata, toggle_selection_cb);
                                }
 
-                               userdata.marker->flag|= MARKER_GRAPH_SEL;
+                               if(userdata.coord==0)
+                                       userdata.marker->flag|= MARKER_GRAPH_SEL_X;
+                               else
+                                       userdata.marker->flag|= MARKER_GRAPH_SEL_Y;
 
                                return 1;
                        }
@@ -335,7 +338,7 @@ static int delete_knot_exec(bContext *C, wmOperator *UNUSED(op))
                while(a<act_track->markersnr) {
                        MovieTrackingMarker *marker= &act_track->markers[a];
 
-                       if(marker->flag&MARKER_GRAPH_SEL)
+                       if(marker->flag & (MARKER_GRAPH_SEL_X|MARKER_GRAPH_SEL_Y))
                                clip_delete_marker(C, clip, tracksbase, act_track, marker);
                        else
                                a++;
index 3ca8fc35c7fc1d3710ae9876200c3e5dd15bab3f..46442d39a7bee3c42767aa479f46c425f5b8bbc3 100644 (file)
@@ -95,7 +95,7 @@ void clip_graph_tracking_values_iterate_track(SpaceClip *sc, MovieTrackingTrack
                        }
 
                        /* value is a pixels per frame speed */
-                       val= (marker->pos[coord] - prevval) * ((i==0) ? (width) : (height));
+                       val= (marker->pos[coord] - prevval) * ((coord==0) ? (width) : (height));
                        val/= marker->framenr-prevfra;
 
                        if(func)
index 3d58437813595c2e43e06641e058cd96647fc05d..04871156412c1e423ab84b8e7b16f60d45de0bc8 100644 (file)
@@ -545,6 +545,8 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
 
        WM_keymap_add_item(keymap, "CLIP_OT_graph_delete_knot", DELKEY, KM_PRESS, KM_SHIFT, 0);
        WM_keymap_add_item(keymap, "CLIP_OT_graph_delete_knot", XKEY, KM_PRESS, KM_SHIFT, 0);
+
+       transform_keymap_for_space(keyconf, keymap, SPACE_CLIP);
 }
 
 const char *clip_context_dir[]= {"edit_movieclip", NULL};
index 712941a6451d422f39b31f0951a8028a4ee75f6e..0563cc3adf5cd9e55f4d1e1fd24600f5bc550ff5 100644 (file)
@@ -5330,7 +5330,15 @@ static void createTransNodeData(bContext *C, TransInfo *t)
 
 /* *** CLIP EDITOR *** */
 
+enum {
+       transDataTracking_ModeTracks = 0,
+       transDataTracking_ModeCurves = 1,
+} transDataTracking_Mode;
+
 typedef struct TransDataTracking {
+       int mode, flag;
+
+       /* tracks transformation from main window */
        int area;
        float *relative, *loc;
        float soffset[2], srelative[2];
@@ -5339,6 +5347,10 @@ typedef struct TransDataTracking {
        float (*smarkers)[2];
        int markersnr;
        MovieTrackingMarker *markers;
+
+       /* marker transformation from curves editor */
+       float *prev_pos, scale;
+       short coord;
 } TransDataTracking;
 
 static void markerToTransDataInit(TransData *td, TransData2D *td2d,
@@ -5346,6 +5358,8 @@ static void markerToTransDataInit(TransData *td, TransData2D *td2d,
 {
        int anchor = area==TRACK_AREA_POINT && off;
 
+       tdt->mode = transDataTracking_ModeTracks;
+
        if(anchor) {
                td2d->loc[0] = rel[0]; /* hold original location */
                td2d->loc[1] = rel[1];
@@ -5400,8 +5414,7 @@ static void trackToTransData(SpaceClip *sc, TransData *td, TransData2D *td2d,
 {
        MovieTrackingMarker *marker= BKE_tracking_ensure_marker(track, sc->user.framenr);
 
-       track->transflag= marker->flag;
-
+       tdt->flag= marker->flag;
        marker->flag&= ~(MARKER_DISABLED|MARKER_TRACKED);
 
        markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_POINT, track->offset, marker->pos, track->offset);
@@ -5430,7 +5443,7 @@ static void transDataTrackingFree(TransInfo *t)
        }
 }
 
-static void createTransTrackingData(bContext *C, TransInfo *t)
+static void createTransTrackingTracksData(bContext *C, TransInfo *t)
 {
        TransData *td;
        TransData2D *td2d;
@@ -5442,11 +5455,6 @@ static void createTransTrackingData(bContext *C, TransInfo *t)
        TransDataTracking *tdt;
        int framenr = sc->user.framenr;
 
-       if(!clip || !BKE_movieclip_has_frame(clip, &sc->user)) {
-               t->total = 0;
-               return;
-       }
-
        /* count */
        t->total = 0;
 
@@ -5455,13 +5463,11 @@ static void createTransTrackingData(bContext *C, TransInfo *t)
                if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_LOCKED)==0) {
                        marker= BKE_tracking_get_marker(track, framenr);
 
-                       if(marker) {
-                               t->total++;     /* offset */
+                       t->total++;     /* offset */
 
-                               if(track->flag&SELECT) t->total++;
-                               if(track->pat_flag&SELECT) t->total+= 2;
-                               if(track->search_flag&SELECT) t->total+= 2;
-                       }
+                       if(track->flag&SELECT) t->total++;
+                       if(track->pat_flag&SELECT) t->total+= 2;
+                       if(track->search_flag&SELECT) t->total+= 2;
                }
 
                track = track->next;
@@ -5511,6 +5517,194 @@ static void createTransTrackingData(bContext *C, TransInfo *t)
        }
 }
 
+static void markerToTransCurveDataInit(TransData *td, TransData2D *td2d, TransDataTracking *tdt,
+                                                                          MovieTrackingMarker *marker, MovieTrackingMarker *prev_marker,
+                                       short coord, float size)
+{
+       float frames_delta = (marker->framenr - prev_marker->framenr);
+
+       tdt->flag = marker->flag;
+       marker->flag &= ~MARKER_TRACKED;
+
+       tdt->mode = transDataTracking_ModeCurves;
+       tdt->coord = coord;
+       tdt->scale = 1.0f / size * frames_delta;
+       tdt->prev_pos = prev_marker->pos;
+
+       /* calculate values depending on marker's speed */
+       td2d->loc[0] = marker->framenr;
+       td2d->loc[1] = (marker->pos[coord] - prev_marker->pos[coord]) * size / frames_delta;
+       td2d->loc[2] = 0.0f;
+
+       td2d->loc2d = marker->pos; /* current location */
+
+       td->flag = 0;
+       td->loc = td2d->loc;
+       VECCOPY(td->center, td->loc);
+       VECCOPY(td->iloc, td->loc);
+
+       memset(td->axismtx, 0, sizeof(td->axismtx));
+       td->axismtx[2][2] = 1.0f;
+
+       td->ext= NULL; td->val= NULL;
+
+       td->flag |= TD_SELECTED;
+       td->dist= 0.0;
+
+       unit_m3(td->mtx);
+       unit_m3(td->smtx);
+}
+
+static void createTransTrackingCurvesData(bContext *C, TransInfo *t)
+{
+       TransData *td;
+       TransData2D *td2d;
+       SpaceClip *sc = CTX_wm_space_clip(C);
+       MovieClip *clip = ED_space_clip(sc);
+       ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
+       MovieTrackingTrack *track;
+       MovieTrackingMarker *marker, *prev_marker;
+       TransDataTracking *tdt;
+       int i, width, height;
+
+       BKE_movieclip_get_size(clip, &sc->user, &width, &height);
+
+       /* count */
+       t->total = 0;
+
+       track = tracksbase->first;
+       while(track) {
+               if(TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) {
+                       for(i = 1; i < track->markersnr; i++) {
+                               marker = &track->markers[i];
+                               prev_marker = &track->markers[i-1];
+
+                               if((marker->flag & MARKER_DISABLED) || (prev_marker->flag & MARKER_DISABLED))
+                                       continue;
+
+                               if(marker->flag & MARKER_GRAPH_SEL_X)
+                                       t->total += 1;
+
+                               if(marker->flag & MARKER_GRAPH_SEL_Y)
+                                       t->total += 1;
+                       }
+               }
+
+               track = track->next;
+       }
+
+       if(t->total==0)
+               return;
+
+       td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransTracking TransData");
+       td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransTracking TransData2D");
+       tdt = t->customData = MEM_callocN(t->total*sizeof(TransDataTracking), "TransTracking TransDataTracking");
+
+       t->customFree = transDataTrackingFree;
+
+       /* create actual data */
+       track = tracksbase->first;
+       while(track) {
+               if(TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) {
+                       for(i = 1; i < track->markersnr; i++) {
+                               marker = &track->markers[i];
+                               prev_marker = &track->markers[i-1];
+
+                               if((marker->flag & MARKER_DISABLED) || (prev_marker->flag & MARKER_DISABLED))
+                                       continue;
+
+                               if(marker->flag & MARKER_GRAPH_SEL_X) {
+                                       markerToTransCurveDataInit(td, td2d, tdt, marker, &track->markers[i-1], 0, width);
+                                       td += 1;
+                                       td2d += 1;
+                                       tdt += 1;
+                               }
+
+                               if(marker->flag & MARKER_GRAPH_SEL_Y) {
+                                       markerToTransCurveDataInit(td, td2d, tdt, marker, &track->markers[i-1], 1, height);
+
+                                       td += 1;
+                                       td2d += 1;
+                                       tdt += 1;
+                               }
+                       }
+               }
+
+               track = track->next;
+       }
+}
+
+static void createTransTrackingData(bContext *C, TransInfo *t)
+{
+       ARegion *ar = CTX_wm_region(C);
+       SpaceClip *sc = CTX_wm_space_clip(C);
+       MovieClip *clip = ED_space_clip(sc);
+
+       if(!clip || !BKE_movieclip_has_frame(clip, &sc->user)) {
+               t->total = 0;
+               return;
+       }
+
+       if(ar->regiontype == RGN_TYPE_PREVIEW) {
+               /* transformation was called from graph editor */
+               createTransTrackingCurvesData(C, t);
+       }
+       else {
+               createTransTrackingTracksData(C, t);
+       }
+}
+
+static void cancelTransTracking(TransInfo *t)
+{
+       TransDataTracking *tdt = t->customData;
+       SpaceClip *sc= t->sa->spacedata.first;
+       MovieClip *clip= ED_space_clip(sc);
+       ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
+       MovieTrackingTrack *track;
+       MovieTrackingMarker *marker;
+       int a, framenr = sc->user.framenr;
+
+       if(tdt->mode == transDataTracking_ModeTracks) {
+               track = tracksbase->first;
+               while(track) {
+                       if(TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) {
+                               marker = BKE_tracking_get_marker(track, framenr);
+                               marker->flag = tdt->flag;
+
+                               tdt++;
+
+                               if(track->flag&SELECT) tdt++;
+                               if(track->pat_flag&SELECT) tdt += 2;
+                               if(track->search_flag&SELECT) tdt += 2;
+                       }
+
+                       track = track->next;
+               }
+       }
+       else if(tdt->mode == transDataTracking_ModeCurves) {
+               MovieTrackingMarker *prev_marker;
+
+               track = tracksbase->first;
+               while(track) {
+                       if(TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) {
+                               for(a = 1; a < track->markersnr; a++) {
+                                       marker = &track->markers[a];
+                                       prev_marker = &track->markers[a-1];
+
+                                       if((marker->flag & MARKER_DISABLED) || (prev_marker->flag & MARKER_DISABLED))
+                                               continue;
+
+                                       if(marker->flag & (MARKER_GRAPH_SEL_X|MARKER_GRAPH_SEL_Y)) {
+                                               marker->flag = tdt->flag;
+                                       }
+                               }
+                       }
+
+                       track = track->next;
+               }
+       }
+}
+
 void flushTransTracking(TransInfo *t)
 {
        TransData *td;
@@ -5518,36 +5712,44 @@ void flushTransTracking(TransInfo *t)
        TransDataTracking *tdt;
        int a;
 
+       if(t->state == TRANS_CANCEL)
+               cancelTransTracking(t);
+
        /* flush to 2d vector from internally used 3d vector */
        for(a=0, td= t->data, td2d= t->data2d, tdt= t->customData; a<t->total; a++, td2d++, td++, tdt++) {
-               if(t->flag&T_ALT_TRANSFORM) {
-                       if(tdt->area==TRACK_AREA_POINT && tdt->relative) {
-                               float d[2], d2[2];
-
-                               if(!tdt->smarkers) {
-                                       tdt->smarkers= MEM_callocN(sizeof(*tdt->smarkers)*tdt->markersnr, "flushTransTracking markers");
-                                       for(a= 0; a<tdt->markersnr; a++)
-                                               copy_v2_v2(tdt->smarkers[a], tdt->markers[a].pos);
-                               }
+               if(tdt->mode == transDataTracking_ModeTracks) {
+                       if(t->flag&T_ALT_TRANSFORM) {
+                               if(tdt->area==TRACK_AREA_POINT && tdt->relative) {
+                                       float d[2], d2[2];
+
+                                       if(!tdt->smarkers) {
+                                               tdt->smarkers= MEM_callocN(sizeof(*tdt->smarkers)*tdt->markersnr, "flushTransTracking markers");
+                                               for(a= 0; a<tdt->markersnr; a++)
+                                                       copy_v2_v2(tdt->smarkers[a], tdt->markers[a].pos);
+                                       }
 
-                               sub_v2_v2v2(d, td2d->loc, tdt->soffset);
-                               sub_v2_v2(d, tdt->srelative);
+                                       sub_v2_v2v2(d, td2d->loc, tdt->soffset);
+                                       sub_v2_v2(d, tdt->srelative);
 
-                               sub_v2_v2v2(d2, td2d->loc, tdt->srelative);
+                                       sub_v2_v2v2(d2, td2d->loc, tdt->srelative);
 
-                               for(a= 0; a<tdt->markersnr; a++)
-                                       add_v2_v2v2(tdt->markers[a].pos, tdt->smarkers[a], d2);
+                                       for(a= 0; a<tdt->markersnr; a++)
+                                               add_v2_v2v2(tdt->markers[a].pos, tdt->smarkers[a], d2);
 
-                               negate_v2_v2(td2d->loc2d, d);
+                                       negate_v2_v2(td2d->loc2d, d);
+                               }
                        }
-               }
 
-               if(tdt->area!=TRACK_AREA_POINT || tdt->relative==0) {
-                       td2d->loc2d[0] = td2d->loc[0];
-                       td2d->loc2d[1] = td2d->loc[1];
+                       if(tdt->area!=TRACK_AREA_POINT || tdt->relative==0) {
+                               td2d->loc2d[0] = td2d->loc[0];
+                               td2d->loc2d[1] = td2d->loc[1];
 
-                       if(tdt->relative)
-                               sub_v2_v2(td2d->loc2d, tdt->relative);
+                               if(tdt->relative)
+                                       sub_v2_v2(td2d->loc2d, tdt->relative);
+                       }
+               }
+               else if(tdt->mode == transDataTracking_ModeCurves) {
+                       td2d->loc2d[tdt->coord] = tdt->prev_pos[tdt->coord] + td2d->loc[1] * tdt->scale;
                }
        }
 }
index fff683b1ef6028d2426b8e2fa44931828468188a..3c019c1680f6c0c1aa28273f600d4d410c2b5b9b 100644 (file)
@@ -644,24 +644,11 @@ static void recalcData_clip(TransInfo *t)
        ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
        MovieTrackingTrack *track;
        
-       if(t->state == TRANS_CANCEL) {
-               track= tracksbase->first;
-               while(track) {
-                       if(TRACK_VIEW_SELECTED(sc, track)) {
-                               MovieTrackingMarker *marker= BKE_tracking_ensure_marker(track, sc->user.framenr);
-                               
-                               marker->flag= track->transflag;
-                       }
-                       
-                       track= track->next;
-               }
-       }
-       
        flushTransTracking(t);
        
        track= tracksbase->first;
        while(track) {
-               if(TRACK_VIEW_SELECTED(sc, track)) {
+               if(TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) {
                        if (t->mode == TFM_TRANSLATION) {
                                if(TRACK_AREA_SELECTED(track, TRACK_AREA_PAT))
                                        BKE_tracking_clamp_track(track, CLAMP_PAT_POS);
index a8b3a7183cfb0cd6dd2c43ca1d3ded3ff888bc4e..6ab8b5524ffaefb0226a4812df8fad53abe556a9 100644 (file)
@@ -91,12 +91,8 @@ typedef struct MovieTrackingTrack {
        float bundle_pos[3];                    /* reconstructed position */
        float error;                                    /* average track reprojection error */
 
-       int pad;
-
        /* ** UI editing ** */
        int flag, pat_flag, search_flag;        /* flags (selection, ...) */
-       short transflag;                                        /* transform flags */
-       char pad3[2];
        float color[3];                                         /* custom color for track */
 
        /* tracking algorithm to use; can be KLT or SAD */
@@ -213,7 +209,8 @@ enum {
 /* MovieTrackingMarker->flag */
 #define MARKER_DISABLED        (1<<0)
 #define MARKER_TRACKED (1<<1)
-#define MARKER_GRAPH_SEL (1<<2)
+#define MARKER_GRAPH_SEL_X (1<<2)
+#define MARKER_GRAPH_SEL_Y (1<<3)
 
 /* MovieTrackingTrack->flag */
 #define TRACK_HAS_BUNDLE       (1<<1)