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; }
void PlaneTrackCommonOperation::initExecution() { MovieTracking *tracking; MovieTrackingObject *object; memset(this->m_corners, 0, sizeof(this->m_corners)); memset(this->m_frameSpaceCorners, 0, sizeof(this->m_frameSpaceCorners)); if (!this->m_movieClip) return; tracking = &this->m_movieClip->tracking; object = BKE_tracking_object_get_named(tracking, this->m_trackingObjectName); if (object) { MovieTrackingPlaneTrack *plane_track; plane_track = BKE_tracking_plane_track_get_named(tracking, object, this->m_planeTrackName); if (plane_track) { MovieTrackingPlaneMarker *plane_marker; int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(this->m_movieClip, this->m_framenumber); plane_marker = BKE_tracking_plane_marker_get(plane_track, clip_framenr); memcpy(this->m_corners, plane_marker->corners, sizeof(this->m_corners)); } } for (int i = 0; i < 4; i++) { this->m_frameSpaceCorners[i][0] = this->m_corners[i][0] * this->getWidth(); this->m_frameSpaceCorners[i][1] = this->m_corners[i][1] * this->getHeight(); } }
static MovieTrackingPlaneTrack *tracking_plane_marker_check_slide( bContext *C, const wmEvent *event, int *corner_r) { const float distance_clip_squared = 12.0f * 12.0f; SpaceClip *sc = CTX_wm_space_clip(C); ARegion *ar = CTX_wm_region(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; int width, height; float co[2]; ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); int framenr = ED_space_clip_get_clip_frame_number(sc); ED_space_clip_get_size(sc, &width, &height); if (width == 0 || height == 0) { return NULL; } ED_clip_mouse_pos(sc, ar, event->mval, co); float min_distance_squared = FLT_MAX; int min_corner = -1; MovieTrackingPlaneTrack *min_plane_track = NULL; for (MovieTrackingPlaneTrack *plane_track = plane_tracks_base->first; plane_track != NULL; plane_track = plane_track->next) { if (PLANE_TRACK_VIEW_SELECTED(plane_track)) { MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr); for (int i = 0; i < 4; i++) { float distance_squared = mouse_to_plane_slide_zone_distance_squared( co, plane_marker->corners[i], width, height); if (distance_squared < min_distance_squared) { min_distance_squared = distance_squared; min_corner = i; min_plane_track = plane_track; } } } } if (min_distance_squared < distance_clip_squared / sc->zoom) { if (corner_r != NULL) { *corner_r = min_corner; } return min_plane_track; } return NULL; }
static void draw_plane_track(SpaceClip *sc, Scene *scene, MovieTrackingPlaneTrack *plane_track, int framenr, bool is_active_track, int width, int height) { MovieTrackingPlaneMarker *plane_marker; plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr); draw_plane_marker_outline(sc, scene, plane_track, plane_marker, width, height); draw_plane_marker(sc, scene, plane_track, plane_marker, is_active_track, width, height); }
static MovieTrackingPlaneMarker *find_plane_keyframe(MovieTrackingPlaneTrack *plane_track, int start_frame, int direction) { MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, start_frame); int index = plane_marker - plane_track->markers; int frame_delta = direction > 0 ? 1 : -1; while (index >= 0 && index < plane_track->markersnr) { if ((plane_marker->flag & PLANE_MARKER_TRACKED) == 0) { return plane_marker; } plane_marker += frame_delta; } return NULL; }
static void rna_Mask_update_parent(Main *bmain, Scene *scene, PointerRNA *ptr) { MaskParent *parent = ptr->data; if (parent->id) { if (GS(parent->id->name) == ID_MC) { MovieClip *clip = (MovieClip *) parent->id; MovieTracking *tracking = &clip->tracking; MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, parent->parent); if (object) { int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, scene->r.cfra); if (parent->type == MASK_PARENT_POINT_TRACK) { MovieTrackingTrack *track = BKE_tracking_track_get_named(tracking, object, parent->sub_parent); if (track) { MovieTrackingMarker *marker = BKE_tracking_marker_get(track, clip_framenr); float marker_pos_ofs[2], parmask_pos[2]; MovieClipUser user = {0}; BKE_movieclip_user_set_frame(&user, scene->r.cfra); add_v2_v2v2(marker_pos_ofs, marker->pos, track->offset); BKE_mask_coord_from_movieclip(clip, &user, parmask_pos, marker_pos_ofs); copy_v2_v2(parent->parent_orig, parmask_pos); } } else /* if (parent->type == MASK_PARENT_PLANE_TRACK) */ { MovieTrackingPlaneTrack *plane_track = BKE_tracking_plane_track_get_named(tracking, object, parent->sub_parent); if (plane_track) { MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, clip_framenr); memcpy(parent->parent_corners_orig, plane_marker->corners, sizeof(parent->parent_corners_orig)); zero_v2(parent->parent_orig); } } } } } rna_Mask_update_data(bmain, scene, ptr); }
/* NOTE: frame number should be in clip space, not scene space */ static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_track, int start_frame, int direction, bool retrack) { MovieTrackingPlaneMarker *start_plane_marker = BKE_tracking_plane_marker_get(plane_track, start_frame); MovieTrackingPlaneMarker *keyframe_plane_marker = NULL; MovieTrackingPlaneMarker new_plane_marker; int current_frame, frame_delta = direction > 0 ? 1 : -1; if (plane_track->flag & PLANE_TRACK_AUTOKEY) { /* Find a keyframe in given direction. */ for (current_frame = start_frame; ; current_frame += frame_delta) { MovieTrackingPlaneMarker *next_plane_marker = BKE_tracking_plane_marker_get_exact(plane_track, current_frame + frame_delta); if (next_plane_marker == NULL) { break; } if ((next_plane_marker->flag & PLANE_MARKER_TRACKED) == 0) { keyframe_plane_marker = next_plane_marker; break; } } } else { start_plane_marker->flag |= PLANE_MARKER_TRACKED; } new_plane_marker = *start_plane_marker; new_plane_marker.flag |= PLANE_MARKER_TRACKED; for (current_frame = start_frame; ; current_frame += frame_delta) { MovieTrackingPlaneMarker *next_plane_marker = BKE_tracking_plane_marker_get_exact(plane_track, current_frame + frame_delta); Vec2 *x1, *x2; int i, num_correspondences; double H_double[3][3]; float H[3][3]; /* As soon as we meet keyframed plane, we stop updating the sequence. */ if (next_plane_marker && (next_plane_marker->flag & PLANE_MARKER_TRACKED) == 0) { /* Don't override keyframes if track is in auto-keyframe mode */ if (plane_track->flag & PLANE_TRACK_AUTOKEY) { break; } } num_correspondences = point_markers_correspondences_on_both_image(plane_track, current_frame, current_frame + frame_delta, &x1, &x2); if (num_correspondences < 4) { MEM_freeN(x1); MEM_freeN(x2); break; } libmv_homography2DFromCorrespondencesEuc(x1, x2, num_correspondences, H_double); copy_m3_m3d(H, H_double); for (i = 0; i < 4; i++) { float vec[3] = {0.0f, 0.0f, 1.0f}, vec2[3]; copy_v2_v2(vec, new_plane_marker.corners[i]); /* Apply homography */ mul_v3_m3v3(vec2, H, vec); /* Normalize. */ vec2[0] /= vec2[2]; vec2[1] /= vec2[2]; copy_v2_v2(new_plane_marker.corners[i], vec2); } new_plane_marker.framenr = current_frame + frame_delta; if (!retrack && keyframe_plane_marker && next_plane_marker && (plane_track->flag & PLANE_TRACK_AUTOKEY)) { float fac = ((float) next_plane_marker->framenr - start_plane_marker->framenr) / ((float) keyframe_plane_marker->framenr - start_plane_marker->framenr); fac = 3 * fac * fac - 2 * fac * fac * fac; for (i = 0; i < 4; i++) { interp_v2_v2v2(new_plane_marker.corners[i], new_plane_marker.corners[i], next_plane_marker->corners[i], fac); } } BKE_tracking_plane_marker_insert(plane_track, &new_plane_marker); MEM_freeN(x1); MEM_freeN(x2); } }
static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) { Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; /* parent info */ SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking; MovieTrackingTrack *track; MovieTrackingPlaneTrack *plane_track; MovieTrackingObject *tracking_object; /* done */ int framenr, parent_type; float parmask_pos[2], orig_corners[4][2]; char *sub_parent_name; if (ELEM(NULL, sc, clip)) { return OPERATOR_CANCELLED; } framenr = ED_space_clip_get_clip_frame_number(sc); tracking = &clip->tracking; tracking_object = BKE_tracking_object_get_active(&clip->tracking); if (tracking_object == NULL) { return OPERATOR_CANCELLED; } if ((track = BKE_tracking_track_get_active(tracking)) != NULL) { MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); float marker_pos_ofs[2]; add_v2_v2v2(marker_pos_ofs, marker->pos, track->offset); BKE_mask_coord_from_movieclip(clip, &sc->user, parmask_pos, marker_pos_ofs); sub_parent_name = track->name; parent_type = MASK_PARENT_POINT_TRACK; memset(orig_corners, 0, sizeof(orig_corners)); } else if ((plane_track = BKE_tracking_plane_track_get_active(tracking)) != NULL) { MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr); zero_v2(parmask_pos); sub_parent_name = plane_track->name; parent_type = MASK_PARENT_PLANE_TRACK; memcpy(orig_corners, plane_marker->corners, sizeof(orig_corners)); } else { return OPERATOR_CANCELLED; } for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; int i; if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } for (spline = masklay->splines.first; spline; spline = spline->next) { for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; if (MASKPOINT_ISSEL_ANY(point)) { point->parent.id_type = ID_MC; point->parent.id = &clip->id; point->parent.type = parent_type; BLI_strncpy(point->parent.parent, tracking_object->name, sizeof(point->parent.parent)); BLI_strncpy(point->parent.sub_parent, sub_parent_name, sizeof(point->parent.sub_parent)); copy_v2_v2(point->parent.parent_orig, parmask_pos); memcpy(point->parent.parent_corners_orig, orig_corners, sizeof(point->parent.parent_corners_orig)); } } } } WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); DAG_id_tag_update(&mask->id, 0); return OPERATOR_FINISHED; }
static int circle_select_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); ARegion *ar = CTX_wm_region(C); 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; bool changed = false; float zoomx, zoomy, offset[2], ellipse[2]; int framenr = ED_space_clip_get_clip_frame_number(sc); /* get operator properties */ x = RNA_int_get(op->ptr, "x"); y = RNA_int_get(op->ptr, "y"); radius = RNA_int_get(op->ptr, "radius"); mode = RNA_int_get(op->ptr, "gesture_mode"); /* compute ellipse and position in unified coordinates */ ED_space_clip_get_size(sc, &width, &height); ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy); ellipse[0] = width * zoomx / radius; ellipse[1] = height * zoomy / radius; ED_clip_point_stable_pos(sc, ar, x, y, &offset[0], &offset[1]); /* do selection */ track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker) && marker_inside_ellipse(marker, offset, ellipse)) { if (mode == GESTURE_MODAL_SELECT) BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); else BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); changed = 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) { 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; } } } changed = true; } } if (changed) { BKE_tracking_dopesheet_tag_update(tracking); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); return OPERATOR_FINISHED; } return OPERATOR_CANCELLED; }
static int do_lasso_select_marker(bContext *C, const int mcords[][2], const short moves, bool select) { SpaceClip *sc = CTX_wm_space_clip(C); ARegion *ar = CTX_wm_region(C); 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; bool changed = false; int framenr = ED_space_clip_get_clip_frame_number(sc); /* get rectangle from operator */ BLI_lasso_boundbox(&rect, mcords, moves); /* do actual selection */ track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { float screen_co[2]; /* marker in screen coords */ ED_clip_point_stable_pos__reverse(sc, ar, marker->pos, 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) BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); else BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); } changed = 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) { 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; } } } changed = true; } } if (changed) { BKE_tracking_dopesheet_tag_update(tracking); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); } return changed; }
static int border_select_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); ARegion *ar = CTX_wm_region(C); 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; bool changed = false; int mode, extend; int framenr = ED_space_clip_get_clip_frame_number(sc); /* get rectangle from operator */ WM_operator_properties_border_to_rcti(op, &rect); ED_clip_point_stable_pos(sc, ar, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin); ED_clip_point_stable_pos(sc, ar, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax); mode = RNA_int_get(op->ptr, "gesture_mode"); extend = RNA_boolean_get(op->ptr, "extend"); /* do actual selection */ track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { if (BLI_rctf_isect_pt_v(&rectf, marker->pos)) { if (mode == GESTURE_MODAL_SELECT) BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); else BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); } else if (!extend) { BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); } changed = 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) { 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; } } changed = true; } } if (changed) { BKE_tracking_dopesheet_tag_update(tracking); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); return OPERATOR_FINISHED; } return OPERATOR_CANCELLED; }