Camera tracking integration
authorSergey Sharybin <sergey.vfx@gmail.com>
Wed, 7 Sep 2011 08:09:50 +0000 (08:09 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Wed, 7 Sep 2011 08:09:50 +0000 (08:09 +0000)
===========================

- Added python method MovieClip.tracking.tracs.add() to add new track.
  Marker for this track is getting created on position (0, 0) and it's
  keyframed to specified frame number.

- Implemented rotation 2D stabilization. It's supposed to be used in the
  following workflow:

  * Set tracks which defines location stabilization.
  * Choose one track which defines orientation.
  * Vector which connects median point of location and track used for
    rotation would have the same orientation along all frames.

  2D stabilization with rotation can be a bit slow.

- Some internal refactor and code clean-up.

21 files changed:
release/scripts/startup/bl_ui/space_clip.py
source/blender/blenkernel/BKE_movieclip.h
source/blender/blenkernel/BKE_tracking.h
source/blender/blenkernel/intern/movieclip.c
source/blender/blenkernel/intern/tracking.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/include/ED_clip.h
source/blender/editors/space_clip/clip_draw.c
source/blender/editors/space_clip/clip_editor.c
source/blender/editors/space_clip/clip_intern.h
source/blender/editors/space_clip/space_clip.c
source/blender/editors/space_clip/tracking_ops.c
source/blender/editors/transform/transform_conversions.c
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/DNA_tracking_types.h
source/blender/makesrna/intern/rna_movieclip.c
source/blender/makesrna/intern/rna_tracking.c
source/blender/nodes/composite/node_composite_util.h
source/blender/nodes/composite/nodes/node_composite_movieclip.c
source/blender/nodes/composite/nodes/node_composite_stabilize2d.c
source/blender/nodes/composite/nodes/node_composite_transform.c

index 4a0136cf35af065d5fff50cb36332b985e6a47c2..00fdf70dc90477131d2d522fab0d82e23b5deb48 100644 (file)
@@ -570,10 +570,25 @@ class CLIP_PT_stabilization(Panel):
 
         layout.prop(stab, "influence_location")
 
+        layout.separator()
+
         layout.prop(stab, "use_autoscale")
+        col = layout.column()
+        col.active = stab.use_autoscale
+        col.prop(stab, "max_scale")
+        col.prop(stab, "influence_scale")
+
+        layout.separator()
+
+        layout.label(text="Rotation:")
+
+        row = layout.row(align=True)
+        row.prop_search(stab, "rotation_track", tracking, "tracks", text="")
+        row.operator("clip.stabilize_2d_set_rotation", text="", icon='ZOOMIN')
+
         row = layout.row()
-        row.active = stab.use_autoscale
-        row.prop(stab, "influence_scale")
+        row.active = stab.rotation_track is not None
+        row.prop(stab, "influence_rotation")
 
 
 class CLIP_PT_marker(Panel):
index 82007a20bd34d0fc94dd43718d196c4e6c5c6461..32bf4f9ce8cb7fa0ee8bb066689b77867ab98de4 100644 (file)
@@ -48,7 +48,7 @@ struct MovieClip *BKE_add_movieclip_file(const char *name);
 void BKE_movieclip_reload(struct MovieClip *clip);
 
 struct ImBuf *BKE_movieclip_acquire_ibuf(struct MovieClip *clip, struct MovieClipUser *user);
-struct ImBuf *BKE_movieclip_acquire_stable_ibuf(struct MovieClip *clip, struct MovieClipUser *user, float loc[2], float *scale);
+struct ImBuf *BKE_movieclip_acquire_stable_ibuf(struct MovieClip *clip, struct MovieClipUser *user, float loc[2], float *scale, float *angle);
 struct ImBuf *BKE_movieclip_acquire_ibuf_flag(struct MovieClip *clip, struct MovieClipUser *user, int flag);
 void BKE_movieclip_acquire_size(struct MovieClip *clip, struct MovieClipUser *user, int *width, int *height);
 void BKE_movieclip_aspect(struct MovieClip *clip, float *aspx, float *aspy);
index efb55c1c80354a1d87baf4b84889a5e30179e870..ab123d22a00527806e71644fa4dbc55c59fbc627 100644 (file)
@@ -88,11 +88,12 @@ void BKE_tracking_detect(struct MovieTracking *tracking, struct ImBuf *imbuf, in
 
 struct MovieTrackingTrack *BKE_tracking_indexed_bundle(struct MovieTracking *tracking, int bundlenr);
 
-void BKE_tracking_stabilization_data(struct MovieTracking *tracking, int framenr, int width, int height, float loc[2], float *scale);
-struct ImBuf *BKE_tracking_stabilize_shot(struct MovieTracking *tracking, int framenr, struct ImBuf *ibuf, float loc[2], float *scale);
-void BKE_tracking_stabdata_to_mat4(float loc[2], float scale, float mat[4][4]);
+void BKE_tracking_stabilization_data(struct MovieTracking *tracking, int framenr, int width, int height, float loc[2], float *scale, float *angle);
+struct ImBuf *BKE_tracking_stabilize(struct MovieTracking *tracking, int framenr, struct ImBuf *ibuf, float loc[2], float *scale, float *angle);
+void BKE_tracking_stabdata_to_mat4(int width, int height, float loc[2], float scale, float angle, float mat[4][4]);
 
 struct ImBuf *BKE_tracking_undistort(struct MovieTracking *tracking, struct ImBuf *ibuf);
+struct ImBuf *BKE_tracking_distort(struct MovieTracking *tracking, struct ImBuf *ibuf);
 
 #define TRACK_SELECTED(track)                          ((((track)->flag&TRACK_HIDDEN)==0) && ((track)->flag&SELECT || (track)->pat_flag&SELECT || (track)->search_flag&SELECT))
 #define TRACK_AREA_SELECTED(track, area)       ((((track)->flag&TRACK_HIDDEN)==0) && ((area)==TRACK_AREA_POINT?(track)->flag&SELECT : ((area)==TRACK_AREA_PAT?(track)->pat_flag&SELECT:(track)->search_flag&SELECT)))
index 220a050fcc03a2f8eb9e98586173d60ee651bce6..c006b51dbafb6a548de043f358af44b8e0713e40 100644 (file)
@@ -255,7 +255,7 @@ typedef struct MovieClipCache {
 
        /* cache for stable shot */
        int stable_framenr;
-       float stable_loc[2], stable_scale;
+       float stable_loc[2], stable_scale, stable_angle;
        ImBuf *stableibuf;
 } MovieClipCache;
 
@@ -352,6 +352,8 @@ static MovieClip *movieclip_alloc(const char *name)
 
        clip->tracking.stabilization.scaleinf= 1.f;
        clip->tracking.stabilization.locinf= 1.f;
+       clip->tracking.stabilization.rotinf= 1.f;
+       clip->tracking.stabilization.maxscale= 2.f;
 
        clip->proxy.build_size_flags= IMB_PROXY_25;
        clip->proxy.build_tc_flags= IMB_TC_RECORD_RUN|IMB_TC_FREE_RUN|IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN;
@@ -511,7 +513,7 @@ ImBuf *BKE_movieclip_acquire_ibuf_flag(MovieClip *clip, MovieClipUser *user, int
        return ibuf;
 }
 
-ImBuf *BKE_movieclip_acquire_stable_ibuf(MovieClip *clip, MovieClipUser *user, float loc[2], float *scale)
+ImBuf *BKE_movieclip_acquire_stable_ibuf(MovieClip *clip, MovieClipUser *user, float loc[2], float *scale, float *angle)
 {
        ImBuf *ibuf, *stableibuf= NULL;
        int framenr= user?user->framenr:clip->lastframe;
@@ -519,14 +521,14 @@ ImBuf *BKE_movieclip_acquire_stable_ibuf(MovieClip *clip, MovieClipUser *user, f
        ibuf= BKE_movieclip_acquire_ibuf(clip, user);
 
        if(clip->tracking.stabilization.flag&TRACKING_2D_STABILIZATION) {
-               float tloc[2], tscale;
+               float tloc[2], tscale, tangle;
 
                if(clip->cache->stableibuf && clip->cache->stable_framenr==framenr) {
                        stableibuf= clip->cache->stableibuf;
 
-                       BKE_tracking_stabilization_data(&clip->tracking, framenr, stableibuf->x, stableibuf->y, tloc, &tscale);
+                       BKE_tracking_stabilization_data(&clip->tracking, framenr, stableibuf->x, stableibuf->y, tloc, &tscale, &tangle);
 
-                       if(!equals_v2v2(tloc, clip->cache->stable_loc) || tscale!=clip->cache->stable_scale) {
+                       if(!equals_v2v2(tloc, clip->cache->stable_loc) || tscale!=clip->cache->stable_scale || tangle!=clip->cache->stable_angle) {
                                stableibuf= NULL;
                        }
                }
@@ -535,10 +537,11 @@ ImBuf *BKE_movieclip_acquire_stable_ibuf(MovieClip *clip, MovieClipUser *user, f
                        if(clip->cache->stableibuf)
                                IMB_freeImBuf(clip->cache->stableibuf);
 
-                       stableibuf= BKE_tracking_stabilize_shot(&clip->tracking, framenr, ibuf, tloc, &tscale);
+                       stableibuf= BKE_tracking_stabilize(&clip->tracking, framenr, ibuf, tloc, &tscale, &tangle);
 
                        copy_v2_v2(clip->cache->stable_loc, tloc);
                        clip->cache->stable_scale= tscale;
+                       clip->cache->stable_angle= tangle;
                        clip->cache->stable_framenr= framenr;
                        clip->cache->stableibuf= stableibuf;
                }
@@ -547,9 +550,11 @@ ImBuf *BKE_movieclip_acquire_stable_ibuf(MovieClip *clip, MovieClipUser *user, f
 
                if(loc)         copy_v2_v2(loc, tloc);
                if(scale)       *scale= tscale;
+               if(angle)       *angle= tangle;
        } else {
                if(loc)         zero_v2(loc);
                if(scale)       *scale= 1.f;
+               if(angle)       *angle= 0.f;
 
                stableibuf= ibuf;
        }
index a60c2a1e351c97ed021319a22c181b31164fd7f6..87077ee993ad6aee33b436848e4205ff02b08473 100644 (file)
@@ -842,6 +842,7 @@ static void acquire_warped(TrackContext *track_context, int x, int y, int width,
 void BKE_tracking_sync(MovieTrackingContext *context)
 {
        TrackContext *track_context;
+       MovieTracking *tracking= &context->clip->tracking;
        MovieTrackingTrack *track;
        ListBase tracks= {NULL, NULL}, new_tracks= {NULL, NULL};
        ListBase *old_tracks= &context->clip->tracking.tracks;
@@ -870,7 +871,7 @@ void BKE_tracking_sync(MovieTrackingContext *context)
 
                        /* original track was found, re-use flags and remove this track */
                        if(cur) {
-                               if(cur==context->clip->tracking.act_track)
+                               if(cur==tracking->act_track)
                                        replace_sel= 1;
 
                                track->flag= cur->flag;
@@ -888,7 +889,7 @@ void BKE_tracking_sync(MovieTrackingContext *context)
                BLI_ghash_insert(context->hash, track, new_track);
 
                if(replace_sel)         /* update current selection in clip */
-                       context->clip->tracking.act_track= new_track;
+                       tracking->act_track= new_track;
 
                BLI_addtail(&tracks, new_track);
        }
@@ -1572,7 +1573,48 @@ static int stabilization_median_point(MovieTracking *tracking, int framenr, floa
        return ok;
 }
 
-static float stabilization_auto_scale_factor(MovieTracking *tracking)
+static void calculate_stabdata(MovieTracking *tracking, int framenr, float width, float height,
+                       float firstmedian[2], float median[2], float loc[2], float *scale, float *angle)
+{
+       MovieTrackingStabilization *stab= &tracking->stabilization;
+
+       *scale= (stab->scale-1.f)*stab->scaleinf+1.f;
+       *angle= 0.f;
+
+       loc[0]= (firstmedian[0]-median[0])*width*(*scale);
+       loc[1]= (firstmedian[1]-median[1])*height*(*scale);
+
+       loc[0]-= (firstmedian[0]*(*scale)-firstmedian[0])*width;
+       loc[1]-= (firstmedian[1]*(*scale)-firstmedian[1])*height;
+
+       mul_v2_fl(loc, stab->locinf);
+
+       if(stab->rot_track && stab->rotinf) {
+               MovieTrackingMarker *marker;
+               float a[2], b[2];
+               float x0= (float)width/2.f, y0= (float)height/2.f;
+               float x= median[0]*width, y= median[1]*height;
+
+               marker= BKE_tracking_get_marker(stab->rot_track, 1);
+               sub_v2_v2v2(a, marker->pos, firstmedian);
+               a[0]*= width;
+               a[1]*= height;
+
+               marker= BKE_tracking_get_marker(stab->rot_track, framenr);
+               sub_v2_v2v2(b, marker->pos, median);
+               b[0]*= width;
+               b[1]*= height;
+
+               *angle= -atan2(a[0]*b[1]-a[1]*b[0], a[0]*b[0]+a[1]*b[1]);
+               *angle*= stab->rotinf;
+
+               /* convert to rotation around image center */
+               loc[0]-= (x0 + (x-x0)*cos(*angle)-(y-y0)*sin(*angle) - x);
+               loc[1]-= (y0 + (x-x0)*sin(*angle)+(y-y0)*cos(*angle) - y);
+       }
+}
+
+static float stabilization_auto_scale_factor(MovieTracking *tracking, int width, int height)
 {
        float firstmedian[2];
        MovieTrackingStabilization *stab= &tracking->stabilization;
@@ -1582,12 +1624,14 @@ static float stabilization_auto_scale_factor(MovieTracking *tracking)
 
        if(stabilization_median_point(tracking, 1, firstmedian)) {
                int sfra= INT_MAX, efra= INT_MIN, cfra;
-               float delta[2]= {0.f, 0.f}, scalex, scaley, near[2]={1.f, 1.f};
+               float delta[2]= {0.f, 0.f}, scalex= 1.f, scaley= 1.f;
                MovieTrackingTrack *track;
 
+               stab->scale= 1.f;
+
                track= tracking->tracks.first;
                while(track) {
-                       if(track->flag&TRACK_USE_2D_STAB) {
+                       if(track->flag&TRACK_USE_2D_STAB || track==stab->rot_track) {
                                if(track->markersnr) {
                                        sfra= MIN2(sfra, track->markers[0].framenr);
                                        efra= MAX2(efra, track->markers[track->markersnr-1].framenr);
@@ -1598,28 +1642,69 @@ static float stabilization_auto_scale_factor(MovieTracking *tracking)
                }
 
                for(cfra=sfra; cfra<=efra; cfra++) {
-                       float median[2], d[2];
+                       float median[2], near[2];
+                       float loc[2], scale, angle;
 
                        stabilization_median_point(tracking, cfra, median);
 
-                       sub_v2_v2v2(d, firstmedian, median);
-                       d[0]= fabsf(d[0]);
-                       d[1]= fabsf(d[1]);
+                       calculate_stabdata(tracking, cfra, width, height, firstmedian, median,
+                                               loc, &scale, &angle);
 
-                       delta[0]= MAX2(delta[0], d[0]);
-                       delta[1]= MAX2(delta[1], d[1]);
+                       if(angle==0.f) {
+                               loc[0]= fabsf(loc[0]);
+                               loc[1]= fabsf(loc[1]);
 
-                       near[0]= MIN3(near[0], median[0], 1.f-median[0]);
-                       near[1]= MIN3(near[1], median[1], 1.f-median[1]);
-               }
+                               delta[0]= MAX2(delta[0], loc[0]);
+                               delta[1]= MAX2(delta[1], loc[1]);
+
+                               near[0]= MIN2(median[0], 1.f-median[0]);
+                               near[1]= MIN2(median[1], 1.f-median[1]);
+                               near[0]= MAX2(near[0], 0.05);
+                               near[1]= MAX2(near[1], 0.05);
+
+                               scalex= 1.f+delta[0]/(near[0]*width);
+                               scaley= 1.f+delta[1]/(near[1]*height);
+                       } else {
+                               int i;
+                               float mat[4][4];
+                               float points[4][2]={{0.f, 0.f}, {0.f, height}, {width, height}, {width, 0.f}};
+
+                               BKE_tracking_stabdata_to_mat4(width, height, loc, scale, angle, mat);
+
+                               for(i= 0; i<4; i++) {
+                                       int j;
+                                       float a[3]= {0.f}, b[3]= {0.f};
+
+                                       copy_v3_v3(a, points[i]);
+                                       copy_v3_v3(b, points[(i+1)%4]);
+
+                                       mul_m4_v3(mat, a);
+                                       mul_m4_v3(mat, b);
 
-               near[0]= MAX2(near[0], 0.05);
-               near[1]= MAX2(near[1], 0.05);
+                                       for(j= 0; j<4; j++) {
+                                               float point[3]= {points[j][0], points[j][1], 0.f};
+                                               float v1[3], v2[3];
 
-               scalex= 1.f+delta[0]/near[0];
-               scaley= 1.f+delta[1]/near[1];
+                                               sub_v3_v3v3(v1, b, a);
+                                               sub_v3_v3v3(v2, point, a);
+
+                                               if(cross_v2v2(v1, v2) >= 0.f) {
+                                                       float dist= dist_to_line_v2(point, a, b);
+                                                       if(i%2==0) {
+                                                               scalex= MAX2(scalex, (width+2*dist)/width);
+                                                       } else {
+                                                               scaley= MAX2(scaley, (height+2*dist)/height);
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
 
                stab->scale= MAX2(scalex, scaley);
+
+               if(stab->maxscale>0.f)
+                       stab->scale= MIN2(stab->scale, stab->maxscale);
        } else {
                stab->scale= 1.f;
        }
@@ -1629,22 +1714,7 @@ static float stabilization_auto_scale_factor(MovieTracking *tracking)
        return stab->scale;
 }
 
-static void calculate_stabdata(MovieTrackingStabilization *stab, float width, float height,
-                       float firstmedian[2], float curmedian[2], float loc[2], float *scale)
-{
-       *scale= (stab->scale-1.f)*stab->scaleinf+1.f;
-
-       loc[0]= (firstmedian[0]-curmedian[0])*width*(*scale);
-       loc[1]= (firstmedian[1]-curmedian[1])*height*(*scale);
-
-       loc[0]-= (firstmedian[0]*(*scale)-firstmedian[0])*width;
-       loc[1]-= (firstmedian[1]*(*scale)-firstmedian[1])*height;
-
-       mul_v2_fl(loc, stab->locinf);
-}
-
-
-static ImBuf* stabilize_acquire_ibuf(ImBuf *cacheibuf, ImBuf *srcibuf, int fill)
+static ImBuf* stabilize_alloc_ibuf(ImBuf *cacheibuf, ImBuf *srcibuf, int fill)
 {
        int flags;
 
@@ -1672,43 +1742,45 @@ static ImBuf* stabilize_acquire_ibuf(ImBuf *cacheibuf, ImBuf *srcibuf, int fill)
        return cacheibuf;
 }
 
-void BKE_tracking_stabilization_data(MovieTracking *tracking, int framenr, int width, int height, float loc[2], float *scale)
+void BKE_tracking_stabilization_data(MovieTracking *tracking, int framenr, int width, int height, float loc[2], float *scale, float *angle)
 {
-       float firstmedian[2], curmedian[2];
+       float firstmedian[2], median[2];
        MovieTrackingStabilization *stab= &tracking->stabilization;
 
        if((stab->flag&TRACKING_2D_STABILIZATION)==0) {
                zero_v2(loc);
                *scale= 1.f;
+               *angle= 0.f;
 
                return;
        }
 
        if(stabilization_median_point(tracking, 1, firstmedian)) {
-               stabilization_median_point(tracking, framenr, curmedian);
+               stabilization_median_point(tracking, framenr, median);
 
                if((stab->flag&TRACKING_AUTOSCALE)==0)
-                               stab->scale= 1.f;
+                       stab->scale= 1.f;
 
                if(!stab->ok) {
                        if(stab->flag&TRACKING_AUTOSCALE)
-                               stabilization_auto_scale_factor(tracking);
+                               stabilization_auto_scale_factor(tracking, width, height);
 
-                       calculate_stabdata(stab, width, height, firstmedian, curmedian, loc, scale);
+                       calculate_stabdata(tracking, framenr, width, height, firstmedian, median, loc, scale, angle);
 
                        stab->ok= 1;
                } else {
-                       calculate_stabdata(stab, width, height, firstmedian, curmedian, loc, scale);
+                       calculate_stabdata(tracking, framenr, width, height, firstmedian, median, loc, scale, angle);
                }
        } else {
                zero_v2(loc);
                *scale= 1.f;
+               *angle= 0.f;
        }
 }
 
-ImBuf *BKE_tracking_stabilize_shot(MovieTracking *tracking, int framenr, ImBuf *ibuf, float loc[2], float *scale)
+ImBuf *BKE_tracking_stabilize(MovieTracking *tracking, int framenr, ImBuf *ibuf, float loc[2], float *scale, float *angle)
 {
-       float tloc[2], tscale;
+       float tloc[2], tscale, tangle;
        MovieTrackingStabilization *stab= &tracking->stabilization;
        ImBuf *tmpibuf;
        float width= ibuf->x, height= ibuf->y;
@@ -1723,17 +1795,18 @@ ImBuf *BKE_tracking_stabilize_shot(MovieTracking *tracking, int framenr, ImBuf *
                return ibuf;
        }
 
-       BKE_tracking_stabilization_data(tracking, framenr, width, height, tloc, &tscale);
+       BKE_tracking_stabilization_data(tracking, framenr, width, height, tloc, &tscale, &tangle);
 
-       tmpibuf= stabilize_acquire_ibuf(NULL, ibuf, 1);
+       tmpibuf= stabilize_alloc_ibuf(NULL, ibuf, 1);
 
-       if(tscale!=1.f) {
+       /* scale would be handled by matrix transformation when angle is non-zero */
+       if(tscale!=1.f && tangle==0.f) {
                ImBuf *scaleibuf;
                float scale= (stab->scale-1.f)*stab->scaleinf+1.f;
 
-               stabilization_auto_scale_factor(tracking);
+               stabilization_auto_scale_factor(tracking, width, height);
 
-               scaleibuf= stabilize_acquire_ibuf(stab->scaleibuf, ibuf, 0);
+               scaleibuf= stabilize_alloc_ibuf(stab->scaleibuf, ibuf, 0);
                stab->scaleibuf= scaleibuf;
 
                IMB_rectcpy(scaleibuf, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y);
@@ -1742,7 +1815,28 @@ ImBuf *BKE_tracking_stabilize_shot(MovieTracking *tracking, int framenr, ImBuf *
                ibuf= scaleibuf;
        }
 
-       IMB_rectcpy(tmpibuf, ibuf, tloc[0], tloc[1], 0, 0, ibuf->x, ibuf->y);
+       if(tangle==0.f) {
+               /* if angle is zero, then it's much faster to use rect copy
+                  but could be issues with subpixel precisions */
+               IMB_rectcpy(tmpibuf, ibuf, tloc[0], tloc[1], 0, 0, ibuf->x, ibuf->y);
+       } else {
+               float mat[4][4];
+               int i, j;
+
+               BKE_tracking_stabdata_to_mat4(ibuf->x, ibuf->y, tloc, tscale, tangle, mat);
+               invert_m4(mat);
+
+               for(j=0; j<tmpibuf->y; j++) {
+                       for(i=0; i<tmpibuf->x;i++) {
+                               float vec[3]= {i, j, 0};
+
+                               mul_v3_m4v3(vec, mat, vec);
+
+                               /* TODO: add selector for interpolation method */
+                               neareast_interpolation(ibuf, tmpibuf, vec[0], vec[1], i, j);
+                       }
+               }
+       }
 
        tmpibuf->userflags|= IB_MIPMAP_INVALID;
 
@@ -1751,19 +1845,32 @@ ImBuf *BKE_tracking_stabilize_shot(MovieTracking *tracking, int framenr, ImBuf *
 
        if(loc)         copy_v2_v2(loc, tloc);
        if(scale)       *scale= tscale;
+       if(angle)       *angle= tangle;
 
        return tmpibuf;
 }
 
-void BKE_tracking_stabdata_to_mat4(float loc[2], float scale, float mat[4][4])
+void BKE_tracking_stabdata_to_mat4(int width, int height, float loc[2], float scale, float angle, float mat[4][4])
 {
-       unit_m4(mat);
+       float lmat[4][4], rmat[4][4], smat[4][4], cmat[4][4], icmat[4][4];
+       float svec[3]= {scale, scale, scale};
+
+       unit_m4(rmat);
+       unit_m4(lmat);
+       unit_m4(smat);
+       unit_m4(cmat);
+
+       /* image center as rotation center */
+       cmat[3][0]= (float)width/2.f;
+       cmat[3][1]= (float)height/2.f;
+       invert_m4_m4(icmat, cmat);
 
-       mat[0][0]*= scale;
-       mat[1][1]*= scale;
-       mat[2][2]*= scale;
+       size_to_mat4(smat, svec);               /* scale matrix */
+       add_v2_v2(lmat[3], loc);                /* tranlation matrix */
+       rotate_m4(rmat, 'Z', angle);    /* rotation matrix */
 
-       copy_v2_v2(mat[3], loc);
+       /* compose transformation matrix */
+       mul_serie_m4(mat, lmat, smat, cmat, rmat, icmat, NULL, NULL, NULL);
 }
 
 ImBuf *BKE_tracking_undistort(MovieTracking *tracking, ImBuf *ibuf)
index 7feb7e3fc2567382f16cea6f49a56f756b2e84e7..a1e956951326534245881597d3636991d81b6a40 100644 (file)
@@ -5808,6 +5808,7 @@ static void direct_link_movieclip(FileData *fd, MovieClip *clip)
 
        clip->tracking.stabilization.ok= 0;
        clip->tracking.stabilization.scaleibuf= NULL;
+       clip->tracking.stabilization.rot_track= newdataadr(fd, clip->tracking.stabilization.rot_track);
 }
 
 static void lib_link_movieclip(FileData *fd, Main *main)
index 0f0669128bd809aceb3384007048b621c6f6d73e..fc71a04f2d85c1cdf8d9e95a871be3e893858d81 100644 (file)
@@ -51,7 +51,7 @@ void ED_space_clip_zoom(struct SpaceClip *sc, ARegion *ar, float *zoomx, float *
 void ED_space_clip_aspect(struct SpaceClip *sc, float *aspx, float *aspy);
 
 struct ImBuf *ED_space_clip_acquire_buffer(struct SpaceClip *sc);
-struct ImBuf *ED_space_clip_acquire_stable_buffer(struct SpaceClip *sc, float loc[2], float *scale);
+struct ImBuf *ED_space_clip_acquire_stable_buffer(struct SpaceClip *sc, float loc[2], float *scale, float *angle);
 
 void ED_clip_update_frame(const struct Main *mainp, int cfra);
 void ED_clip_view_selection(struct SpaceClip *sc, struct ARegion *ar, int fit);
index ebfef878e9163ba7955692bebd0ad07c600d827a..b9e5ac79f6f6a1a90c28f52e9f7f09c44d2c4ad3 100644 (file)
@@ -195,6 +195,7 @@ static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf,
                        int width, int height, float zoomx, float zoomy)
 {
        int x, y;
+       MovieClip *clip= ED_space_clip(sc);
 
        /* set zoom */
        glPixelZoom(zoomx*width/ibuf->x, zoomy*height/ibuf->y);
@@ -210,40 +211,38 @@ static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf,
                        IMB_rect_from_float(ibuf);
                }
 
-               if(ibuf->rect) {
-                       MovieClip *clip= ED_space_clip(sc);
-
+               if(ibuf->rect)
                        glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
+       }
 
-                       /* draw boundary border for frame if stabilization is enabled */
-                       if(sc->flag&SC_SHOW_STABLE && clip->tracking.stabilization.flag&TRACKING_2D_STABILIZATION) {
-                               glColor3f(0.f, 0.f, 0.f);
-                               glLineStipple(3, 0xaaaa);
-                               glEnable(GL_LINE_STIPPLE);
-                               glEnable(GL_COLOR_LOGIC_OP);
-                               glLogicOp(GL_NOR);
+       /* draw boundary border for frame if stabilization is enabled */
+       if(sc->flag&SC_SHOW_STABLE && clip->tracking.stabilization.flag&TRACKING_2D_STABILIZATION) {
+               glColor3f(0.f, 0.f, 0.f);
+               glLineStipple(3, 0xaaaa);
+               glEnable(GL_LINE_STIPPLE);
+               glEnable(GL_COLOR_LOGIC_OP);
+               glLogicOp(GL_NOR);
 
-                               glPushMatrix();
-                               glTranslatef(x, y, 0);
+               glPushMatrix();
+               glTranslatef(x, y, 0);
 
-                               glScalef(zoomx, zoomy, 0);
-                               glMultMatrixf(sc->stabmat);
+               glScalef(zoomx, zoomy, 0);
+               glMultMatrixf(sc->stabmat);
 
-                               glBegin(GL_LINE_LOOP);
-                                       glVertex2f(0.f, 0.f);
-                                       glVertex2f(ibuf->x, 0.f);
-                                       glVertex2f(ibuf->x, ibuf->y);
-                                       glVertex2f(0.f, ibuf->y);
-                               glEnd();
+               glBegin(GL_LINE_LOOP);
+                       glVertex2f(0.f, 0.f);
+                       glVertex2f(ibuf->x, 0.f);
+                       glVertex2f(ibuf->x, ibuf->y);
+                       glVertex2f(0.f, ibuf->y);
+               glEnd();
 
-                               glPopMatrix();
+               glPopMatrix();
 
-                               glDisable(GL_COLOR_LOGIC_OP);
-                               glDisable(GL_LINE_STIPPLE);
-                       }
-               }
+               glDisable(GL_COLOR_LOGIC_OP);
+               glDisable(GL_LINE_STIPPLE);
        }
 
+
        /* reset zoom */
        glPixelZoom(1.f, 1.f);
 }
@@ -706,7 +705,7 @@ static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTra
                        int width, int height, float zoomx, float zoomy)
 {
        char str[128]= {0}, state[64]= {0};
-       float x, y, dx= 0.f, dy= 0.f, fontsize;
+       float dx= 0.f, dy= 0.f, fontsize, pos[3];
        uiStyle *style= U.uistyles.first;
        int fontid= style->widget.uifont_id;
 
@@ -732,8 +731,14 @@ static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTra
                dy= track->pat_min[1];
        }
 
-       x= (marker->pos[0]+dx)*width*sc->scale*zoomx+sc->loc[0]*zoomx;
-       y= (marker->pos[1]+dy)*height*sc->scale*zoomy-fontsize+sc->loc[1]*zoomy;
+       pos[0]= (marker->pos[0]+dx)*width;
+       pos[1]= (marker->pos[1]+dy)*height;
+       pos[2]= 0.f;
+
+       mul_m4_v3(sc->stabmat, pos);
+
+       pos[0]= pos[0]*zoomx;
+       pos[1]= pos[1]*zoomy - fontsize;
 
        if(marker->flag&MARKER_DISABLED) strcpy(state, "disabled");
        else if(marker->framenr!=sc->user.framenr) strcpy(state, "estimated");
@@ -745,19 +750,19 @@ static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTra
        else
                BLI_snprintf(str, sizeof(str), "%s", track->name);
 
-       BLF_position(fontid, x, y, 0.f);
+       BLF_position(fontid, pos[0], pos[1], 0.f);
        BLF_draw(fontid, str, strlen(str));
-       y-= fontsize;
+       pos[1]-= fontsize;
 
        if(track->flag&TRACK_HAS_BUNDLE) {
                BLI_snprintf(str, sizeof(str), "Average error: %.3f", track->error);
-               BLF_position(fontid, x, y, 0.f);
+               BLF_position(fontid, pos[0], pos[1], 0.f);
                BLF_draw(fontid, str, strlen(str));
-               y-= fontsize;
+               pos[1]-= fontsize;
        }
 
        if(track->flag&TRACK_LOCKED) {
-               BLF_position(fontid, x, y, 0.f);
+               BLF_position(fontid, pos[0], pos[1], 0.f);
                BLF_draw(fontid, "locked", 6);
        }
 }
@@ -1125,8 +1130,8 @@ void draw_clip_main(SpaceClip *sc, ARegion *ar, Scene *scene)
        ED_space_clip_zoom(sc, ar, &zoomx, &zoomy);
 
        if(sc->flag&SC_SHOW_STABLE) {
-               ibuf= ED_space_clip_acquire_stable_buffer(sc, sc->loc, &sc->scale);
-               BKE_tracking_stabdata_to_mat4(sc->loc, sc->scale, sc->stabmat);
+               ibuf= ED_space_clip_acquire_stable_buffer(sc, sc->loc, &sc->scale, &sc->angle);
+               BKE_tracking_stabdata_to_mat4(width, height, sc->loc, sc->scale, sc->angle, sc->stabmat);
        } else {
                ibuf= ED_space_clip_acquire_buffer(sc);
 
index 9207b0d4e5f2a4988f98cf969f73fac044a1a082..970cbfa4a41c0f2a271cdddf9dd21752b604490c 100644 (file)
@@ -98,12 +98,12 @@ ImBuf *ED_space_clip_acquire_buffer(SpaceClip *sc)
        return NULL;
 }
 
-ImBuf *ED_space_clip_acquire_stable_buffer(SpaceClip *sc, float loc[2], float *scale)
+ImBuf *ED_space_clip_acquire_stable_buffer(SpaceClip *sc, float loc[2], float *scale, float *angle)
 {
        if(sc->clip) {
                ImBuf *ibuf;
 
-               ibuf= BKE_movieclip_acquire_stable_ibuf(sc->clip, &sc->user, loc, scale);
+               ibuf= BKE_movieclip_acquire_stable_ibuf(sc->clip, &sc->user, loc, scale, angle);
 
                if(ibuf && (ibuf->rect || ibuf->rect_float))
                        return ibuf;
index d5a4ae43ec6933c9674003b49c7cc7be3ba13b15..a991566e9a2f95f5ae4ca8281af7e65f6a8ac7b2 100644 (file)
@@ -98,6 +98,7 @@ void CLIP_OT_detect_features(struct wmOperatorType *ot);
 void CLIP_OT_stabilize_2d_add(struct wmOperatorType *ot);
 void CLIP_OT_stabilize_2d_remove(struct wmOperatorType *ot);
 void CLIP_OT_stabilize_2d_select(struct wmOperatorType *ot);
+void CLIP_OT_stabilize_2d_set_rotation(struct wmOperatorType *ot);
 
 void CLIP_OT_clean_tracks(wmOperatorType *ot);
 
index 7bd09fd1e743a3ee6eedda8db6c39ee5b4bf1e25..c3da4027284ba6ef8f6555bd3f5bf17fd595358f 100644 (file)
@@ -302,6 +302,7 @@ static void clip_operatortypes(void)
        WM_operatortype_append(CLIP_OT_stabilize_2d_add);
        WM_operatortype_append(CLIP_OT_stabilize_2d_remove);
        WM_operatortype_append(CLIP_OT_stabilize_2d_select);
+       WM_operatortype_append(CLIP_OT_stabilize_2d_set_rotation);
 
        /* clean-up */
        WM_operatortype_append(CLIP_OT_clear_track_path);
@@ -555,7 +556,7 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar)
                ImBuf *tmpibuf= NULL;
 
                if(clip && clip->tracking.stabilization.flag&TRACKING_2D_STABILIZATION) {
-                       tmpibuf= ED_space_clip_acquire_stable_buffer(sc, NULL, NULL);
+                       tmpibuf= ED_space_clip_acquire_stable_buffer(sc, NULL, NULL, NULL);
                }
 
                ED_clip_view_selection(sc, ar, 0);
index c23dcfa0ef0f3ed2587ba4f90461e2cc8d110e5b..f5d91d4c4e74b147b0c2ea98dc598b4e3450c3fc 100644 (file)
@@ -186,21 +186,30 @@ static int delete_track_exec(bContext *C, wmOperator *UNUSED(op))
 {
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
-       MovieTrackingTrack *track= clip->tracking.tracks.first, *next;
-       int has_bundle= 0;
+       MovieTracking *tracking= &clip->tracking;
+       MovieTrackingTrack *track= tracking->tracks.first, *next;
+       MovieTrackingStabilization *stab= &tracking->stabilization;
+       int has_bundle= 0, update_stab= 0;
 
        while(track) {
                next= track->next;
 
                if(TRACK_VIEW_SELECTED(sc, track)) {
-                       if(track==clip->tracking.act_track)
-                               clip->tracking.act_track= NULL;
+                       if(track==tracking->act_track)
+                               tracking->act_track= NULL;
+
+                       if(track==stab->rot_track) {
+                               stab->rot_track= NULL;
+
+                               update_stab= 1;
+                       }
 
+                       /* handle reconstruction display in 3d viewport */
                        if(track->flag&TRACK_HAS_BUNDLE)
                                has_bundle= 1;
 
                        BKE_tracking_free_track(track);
-                       BLI_freelinkN(&clip->tracking.tracks, track);
+                       BLI_freelinkN(&tracking->tracks, track);
                }
 
                track= next;
@@ -208,6 +217,13 @@ static int delete_track_exec(bContext *C, wmOperator *UNUSED(op))
 
        WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip);
 
+       if(update_stab) {
+               tracking->stabilization.ok= 0;
+
+               DAG_id_tag_update(&clip->id, 0);
+               WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, clip);
+       }
+
        if(has_bundle)
                WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, NULL);
 
@@ -2493,21 +2509,26 @@ static int stabilize_2d_add_exec(bContext *C, wmOperator *UNUSED(op))
        MovieTracking *tracking= &clip->tracking;
        MovieTrackingTrack *track;
        MovieTrackingStabilization *stab= &tracking->stabilization;
+       int update= 0;
 
        track= tracking->tracks.first;
        while(track) {
-               if(TRACK_VIEW_SELECTED(sc, track)) {
+               if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_USE_2D_STAB)==0) {
                        track->flag|= TRACK_USE_2D_STAB;
                        stab->tot_track++;
+
+                       update= 1;
                }
 
                track= track->next;
        }
 
-       stab->ok= 0;
+       if(update) {
+               stab->ok= 0;
 
-       DAG_id_tag_update(&clip->id, 0);
-       WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, clip);
+               DAG_id_tag_update(&clip->id, 0);
+               WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, clip);
+       }
 
        return OPERATOR_FINISHED;
 }
@@ -2536,7 +2557,7 @@ static int stabilize_2d_remove_exec(bContext *C, wmOperator *UNUSED(op))
        MovieTracking *tracking= &clip->tracking;
        MovieTrackingStabilization *stab= &tracking->stabilization;
        MovieTrackingTrack *track;
-       int a= 0;
+       int a= 0, update= 0;
 
        track= tracking->tracks.first;
        while(track) {
@@ -2550,6 +2571,8 @@ static int stabilize_2d_remove_exec(bContext *C, wmOperator *UNUSED(op))
                                if(stab->act_track<0)
                                        stab->act_track= 0;
 
+                               update= 1;
+
                                break;
                        }
 
@@ -2559,10 +2582,12 @@ static int stabilize_2d_remove_exec(bContext *C, wmOperator *UNUSED(op))
                track= track->next;
        }
 
-       stab->ok= 0;
+       if(update) {
+               stab->ok= 0;
 
-       DAG_id_tag_update(&clip->id, 0);
-       WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, clip);
+               DAG_id_tag_update(&clip->id, 0);
+               WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, clip);
+       }
 
        return OPERATOR_FINISHED;
 }
@@ -2590,20 +2615,21 @@ static int stabilize_2d_select_exec(bContext *C, wmOperator *UNUSED(op))
        MovieClip *clip= ED_space_clip(sc);
        MovieTracking *tracking= &clip->tracking;
        MovieTrackingTrack *track;
-       int a= 0;
+       int update= 0;
 
        track= tracking->tracks.first;
        while(track) {
                if(track->flag&TRACK_USE_2D_STAB) {
                        BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, 0);
 
-                       a++;
+                       update= 1;
                }
 
                track= track->next;
        }
 
-       WM_event_add_notifier(C, NC_MOVIECLIP|ND_SELECT, clip);
+       if(update)
+               WM_event_add_notifier(C, NC_MOVIECLIP|ND_SELECT, clip);
 
        return OPERATOR_FINISHED;
 }
@@ -2623,6 +2649,42 @@ void CLIP_OT_stabilize_2d_select(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
+/********************** set 2d stabilization rotation track operator *********************/
+
+static int stabilize_2d_set_rotation_exec(bContext *C, wmOperator *UNUSED(op))
+{
+       SpaceClip *sc= CTX_wm_space_clip(C);
+       MovieClip *clip= ED_space_clip(sc);
+       MovieTracking *tracking= &clip->tracking;
+
+       if(tracking->act_track) {
+               MovieTrackingStabilization *stab= &tracking->stabilization;
+
+               stab->rot_track= tracking->act_track;
+               stab->ok= 0;
+
+               DAG_id_tag_update(&clip->id, 0);
+               WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, clip);
+       }
+
+       return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_stabilize_2d_set_rotation(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Set Rotation Track";
+       ot->description= "Use active track to compensate rotaiton when doing 2D stabilization";
+       ot->idname= "CLIP_OT_stabilize_2d_set_rotation";
+
+       /* api callbacks */
+       ot->exec= stabilize_2d_set_rotation_exec;
+       ot->poll= ED_space_clip_poll;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
 /********************** select un-clean operator *********************/
 
 static int is_track_clean(MovieTrackingTrack *track, int frames, int del)
index b99431fa3a686afb0a676550ec4a6393f51ce792..bde58a007b17b9a4bbf4f5a810254cef5437a05c 100644 (file)
@@ -79,6 +79,7 @@
 #include "BKE_report.h"
 #include "BKE_tracking.h"
 #include "BKE_movieclip.h"
+#include "BKE_node.h"
 
 
 #include "ED_anim_api.h"
@@ -97,6 +98,9 @@
 #include "ED_curve.h" /* for ED_curve_editnurbs */
 #include "ED_util.h"  /* for crazyspace correction */
 
+#include "WM_api.h"            /* for WM_event_add_notifier to deal with stabilization nodes */
+#include "WM_types.h"
+
 #include "UI_view2d.h"
 
 #include "BLI_math.h"
@@ -4785,7 +4789,15 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
                ED_node_link_intersect_test(t->sa, 0);
        }
        else if (t->spacetype == SPACE_CLIP) {
-               /* pass */
+               SpaceClip *sc= t->sa->spacedata.first;
+               MovieClip *clip= ED_space_clip(sc);
+
+               if(t->scene->nodetree) {
+                       /* tracks can be used for stabilization nodes,
+                          flush update for such nodes */
+                       NodeTagIDChanged(t->scene->nodetree, &clip->id);
+                       WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL);
+               }
        }
        else if (t->spacetype == SPACE_ACTION) {
                SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first;
index e05bd0e8bcd58d52a9e1a911e1d0b3a4427192eb..6ba2cedb22bc6eb8541db55f8a907a4eb17627d3 100644 (file)
@@ -583,8 +583,9 @@ typedef struct SpaceClip {
        int path_length;                        /* length of displaying path, in frames */
 
        /* current stabilization data */
-       float loc[2], scale;    /* pre-composed stabilization data */
-       float stabmat[4][4];    /* current stabilization matrix, defined when drawing
+       float loc[2], scale, angle;     /* pre-composed stabilization data */
+       int pad;
+       float stabmat[4][4];            /* current stabilization matrix, defined when drawing
                                                           and used for mouse position calculation */
 } SpaceClip;
 
index 658da0be51c7e600d4720b66cadd05c5a5649ff2..b4445c8e4d77e8d9c3a5596bcaac2690184afb3f 100644 (file)
@@ -128,7 +128,11 @@ typedef struct MovieTrackingStabilization {
        int flag;
        int tot_track, act_track;               /* total number and index of active track in list */
 
-       float locinf, scaleinf;         /* influence on location and scale */
+       /* 2d stabilization */
+       float maxscale;                 /* max auto-scale factor */
+       MovieTrackingTrack *rot_track;  /* track used to stabilize rotation */
+
+       float locinf, scaleinf, rotinf; /* influence on location, scale and rotation */
 
        /* some pre-computing run-time variables */
        int ok, pad;                            /* are precomputed values and scaled buf relevant? */
index def9b33bddd8b58813de4a1cc59aff201e5244b6..22ca8643f2b7e98106ee2171c2f5afe0ce5e022d 100644 (file)
@@ -157,7 +157,7 @@ static void rna_def_moviecliUuser(BlenderRNA *brna)
        prop= RNA_def_property(srna, "current_frame", PROP_INT, PROP_TIME);
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
        RNA_def_property_int_sdna(prop, NULL, "framenr");
-       RNA_def_property_range(prop, MINAFRAMEF, MAXFRAMEF);
+       RNA_def_property_range(prop, MINAFRAME, MAXFRAME);
        RNA_def_property_ui_text(prop, "Current Frame", "Get frame number user is points to in clip");
 }
 
index 149cd30be2ee90b478699d7726d6ad13755443b7..84664935b7675ec847026a41d36d21f2fa2542f3 100644 (file)
@@ -60,6 +60,12 @@ static void rna_tracking_tracks_begin(CollectionPropertyIterator *iter, PointerR
        rna_iterator_listbase_begin(iter, &clip->tracking.tracks, NULL);
 }
 
+static void rna_tracking_tracks_add(MovieTracking *tracking, int framenr, int number)
+{
+       BKE_tracking_add_track(tracking, 0, 0, framenr, 1, 1);
+       WM_main_add_notifier(NC_MOVIECLIP|NA_EDITED, NULL);
+}
+
 static PointerRNA rna_tracking_active_track_get(PointerRNA *ptr)
 {
        MovieClip *clip= (MovieClip*)ptr->id.data;
@@ -435,6 +441,7 @@ static void rna_def_trackingTrack(BlenderRNA *brna)
 
        srna= RNA_def_struct(brna, "MovieTrackingTrack", NULL);
        RNA_def_struct_ui_text(srna, "Movie tracking track data", "Match-moving track data for tracking");
+       RNA_def_struct_ui_icon(srna, ICON_ANIM_DATA);
 
        /* name */
        prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
@@ -568,6 +575,12 @@ static void rna_def_trackingStabilization(BlenderRNA *brna)
        srna= RNA_def_struct(brna, "MovieTrackingStabilization", NULL);
        RNA_def_struct_ui_text(srna, "Movie tracking stabilization data", "Match-moving stabilization data for tracking");
 
+       /* 2d stabilization */
+       prop= RNA_def_property(srna, "use_2d_stabilization", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_2D_STABILIZATION);
+       RNA_def_property_ui_text(prop, "Use 2D stabilization", "Use 2D stabilization for footage");
+       RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate");
+
        /* tracks */
        prop= RNA_def_property(srna, "tracks", PROP_COLLECTION, PROP_NONE);
        RNA_def_property_collection_funcs(prop, "rna_tracking_stabTracks_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0);
@@ -575,11 +588,12 @@ static void rna_def_trackingStabilization(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Tracks", "Collection of tracks used for stabilization");
        RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate");
 
-       /* 2d stabilization */
-       prop= RNA_def_property(srna, "use_2d_stabilization", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_2D_STABILIZATION);
-       RNA_def_property_ui_text(prop, "Use 2D stabilization", "Use 2D stabilization for footage");
-       RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate");
+       /* rotation track */
+       prop= RNA_def_property(srna, "rotation_track", PROP_POINTER, PROP_NONE);
+       RNA_def_property_pointer_sdna(prop, NULL, "rot_track");
+       RNA_def_property_flag(prop, PROP_EDITABLE);
+       RNA_def_property_ui_text(prop, "Rotation Track", "Track used to compensate rotation");
+       RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_flushUpdate");
 
        /* active track index */
        prop= RNA_def_property(srna, "active_track_index", PROP_INT, PROP_NONE);
@@ -593,6 +607,13 @@ static void rna_def_trackingStabilization(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Autoscale", "Automatically scale footage to cover unfilled areas when stabilizating");
        RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate");
 
+       /* max scale */
+       prop= RNA_def_property(srna, "max_scale", PROP_FLOAT, PROP_FACTOR);
+       RNA_def_property_float_sdna(prop, NULL, "maxscale");
+       RNA_def_property_range(prop, 0.f, 10.f);
+       RNA_def_property_ui_text(prop, "Miximal Scale", "Maximal value for scale factor");
+       RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate");
+
        /* influence_location */
        prop= RNA_def_property(srna, "influence_location", PROP_FLOAT, PROP_FACTOR);
        RNA_def_property_float_sdna(prop, NULL, "locinf");
@@ -606,6 +627,13 @@ static void rna_def_trackingStabilization(BlenderRNA *brna)
        RNA_def_property_range(prop, 0.f, 1.f);
        RNA_def_property_ui_text(prop, "Scale Influence", "Influence of stabilization algorithm on footage scale");
        RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate");
+
+       /* influence_rotation */
+       prop= RNA_def_property(srna, "influence_rotation", PROP_FLOAT, PROP_FACTOR);
+       RNA_def_property_float_sdna(prop, NULL, "rotinf");
+       RNA_def_property_range(prop, 0.f, 1.f);
+       RNA_def_property_ui_text(prop, "Rotation Influence", "Influence of stabilization algorithm on footage rotation");
+       RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate");
 }
 
 static void rna_def_reconstructedCamera(BlenderRNA *brna)
@@ -659,6 +687,22 @@ static void rna_def_trackingReconstruction(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Cameras", "Collection of solved cameras");
 }
 
+static void rna_def_trackingTracks(BlenderRNA *brna, PropertyRNA *cprop)
+{
+       StructRNA *srna;
+       FunctionRNA *func;
+
+       RNA_def_property_srna(cprop, "MovieTrackingTracks");
+       srna= RNA_def_struct(brna, "MovieTrackingTracks", NULL);
+       RNA_def_struct_sdna(srna, "MovieTracking");
+       RNA_def_struct_ui_text(srna, "Movie Tracks", "Collection of movie tracking tracks");
+
+       func= RNA_def_function(srna, "add", "rna_tracking_tracks_add");
+       RNA_def_function_ui_description(func, "Add a number of tracks to this movie clip.");
+       RNA_def_int(func, "framenr", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to add tracks on", MINFRAME, MAXFRAME);
+       RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of tracks to add to the movie clip", 0, INT_MAX);
+}
+
 static void rna_def_tracking(BlenderRNA *brna)
 {
        StructRNA *srna;
@@ -686,6 +730,7 @@ static void rna_def_tracking(BlenderRNA *brna)
        RNA_def_property_collection_funcs(prop, "rna_tracking_tracks_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0);
        RNA_def_property_struct_type(prop, "MovieTrackingTrack");
        RNA_def_property_ui_text(prop, "Tracks", "Collection of tracks in this tracking data object");
+       rna_def_trackingTracks(brna, prop);
 
        /* active track */
        prop= RNA_def_property(srna, "active_track", PROP_POINTER, PROP_NONE);
index ce441a3bbf9c4111af4a51da11a44faaa38ce4a1..60ea333807cd3fd2c1271b571fdffa246db69fdf 100644 (file)
@@ -214,6 +214,6 @@ void IIR_gauss(CompBuf* src, float sigma, int chan, int xy);
 
 #define CMP_SCALE_MAX  12000
 
-CompBuf* node_composit_transform(CompBuf *cbuf, float x, float y, float rotate, float scale, int filter_type);
+CompBuf* node_composit_transform(CompBuf *cbuf, float x, float y, float angle, float scale, int filter_type);
 
 #endif
index fc68b052be5850b550423cfb8885b533dd0bf926..d3fdb0795381e8b0cb0e5bbec93e09057c9a3c63 100644 (file)
@@ -40,6 +40,7 @@ static bNodeSocketTemplate cmp_node_movieclip_out[]= {
        {       SOCK_FLOAT,             1,      "Offset X"},
        {       SOCK_FLOAT,             1,      "Offset Y"},
        {       SOCK_FLOAT,             1,      "Scale"},
+       {       SOCK_FLOAT,             1,      "Degr"},
        {       -1, 0, ""       }
 };
 
@@ -136,15 +137,16 @@ static void node_composit_exec_movieclip(void *data, bNode *node, bNodeStack **U
                        out[0]->data= stackbuf;
 
                        if(stab->flag&TRACKING_2D_STABILIZATION) {
-                               float loc[2], scale;
+                               float loc[2], scale, angle;
 
                                BKE_tracking_stabilization_data(&clip->tracking, rd->cfra, stackbuf->x, stackbuf->y,
-                                                       loc, &scale);
+                                                       loc, &scale, &angle);
 
                                out[1]->vec[0]= loc[0];
                                out[2]->vec[0]= loc[1];
 
                                out[3]->vec[0]= scale;
+                               out[4]->vec[0]= RAD2DEG(angle);
                        }
 
                        /* generate preview */
index 09a524b38eb6898c879ec7047aa97c9c1f0346a9..eafdf3286adb36457a9efb7e186bf5159945fac0 100644 (file)
@@ -54,11 +54,11 @@ static void node_composit_exec_stabilize2d(void *data, bNode *node, bNodeStack *
                MovieClip *clip= (MovieClip *)node->id;
                CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
                CompBuf *stackbuf;
-               float loc[2], scale;
+               float loc[2], scale, angle;
 
-               BKE_tracking_stabilization_data(&clip->tracking, rd->cfra, cbuf->x, cbuf->y, loc, &scale);
+               BKE_tracking_stabilization_data(&clip->tracking, rd->cfra, cbuf->x, cbuf->y, loc, &scale, &angle);
 
-               stackbuf= node_composit_transform(cbuf, loc[0], loc[1], 0.f, scale, node->custom1);
+               stackbuf= node_composit_transform(cbuf, loc[0], loc[1], angle, scale, node->custom1);
 
                /* pass on output and free */
                out[0]->data= stackbuf;
index 4fe83a6c89b2de75b6cbf7f6a95bcbd9d2f9dd9c..9ee9cf84cc1dbe2733ca91342d9ec2501ed6b6d5 100644 (file)
@@ -40,7 +40,7 @@ static bNodeSocketTemplate cmp_node_stabilize2d_in[]= {
        {       SOCK_RGBA,              1,      "Image",                        0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
        {       SOCK_FLOAT,             1,      "X",                            0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
        {       SOCK_FLOAT,             1,      "Y",                            0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
-       {       SOCK_FLOAT,             1,      "Rotate",                       0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
+       {       SOCK_FLOAT,             1,      "Degr",                 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
        {       SOCK_FLOAT,             1,      "Scale",                        1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, CMP_SCALE_MAX},
        {       -1, 0, ""       }
 };
@@ -50,32 +50,29 @@ static bNodeSocketTemplate cmp_node_stabilize2d_out[]= {
        {       -1, 0, ""       }
 };
 
-CompBuf* node_composit_transform(CompBuf *cbuf, float x, float y, float rotate, float scale, int filter_type)
+CompBuf* node_composit_transform(CompBuf *cbuf, float x, float y, float angle, float scale, int filter_type)
 {
        CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1);
        ImBuf *ibuf, *obuf;
        float mat[4][4], lmat[4][4], rmat[4][4], smat[4][4], cmat[4][4], icmat[4][4];
-       float rad= (M_PI*rotate)/180.0f;
+       float svec[3]= {scale, scale, scale}, loc[2]= {x, y};
 
        unit_m4(rmat);
        unit_m4(lmat);
        unit_m4(smat);
        unit_m4(cmat);
 
+       /* image center as rotation center */
        cmat[3][0]= (float)cbuf->x/2.f;
        cmat[3][1]= (float)cbuf->y/2.f;
        invert_m4_m4(icmat, cmat);
 
-       smat[0][0]*= scale;
-       smat[1][1]*= scale;
-       smat[2][2]*= scale;
+       size_to_mat4(smat, svec);               /* scale matrix */
+       add_v2_v2(lmat[3], loc);                /* tranlation matrix */
+       rotate_m4(rmat, 'Z', angle);    /* rotation matrix */
 
-       rotate_m4(rmat, 'Z', rad);
-
-       lmat[3][0]+= x;
-       lmat[3][1]+= y;
-
-       mul_serie_m4(mat, cmat, rmat, icmat, lmat, smat, NULL, NULL, NULL);
+       /* compose transformation matrix */
+       mul_serie_m4(mat, lmat, smat, cmat, rmat, icmat, NULL, NULL, NULL);
 
        invert_m4(mat);
 
@@ -122,7 +119,7 @@ static void node_composit_exec_stabilize2d(void *UNUSED(data), bNode *node, bNod
                CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
                CompBuf *stackbuf;
 
-               stackbuf= node_composit_transform(cbuf, in[1]->vec[0], in[2]->vec[0], in[3]->vec[0], in[4]->vec[0], node->custom1);
+               stackbuf= node_composit_transform(cbuf, in[1]->vec[0], in[2]->vec[0], DEG2RAD(in[3]->vec[0]), in[4]->vec[0], node->custom1);
 
                /* pass on output and free */
                out[0]->data= stackbuf;