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_select.c')
-rw-r--r--source/blender/editors/space_clip/tracking_select.c257
1 files changed, 243 insertions, 14 deletions
diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c
index b03209173d8..6e4d10173fb 100644
--- a/source/blender/editors/space_clip/tracking_select.c
+++ b/source/blender/editors/space_clip/tracking_select.c
@@ -169,6 +169,7 @@ static float dist_to_rect(float co[2], float pos[2], float min[2], float max[2])
return sqrtf(min_ffff(d1, d2, d3, d4));
}
+/* Distance to quad defined by it's corners, corners are relative to pos */
static float dist_to_crns(float co[2], float pos[2], float crns[4][2])
{
float d1, d2, d3, d4;
@@ -184,7 +185,22 @@ static float dist_to_crns(float co[2], float pos[2], float crns[4][2])
return sqrtf(min_ffff(d1, d2, d3, d4));
}
-static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbase, float co[2])
+/* Same as above, but all the coordinates are absolute */
+static float dist_to_crns_abs(float co[2], float corners[4][2])
+{
+ float d1, d2, d3, d4;
+ float *v1 = corners[0], *v2 = corners[1];
+ float *v3 = corners[2], *v4 = corners[3];
+
+ d1 = dist_squared_to_line_segment_v2(co, v1, v2);
+ d2 = dist_squared_to_line_segment_v2(co, v2, v3);
+ d3 = dist_squared_to_line_segment_v2(co, v3, v4);
+ d4 = dist_squared_to_line_segment_v2(co, v4, v1);
+
+ return sqrtf(min_ffff(d1, d2, d3, d4));
+}
+
+static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbase, float co[2], float *distance_r)
{
MovieTrackingTrack *track = NULL, *cur;
float mindist = 0.0f;
@@ -221,19 +237,88 @@ static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbas
cur = cur->next;
}
+ *distance_r = mindist;
+
return track;
}
+static MovieTrackingPlaneTrack *find_nearest_plane_track(SpaceClip *sc, ListBase *plane_tracks_base,
+ float co[2], float *distance_r)
+{
+ MovieTrackingPlaneTrack *plane_track = NULL, *current_plane_track;
+ float min_distance = 0.0f;
+ int framenr = ED_space_clip_get_clip_frame_number(sc);
+
+ for (current_plane_track = plane_tracks_base->first;
+ current_plane_track;
+ current_plane_track = current_plane_track->next)
+ {
+ MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(current_plane_track, framenr);
+
+ if ((current_plane_track->flag & TRACK_HIDDEN) == 0) {
+ float distance = dist_to_crns_abs(co, plane_marker->corners);
+ if (plane_track == NULL || distance < min_distance) {
+ plane_track = current_plane_track;
+ min_distance = distance;
+ }
+ }
+ }
+
+ *distance_r = min_distance;
+
+ return plane_track;
+}
+
+static void delect_all_tracks(ListBase *tracks_base)
+{
+ MovieTrackingTrack *track;
+ for (track = tracks_base->first;
+ track;
+ track = track->next)
+ {
+ BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT);
+ }
+}
+
+static void delect_all_plane_tracks(ListBase *plane_tracks_base)
+{
+ MovieTrackingPlaneTrack *plane_track;
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = plane_track->next)
+ {
+ plane_track->flag &= ~SELECT;
+ }
+}
+
static int mouse_select(bContext *C, float co[2], int extend)
{
SpaceClip *sc = CTX_wm_space_clip(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+ ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
- MovieTrackingTrack *track = NULL; /* selected marker */
+ MovieTrackingTrack *track;
+ MovieTrackingPlaneTrack *plane_track;
+ float distance_to_track, distance_to_plane_track;
+
+ track = find_nearest_track(sc, tracksbase, co, &distance_to_track);
+ plane_track = find_nearest_plane_track(sc, plane_tracks_base, co, &distance_to_plane_track);
+
+ /* Between track and plane we choose closest to the mouse for selection here. */
+ if (track && plane_track) {
+ if (distance_to_track < distance_to_plane_track) {
+ plane_track = NULL;
+ }
+ else {
+ track = NULL;
+ }
+ }
- track = find_nearest_track(sc, tracksbase, co);
+ if (!extend) {
+ delect_all_plane_tracks(plane_tracks_base);
+ }
if (track) {
int area = track_mouse_area(C, co, track);
@@ -242,10 +327,13 @@ static int mouse_select(bContext *C, float co[2], int extend)
area = TRACK_AREA_ALL;
if (extend && TRACK_AREA_SELECTED(track, area)) {
- if (track == act_track)
+ if (track == act_track) {
BKE_tracking_track_deselect(track, area);
- else
+ }
+ else {
clip->tracking.act_track = track;
+ clip->tracking.act_plane_track = NULL;
+ }
}
else {
if (area == TRACK_AREA_POINT)
@@ -253,7 +341,25 @@ static int mouse_select(bContext *C, float co[2], int extend)
BKE_tracking_track_select(tracksbase, track, area, extend);
clip->tracking.act_track = track;
+ clip->tracking.act_plane_track = NULL;
+ }
+ }
+ else if (plane_track) {
+ if (!extend) {
+ delect_all_tracks(tracksbase);
+ }
+
+ if (plane_track->flag & SELECT) {
+ if (extend) {
+ plane_track->flag &= ~SELECT;
+ }
+ }
+ else {
+ plane_track->flag |= SELECT;
}
+
+ clip->tracking.act_track = NULL;
+ clip->tracking.act_plane_track = plane_track;
}
if (!extend) {
@@ -350,7 +456,9 @@ static int border_select_exec(bContext *C, wmOperator *op)
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
MovieTrackingTrack *track;
+ MovieTrackingPlaneTrack *plane_track;
ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+ ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
rcti rect;
rctf rectf;
int change = FALSE, mode, extend;
@@ -389,6 +497,33 @@ static int border_select_exec(bContext *C, wmOperator *op)
track = track->next;
}
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = plane_track->next)
+ {
+ if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) {
+ MovieTrackingPlaneMarker *plane_marker =
+ BKE_tracking_plane_marker_get(plane_track, framenr);
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (BLI_rctf_isect_pt_v(&rectf, plane_marker->corners[i])) {
+ if (mode == GESTURE_MODAL_SELECT) {
+ plane_track->flag |= SELECT;
+ }
+ else {
+ plane_track->flag &= ~SELECT;
+ }
+ }
+ else if (!extend) {
+ plane_track->flag &= ~SELECT;
+ }
+ }
+
+ change = TRUE;
+ }
+ }
+
if (change) {
BKE_tracking_dopesheet_tag_update(tracking);
@@ -430,7 +565,9 @@ static int do_lasso_select_marker(bContext *C, const int mcords[][2], const shor
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
MovieTrackingTrack *track;
+ MovieTrackingPlaneTrack *plane_track;
ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+ ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
rcti rect;
int change = FALSE;
int framenr = ED_space_clip_get_clip_frame_number(sc);
@@ -466,6 +603,37 @@ static int do_lasso_select_marker(bContext *C, const int mcords[][2], const shor
track = track->next;
}
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = plane_track->next)
+ {
+ if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) {
+ MovieTrackingPlaneMarker *plane_marker =
+ BKE_tracking_plane_marker_get(plane_track, framenr);
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ float screen_co[2];
+
+ /* marker in screen coords */
+ ED_clip_point_stable_pos__reverse(sc, ar, plane_marker->corners[i], screen_co);
+
+ if (BLI_rcti_isect_pt(&rect, screen_co[0], screen_co[1]) &&
+ BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], V2D_IS_CLIPPED))
+ {
+ if (select) {
+ plane_track->flag |= SELECT;
+ }
+ else {
+ plane_track->flag &= ~SELECT;
+ }
+ }
+ }
+
+ change = TRUE;
+ }
+ }
+
if (change) {
BKE_tracking_dopesheet_tag_update(tracking);
@@ -518,17 +686,22 @@ void CLIP_OT_select_lasso(wmOperatorType *ot)
/********************** circle select operator *********************/
-static int marker_inside_ellipse(MovieTrackingMarker *marker, float offset[2], float ellipse[2])
+static int point_inside_ellipse(float point[2], float offset[2], float ellipse[2])
{
/* normalized ellipse: ell[0] = scaleX, ell[1] = scaleY */
float x, y;
- x = (marker->pos[0] - offset[0]) * ellipse[0];
- y = (marker->pos[1] - offset[1]) * ellipse[1];
+ x = (point[0] - offset[0]) * ellipse[0];
+ y = (point[1] - offset[1]) * ellipse[1];
return x * x + y * y < 1.0f;
}
+static int marker_inside_ellipse(MovieTrackingMarker *marker, float offset[2], float ellipse[2])
+{
+ return point_inside_ellipse(marker->pos, offset, ellipse);
+}
+
static int circle_select_exec(bContext *C, wmOperator *op)
{
SpaceClip *sc = CTX_wm_space_clip(C);
@@ -537,7 +710,9 @@ static int circle_select_exec(bContext *C, wmOperator *op)
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
MovieTrackingTrack *track;
+ MovieTrackingPlaneTrack *plane_track;
ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+ ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
int x, y, radius, width, height, mode, change = FALSE;
float zoomx, zoomy, offset[2], ellipse[2];
int framenr = ED_space_clip_get_clip_frame_number(sc);
@@ -577,6 +752,30 @@ static int circle_select_exec(bContext *C, wmOperator *op)
track = track->next;
}
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = plane_track->next)
+ {
+ if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) {
+ MovieTrackingPlaneMarker *plane_marker =
+ BKE_tracking_plane_marker_get(plane_track, framenr);
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (point_inside_ellipse(plane_marker->corners[i], offset, ellipse)) {
+ if (mode == GESTURE_MODAL_SELECT) {
+ plane_track->flag |= SELECT;
+ }
+ else {
+ plane_track->flag &= ~SELECT;
+ }
+ }
+ }
+
+ change = TRUE;
+ }
+ }
+
if (change) {
BKE_tracking_dopesheet_tag_update(tracking);
@@ -619,16 +818,18 @@ static int select_all_exec(bContext *C, wmOperator *op)
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
MovieTrackingTrack *track = NULL; /* selected track */
+ MovieTrackingPlaneTrack *plane_track = NULL; /* selected plane track */
MovieTrackingMarker *marker;
ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+ ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
int action = RNA_enum_get(op->ptr, "action");
int framenr = ED_space_clip_get_clip_frame_number(sc);
int has_selection = FALSE;
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
- track = tracksbase->first;
- while (track) {
+
+ for (track = tracksbase->first; track; track = track->next) {
if (TRACK_VIEW_SELECTED(sc, track)) {
marker = BKE_tracking_marker_get(track, framenr);
@@ -637,13 +838,20 @@ static int select_all_exec(bContext *C, wmOperator *op)
break;
}
}
+ }
- track = track->next;
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = plane_track->next)
+ {
+ if (plane_track->flag & SELECT) {
+ action = SEL_DESELECT;
+ break;
+ }
}
}
- track = tracksbase->first;
- while (track) {
+ for (track = tracksbase->first; track; track = track->next) {
if ((track->flag & TRACK_HIDDEN) == 0) {
marker = BKE_tracking_marker_get(track, framenr);
@@ -670,8 +878,29 @@ static int select_all_exec(bContext *C, wmOperator *op)
if (TRACK_VIEW_SELECTED(sc, track))
has_selection = TRUE;
+ }
- track = track->next;
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = plane_track->next)
+ {
+ if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) {
+ switch (action) {
+ case SEL_SELECT:
+ plane_track->flag |= SELECT;
+ break;
+ case SEL_DESELECT:
+ plane_track->flag &= ~SELECT;
+ break;
+ case SEL_INVERT:
+ plane_track->flag ^= SELECT;
+ break;
+ }
+ }
+
+ if (plane_track->flag & SELECT) {
+ has_selection = TRUE;
+ }
}
if (!has_selection)