Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_clip/tracking_ops.c')
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c301
1 files changed, 243 insertions, 58 deletions
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index 08fc84d193c..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)
@@ -260,15 +262,16 @@ 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);
@@ -288,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;
@@ -303,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];
@@ -326,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;
@@ -337,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;
@@ -370,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);
@@ -424,28 +509,45 @@ static void *slide_marker_customdata(bContext *C, wmEvent *event)
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)
@@ -493,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;
@@ -531,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;
@@ -560,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);
@@ -569,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->corners[1][0] = data->scorners[1][0] + dx;
+ data->corners[1][1] = data->scorners[1][1] + dy;
- data->min[1] = data->smin[1] + dy;
- data->max[1] = data->smax[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) {
@@ -597,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;
@@ -673,31 +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)
{
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;
@@ -728,6 +897,21 @@ 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;
@@ -743,15 +927,15 @@ static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbas
/* 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);
@@ -861,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;