diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-06-11 00:50:43 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-06-11 00:50:43 +0400 |
commit | 8135cc9f954e0d63ab3e97d4a7c52ff5e573eef0 (patch) | |
tree | a12ec0daccfc45b7e3c68e4a2d7099655daf619d /source/blender/editors/space_clip | |
parent | 0f33d5719fd0adc666e7e92e0f062281f4285f13 (diff) | |
parent | 298feff39006c14aa28b5e0232aa7ed70a83a496 (diff) |
Merged changes in the trunk up to revision 47700.
Conflicts resolved:
source/blender/blenkernel/BKE_main.h
source/blender/blenkernel/CMakeLists.txt
source/blender/blenkernel/intern/library.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/interface/resources.c
source/blender/makesdna/DNA_ID.h
source/blender/makesdna/DNA_action_types.h
source/blender/makesdna/intern/makesdna.c
source/blender/makesrna/SConscript
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_main.c
source/blender/makesrna/intern/rna_main_api.c
source/blender/windowmanager/WM_types.h
Diffstat (limited to 'source/blender/editors/space_clip')
-rw-r--r-- | source/blender/editors/space_clip/clip_buttons.c | 93 | ||||
-rw-r--r-- | source/blender/editors/space_clip/clip_dopesheet_draw.c | 13 | ||||
-rw-r--r-- | source/blender/editors/space_clip/clip_dopesheet_ops.c | 6 | ||||
-rw-r--r-- | source/blender/editors/space_clip/clip_draw.c | 368 | ||||
-rw-r--r-- | source/blender/editors/space_clip/clip_editor.c | 145 | ||||
-rw-r--r-- | source/blender/editors/space_clip/clip_graph_draw.c | 8 | ||||
-rw-r--r-- | source/blender/editors/space_clip/clip_graph_ops.c | 17 | ||||
-rw-r--r-- | source/blender/editors/space_clip/clip_intern.h | 4 | ||||
-rw-r--r-- | source/blender/editors/space_clip/clip_utils.c | 11 | ||||
-rw-r--r-- | source/blender/editors/space_clip/space_clip.c | 113 | ||||
-rw-r--r-- | source/blender/editors/space_clip/tracking_ops.c | 428 |
11 files changed, 840 insertions, 366 deletions
diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c index 18f191a46a6..ca2ae6e8461 100644 --- a/source/blender/editors/space_clip/clip_buttons.c +++ b/source/blender/editors/space_clip/clip_buttons.c @@ -168,7 +168,7 @@ void uiTemplateTrack(uiLayout *layout, PointerRNA *ptr, const char *propname) scopes->track_preview_height = (scopes->track_preview_height <= UI_UNIT_Y)?UI_UNIT_Y : scopes->track_preview_height; uiDefBut(block, TRACKPREVIEW, 0, "", rect.xmin, rect.ymin, rect.xmax - rect.xmin, - scopes->track_preview_height, scopes, 0, 0, 0, 0, ""); + scopes->track_preview_height, scopes, 0, 0, 0, 0, ""); } /********************* Marker Template ************************/ @@ -186,12 +186,13 @@ typedef struct { MovieClip *clip; MovieClipUser *user; /* user of clip */ MovieTrackingTrack *track; + MovieTrackingMarker *marker; int framenr; /* current frame number */ float marker_pos[2]; /* position of marker in pixel coords */ - float track_pat[2]; /* position and dimensions of marker pattern in pixel coords */ + float marker_pat[2]; /* position and dimensions of marker pattern in pixel coords */ float track_offset[2]; /* offset of "parenting" point */ - float track_search_pos[2], track_search[2]; /* position and dimensions of marker search in pixel coords */ + float marker_search_pos[2], marker_search[2]; /* position and dimensions of marker search in pixel coords */ int marker_flag; /* marker's flags */ } MarkerUpdateCb; @@ -238,60 +239,63 @@ static void marker_block_handler(bContext *C, void *arg_cb, int event) ok = TRUE; } else if (event == B_MARKER_PAT_DIM) { - float dim[2], pat_dim[2]; + float dim[2], pat_dim[2], pat_min[2], pat_max[2]; + float scale_x, scale_y; + int a; - sub_v2_v2v2(pat_dim, cb->track->pat_max, cb->track->pat_min); + BKE_tracking_marker_pattern_minmax(cb->marker, pat_min, pat_max); - dim[0] = cb->track_pat[0] / width; - dim[1] = cb->track_pat[1] / height; + sub_v2_v2v2(pat_dim, pat_max, pat_min); - sub_v2_v2(dim, pat_dim); - mul_v2_fl(dim, 0.5f); + dim[0] = cb->marker_pat[0] / width; + dim[1] = cb->marker_pat[1] / height; - cb->track->pat_min[0] -= dim[0]; - cb->track->pat_min[1] -= dim[1]; + scale_x = dim[0] / pat_dim[0]; + scale_y = dim[1] / pat_dim[1]; - cb->track->pat_max[0] += dim[0]; - cb->track->pat_max[1] += dim[1]; + for (a = 0; a < 4; a++) { + cb->marker->pattern_corners[a][0] *= scale_x; + cb->marker->pattern_corners[a][1] *= scale_y; + } - BKE_tracking_clamp_track(cb->track, CLAMP_PAT_DIM); + BKE_tracking_clamp_marker(cb->marker, CLAMP_PAT_DIM); ok = TRUE; } else if (event == B_MARKER_SEARCH_POS) { float delta[2], side[2]; - sub_v2_v2v2(side, cb->track->search_max, cb->track->search_min); + sub_v2_v2v2(side, cb->marker->search_max, cb->marker->search_min); mul_v2_fl(side, 0.5f); - delta[0] = cb->track_search_pos[0] / width; - delta[1] = cb->track_search_pos[1] / height; + delta[0] = cb->marker_search_pos[0] / width; + delta[1] = cb->marker_search_pos[1] / height; - sub_v2_v2v2(cb->track->search_min, delta, side); - add_v2_v2v2(cb->track->search_max, delta, side); + sub_v2_v2v2(cb->marker->search_min, delta, side); + add_v2_v2v2(cb->marker->search_max, delta, side); - BKE_tracking_clamp_track(cb->track, CLAMP_SEARCH_POS); + BKE_tracking_clamp_marker(cb->marker, CLAMP_SEARCH_POS); ok = TRUE; } else if (event == B_MARKER_SEARCH_DIM) { float dim[2], search_dim[2]; - sub_v2_v2v2(search_dim, cb->track->search_max, cb->track->search_min); + sub_v2_v2v2(search_dim, cb->marker->search_max, cb->marker->search_min); - dim[0] = cb->track_search[0] / width; - dim[1] = cb->track_search[1] / height; + dim[0] = cb->marker_search[0] / width; + dim[1] = cb->marker_search[1] / height; sub_v2_v2(dim, search_dim); mul_v2_fl(dim, 0.5f); - cb->track->search_min[0] -= dim[0]; - cb->track->search_min[1] -= dim[1]; + cb->marker->search_min[0] -= dim[0]; + cb->marker->search_min[1] -= dim[1]; - cb->track->search_max[0] += dim[0]; - cb->track->search_max[1] += dim[1]; + cb->marker->search_max[0] += dim[0]; + cb->marker->search_max[1] += dim[1]; - BKE_tracking_clamp_track(cb->track, CLAMP_SEARCH_DIM); + BKE_tracking_clamp_marker(cb->marker, CLAMP_SEARCH_DIM); ok = TRUE; } @@ -337,6 +341,7 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P MovieTrackingMarker *marker; MarkerUpdateCb *cb; const char *tip; + float pat_min[2], pat_max[2]; if (!ptr->data) return; @@ -366,6 +371,7 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P cb->clip = clip; cb->user = user; cb->track = track; + cb->marker = marker; cb->marker_flag = marker->flag; cb->framenr = user->framenr; @@ -383,7 +389,7 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P } else { int width, height, step, digits; - float pat_dim[2], pat_pos[2], search_dim[2], search_pos[2]; + float pat_dim[2], search_dim[2], search_pos[2]; uiLayout *col; BKE_movieclip_get_size(clip, user, &width, &height); @@ -399,19 +405,18 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P step = 100; digits = 2; - sub_v2_v2v2(pat_dim, track->pat_max, track->pat_min); - sub_v2_v2v2(search_dim, track->search_max, track->search_min); + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); - add_v2_v2v2(search_pos, track->search_max, track->search_min); - mul_v2_fl(search_pos, 0.5); + sub_v2_v2v2(pat_dim, pat_max, pat_min); + sub_v2_v2v2(search_dim, marker->search_max, marker->search_min); - add_v2_v2v2(pat_pos, track->pat_max, track->pat_min); - mul_v2_fl(pat_pos, 0.5); + add_v2_v2v2(search_pos, marker->search_max, marker->search_min); + mul_v2_fl(search_pos, 0.5); to_pixel_space(cb->marker_pos, marker->pos, width, height); - to_pixel_space(cb->track_pat, pat_dim, width, height); - to_pixel_space(cb->track_search, search_dim, width, height); - to_pixel_space(cb->track_search_pos, search_pos, width, height); + to_pixel_space(cb->marker_pat, pat_dim, width, height); + to_pixel_space(cb->marker_search, search_dim, width, height); + to_pixel_space(cb->marker_search_pos, search_pos, width, height); to_pixel_space(cb->track_offset, track->offset, width, height); cb->marker_flag = marker->flag; @@ -447,19 +452,19 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P -10*height, 10.0*height, step, digits, "Y-offset to parenting point"); uiDefBut(block, LABEL, 0, "Pattern Area:", 0, 114, 300, 19, NULL, 0, 0, 0, 0, ""); - uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Width:", 10, 95, 300, 19, &cb->track_pat[0], 3.0f, + uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Width:", 10, 95, 300, 19, &cb->marker_pat[0], 3.0f, 10.0*width, step, digits, "Width of marker's pattern in screen coordinates"); - uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Height:", 10, 76, 300, 19, &cb->track_pat[1], 3.0f, + uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Height:", 10, 76, 300, 19, &cb->marker_pat[1], 3.0f, 10.0*height, step, digits, "Height of marker's pattern in screen coordinates"); uiDefBut(block, LABEL, 0, "Search Area:", 0, 57, 300, 19, NULL, 0, 0, 0, 0, ""); - uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "X:", 10, 38, 145, 19, &cb->track_search_pos[0], + uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "X:", 10, 38, 145, 19, &cb->marker_search_pos[0], -width, width, step, digits, "X-position of search at frame relative to marker's position"); - uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "Y:", 165, 38, 145, 19, &cb->track_search_pos[1], + uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "Y:", 165, 38, 145, 19, &cb->marker_search_pos[1], -height, height, step, digits, "X-position of search at frame relative to marker's position"); - uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Width:", 10, 19, 300, 19, &cb->track_search[0], 3.0f, + uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Width:", 10, 19, 300, 19, &cb->marker_search[0], 3.0f, 10.0*width, step, digits, "Width of marker's search in screen soordinates"); - uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Height:", 10, 0, 300, 19, &cb->track_search[1], 3.0f, + uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Height:", 10, 0, 300, 19, &cb->marker_search[1], 3.0f, 10.0*height, step, digits, "Height of marker's search in screen soordinates"); uiBlockEndAlign(block); diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c index e264d7f3885..67609fee653 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_draw.c +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -25,7 +25,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/editors/space_clip/clip_graph_draw.c +/** \file blender/editors/space_clip/clip_dopesheet_draw.c * \ingroup spclip */ @@ -200,8 +200,8 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) /* tracked segments */ for (i = 0; i < channel->tot_segment; i++) { - int start_frame = channel->segments[2 * i]; - int end_frame = channel->segments[2 * i + 1]; + int start_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, channel->segments[2 * i]); + int end_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, channel->segments[2 * i + 1]); if (sel) glColor4fv(selected_strip); @@ -224,8 +224,11 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) while (i < track->markersnr) { MovieTrackingMarker *marker = &track->markers[i]; - if ((marker->flag & (MARKER_DISABLED | MARKER_TRACKED)) == 0) - draw_keyframe_shape(marker->framenr, y, xscale, yscale, sel, alpha); + if ((marker->flag & (MARKER_DISABLED | MARKER_TRACKED)) == 0) { + int framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr); + + draw_keyframe_shape(framenr, y, xscale, yscale, sel, alpha); + } i++; } diff --git a/source/blender/editors/space_clip/clip_dopesheet_ops.c b/source/blender/editors/space_clip/clip_dopesheet_ops.c index 0fd17523425..914e82472bb 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_ops.c +++ b/source/blender/editors/space_clip/clip_dopesheet_ops.c @@ -25,7 +25,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/editors/space_clip/clip_graph_ops.c +/** \file blender/editors/space_clip/clip_dopesheet_ops.c * \ingroup spclip */ @@ -93,6 +93,10 @@ static int dopesheet_select_channel_exec(bContext *C, wmOperator *op) track->flag ^= TRACK_DOPE_SEL; else track->flag |= TRACK_DOPE_SEL; + + if (track->flag & TRACK_DOPE_SEL) { + tracking->act_track = track; + } } else if (!extend) track->flag &= ~TRACK_DOPE_SEL; diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index c00359f0f32..2e16a9095f0 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -33,12 +33,14 @@ #include "DNA_movieclip_types.h" #include "DNA_scene_types.h" #include "DNA_object_types.h" /* SELECT */ +#include "DNA_mask_types.h" #include "MEM_guardedalloc.h" #include "BKE_context.h" #include "BKE_movieclip.h" #include "BKE_tracking.h" +#include "BKE_mask.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -124,7 +126,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc if (act_track) { MovieTrackingTrack *track = act_track; - for (i = sfra, a = 0; i <= efra; i++) { + for (i = sfra - clip->start_frame + 1, a = 0; i <= efra - clip->start_frame + 1; i++) { int framenr; MovieTrackingMarker *marker; @@ -153,7 +155,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc else glColor4ub(255, 255, 0, 96); - glRecti((i - sfra) * framelen, 0, (i - sfra + 1)*framelen, 4); + glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 4); } } } @@ -181,7 +183,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc } if (!ok) - glRecti((i - sfra) * framelen, 0, (i - sfra + 1) * framelen, 8); + glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 8); } } @@ -194,6 +196,32 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc glRecti(x, 0, x + framelen, 8); clip_draw_curfra_label(sc, x, 8.0f); + + /* movie clip animation */ + if ((sc->mode == SC_MODE_MASKEDIT) && sc->mask) { + MaskLayer *masklay = BKE_mask_layer_active(sc->mask); + if (masklay) { + MaskLayerShape *masklay_shape; + + glColor4ub(255, 175, 0, 255); + glBegin(GL_LINES); + + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) + { + i = masklay_shape->frame; + + /* glRecti((i - sfra) * framelen, 0, (i - sfra + 1) * framelen, 4); */ + + /* use a line so we always see the keyframes */ + glVertex2i((i - sfra) * framelen, 0); + glVertex2i((i - sfra) * framelen, (i == CFRA) ? 22 : 10); + } + + glEnd(); + } + } } static void draw_movieclip_notes(SpaceClip *sc, ARegion *ar) @@ -310,17 +338,17 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin int count = sc->path_length; int i, a, b, curindex = -1; float path[102][2]; - int tiny = sc->flag & SC_SHOW_TINY_MARKER, framenr; + int tiny = sc->flag & SC_SHOW_TINY_MARKER, framenr, start_frame; MovieTrackingMarker *marker; if (count == 0) return; - marker = BKE_tracking_get_marker(track, sc->user.framenr); - if (marker->framenr != sc->user.framenr || marker->flag & MARKER_DISABLED) - return; + start_frame = framenr = ED_space_clip_clip_framenr(sc); - framenr = marker->framenr; + marker = BKE_tracking_get_marker(track, framenr); + if (marker->framenr != framenr || marker->flag & MARKER_DISABLED) + return; a = count; i = framenr - 1; @@ -334,7 +362,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin add_v2_v2v2(path[--a], marker->pos, track->offset); ED_clip_point_undistorted_pos(sc, path[a], path[a]); - if (marker->framenr == sc->user.framenr) + if (marker->framenr == start_frame) curindex = a; } else { @@ -353,7 +381,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin break; if (marker->framenr == i) { - if (marker->framenr == sc->user.framenr) + if (marker->framenr == start_frame) curindex = b; add_v2_v2v2(path[b++], marker->pos, track->offset); @@ -428,14 +456,17 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT if ((marker->flag & MARKER_DISABLED) == 0) { float pos[2]; - rctf r; + float p[2]; - BLI_init_rctf(&r, track->pat_min[0], track->pat_max[0], track->pat_min[1], track->pat_max[1]); add_v2_v2v2(pos, marker->pos, track->offset); ED_clip_point_undistorted_pos(sc, pos, pos); - if (BLI_in_rctf(&r, pos[0] - marker_pos[0], pos[1] - marker_pos[1])) { + sub_v2_v2v2(p, pos, marker_pos); + + if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1], + marker->pattern_corners[2], marker->pattern_corners[3])) + { if (tiny) glPointSize(3.0f); else glPointSize(4.0f); glBegin(GL_POINTS); @@ -471,10 +502,10 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT if (sc->flag & SC_SHOW_MARKER_PATTERN) { glBegin(GL_LINE_LOOP); - glVertex2f(track->pat_min[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_max[1]); - glVertex2f(track->pat_min[0], track->pat_max[1]); + glVertex2fv(marker->pattern_corners[0]); + glVertex2fv(marker->pattern_corners[1]); + glVertex2fv(marker->pattern_corners[2]); + glVertex2fv(marker->pattern_corners[3]); glEnd(); } @@ -482,10 +513,10 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0); if (sc->flag & SC_SHOW_MARKER_SEARCH && show_search) { glBegin(GL_LINE_LOOP); - glVertex2f(track->search_min[0], track->search_min[1]); - glVertex2f(track->search_max[0], track->search_min[1]); - glVertex2f(track->search_max[0], track->search_max[1]); - glVertex2f(track->search_min[0], track->search_max[1]); + glVertex2f(marker->search_min[0], marker->search_min[1]); + glVertex2f(marker->search_max[0], marker->search_min[1]); + glVertex2f(marker->search_max[0], marker->search_max[1]); + glVertex2f(marker->search_min[0], marker->search_max[1]); glEnd(); } glPopMatrix(); @@ -528,8 +559,7 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra /* marker position and offset position */ if ((track->flag & SELECT) == sel && (marker->flag & MARKER_DISABLED) == 0) { - float pos[2]; - rctf r; + float pos[2], p[2]; if (track->flag & TRACK_LOCKED) { if (act) @@ -546,11 +576,14 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra glColor3fv(col); } - BLI_init_rctf(&r, track->pat_min[0], track->pat_max[0], track->pat_min[1], track->pat_max[1]); add_v2_v2v2(pos, marker->pos, track->offset); ED_clip_point_undistorted_pos(sc, pos, pos); - if (BLI_in_rctf(&r, pos[0] - marker_pos[0], pos[1] - marker_pos[1])) { + sub_v2_v2v2(p, pos, marker_pos); + + if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1], + marker->pattern_corners[2], marker->pattern_corners[3])) + { if (!tiny) glPointSize(2.0f); @@ -623,10 +656,10 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra } glBegin(GL_LINE_LOOP); - glVertex2f(track->pat_min[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_max[1]); - glVertex2f(track->pat_min[0], track->pat_max[1]); + glVertex2fv(marker->pattern_corners[0]); + glVertex2fv(marker->pattern_corners[1]); + glVertex2fv(marker->pattern_corners[2]); + glVertex2fv(marker->pattern_corners[3]); glEnd(); } @@ -656,70 +689,82 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra } glBegin(GL_LINE_LOOP); - glVertex2f(track->search_min[0], track->search_min[1]); - glVertex2f(track->search_max[0], track->search_min[1]); - glVertex2f(track->search_max[0], track->search_max[1]); - glVertex2f(track->search_min[0], track->search_max[1]); + glVertex2f(marker->search_min[0], marker->search_min[1]); + glVertex2f(marker->search_max[0], marker->search_min[1]); + glVertex2f(marker->search_max[0], marker->search_max[1]); + glVertex2f(marker->search_min[0], marker->search_max[1]); glEnd(); } - /* pyramid */ - if (sel && TRACK_VIEW_SELECTED(sc, track) && - (track->tracker == TRACKER_KLT) && - (marker->flag & MARKER_DISABLED) == 0) - { - if (track->flag & TRACK_LOCKED) { - if (act) - UI_ThemeColor(TH_ACT_MARKER); - else if (track->pat_flag & SELECT) - UI_ThemeColorShade(TH_LOCK_MARKER, 64); - else UI_ThemeColor(TH_LOCK_MARKER); - } - else if (marker->flag & MARKER_DISABLED) { - if (act) - UI_ThemeColor(TH_ACT_MARKER); - else if (track->pat_flag & SELECT) - UI_ThemeColorShade(TH_DIS_MARKER, 128); - else UI_ThemeColor(TH_DIS_MARKER); - } - else { - if (track->pat_flag & SELECT) - glColor3fv(scol); - else - glColor3fv(col); - } - - { - int i = 0; - glPushMatrix(); - glEnable(GL_LINE_STIPPLE); - for (i = 1; i < track->pyramid_levels; ++i) { - glScalef(2.0f, 2.0f, 1.0); - } - /* only draw a pattern for the coarsest level */ - glBegin(GL_LINE_LOOP); - glVertex2f(track->pat_min[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_max[1]); - glVertex2f(track->pat_min[0], track->pat_max[1]); - glEnd(); - glDisable(GL_LINE_STIPPLE); - glPopMatrix(); - } - } - if (tiny) glDisable(GL_LINE_STIPPLE); glPopMatrix(); } +static float get_shortest_pattern_side(MovieTrackingMarker *marker) +{ + int i, next; + float len = FLT_MAX; + + for (i = 0; i < 4; i++) { + float cur_len; + + next = (i + 1) % 4; + + cur_len = len_v2v2(marker->pattern_corners[i], marker->pattern_corners[next]); + + len = MIN2(cur_len, len); + } + + return len; +} + +static void draw_marker_slide_square(float x, float y, float dx, float dy, int outline, float px[2]) +{ + float tdx, tdy; + + tdx = dx; + tdy = dy; + + if (outline) { + tdx += px[0]; + tdy += px[1]; + } + + glBegin(GL_QUADS); + glVertex3f(x - tdx, y + tdy, 0.0f); + glVertex3f(x + tdx, y + tdy, 0.0f); + glVertex3f(x + tdx, y - tdy, 0.0f); + glVertex3f(x - tdx, y - tdy, 0.0f); + glEnd(); +} + +static void draw_marker_slide_triangle(float x, float y, float dx, float dy, int outline, float px[2]) +{ + float tdx, tdy; + + tdx = dx * 2.0f; + tdy = dy * 2.0f; + + if (outline) { + tdx += px[0]; + tdy += px[1]; + } + + glBegin(GL_TRIANGLES); + glVertex3f(x, y, 0.0f); + glVertex3f(x - tdx, y, 0.0f); + glVertex3f(x, y + tdy, 0.0f); + glEnd(); +} + static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, float marker_pos[2], int outline, int sel, int act, int width, int height) { - float x, y, dx, dy, patdx, patdy, searchdx, searchdy, tdx, tdy; + float dx, dy, patdx, patdy, searchdx, searchdy; int tiny = sc->flag & SC_SHOW_TINY_MARKER; - float col[3], scol[3], px[2]; + float col[3], scol[3], px[2], side; if ((tiny && outline) || (marker->flag & MARKER_DISABLED)) return; @@ -740,11 +785,12 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo dx = 6.0f / width / sc->zoom; dy = 6.0f / height / sc->zoom; - patdx = MIN2(dx * 2.0f / 3.0f, (track->pat_max[0] - track->pat_min[0]) / 6.0f); - patdy = MIN2(dy * 2.0f / 3.0f, (track->pat_max[1] - track->pat_min[1]) / 6.0f); + side = get_shortest_pattern_side(marker); + patdx = MIN2(dx * 2.0f / 3.0f, side / 6.0f); + patdy = MIN2(dy * 2.0f / 3.0f, side * width / height / 6.0f); - searchdx = MIN2(dx, (track->search_max[0] - track->search_min[0]) / 6.0f); - searchdy = MIN2(dy, (track->search_max[1] - track->search_min[1]) / 6.0f); + searchdx = MIN2(dx, (marker->search_max[0] - marker->search_min[0]) / 6.0f); + searchdy = MIN2(dy, (marker->search_max[1] - marker->search_min[1]) / 6.0f); px[0] = 1.0f / sc->zoom / width / sc->scale; px[1] = 1.0f / sc->zoom / height / sc->scale; @@ -758,41 +804,10 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo } /* search offset square */ - x = track->search_min[0]; - y = track->search_max[1]; - - tdx = searchdx; - tdy = searchdy; - - if (outline) { - tdx += px[0]; - tdy += px[1]; - } - - glBegin(GL_QUADS); - glVertex3f(x - tdx, y + tdy, 0); - glVertex3f(x + tdx, y + tdy, 0); - glVertex3f(x + tdx, y - tdy, 0); - glVertex3f(x - tdx, y - tdy, 0); - glEnd(); + draw_marker_slide_square(marker->search_min[0], marker->search_max[1], searchdx, searchdy, outline, px); /* search re-sizing triangle */ - x = track->search_max[0]; - y = track->search_min[1]; - - tdx = searchdx * 2.0f; - tdy = searchdy * 2.0f; - - if (outline) { - tdx += px[0]; - tdy += px[1]; - } - - glBegin(GL_TRIANGLES); - glVertex3f(x, y, 0); - glVertex3f(x - tdx, y, 0); - glVertex3f(x, y + tdy, 0); - glEnd(); + draw_marker_slide_triangle(marker->search_max[0], marker->search_min[1], searchdx, searchdy, outline, px); } if ((sc->flag & SC_SHOW_MARKER_PATTERN) && ((track->pat_flag & SELECT) == sel || outline)) { @@ -803,42 +818,26 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo glColor3fv(col); } - /* pattern offset square */ - x = track->pat_min[0]; - y = track->pat_max[1]; + /* XXX: need to be real check if affine tracking is enabled, but for now not + * sure how to do this, so assume affine tracker is always enabled */ + if (TRUE) { + int i; - tdx = patdx; - tdy = patdy; - - if (outline) { - tdx += px[0]; - tdy += px[1]; + /* pattern's corners sliding squares */ + for (i = 0; i < 4; i++) { + draw_marker_slide_square(marker->pattern_corners[i][0], marker->pattern_corners[i][1], + patdx / 1.5f, patdy / 1.5f, outline, px); + } } + else { + /* pattern offset square */ + draw_marker_slide_square(marker->pattern_corners[3][0], marker->pattern_corners[3][1], + patdx, patdy, outline, px); - glBegin(GL_QUADS); - glVertex3f(x - tdx, y + tdy, 0); - glVertex3f(x + tdx, y + tdy, 0); - glVertex3f(x + tdx, y - tdy, 0); - glVertex3f(x - tdx, y - tdy, 0); - glEnd(); - - /* pattern re-sizing triangle */ - x = track->pat_max[0]; - y = track->pat_min[1]; - - tdx = patdx*2.0f; - tdy = patdy*2.0f; - - if (outline) { - tdx += px[0]; - tdy += px[1]; + /* pattern re-sizing triangle */ + draw_marker_slide_triangle(marker->pattern_corners[1][0], marker->pattern_corners[1][1], + patdx, patdy, outline, px); } - - glBegin(GL_TRIANGLES); - glVertex3f(x, y, 0); - glVertex3f(x - tdx, y, 0); - glVertex3f(x, y + tdy, 0); - glEnd(); } glPopMatrix(); @@ -877,12 +876,15 @@ static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTra if ((sc->flag & SC_SHOW_MARKER_SEARCH) && ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) { - dx = track->search_min[0]; - dy = track->search_min[1]; + dx = marker->search_min[0]; + dy = marker->search_min[1]; } else if (sc->flag & SC_SHOW_MARKER_PATTERN) { - dx = track->pat_min[0]; - dy = track->pat_min[1]; + float pat_min[2], pat_max[2]; + + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); + dx = pat_min[0]; + dy = pat_min[1]; } pos[0] = (marker_pos[0] + dx) * width; @@ -896,7 +898,7 @@ static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTra if (marker->flag & MARKER_DISABLED) strcpy(state, "disabled"); - else if (marker->framenr != sc->user.framenr) + else if (marker->framenr != ED_space_clip_clip_framenr(sc)) strcpy(state, "estimated"); else if (marker->flag & MARKER_TRACKED) strcpy(state, "tracked"); @@ -944,7 +946,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, ListBase *tracksbase = BKE_tracking_get_tracks(tracking); MovieTrackingTrack *track, *act_track; MovieTrackingMarker *marker; - int framenr = sc->user.framenr; + int framenr = ED_space_clip_clip_framenr(sc); int undistort = sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT; float *marker_pos = NULL, *fp, *active_pos = NULL, cur_pos[2]; @@ -1175,8 +1177,10 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, int i, j, a; float pos[2], tpos[2], grid[11][11][2]; MovieTracking *tracking = &clip->tracking; + bGPdata *gpd = NULL; float aspy = 1.0f / tracking->camera.pixel_aspect; float dx = (float)width / n, dy = (float)height / n * aspy; + float offsx = 0.0f, offsy = 0.0f; if (sc->mode != SC_MODE_DISTORTION) return; @@ -1284,8 +1288,26 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, } } - if (sc->flag & SC_MANUAL_CALIBRATION && clip->gpd) { - bGPDlayer *layer = clip->gpd->layers.first; + if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { + MovieTrackingTrack *track = BKE_tracking_active_track(&sc->clip->tracking); + + if (track) { + int framenr = sc->user.framenr; + MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); + + offsx = marker->pos[0]; + offsy = marker->pos[1]; + + gpd = track->gpd; + } + + } + else { + gpd = clip->gpd; + } + + if (sc->flag & SC_MANUAL_CALIBRATION && gpd) { + bGPDlayer *layer = gpd->layers.first; while (layer) { bGPDframe *frame = layer->frames.first; @@ -1310,11 +1332,11 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, float npos[2], dpos[2], len; int steps; - pos[0] = stroke->points[i].x * width; - pos[1] = stroke->points[i].y * height * aspy; + pos[0] = (stroke->points[i].x + offsx) * width; + pos[1] = (stroke->points[i].y + offsy) * height * aspy; - npos[0] = stroke->points[i + 1].x * width; - npos[1] = stroke->points[i + 1].y * height * aspy; + npos[0] = (stroke->points[i + 1].x + offsx) * width; + npos[1] = (stroke->points[i + 1].y + offsy) * height * aspy; len = len_v2v2(pos, npos); steps = ceil(len / 5.0f); @@ -1339,7 +1361,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, } else if (stroke->totpoints == 1) { glBegin(GL_POINTS); - glVertex2f(stroke->points[0].x, stroke->points[0].y); + glVertex2f(stroke->points[0].x + offsx, stroke->points[0].y + offsy); glEnd(); } } @@ -1429,7 +1451,6 @@ void clip_draw_grease_pencil(bContext *C, int onlyv2d) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); - ImBuf *ibuf; if (!clip) return; @@ -1438,16 +1459,23 @@ void clip_draw_grease_pencil(bContext *C, int onlyv2d) /* if manual calibration is used then grease pencil data is already * drawed in draw_distortion */ if ((sc->flag & SC_MANUAL_CALIBRATION) == 0 || sc->mode != SC_MODE_DISTORTION) { - ibuf = ED_space_clip_get_buffer(sc); + glPushMatrix(); + glMultMatrixf(sc->unistabmat); - if (ibuf) { - glPushMatrix(); - glMultMatrixf(sc->unistabmat); - draw_gpencil_2dimage(C, ibuf); + if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { + MovieTrackingTrack *track = BKE_tracking_active_track(&sc->clip->tracking); - IMB_freeImBuf(ibuf); - glPopMatrix(); + if (track) { + int framenr = sc->user.framenr; + MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); + + glTranslatef(marker->pos[0], marker->pos[1], 0.0f); + } } + + draw_gpencil_2dimage(C); + + glPopMatrix(); } } else { diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index a477a7435fd..504d96df072 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -34,10 +34,12 @@ #include "MEM_guardedalloc.h" #include "BKE_main.h" +#include "BKE_mask.h" #include "BKE_movieclip.h" #include "BKE_context.h" #include "BKE_tracking.h" +#include "DNA_mask_types.h" #include "DNA_object_types.h" /* SELECT */ #include "BLI_utildefines.h" @@ -94,33 +96,26 @@ int ED_space_clip_tracking_poll(bContext *C) return FALSE; } -int ED_space_clip_tracking_size_poll(bContext *C) +int ED_space_clip_maskedit_poll(bContext *C) { - if (ED_space_clip_tracking_poll(C)) { - MovieClip *clip = CTX_data_edit_movieclip(C); - - if (clip) { - SpaceClip *sc = CTX_wm_space_clip(C); - int width, height; - - BKE_movieclip_get_size(clip, &sc->user, &width, &height); + SpaceClip *sc = CTX_wm_space_clip(C); - return width > 0 && height > 0; - } + if (sc && sc->clip) { + return ED_space_clip_show_maskedit(sc); } return FALSE; } -int ED_space_clip_tracking_frame_poll(bContext *C) +int ED_space_clip_maskedit_mask_poll(bContext *C) { - if (ED_space_clip_tracking_poll(C)) { + if (ED_space_clip_maskedit_poll(C)) { MovieClip *clip = CTX_data_edit_movieclip(C); if (clip) { - SpaceClip *sc = CTX_wm_space_clip(C); + SpaceClip *sc= CTX_wm_space_clip(C); - return BKE_movieclip_has_frame(clip, &sc->user); + return sc->mask != NULL; } } @@ -170,6 +165,11 @@ MovieClip *ED_space_clip(SpaceClip *sc) return sc->clip; } +Mask *ED_space_clip_mask(SpaceClip *sc) +{ + return sc->mask; +} + ImBuf *ED_space_clip_get_buffer(SpaceClip *sc) { if (sc->clip) { @@ -214,6 +214,51 @@ void ED_space_clip_size(SpaceClip *sc, int *width, int *height) } } +void ED_space_clip_mask_size(SpaceClip *sc, int *width, int *height) +{ + /* quite the same as ED_space_clip_size, but it also runs aspect correction on output resolution + * this is needed because mask should be rasterized with exactly the same resolution as + * currently displaying frame and it doesn't have access to aspect correction currently + * used for display. (sergey) + */ + + if (!sc->mask) { + *width = 0; + *height = 0; + } else { + float aspx, aspy; + + ED_space_clip_size(sc, width, height); + ED_space_clip_aspect(sc, &aspx, &aspy); + + *width *= aspx; + *height *= aspy; + } +} + +void ED_space_clip_mask_aspect(SpaceClip *sc, float *aspx, float *aspy) +{ + int w, h; + + ED_space_clip_aspect(sc, aspx, aspy); + ED_space_clip_size(sc, &w, &h); + + /* now this is not accounted for! */ +#if 0 + *aspx *= (float)w; + *aspy *= (float)h; +#endif + + if (*aspx < *aspy) { + *aspy= *aspy / *aspx; + *aspx= 1.0f; + } + else { + *aspx= *aspx / *aspy; + *aspy= 1.0f; + } +} + void ED_space_clip_zoom(SpaceClip *sc, ARegion *ar, float *zoomx, float *zoomy) { int width, height; @@ -234,6 +279,33 @@ void ED_space_clip_aspect(SpaceClip *sc, float *aspx, float *aspy) *aspx = *aspy = 1.0f; } +void ED_space_clip_aspect_dimension_aware(SpaceClip *sc, float *aspx, float *aspy) +{ + int w, h; + + /* most of tools does not require aspect to be returned with dimensions correction + * due to they're invariant to this stuff, but some transformation tools like rotation + * should be aware of aspect correction caused by different resolution in different + * directions. + * mainly this is sued for transformation stuff + */ + + ED_space_clip_aspect(sc, aspx, aspy); + ED_space_clip_size(sc, &w, &h); + + *aspx *= (float)w; + *aspy *= (float)h; + + if (*aspx < *aspy) { + *aspy= *aspy / *aspx; + *aspx= 1.0f; + } + else { + *aspx= *aspx / *aspy; + *aspy= 1.0f; + } +} + void ED_clip_update_frame(const Main *mainp, int cfra) { wmWindowManager *wm; @@ -257,6 +329,14 @@ void ED_clip_update_frame(const Main *mainp, int cfra) } } +/* return current frame number in clip space */ +int ED_space_clip_clip_framenr(SpaceClip *sc) +{ + MovieClip *clip = ED_space_clip(sc); + + return BKE_movieclip_remap_scene_to_clip_frame(clip, sc->user.framenr); +} + static int selected_boundbox(SpaceClip *sc, float min[2], float max[2]) { MovieClip *clip = ED_space_clip(sc); @@ -439,7 +519,10 @@ typedef struct SpaceClipDrawContext { struct ImBuf *texture_ibuf; /* image buffer for which texture was created */ int image_width, image_height; /* image width and height for which texture was created */ unsigned last_texture; /* ID of previously used texture, so it'll be restored after clip drawing */ - int framenr; + + /* fields to check if cache is still valid */ + int framenr, start_frame; + short render_size, render_flag; } SpaceClipDrawContext; int ED_space_clip_texture_buffer_supported(SpaceClip *sc) @@ -477,6 +560,9 @@ int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf) * so not changed image buffer pointer means unchanged image content */ need_rebind |= context->texture_ibuf != ibuf; need_rebind |= context->framenr != sc->user.framenr; + need_rebind |= context->render_size != sc->user.render_size; + need_rebind |= context->render_flag != sc->user.render_flag; + need_rebind |= context->start_frame != clip->start_frame; if (need_rebind) { int width = ibuf->x, height = ibuf->y; @@ -531,6 +617,9 @@ int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf) context->image_width = ibuf->x; context->image_height = ibuf->y; context->framenr = sc->user.framenr; + context->render_size = sc->user.render_size; + context->render_flag = sc->user.render_flag; + context->start_frame = clip->start_frame; } else { /* displaying exactly the same image which was loaded t oa texture, @@ -562,6 +651,8 @@ void ED_space_clip_free_texture_buffer(SpaceClip *sc) } } +/* ******** masking editing related functions ******** */ + int ED_space_clip_show_trackedit(SpaceClip *sc) { if (sc) { @@ -570,3 +661,25 @@ int ED_space_clip_show_trackedit(SpaceClip *sc) return FALSE; } + +int ED_space_clip_show_maskedit(SpaceClip *sc) +{ + if (sc) { + return sc->mode == SC_MODE_MASKEDIT; + } + + return FALSE; +} + +void ED_space_clip_set_mask(bContext *C, SpaceClip *sc, Mask *mask) +{ + sc->mask = mask; + + if (sc->mask && sc->mask->id.us==0) { + sc->clip->id.us = 1; + } + + if (C) { + WM_event_add_notifier(C, NC_MASK|NA_SELECTED, mask); + } +} diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c index 853a7d7cad1..8d30242c128 100644 --- a/source/blender/editors/space_clip/clip_graph_draw.c +++ b/source/blender/editors/space_clip/clip_graph_draw.c @@ -88,9 +88,9 @@ static void draw_curve_knot(float x, float y, float xscale, float yscale, float } static void tracking_segment_point_cb(void *UNUSED(userdata), MovieTrackingTrack *UNUSED(track), - MovieTrackingMarker *marker, int UNUSED(coord), float val) + MovieTrackingMarker *UNUSED(marker), int UNUSED(coord), int scene_framenr, float val) { - glVertex2f(marker->framenr, val); + glVertex2f(scene_framenr, val); } void tracking_segment_start_cb(void *userdata, MovieTrackingTrack *track, int coord) @@ -123,7 +123,7 @@ void tracking_segment_end_cb(void *UNUSED(userdata)) } static void tracking_segment_knot_cb(void *userdata, MovieTrackingTrack *track, - MovieTrackingMarker *marker, int coord, float val) + MovieTrackingMarker *marker, int coord, int scene_framenr, float val) { struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } *data = userdata; int sel = 0, sel_flag; @@ -140,7 +140,7 @@ static void tracking_segment_knot_cb(void *userdata, MovieTrackingTrack *track, else UI_ThemeColor(TH_HANDLE_VERTEX); - draw_curve_knot(marker->framenr, val, data->xscale, data->yscale, data->hsize); + draw_curve_knot(scene_framenr, val, data->xscale, data->yscale, data->hsize); } } diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c index 10692ada5d9..79e199a8f06 100644 --- a/source/blender/editors/space_clip/clip_graph_ops.c +++ b/source/blender/editors/space_clip/clip_graph_ops.c @@ -109,10 +109,11 @@ typedef struct { } MouseSelectUserData; static void find_nearest_tracking_segment_cb(void *userdata, MovieTrackingTrack *track, - MovieTrackingMarker *marker, int coord, float val) + MovieTrackingMarker *UNUSED(marker), + int coord, int scene_framenr, float val) { MouseSelectUserData *data = userdata; - float co[2] = {marker->framenr, val}; + float co[2] = {scene_framenr, val}; if (data->has_prev) { float d = dist_to_line_segment_v2(data->mouse_co, data->prev_co, co); @@ -137,14 +138,14 @@ void find_nearest_tracking_segment_end_cb(void *userdata) } static void find_nearest_tracking_knot_cb(void *userdata, MovieTrackingTrack *track, - MovieTrackingMarker *marker, int coord, float val) + MovieTrackingMarker *marker, int coord, int scene_framenr, float val) { MouseSelectUserData *data = userdata; - float dx = marker->framenr - data->mouse_co[0], dy = val - data->mouse_co[1]; + float dx = scene_framenr - data->mouse_co[0], dy = val - data->mouse_co[1]; float d = dx * dx + dy * dy; if (data->marker == NULL || d < data->min_dist) { - float co[2] = {marker->framenr, val}; + float co[2] = {scene_framenr, val}; data->track = track; data->marker = marker; @@ -308,11 +309,11 @@ typedef struct BorderSelectuserData { } BorderSelectuserData; static void border_select_cb(void *userdata, MovieTrackingTrack *UNUSED(track), - MovieTrackingMarker *marker, int coord, float val) + MovieTrackingMarker *marker, int coord, int scene_framenr, float val) { BorderSelectuserData *data = (BorderSelectuserData *) userdata; - if (BLI_in_rctf(&data->rect, marker->framenr, val)) { + if (BLI_in_rctf(&data->rect, scene_framenr, val)) { int flag = 0; if (coord == 0) @@ -532,7 +533,7 @@ typedef struct { } ViewAllUserData; static void view_all_cb(void *userdata, MovieTrackingTrack *UNUSED(track), MovieTrackingMarker *UNUSED(marker), - int UNUSED(coord), float val) + int UNUSED(coord), int UNUSED(scene_framenr), float val) { ViewAllUserData *data = (ViewAllUserData *) userdata; diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h index 00105fb8561..6908e488157 100644 --- a/source/blender/editors/space_clip/clip_intern.h +++ b/source/blender/editors/space_clip/clip_intern.h @@ -110,12 +110,12 @@ void ED_clip_tool_props_register(struct ARegionType *art); /* clip_utils.c */ void clip_graph_tracking_values_iterate_track(struct SpaceClip *sc, struct MovieTrackingTrack *track, void *userdata, - void (*func) (void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, float val), + void (*func) (void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, int scene_framenr, float val), void (*segment_start) (void *userdata, struct MovieTrackingTrack *track, int coord), void (*segment_end) (void *userdata)); void clip_graph_tracking_values_iterate(struct SpaceClip *sc, void *userdata, - void (*func) (void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, float val), + void (*func) (void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, int scene_framenr, float val), void (*segment_start) (void *userdata, struct MovieTrackingTrack *track, int coord), void (*segment_end) (void *userdata)); diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c index 4142c30d825..6b69f316880 100644 --- a/source/blender/editors/space_clip/clip_utils.c +++ b/source/blender/editors/space_clip/clip_utils.c @@ -64,7 +64,7 @@ #include "clip_intern.h" // own include void clip_graph_tracking_values_iterate_track(SpaceClip *sc, MovieTrackingTrack *track, void *userdata, - void (*func) (void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, float val), + void (*func) (void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, int scene_framenr, float val), void (*segment_start) (void *userdata, MovieTrackingTrack *track, int coord), void (*segment_end) (void *userdata)) { @@ -104,8 +104,11 @@ void clip_graph_tracking_values_iterate_track(SpaceClip *sc, MovieTrackingTrack val = (marker->pos[coord] - prevval) * ((coord == 0) ? (width) : (height)); val /= marker->framenr - prevfra; - if (func) - func(userdata, track, marker, coord, val); + if (func) { + int scene_framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr); + + func(userdata, track, marker, coord, scene_framenr, val); + } prevval = marker->pos[coord]; prevfra = marker->framenr; @@ -119,7 +122,7 @@ void clip_graph_tracking_values_iterate_track(SpaceClip *sc, MovieTrackingTrack } void clip_graph_tracking_values_iterate(SpaceClip *sc, void *userdata, - void (*func) (void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, float val), + void (*func) (void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, int scene_framenr, float val), void (*segment_start) (void *userdata, MovieTrackingTrack *track, int coord), void (*segment_end) (void *userdata)) { diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index a6fda200ff4..54724881e37 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -33,7 +33,9 @@ #include <stdio.h> #include "DNA_scene_types.h" +#include "DNA_mask_types.h" #include "DNA_movieclip_types.h" +#include "DNA_view3d_types.h" /* for pivot point */ #include "MEM_guardedalloc.h" @@ -49,6 +51,8 @@ #include "IMB_imbuf_types.h" +#include "ED_mask.h" +#include "ED_space_api.h" #include "ED_screen.h" #include "ED_clip.h" #include "ED_transform.h" @@ -237,6 +241,7 @@ static SpaceLink *clip_new(const bContext *C) sc->zoom = 1.0f; sc->path_length = 20; sc->scopes.track_preview_height = 120; + sc->around = V3D_LOCAL; /* header */ ar = MEM_callocN(sizeof(ARegion), "header for clip"); @@ -301,6 +306,9 @@ static void clip_free(SpaceLink *sl) if (sc->scopes.track_preview) IMB_freeImBuf(sc->scopes.track_preview); + if (sc->scopes.track_search) + IMB_freeImBuf(sc->scopes.track_search); + ED_space_clip_free_texture_buffer(sc); } @@ -318,6 +326,7 @@ static SpaceLink *clip_duplicate(SpaceLink *sl) SpaceClip *scn = MEM_dupallocN(sl); /* clear or remove stuff from old */ + scn->scopes.track_search = NULL; scn->scopes.track_preview = NULL; scn->scopes.ok = FALSE; scn->draw_context = NULL; @@ -361,6 +370,24 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn) break; } break; + case NC_MASK: + switch (wmn->data) { + case ND_SELECT: + case ND_DATA: + case ND_DRAW: + ED_area_tag_redraw(sa); + break; + } + switch (wmn->action) { + case NA_SELECTED: + clip_scopes_tag_refresh(sa); + ED_area_tag_redraw(sa); + break; + case NA_EDITED: + ED_area_tag_redraw(sa); + break; + } + break; case NC_GEOM: switch (wmn->data) { case ND_SELECT: @@ -369,9 +396,12 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn) break; } break; - case NC_SCREEN: - if (wmn->data == ND_ANIMPLAY) { - ED_area_tag_redraw(sa); + case NC_SCREEN: + switch (wmn->data) { + case ND_ANIMPLAY: + case ND_GPENCIL: + ED_area_tag_redraw(sa); + break; } break; case NC_SPACE: @@ -532,7 +562,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf) /* ******** Hotkeys avalaible for main region only ******** */ keymap = WM_keymap_find(keyconf, "Clip Editor", SPACE_CLIP, 0); - +// keymap->poll = ED_space_clip_tracking_poll; /* ** View/navigation ** */ WM_keymap_add_item(keymap, "CLIP_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0); @@ -715,7 +745,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf) RNA_boolean_set(kmi->ptr, "extend", TRUE); /* toggle */ } -const char *clip_context_dir[] = {"edit_movieclip", NULL}; +const char *clip_context_dir[] = {"edit_movieclip", "edit_mask", NULL}; static int clip_context(const bContext *C, const char *member, bContextDataResult *result) { @@ -729,7 +759,11 @@ static int clip_context(const bContext *C, const char *member, bContextDataResul else if (CTX_data_equals(member, "edit_movieclip")) { if (sc->clip) CTX_data_id_pointer_set(result, &sc->clip->id); - + return TRUE; + } + else if (CTX_data_equals(member, "edit_mask")) { + if (sc->mask) + CTX_data_id_pointer_set(result, &sc->mask->id); return TRUE; } @@ -1020,6 +1054,9 @@ static void clip_main_area_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy); /* own keymap */ + keymap = WM_keymap_find(wm->defaultconf, "Mask Editing", 0, 0); + WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); + keymap = WM_keymap_find(wm->defaultconf, "Clip", SPACE_CLIP, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); @@ -1067,6 +1104,49 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar) /* Grease Pencil */ clip_draw_grease_pencil((bContext *)C, 1); + if (sc->mode == SC_MODE_MASKEDIT) { + int x, y; + int width, height; + float zoomx, zoomy, aspx, aspy; + + /* frame image */ + float maxdim; + float xofs, yofs; + + /* find window pixel coordinates of origin */ + UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y); + + ED_space_clip_size(sc, &width, &height); + ED_space_clip_zoom(sc, ar, &zoomx, &zoomy); + ED_space_clip_aspect(sc, &aspx, &aspy); + + /* frame the image */ + maxdim = maxf(width, height); + if (width == height) { + xofs = yofs = 0; + } + else if (width < height) { + xofs = ((height - width) / -2.0f) * zoomx; + yofs = 0.0f; + } + else { /* (width > height) */ + xofs = 0.0f; + yofs = ((width - height) / -2.0f) * zoomy; + } + + /* apply transformation so mask editing tools will assume drawing from the origin in normalized space */ + glPushMatrix(); + glTranslatef(x + xofs, y + yofs, 0); + glScalef(maxdim * zoomx, maxdim * zoomy, 0); + glMultMatrixf(sc->stabmat); + + ED_mask_draw((bContext *)C, sc->mask_draw_flag, sc->mask_draw_type); + + ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); + + glPopMatrix(); + } + /* reset view matrix */ UI_view2d_view_restore(C); @@ -1241,6 +1321,26 @@ static void clip_header_area_draw(const bContext *C, ARegion *ar) ED_region_header(C, ar); } +static void clip_header_area_listener(ARegion *ar, wmNotifier *wmn) +{ + /* context changes */ + switch (wmn->category) { + case NC_SCENE: + switch (wmn->data) { + /* for proportional editmode only */ + case ND_TOOLSETTINGS: + /* TODO - should do this when in mask mode only but no datas available */ + // if (sc->mode == SC_MODE_MASKEDIT) + { + ED_region_tag_redraw(ar); + } + break; + } + break; + } +} + + /****************** tools region ******************/ /* add handlers, stuff you only do once or on area/region changes */ @@ -1402,6 +1502,7 @@ void ED_spacetype_clip(void) art->init = clip_header_area_init; art->draw = clip_header_area_draw; + art->listener = clip_header_area_listener; BLI_addhead(&st->regiontypes, art); diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index f6dbae596b8..f6e9622f0a5 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -79,6 +79,8 @@ #include "clip_intern.h" // own include +static float dist_to_crns(float co[2], float pos[2], float crns[4][2]); + /********************** add marker operator *********************/ static void add_marker(SpaceClip *sc, float x, float y) @@ -88,10 +90,11 @@ static void add_marker(SpaceClip *sc, float x, float y) ListBase *tracksbase = BKE_tracking_get_tracks(tracking); MovieTrackingTrack *track; int width, height; + int framenr = ED_space_clip_clip_framenr(sc); ED_space_clip_size(sc, &width, &height); - track = BKE_tracking_add_track(tracking, tracksbase, x, y, sc->user.framenr, width, height); + track = BKE_tracking_add_track(tracking, tracksbase, x, y, framenr, width, height); BKE_tracking_select_track(tracksbase, track, TRACK_AREA_ALL, 0); @@ -106,6 +109,7 @@ static int add_marker_exec(bContext *C, wmOperator *op) int width, height; ED_space_clip_size(sc, &width, &height); + if (!width || !height) return OPERATOR_CANCELLED; @@ -143,7 +147,7 @@ void CLIP_OT_add_marker(wmOperatorType *ot) /* api callbacks */ ot->invoke = add_marker_invoke; ot->exec = add_marker_exec; - ot->poll = ED_space_clip_tracking_size_poll; + ot->poll = ED_space_clip_tracking_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -202,7 +206,7 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op)) MovieClip *clip = ED_space_clip(sc); ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); MovieTrackingTrack *track = tracksbase->first, *next; - int framenr = sc->user.framenr; + int framenr = ED_space_clip_clip_framenr(sc); int has_selection = 0; while (track) { @@ -258,19 +262,21 @@ typedef struct { int mval[2]; int width, height; - float *min, *max, *pos, *offset; - float smin[2], smax[2], spos[2], soff[2]; + float *min, *max, *pos, *offset, (*corners)[2]; + float smin[2], smax[2], spos[2], soff[2], scorners[4][2]; float (*smarkers)[2]; - int lock, accurate; + int lock, accurate, scale; } SlideMarkerData; static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTrack *track, - MovieTrackingMarker *marker, wmEvent *event, int area, int action, int width, int height) + MovieTrackingMarker *marker, wmEvent *event, + int area, int corner, int action, int width, int height) { SlideMarkerData *data = MEM_callocN(sizeof(SlideMarkerData), "slide marker data"); + int framenr = ED_space_clip_clip_framenr(sc); - marker = BKE_tracking_ensure_marker(track, sc->user.framenr); + marker = BKE_tracking_ensure_marker(track, framenr); data->area = area; data->action = action; @@ -285,10 +291,9 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra } else if (area == TRACK_AREA_PAT) { if (action == SLIDE_ACTION_SIZE) { - data->min = track->pat_min; - data->max = track->pat_max; + data->corners = marker->pattern_corners; } - else { + else if (action == SLIDE_ACTION_OFFSET) { int a; data->pos = marker->pos; @@ -300,15 +305,28 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra for (a = 0; a < track->markersnr; a++) copy_v2_v2(data->smarkers[a], track->markers[a].pos); } + else if (action == SLIDE_ACTION_POS) { + data->corners = marker->pattern_corners; + data->pos = marker->pattern_corners[corner]; + + copy_v2_v2(data->spos, data->pos); + } } else if (area == TRACK_AREA_SEARCH) { - data->min = track->search_min; - data->max = track->search_max; + data->min = marker->search_min; + data->max = marker->search_max; } - if (area == TRACK_AREA_SEARCH || (area == TRACK_AREA_PAT && action != SLIDE_ACTION_OFFSET)) { - copy_v2_v2(data->smin, data->min); - copy_v2_v2(data->smax, data->max); + if ((area == TRACK_AREA_SEARCH) || + (area == TRACK_AREA_PAT && action != SLIDE_ACTION_OFFSET)) + { + if (data->corners) { + memcpy(data->scorners, data->corners, sizeof(data->scorners)); + } + else { + copy_v2_v2(data->smin, data->min); + copy_v2_v2(data->smax, data->max); + } } data->mval[0] = event->mval[0]; @@ -323,9 +341,7 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra return data; } -/* corner = 0: right-bottom corner, - * corner = 1: left-top corner */ -static int mouse_on_corner(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, +static int mouse_on_corner(SpaceClip *sc, MovieTrackingMarker *marker, int area, float co[2], int corner, int width, int height) { int inside = 0; @@ -334,12 +350,11 @@ static int mouse_on_corner(SpaceClip *sc, MovieTrackingTrack *track, MovieTracki float crn[2], dx, dy, tdx, tdy; if (area == TRACK_AREA_SEARCH) { - copy_v2_v2(min, track->search_min); - copy_v2_v2(max, track->search_max); + copy_v2_v2(min, marker->search_min); + copy_v2_v2(max, marker->search_max); } else { - copy_v2_v2(min, track->pat_min); - copy_v2_v2(max, track->pat_max); + BKE_tracking_marker_pattern_minmax(marker, min, max); } dx = size / width / sc->zoom; @@ -367,22 +382,95 @@ static int mouse_on_corner(SpaceClip *sc, MovieTrackingTrack *track, MovieTracki return inside; } +static int get_mouse_pattern_corner(SpaceClip *sc, MovieTrackingMarker *marker, float co[2], int width, int height) +{ + int i, next; + float len = FLT_MAX, dx, dy; + + for (i = 0; i < 4; i++) { + float cur_len; + + next = (i + 1) % 4; + + cur_len = len_v2v2(marker->pattern_corners[i], marker->pattern_corners[next]); + + len = MIN2(cur_len, len); + } + + dx = 6.0f / width / sc->zoom; + dy = 6.0f / height / sc->zoom; + + dx = MIN2(dx * 2.0f / 3.0f, len / 6.0f); + dy = MIN2(dy * 2.0f / 3.0f, len * width / height / 6.0f); + + for (i = 0; i < 4; i++) { + float crn[2]; + int inside; + + add_v2_v2v2(crn, marker->pattern_corners[i], marker->pos); + + inside = IN_RANGE_INCL(co[0], crn[0] - dx, crn[0] + dx) && + IN_RANGE_INCL(co[1], crn[1] - dy, crn[1] + dy); + + if (inside) + return i; + } + + return -1; +} + static int mouse_on_offset(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, - float co[2], int width, int height) + float co[2], int width, int height) { float pos[2], dx, dy; + float pat_min[2], pat_max[2]; + + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); add_v2_v2v2(pos, marker->pos, track->offset); dx = 12.0f / width / sc->zoom; dy = 12.0f / height / sc->zoom; - dx = MIN2(dx, (track->pat_max[0] - track->pat_min[0]) / 2.0f); - dy = MIN2(dy, (track->pat_max[1] - track->pat_min[1]) / 2.0f); + dx = MIN2(dx, (pat_max[0] - pat_min[0]) / 2.0f); + dy = MIN2(dy, (pat_max[1] - pat_min[1]) / 2.0f); return co[0] >= pos[0] - dx && co[0] <= pos[0] + dx && co[1] >= pos[1] - dy && co[1] <= pos[1] + dy; } +static int slide_check_corners(float (*corners)[2]) +{ + int i, next, prev; + float cross = 0.0f; + float p[2] = {0.0f, 0.0f}; + + if (!isect_point_quad_v2(p, corners[0], corners[1], corners[2], corners[3])) + return FALSE; + + for (i = 0; i < 4; i++) { + float v1[2], v2[2], cur_cross; + + next = (i + 1) % 4; + prev = (4 + i - 1) % 4; + + sub_v2_v2v2(v1, corners[i], corners[prev]); + sub_v2_v2v2(v2, corners[next], corners[i]); + + cur_cross = cross_v2v2(v1, v2); + + if (fabsf(cur_cross) > FLT_EPSILON) { + if (cross == 0.0f) { + cross = cur_cross; + } + else if (cross * cur_cross < 0.0f) { + return FALSE; + } + } + } + + return TRUE; +} + static void hide_cursor(bContext *C) { wmWindow *win = CTX_wm_window(C); @@ -406,6 +494,7 @@ static void *slide_marker_customdata(bContext *C, wmEvent *event) float co[2]; void *customdata = NULL; ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); + int framenr = ED_space_clip_clip_framenr(sc); ED_space_clip_size(sc, &width, &height); @@ -417,31 +506,48 @@ static void *slide_marker_customdata(bContext *C, wmEvent *event) track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr); + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); if ((marker->flag & MARKER_DISABLED) == 0) { - if (!customdata) + if (!customdata) { if (mouse_on_offset(sc, track, marker, co, width, height)) - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_POINT, + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_POINT, 0, SLIDE_ACTION_POS, width, height); + } if (sc->flag & SC_SHOW_MARKER_SEARCH) { - if (mouse_on_corner(sc, track, marker, TRACK_AREA_SEARCH, co, 1, width, height)) - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, + if (mouse_on_corner(sc, marker, TRACK_AREA_SEARCH, co, 1, width, height)) { + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, 0, SLIDE_ACTION_OFFSET, width, height); - else if (mouse_on_corner(sc, track, marker, TRACK_AREA_SEARCH, co, 0, width, height)) - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, + } + else if (mouse_on_corner(sc, marker, TRACK_AREA_SEARCH, co, 0, width, height)) { + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, 0, SLIDE_ACTION_SIZE, width, height); + } } if (!customdata && (sc->flag & SC_SHOW_MARKER_PATTERN)) { - if (mouse_on_corner(sc, track, marker, TRACK_AREA_PAT, co, 1, width, height)) - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, - SLIDE_ACTION_OFFSET, width, height); - - if (!customdata && mouse_on_corner(sc, track, marker, TRACK_AREA_PAT, co, 0, width, height)) - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, - SLIDE_ACTION_SIZE, width, height); + /* XXX: need to be real check if affine tracking is enabled, but for now not + * sure how to do this, so assume affine tracker is always enabled */ + if (TRUE) { + int corner = get_mouse_pattern_corner(sc, marker, co, width, height); + + if (corner != -1) { + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, corner, + SLIDE_ACTION_POS, width, height); + } + } + else { + if (mouse_on_corner(sc, marker, TRACK_AREA_PAT, co, 1, width, height)) { + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, 0, + SLIDE_ACTION_OFFSET, width, height); + } + + if (!customdata && mouse_on_corner(sc, marker, TRACK_AREA_PAT, co, 0, width, height)) { + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, 0, + SLIDE_ACTION_SIZE, width, height); + } + } } if (customdata) @@ -489,9 +595,16 @@ static void cancel_mouse_slide(SlideMarkerData *data) copy_v2_v2(data->pos, data->spos); } else { - if (data->action == SLIDE_ACTION_SIZE) { - copy_v2_v2(data->min, data->smin); - copy_v2_v2(data->max, data->smax); + if ((data->action == SLIDE_ACTION_SIZE) || + (data->action == SLIDE_ACTION_POS && data->area == TRACK_AREA_PAT)) + { + if (data->corners) { + memcpy(data->corners, data->scorners, sizeof(data->scorners)); + } + else { + copy_v2_v2(data->min, data->smin); + copy_v2_v2(data->max, data->smax); + } } else { int a; @@ -527,6 +640,10 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) if (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY)) data->lock = event->val == KM_RELEASE; + if (data->action == SLIDE_ACTION_POS) + if (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY)) + data->scale = event->val == KM_PRESS; + if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) data->accurate = event->val == KM_PRESS; @@ -556,8 +673,6 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) else { data->pos[0] = data->spos[0] + dx; data->pos[1] = data->spos[1] + dy; - - data->marker->flag &= ~MARKER_TRACKED; } WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); @@ -565,18 +680,33 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) } else { if (data->action == SLIDE_ACTION_SIZE) { - data->min[0] = data->smin[0] - dx; - data->max[0] = data->smax[0] + dx; + if (data->corners) { + data->corners[0][0] = data->scorners[0][0] - dx; + data->corners[0][1] = data->scorners[0][1] + dy; - data->min[1] = data->smin[1] + dy; - data->max[1] = data->smax[1] - dy; + data->corners[1][0] = data->scorners[1][0] + dx; + data->corners[1][1] = data->scorners[1][1] + dy; + + data->corners[2][0] = data->scorners[2][0] + dx; + data->corners[2][1] = data->scorners[2][1] - dy; + + data->corners[3][0] = data->scorners[3][0] - dx; + data->corners[3][1] = data->scorners[3][1] - dy; + } + else { + data->min[0] = data->smin[0] - dx; + data->max[0] = data->smax[0] + dx; + + data->min[1] = data->smin[1] + dy; + data->max[1] = data->smax[1] - dy; + } if (data->area == TRACK_AREA_SEARCH) - BKE_tracking_clamp_track(data->track, CLAMP_SEARCH_DIM); + BKE_tracking_clamp_marker(data->marker, CLAMP_SEARCH_DIM); else - BKE_tracking_clamp_track(data->track, CLAMP_PAT_DIM); + BKE_tracking_clamp_marker(data->marker, CLAMP_PAT_DIM); } - else { + else if (data->action == SLIDE_ACTION_OFFSET) { float d[2] = {dx, dy}; if (data->area == TRACK_AREA_SEARCH) { @@ -593,10 +723,43 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) } if (data->area == TRACK_AREA_SEARCH) - BKE_tracking_clamp_track(data->track, CLAMP_SEARCH_POS); + BKE_tracking_clamp_marker(data->marker, CLAMP_SEARCH_POS); + } + else if (data->action == SLIDE_ACTION_POS) { + if (data->scale) { + float scale = 1.0f + 10.0f * (dx - dy); + + if (scale > 0.0f) { + int a; + + for (a = 0; a < 4; a++) { + mul_v2_v2fl(data->corners[a], data->scorners[a], scale); + } + } + } + else { + float spos[2]; + + copy_v2_v2(spos, data->pos); + + /* corners might've been scaled before, restore their original position */ + memcpy(data->corners, data->scorners, sizeof(data->scorners)); + + data->pos[0] = data->spos[0] + dx; + data->pos[1] = data->spos[1] + dy; + + if (!slide_check_corners(data->corners)) { + copy_v2_v2(data->pos, spos); + } + } + + /* currently only patterns are allowed to have such combination of event and data */ + BKE_tracking_clamp_marker(data->marker, CLAMP_PAT_DIM); } } + data->marker->flag &= ~MARKER_TRACKED; + WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, NULL); break; @@ -635,7 +798,7 @@ void CLIP_OT_slide_marker(wmOperatorType *ot) ot->idname = "CLIP_OT_slide_marker"; /* api callbacks */ - ot->poll = ED_space_clip_tracking_size_poll; + ot->poll = ED_space_clip_tracking_poll; ot->invoke = slide_marker_invoke; ot->modal = slide_marker_modal; @@ -669,30 +832,41 @@ static int mouse_on_rect(float co[2], float pos[2], float min[2], float max[2], mouse_on_side(co, pos[0] + max[0], pos[1] + min[1], pos[0] + max[0], pos[1] + max[1], epsx, epsy); } +static int mouse_on_crns(float co[2], float pos[2], float crns[4][2], float epsx, float epsy) +{ + float dist = dist_to_crns(co, pos, crns); + + return dist < MAX2(epsx, epsy); +} + static int track_mouse_area(SpaceClip *sc, float co[2], MovieTrackingTrack *track) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr); + int framenr = ED_space_clip_clip_framenr(sc); + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); + float pat_min[2], pat_max[2]; float epsx, epsy; int width, height; ED_space_clip_size(sc, &width, &height); - epsx = MIN4(track->pat_min[0] - track->search_min[0], track->search_max[0] - track->pat_max[0], - fabsf(track->pat_min[0]), fabsf(track->pat_max[0])) / 2; - epsy = MIN4(track->pat_min[1] - track->search_min[1], track->search_max[1] - track->pat_max[1], - fabsf(track->pat_min[1]), fabsf(track->pat_max[1])) / 2; + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); + + epsx = MIN4(pat_min[0] - marker->search_min[0], marker->search_max[0] - pat_max[0], + fabsf(pat_min[0]), fabsf(pat_max[0])) / 2; + epsy = MIN4(pat_min[1] - marker->search_min[1], marker->search_max[1] - pat_max[1], + fabsf(pat_min[1]), fabsf(pat_max[1])) / 2; epsx = MAX2(epsx, 2.0f / width); epsy = MAX2(epsy, 2.0f / height); if (sc->flag & SC_SHOW_MARKER_SEARCH) { - if (mouse_on_rect(co, marker->pos, track->search_min, track->search_max, epsx, epsy)) + if (mouse_on_rect(co, marker->pos, marker->search_min, marker->search_max, epsx, epsy)) return TRACK_AREA_SEARCH; } if ((marker->flag & MARKER_DISABLED) == 0) { if (sc->flag & SC_SHOW_MARKER_PATTERN) - if (mouse_on_rect(co, marker->pos, track->pat_min, track->pat_max, epsx, epsy)) + if (mouse_on_crns(co, marker->pos, marker->pattern_corners, epsx, epsy)) return TRACK_AREA_PAT; epsx = 12.0f / width; @@ -723,29 +897,45 @@ static float dist_to_rect(float co[2], float pos[2], float min[2], float max[2]) return MIN4(d1, d2, d3, d4); } +static float dist_to_crns(float co[2], float pos[2], float crns[4][2]) +{ + float d1, d2, d3, d4; + float p[2] = {co[0] - pos[0], co[1] - pos[1]}; + float *v1 = crns[0], *v2 = crns[1], + *v3 = crns[2], *v4 = crns[3]; + + d1 = dist_to_line_segment_v2(p, v1, v2); + d2 = dist_to_line_segment_v2(p, v2, v3); + d3 = dist_to_line_segment_v2(p, v3, v4); + d4 = dist_to_line_segment_v2(p, v4, v1); + + return MIN4(d1, d2, d3, d4); +} + static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbase, float co[2]) { MovieTrackingTrack *track = NULL, *cur; float mindist = 0.0f; + int framenr = ED_space_clip_clip_framenr(sc); cur = tracksbase->first; while (cur) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(cur, sc->user.framenr); + MovieTrackingMarker *marker = BKE_tracking_get_marker(cur, framenr); if (((cur->flag & TRACK_HIDDEN) == 0) && MARKER_VISIBLE(sc, cur, marker)) { float dist, d1, d2 = FLT_MAX, d3 = FLT_MAX; /* distance to marker point */ d1 = sqrtf((co[0] - marker->pos[0] - cur->offset[0]) * (co[0] - marker->pos[0] - cur->offset[0]) + - (co[1] - marker->pos[1] - cur->offset[1]) * (co[1] - marker->pos[1] - cur->offset[1])); + (co[1] - marker->pos[1] - cur->offset[1]) * (co[1] - marker->pos[1] - cur->offset[1])); /* distance to pattern boundbox */ if (sc->flag & SC_SHOW_MARKER_PATTERN) - d2 = dist_to_rect(co, marker->pos, cur->pat_min, cur->pat_max); + d2 = dist_to_crns(co, marker->pos, marker->pattern_corners); /* distance to search boundbox */ if (sc->flag & SC_SHOW_MARKER_SEARCH && TRACK_VIEW_SELECTED(sc, cur)) - d3 = dist_to_rect(co, marker->pos, cur->search_min, cur->search_max); + d3 = dist_to_rect(co, marker->pos, marker->search_min, marker->search_max); /* choose minimal distance. useful for cases of overlapped markers. */ dist = MIN3(d1, d2, d3); @@ -855,7 +1045,8 @@ void CLIP_OT_select(wmOperatorType *ot) /* api callbacks */ ot->exec = select_exec; ot->invoke = select_invoke; - ot->poll = ED_space_clip_tracking_poll; + //ot->poll = ED_space_clip_tracking_poll; // so mask view can Ctrl+RMB markers + ot->poll = ED_space_clip_view_clip_poll; /* flags */ ot->flag = OPTYPE_UNDO; @@ -879,6 +1070,7 @@ static int border_select_exec(bContext *C, wmOperator *op) rcti rect; rctf rectf; int change = FALSE, mode, extend; + int framenr = ED_space_clip_clip_framenr(sc); /* get rectangle from operator */ rect.xmin = RNA_int_get(op->ptr, "xmin"); @@ -896,7 +1088,7 @@ static int border_select_exec(bContext *C, wmOperator *op) track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr); + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { if (BLI_in_rctf(&rectf, marker->pos[0], marker->pos[1])) { @@ -955,6 +1147,7 @@ static int do_lasso_select_marker(bContext *C, int mcords[][2], short moves, sho ListBase *tracksbase = BKE_tracking_get_tracks(tracking); rcti rect; int change = FALSE; + int framenr = ED_space_clip_clip_framenr(sc); /* get rectangle from operator */ BLI_lasso_boundbox(&rect, mcords, moves); @@ -963,7 +1156,7 @@ static int do_lasso_select_marker(bContext *C, int mcords[][2], short moves, sho track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr); + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { float screen_co[2]; @@ -1057,6 +1250,7 @@ static int circle_select_exec(bContext *C, wmOperator *op) ListBase *tracksbase = BKE_tracking_get_tracks(tracking); int x, y, radius, width, height, mode, change = FALSE; float zoomx, zoomy, offset[2], ellipse[2]; + int framenr = ED_space_clip_clip_framenr(sc); /* get operator properties */ x = RNA_int_get(op->ptr, "x"); @@ -1078,7 +1272,7 @@ static int circle_select_exec(bContext *C, wmOperator *op) track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr); + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); if (MARKER_VISIBLE(sc, track, marker) && marker_inside_ellipse(marker, offset, ellipse)) { BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, mode != GESTURE_MODAL_SELECT); @@ -1135,7 +1329,7 @@ static int select_all_exec(bContext *C, wmOperator *op) MovieTrackingMarker *marker; ListBase *tracksbase = BKE_tracking_get_tracks(tracking); int action = RNA_enum_get(op->ptr, "action"); - int framenr = sc->user.framenr; + int framenr = ED_space_clip_clip_framenr(sc); int has_selection = FALSE; if (action == SEL_TOGGLE) { @@ -1225,21 +1419,22 @@ static int select_groped_exec(bContext *C, wmOperator *op) MovieTracking *tracking = &clip->tracking; ListBase *tracksbase = BKE_tracking_get_tracks(tracking); int group = RNA_enum_get(op->ptr, "group"); + int framenr = ED_space_clip_clip_framenr(sc); track = tracksbase->first; while (track) { int ok = FALSE; - marker = BKE_tracking_get_marker(track, sc->user.framenr); + marker = BKE_tracking_get_marker(track, framenr); if (group == 0) { /* Keyframed */ - ok = marker->framenr == sc->user.framenr && (marker->flag & MARKER_TRACKED) == 0; + ok = marker->framenr == framenr && (marker->flag & MARKER_TRACKED) == 0; } else if (group == 1) { /* Estimated */ - ok = marker->framenr != sc->user.framenr; + ok = marker->framenr != framenr; } else if (group == 2) { /* tracked */ - ok = marker->framenr == sc->user.framenr && (marker->flag & MARKER_TRACKED); + ok = marker->framenr == framenr && (marker->flag & MARKER_TRACKED); } else if (group == 3) { /* locked */ ok = track->flag & TRACK_LOCKED; @@ -1299,7 +1494,7 @@ void CLIP_OT_select_grouped(wmOperatorType *ot) /* api callbacks */ ot->exec = select_groped_exec; - ot->poll = ED_space_clip_tracking_size_poll; + ot->poll = ED_space_clip_tracking_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -1332,7 +1527,7 @@ static int track_count_markers(SpaceClip *sc, MovieClip *clip) int tot = 0; ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); MovieTrackingTrack *track; - int framenr = sc->user.framenr; + int framenr = ED_space_clip_clip_framenr(sc); track = tracksbase->first; while (track) { @@ -1376,7 +1571,7 @@ static void track_init_markers(SpaceClip *sc, MovieClip *clip, int *frames_limit { ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); MovieTrackingTrack *track; - int framenr = sc->user.framenr; + int framenr = ED_space_clip_clip_framenr(sc); int frames_limit = 0; clear_invisible_track_selection(sc, clip); @@ -1426,7 +1621,7 @@ static int track_markers_initjob(bContext *C, TrackMarkersJob *tmj, int backward track_init_markers(sc, clip, &frames_limit); - tmj->sfra = sc->user.framenr; + tmj->sfra = ED_space_clip_clip_framenr(sc); tmj->clip = clip; tmj->backwards = backwards; @@ -1443,6 +1638,8 @@ static int track_markers_initjob(bContext *C, TrackMarkersJob *tmj, int backward tmj->efra = MIN2(tmj->efra, tmj->sfra + frames_limit); } + tmj->efra = BKE_movieclip_remap_scene_to_clip_frame(clip, tmj->efra); + if (settings->speed != TRACKING_SPEED_FASTEST) { tmj->delay = 1.0f / scene->r.frs_sec * 1000.0f; @@ -1527,7 +1724,7 @@ static void track_markers_freejob(void *tmv) TrackMarkersJob *tmj = (TrackMarkersJob *)tmv; tmj->clip->tracking_context = NULL; - tmj->scene->r.cfra = tmj->lastfra; + tmj->scene->r.cfra = BKE_movieclip_remap_clip_to_scene_frame(tmj->clip, tmj->lastfra); ED_update_for_newframe(tmj->main, tmj->scene, 0); BKE_tracking_sync(tmj->context); @@ -1544,7 +1741,7 @@ static int track_markers_exec(bContext *C, wmOperator *op) MovieClip *clip = ED_space_clip(sc); Scene *scene = CTX_data_scene(C); struct MovieTrackingContext *context; - int framenr = sc->user.framenr; + int framenr = ED_space_clip_clip_framenr(sc); int sfra = framenr, efra; int backwards = RNA_boolean_get(op->ptr, "backwards"); int sequence = RNA_boolean_get(op->ptr, "sequence"); @@ -1568,6 +1765,8 @@ static int track_markers_exec(bContext *C, wmOperator *op) efra = MIN2(efra, sfra + frames_limit); } + efra = BKE_movieclip_remap_scene_to_clip_frame(clip, efra); + if (!track_markers_check_direction(backwards, framenr, efra)) return OPERATOR_CANCELLED; @@ -1589,7 +1788,7 @@ static int track_markers_exec(bContext *C, wmOperator *op) BKE_tracking_context_free(context); /* update scene current frame to the lastes tracked frame */ - scene->r.cfra = framenr; + scene->r.cfra = BKE_movieclip_remap_clip_to_scene_frame(clip, framenr); WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); @@ -1680,7 +1879,7 @@ void CLIP_OT_track_markers(wmOperatorType *ot) /* api callbacks */ ot->exec = track_markers_exec; ot->invoke = track_markers_invoke; - ot->poll = ED_space_clip_tracking_frame_poll; + ot->poll = ED_space_clip_tracking_poll; ot->modal = track_markers_modal; /* flags */ @@ -1967,16 +2166,17 @@ static int clear_track_path_exec(bContext *C, wmOperator *op) ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); int action = RNA_enum_get(op->ptr, "action"); int clear_active = RNA_boolean_get(op->ptr, "clear_active"); + int framenr = ED_space_clip_clip_framenr(sc); if (clear_active) { track = BKE_tracking_active_track(&clip->tracking); - BKE_tracking_clear_path(track, sc->user.framenr, action); + BKE_tracking_clear_path(track, framenr, action); } else { track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track)) - BKE_tracking_clear_path(track, sc->user.framenr, action); + BKE_tracking_clear_path(track, framenr, action); track = track->next; } @@ -2023,10 +2223,11 @@ static int disable_markers_exec(bContext *C, wmOperator *op) ListBase *tracksbase = BKE_tracking_get_tracks(tracking); MovieTrackingTrack *track = tracksbase->first; int action = RNA_enum_get(op->ptr, "action"); + int framenr = ED_space_clip_clip_framenr(sc); while (track) { if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { - MovieTrackingMarker *marker = BKE_tracking_ensure_marker(track, sc->user.framenr); + MovieTrackingMarker *marker = BKE_tracking_ensure_marker(track, framenr); if (action == 0) marker->flag |= MARKER_DISABLED; @@ -2119,18 +2320,22 @@ static Object *get_orientation_object(bContext *C) static int set_orientation_poll(bContext *C) { - if (ED_space_clip_tracking_size_poll(C)) { + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { Scene *scene = CTX_data_scene(C); - SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); - MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *tracking_object = BKE_tracking_active_object(tracking); - if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { - return TRUE; - } - else { - return OBACT != NULL; + if (clip) { + MovieTracking *tracking = &clip->tracking; + MovieTrackingObject *tracking_object = BKE_tracking_active_object(tracking); + + if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { + return TRUE; + } + else { + return OBACT != NULL; + } } } @@ -2729,16 +2934,20 @@ void CLIP_OT_set_scale(wmOperatorType *ot) static int set_solution_scale_poll(bContext *C) { - if (ED_space_clip_tracking_size_poll(C)) { - SpaceClip *sc = CTX_wm_space_clip(C); + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { MovieClip *clip = ED_space_clip(sc); - MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *tracking_object = BKE_tracking_active_object(tracking); - return (tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0; + if (clip) { + MovieTracking *tracking = &clip->tracking; + MovieTrackingObject *tracking_object = BKE_tracking_active_object(tracking); + + return (tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0; + } } - return 0; + return FALSE; } static int set_solution_scale_exec(bContext *C, wmOperator *op) @@ -2945,8 +3154,14 @@ static int detect_features_exec(bContext *C, wmOperator *op) int min_trackability = RNA_int_get(op->ptr, "min_trackability"); int min_distance = RNA_int_get(op->ptr, "min_distance"); int place_outside_layer = 0; + int framenr = ED_space_clip_clip_framenr(sc); bGPDlayer *layer = NULL; + if (!ibuf) { + BKE_report(op->reports, RPT_ERROR, "Feature detection requires valid clip frame"); + return OPERATOR_CANCELLED; + } + if (placement != 0) { layer = detect_get_layer(clip); place_outside_layer = placement == 2; @@ -2961,7 +3176,7 @@ static int detect_features_exec(bContext *C, wmOperator *op) track = track->next; } - BKE_tracking_detect_fast(tracking, tracksbase, ibuf, sc->user.framenr, margin, + BKE_tracking_detect_fast(tracking, tracksbase, ibuf, framenr, margin, min_trackability, min_distance, layer, place_outside_layer); IMB_freeImBuf(ibuf); @@ -2987,7 +3202,7 @@ void CLIP_OT_detect_features(wmOperatorType *ot) /* api callbacks */ ot->exec = detect_features_exec; - ot->poll = ED_space_clip_tracking_frame_poll; + ot->poll = ED_space_clip_tracking_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -3019,7 +3234,8 @@ static int frame_jump_exec(bContext *C, wmOperator *op) delta = pos == 1 ? 1 : -1; while (sc->user.framenr + delta >= SFRA && sc->user.framenr + delta <= EFRA) { - MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, sc->user.framenr + delta); + int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, sc->user.framenr + delta); + MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); if (!marker || marker->flag & MARKER_DISABLED) break; @@ -3029,7 +3245,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op) } else { /* to to failed frame */ if (clip->tracking.reconstruction.flag & TRACKING_RECONSTRUCTED) { - int a = sc->user.framenr; + int a = ED_space_clip_clip_framenr(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingObject *object = BKE_tracking_active_object(tracking); @@ -3043,7 +3259,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op) cam = BKE_tracking_get_reconstructed_camera(tracking, object, a); if (!cam) { - sc->user.framenr = a; + sc->user.framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, a); break; } @@ -3139,7 +3355,7 @@ void CLIP_OT_join_tracks(wmOperatorType *ot) /* api callbacks */ ot->exec = join_tracks_exec; - ot->poll = ED_space_clip_tracking_size_poll; + ot->poll = ED_space_clip_tracking_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; |