void clip_graph_tracking_iterate(SpaceClip *sc, void *userdata, void (*func) (void *userdata, MovieTrackingMarker *marker)) { MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; MovieTrackingTrack *track; track= tracking->tracks.first; while(track) { if(TRACK_VIEW_SELECTED(sc, track)) { int i; for(i= 0; i<track->markersnr; i++) { MovieTrackingMarker *marker= &track->markers[i]; if(marker->flag&MARKER_DISABLED) continue; if(func) func(userdata, marker); } } track= track->next; } }
static int set_origin_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; Scene *scene = CTX_data_scene(C); Object *camera = get_camera_with_movieclip(scene, clip); int selected_count = count_selected_bundles(C); if (selected_count == 0) { BKE_report(op->reports, RPT_ERROR, "At least one track with bundle should be selected to " "define origin position"); return OPERATOR_CANCELLED; } Object *object = get_orientation_object(C); if (object == NULL) { BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); return OPERATOR_CANCELLED; } MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object); float median[3] = {0.0f, 0.0f, 0.0f}; zero_v3(median); for (MovieTrackingTrack *track = tracksbase->first; track != NULL; track = track->next) { if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_HAS_BUNDLE)) { add_v3_v3(median, track->bundle_pos); } } mul_v3_fl(median, 1.0f / selected_count); float mat[4][4], vec[3]; BKE_tracking_get_camera_object_matrix(scene, camera, mat); mul_v3_m4v3(vec, mat, median); if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { sub_v3_v3(object->loc, vec); } else { object_solver_inverted_matrix(scene, object, mat); mul_v3_m4v3(vec, mat, vec); copy_v3_v3(object->loc, vec); } DEG_id_tag_update(&clip->id, 0); DEG_id_tag_update(&object->id, ID_RECALC_TRANSFORM); WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); return OPERATOR_FINISHED; }
static int count_selected_bundles(bContext *C) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); int tot = 0; for (MovieTrackingTrack *track = tracksbase->first; track != NULL; track = track->next) { if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_HAS_BUNDLE)) { tot++; } } return tot; }
static bool selected_boundbox(SpaceClip *sc, float min[2], float max[2]) { MovieClip *clip = ED_space_clip_get_clip(sc); MovieTrackingTrack *track; int width, height; bool ok = false; ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); int framenr = ED_space_clip_get_clip_frame_number(sc); INIT_MINMAX2(min, max); ED_space_clip_get_size(sc, &width, &height); track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track)) { MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); if (marker) { float pos[3]; pos[0] = marker->pos[0] + track->offset[0]; pos[1] = marker->pos[1] + track->offset[1]; pos[2] = 0.0f; /* undistortion happens for normalized coords */ if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) { /* undistortion happens for normalized coords */ ED_clip_point_undistorted_pos(sc, pos, pos); } pos[0] *= width; pos[1] *= height; mul_v3_m4v3(pos, sc->stabmat, pos); minmax_v2v2_v2(min, max, pos); ok = true; } } track = track->next; } return ok; }
static int set_axis_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); Scene *scene = CTX_data_scene(C); Object *object; int axis = RNA_enum_get(op->ptr, "axis"); if (count_selected_bundles(C) != 1) { BKE_report(op->reports, RPT_ERROR, "Single track with bundle should be selected to define axis"); return OPERATOR_CANCELLED; } object = get_orientation_object(C); if (object == NULL) { BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); return OPERATOR_CANCELLED; } ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object); MovieTrackingTrack *track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_HAS_BUNDLE)) { break; } track = track->next; } set_axis(scene, object, clip, tracking_object, track, axis == 0 ? 'X' : 'Y'); DAG_id_tag_update(&clip->id, 0); DAG_id_tag_update(&object->id, OB_RECALC_OB); WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); return OPERATOR_FINISHED; }
void clip_graph_tracking_values_iterate(SpaceClip *sc, void *userdata, void (*func) (void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, float val), void (*segment_start) (void *userdata, MovieTrackingTrack *track, int coord), void (*segment_end) (void *userdata)) { MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; MovieTrackingTrack *track; track= tracking->tracks.first; while(track) { if(TRACK_VIEW_SELECTED(sc, track)) { clip_graph_tracking_values_iterate_track(sc, track, userdata, func, segment_start, segment_end); } track= track->next; } }
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); MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); MovieTrackingTrack *track = NULL; /* selected marker */ track = find_nearest_track(sc, tracksbase, co); if (track) { int area = track_mouse_area(C, co, track); if (!extend || !TRACK_VIEW_SELECTED(sc, track)) area = TRACK_AREA_ALL; if (extend && TRACK_AREA_SELECTED(track, area)) { if (track == act_track) BKE_tracking_track_deselect(track, area); else clip->tracking.act_track = track; } else { if (area == TRACK_AREA_POINT) area = TRACK_AREA_ALL; BKE_tracking_track_select(tracksbase, track, area, extend); clip->tracking.act_track = track; } } if (!extend) { sc->xlockof = 0.0f; sc->ylockof = 0.0f; } BKE_tracking_dopesheet_tag_update(tracking); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); return OPERATOR_FINISHED; }
static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbase, float co[2], float *distance_r) { MovieTrackingTrack *track = NULL, *cur; float mindist = 0.0f; int framenr = ED_space_clip_get_clip_frame_number(sc); cur = tracksbase->first; while (cur) { MovieTrackingMarker *marker = BKE_tracking_marker_get(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])); /* distance to pattern boundbox */ if (sc->flag & SC_SHOW_MARKER_PATTERN) 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, marker->search_min, marker->search_max); /* choose minimal distance. useful for cases of overlapped markers. */ dist = min_fff(d1, d2, d3); if (track == NULL || dist < mindist) { track = cur; mindist = dist; } } cur = cur->next; } *distance_r = mindist; return track; }
static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, const float marker_pos[2], int width, int height, int act, int sel) { int tiny = sc->flag & SC_SHOW_TINY_MARKER; bool show_search = false; float col[3], scol[3], px[2]; track_colors(track, act, col, scol); px[0] = 1.0f / width / sc->zoom; px[1] = 1.0f / height / sc->zoom; /* marker position and offset position */ if ((track->flag & SELECT) == sel && (marker->flag & MARKER_DISABLED) == 0) { float pos[2], p[2]; if (track->flag & TRACK_LOCKED) { if (act) UI_ThemeColor(TH_ACT_MARKER); else if (track->flag & SELECT) UI_ThemeColorShade(TH_LOCK_MARKER, 64); else UI_ThemeColor(TH_LOCK_MARKER); } else { if (track->flag & SELECT) glColor3fv(scol); else glColor3fv(col); } add_v2_v2v2(pos, marker->pos, track->offset); ED_clip_point_undistorted_pos(sc, pos, pos); 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); glBegin(GL_POINTS); glVertex2f(pos[0], pos[1]); glEnd(); if (!tiny) glPointSize(1.0f); } else { glBegin(GL_LINES); glVertex2f(pos[0] + px[0] * 3, pos[1]); glVertex2f(pos[0] + px[0] * 7, pos[1]); glVertex2f(pos[0] - px[0] * 3, pos[1]); glVertex2f(pos[0] - px[0] * 7, pos[1]); glVertex2f(pos[0], pos[1] - px[1] * 3); glVertex2f(pos[0], pos[1] - px[1] * 7); glVertex2f(pos[0], pos[1] + px[1] * 3); glVertex2f(pos[0], pos[1] + px[1] * 7); glEnd(); glColor3f(0.0f, 0.0f, 0.0f); glLineStipple(3, 0xaaaa); glEnable(GL_LINE_STIPPLE); glEnable(GL_COLOR_LOGIC_OP); glLogicOp(GL_NOR); glBegin(GL_LINES); glVertex2fv(pos); glVertex2fv(marker_pos); glEnd(); glDisable(GL_COLOR_LOGIC_OP); glDisable(GL_LINE_STIPPLE); } } /* pattern */ glPushMatrix(); glTranslatef(marker_pos[0], marker_pos[1], 0); if (tiny) { glLineStipple(3, 0xaaaa); glEnable(GL_LINE_STIPPLE); } if ((track->pat_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_PATTERN)) { 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); } glBegin(GL_LINE_LOOP); glVertex2fv(marker->pattern_corners[0]); glVertex2fv(marker->pattern_corners[1]); glVertex2fv(marker->pattern_corners[2]); glVertex2fv(marker->pattern_corners[3]); glEnd(); } /* search */ show_search = (TRACK_VIEW_SELECTED(sc, track) && ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) != 0; if ((track->search_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_SEARCH) && show_search) { if (track->flag & TRACK_LOCKED) { if (act) UI_ThemeColor(TH_ACT_MARKER); else if (track->search_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->search_flag & SELECT) UI_ThemeColorShade(TH_DIS_MARKER, 128); else UI_ThemeColor(TH_DIS_MARKER); } else { if (track->search_flag & SELECT) glColor3fv(scol); else glColor3fv(col); } glBegin(GL_LINE_LOOP); 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(); } if (tiny) glDisable(GL_LINE_STIPPLE); glPopMatrix(); }
static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, const float marker_pos[2], int width, int height) { int tiny = sc->flag & SC_SHOW_TINY_MARKER; bool show_search = false; float px[2]; UI_ThemeColor(TH_MARKER_OUTLINE); px[0] = 1.0f / width / sc->zoom; px[1] = 1.0f / height / sc->zoom; if ((marker->flag & MARKER_DISABLED) == 0) { float pos[2]; float p[2]; add_v2_v2v2(pos, marker->pos, track->offset); ED_clip_point_undistorted_pos(sc, pos, pos); 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); glVertex2f(pos[0], pos[1]); glEnd(); glPointSize(1.0f); } else { if (!tiny) glLineWidth(3.0f); glBegin(GL_LINES); glVertex2f(pos[0] + px[0] * 2, pos[1]); glVertex2f(pos[0] + px[0] * 8, pos[1]); glVertex2f(pos[0] - px[0] * 2, pos[1]); glVertex2f(pos[0] - px[0] * 8, pos[1]); glVertex2f(pos[0], pos[1] - px[1] * 2); glVertex2f(pos[0], pos[1] - px[1] * 8); glVertex2f(pos[0], pos[1] + px[1] * 2); glVertex2f(pos[0], pos[1] + px[1] * 8); glEnd(); if (!tiny) glLineWidth(1.0f); } } /* pattern and search outline */ glPushMatrix(); glTranslatef(marker_pos[0], marker_pos[1], 0); if (!tiny) glLineWidth(3.0f); if (sc->flag & SC_SHOW_MARKER_PATTERN) { glBegin(GL_LINE_LOOP); glVertex2fv(marker->pattern_corners[0]); glVertex2fv(marker->pattern_corners[1]); glVertex2fv(marker->pattern_corners[2]); glVertex2fv(marker->pattern_corners[3]); glEnd(); } show_search = (TRACK_VIEW_SELECTED(sc, track) && ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) != 0; if (sc->flag & SC_SHOW_MARKER_SEARCH && show_search) { glBegin(GL_LINE_LOOP); 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(); if (!tiny) glLineWidth(1.0f); }
static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackingTrack *track) { int count = sc->path_length; int i, a, b, curindex = -1; float path[102][2]; int tiny = sc->flag & SC_SHOW_TINY_MARKER, framenr, start_frame; MovieTrackingMarker *marker; if (count == 0) return; start_frame = framenr = ED_space_clip_get_clip_frame_number(sc); marker = BKE_tracking_marker_get(track, framenr); if (marker->framenr != framenr || marker->flag & MARKER_DISABLED) return; a = count; i = framenr - 1; while (i >= framenr - count) { marker = BKE_tracking_marker_get(track, i); if (!marker || marker->flag & MARKER_DISABLED) break; if (marker->framenr == i) { add_v2_v2v2(path[--a], marker->pos, track->offset); ED_clip_point_undistorted_pos(sc, path[a], path[a]); if (marker->framenr == start_frame) curindex = a; } else { break; } i--; } b = count; i = framenr; while (i <= framenr + count) { marker = BKE_tracking_marker_get(track, i); if (!marker || marker->flag & MARKER_DISABLED) break; if (marker->framenr == i) { if (marker->framenr == start_frame) curindex = b; add_v2_v2v2(path[b++], marker->pos, track->offset); ED_clip_point_undistorted_pos(sc, path[b - 1], path[b - 1]); } else break; i++; } if (!tiny) { UI_ThemeColor(TH_MARKER_OUTLINE); if (TRACK_VIEW_SELECTED(sc, track)) { glPointSize(5.0f); glBegin(GL_POINTS); for (i = a; i < b; i++) { if (i != curindex) glVertex2f(path[i][0], path[i][1]); } glEnd(); } glLineWidth(3.0f); glBegin(GL_LINE_STRIP); for (i = a; i < b; i++) glVertex2f(path[i][0], path[i][1]); glEnd(); glLineWidth(1.0f); } UI_ThemeColor(TH_PATH_BEFORE); if (TRACK_VIEW_SELECTED(sc, track)) { glPointSize(3.0f); glBegin(GL_POINTS); for (i = a; i < b; i++) { if (i == count + 1) UI_ThemeColor(TH_PATH_AFTER); if (i != curindex) glVertex2f(path[i][0], path[i][1]); } glEnd(); } UI_ThemeColor(TH_PATH_BEFORE); glBegin(GL_LINE_STRIP); for (i = a; i < b; i++) { if (i == count + 1) UI_ThemeColor(TH_PATH_AFTER); glVertex2f(path[i][0], path[i][1]); } glEnd(); glPointSize(1.0f); }
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; 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; } } if (!extend) { delect_all_plane_tracks(plane_tracks_base); } if (track) { int area = track_mouse_area(C, co, track); if (!extend || !TRACK_VIEW_SELECTED(sc, track)) area = TRACK_AREA_ALL; if (extend && TRACK_AREA_SELECTED(track, area)) { if (track == act_track) { BKE_tracking_track_deselect(track, area); } else { clip->tracking.act_track = track; clip->tracking.act_plane_track = NULL; } } else { if (area == TRACK_AREA_POINT) area = TRACK_AREA_ALL; 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_VIEW_SELECTED(plane_track)) { 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) { sc->xlockof = 0.0f; sc->ylockof = 0.0f; } BKE_tracking_dopesheet_tag_update(tracking); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); return OPERATOR_FINISHED; }
static int do_set_scale(bContext *C, wmOperator *op, bool scale_solution, bool apply_scale) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); MovieTrackingTrack *track; Scene *scene = CTX_data_scene(C); Object *object = NULL; Object *camera = get_camera_with_movieclip(scene, clip); ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); int tot = 0; float vec[2][3], mat[4][4], scale; float dist = RNA_float_get(op->ptr, "distance"); if (count_selected_bundles(C) != 2) { BKE_report(op->reports, RPT_ERROR, "Two tracks with bundles should be selected to set scale"); return OPERATOR_CANCELLED; } if (!scale_solution && !apply_scale) { object = get_orientation_object(C); if (object == NULL) { BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); return OPERATOR_CANCELLED; } } BKE_tracking_get_camera_object_matrix(scene, camera, mat); track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track)) { mul_v3_m4v3(vec[tot], mat, track->bundle_pos); tot++; } track = track->next; } sub_v3_v3(vec[0], vec[1]); if (len_v3(vec[0]) > 1e-5f) { scale = dist / len_v3(vec[0]); if (apply_scale) { /* Apply scale on reconstructed scene itself. */ MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction( tracking); MovieReconstructedCamera *reconstructed_cameras; int i; for (track = tracksbase->first; track; track = track->next) { mul_v3_fl(track->bundle_pos, scale); } reconstructed_cameras = reconstruction->cameras; for (i = 0; i < reconstruction->camnr; i++) { mul_v3_fl(reconstructed_cameras[i].mat[3], scale); } WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); } else { if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { mul_v3_fl(object->scale, scale); mul_v3_fl(object->loc, scale); } else if (!scale_solution) { Object *solver_camera = object_solver_camera(scene, object); object->scale[0] = object->scale[1] = object->scale[2] = 1.0f / scale; if (solver_camera) { object->scale[0] /= solver_camera->scale[0]; object->scale[1] /= solver_camera->scale[1]; object->scale[2] /= solver_camera->scale[2]; } } else { tracking_object->scale = scale; } DEG_id_tag_update(&clip->id, 0); if (object) { DEG_id_tag_update(&object->id, ID_RECALC_TRANSFORM); } WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); } } return OPERATOR_FINISHED; }
static int set_plane_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); Scene *scene = CTX_data_scene(C); MovieTracking *tracking = &clip->tracking; MovieTrackingObject *tracking_object; MovieTrackingTrack *track, *axis_track = NULL, *act_track; ListBase *tracksbase; Object *object; Object *camera = get_camera_with_movieclip(scene, clip); Depsgraph *depsgraph = CTX_data_depsgraph(C); int tot = 0; float vec[3][3], mat[4][4], obmat[4][4], newmat[4][4], orig[3] = {0.0f, 0.0f, 0.0f}; int plane = RNA_enum_get(op->ptr, "plane"); float rot[4][4] = { {0.0f, 0.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 1.0f}, }; /* 90 degrees Y-axis rotation matrix */ if (count_selected_bundles(C) != 3) { BKE_report(op->reports, RPT_ERROR, "Three tracks with bundles are needed to orient the floor"); return OPERATOR_CANCELLED; } tracking_object = BKE_tracking_object_get_active(tracking); tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object); act_track = BKE_tracking_track_get_active(tracking); object = get_orientation_object(C); if (object == NULL) { BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); return OPERATOR_CANCELLED; } BKE_tracking_get_camera_object_matrix(scene, camera, mat); /* Get 3 bundles to use as reference. */ track = tracksbase->first; while (track && tot < 3) { if (track->flag & TRACK_HAS_BUNDLE && TRACK_VIEW_SELECTED(sc, track)) { mul_v3_m4v3(vec[tot], mat, track->bundle_pos); if (tot == 0 || track == act_track) { copy_v3_v3(orig, vec[tot]); } else { axis_track = track; } tot++; } track = track->next; } sub_v3_v3(vec[1], vec[0]); sub_v3_v3(vec[2], vec[0]); /* Construct ortho-normal basis. */ unit_m4(mat); if (plane == 0) { /* floor */ cross_v3_v3v3(mat[0], vec[1], vec[2]); copy_v3_v3(mat[1], vec[1]); cross_v3_v3v3(mat[2], mat[0], mat[1]); } else if (plane == 1) { /* wall */ cross_v3_v3v3(mat[2], vec[1], vec[2]); copy_v3_v3(mat[1], vec[1]); cross_v3_v3v3(mat[0], mat[1], mat[2]); } normalize_v3(mat[0]); normalize_v3(mat[1]); normalize_v3(mat[2]); /* Move to origin point. */ mat[3][0] = orig[0]; mat[3][1] = orig[1]; mat[3][2] = orig[2]; if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { invert_m4(mat); BKE_object_to_mat4(object, obmat); mul_m4_m4m4(mat, mat, obmat); mul_m4_m4m4(newmat, rot, mat); BKE_object_apply_mat4(object, newmat, 0, 0); /* Make camera have positive z-coordinate. */ if (object->loc[2] < 0) { invert_m4(rot); mul_m4_m4m4(newmat, rot, mat); BKE_object_apply_mat4(object, newmat, 0, 0); } } else { BKE_object_apply_mat4(object, mat, 0, 0); } BKE_object_where_is_calc(depsgraph, scene, object); set_axis(scene, object, clip, tracking_object, axis_track, 'X'); DEG_id_tag_update(&clip->id, 0); DEG_id_tag_update(&object->id, ID_RECALC_TRANSFORM); WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); return OPERATOR_FINISHED; }
static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, const float marker_pos[2], int outline, int sel, int act, int width, int height) { float dx, dy, patdx, patdy, searchdx, searchdy; int tiny = sc->flag & SC_SHOW_TINY_MARKER; float col[3], scol[3], px[2], side; if ((tiny && outline) || (marker->flag & MARKER_DISABLED)) return; if (!TRACK_VIEW_SELECTED(sc, track) || track->flag & TRACK_LOCKED) return; track_colors(track, act, col, scol); if (outline) { glLineWidth(3.0f); UI_ThemeColor(TH_MARKER_OUTLINE); } glPushMatrix(); glTranslatef(marker_pos[0], marker_pos[1], 0); dx = 6.0f / width / sc->zoom; dy = 6.0f / height / sc->zoom; side = get_shortest_pattern_side(marker); patdx = min_ff(dx * 2.0f / 3.0f, side / 6.0f) * UI_DPI_FAC; patdy = min_ff(dy * 2.0f / 3.0f, side * width / height / 6.0f) * UI_DPI_FAC; searchdx = min_ff(dx, (marker->search_max[0] - marker->search_min[0]) / 6.0f) * UI_DPI_FAC; searchdy = min_ff(dy, (marker->search_max[1] - marker->search_min[1]) / 6.0f) * UI_DPI_FAC; px[0] = 1.0f / sc->zoom / width / sc->scale; px[1] = 1.0f / sc->zoom / height / sc->scale; if ((sc->flag & SC_SHOW_MARKER_SEARCH) && ((track->search_flag & SELECT) == sel || outline)) { if (!outline) { if (track->search_flag & SELECT) glColor3fv(scol); else glColor3fv(col); } /* search offset square */ draw_marker_slide_square(marker->search_min[0], marker->search_max[1], searchdx, searchdy, outline, px); /* search re-sizing triangle */ 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)) { int i; float pat_min[2], pat_max[2]; /* float dx = 12.0f / width, dy = 12.0f / height;*/ /* XXX UNUSED */ float tilt_ctrl[2]; if (!outline) { if (track->pat_flag & SELECT) glColor3fv(scol); else glColor3fv(col); } /* 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); } /* ** sliders to control overall pattern ** */ add_v2_v2v2(tilt_ctrl, marker->pattern_corners[1], marker->pattern_corners[2]); BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); glEnable(GL_LINE_STIPPLE); glLineStipple(3, 0xaaaa); #if 0 /* TODO: disable for now, needs better approach visualizing this */ glBegin(GL_LINE_LOOP); glVertex2f(pat_min[0] - dx, pat_min[1] - dy); glVertex2f(pat_max[0] + dx, pat_min[1] - dy); glVertex2f(pat_max[0] + dx, pat_max[1] + dy); glVertex2f(pat_min[0] - dx, pat_max[1] + dy); glEnd(); /* marker's offset slider */ draw_marker_slide_square(pat_min[0] - dx, pat_max[1] + dy, patdx, patdy, outline, px); /* pattern re-sizing triangle */ draw_marker_slide_triangle(pat_max[0] + dx, pat_min[1] - dy, patdx, patdy, outline, px); #endif glBegin(GL_LINES); glVertex2f(0.0f, 0.0f); glVertex2fv(tilt_ctrl); glEnd(); glDisable(GL_LINE_STIPPLE); /* slider to control pattern tilt */ draw_marker_slide_square(tilt_ctrl[0], tilt_ctrl[1], patdx, patdy, outline, px); } glPopMatrix(); if (outline) glLineWidth(1.0f); }
static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, const float marker_pos[2], int act, int width, int height, float zoomx, float zoomy) { char str[128] = {0}, state[64] = {0}; float dx = 0.0f, dy = 0.0f, fontsize, pos[3]; uiStyle *style = U.uistyles.first; int fontid = style->widget.uifont_id; if (!TRACK_VIEW_SELECTED(sc, track)) return; BLF_size(fontid, 11.0f * U.pixelsize, U.dpi); fontsize = BLF_height_max(fontid); if (marker->flag & MARKER_DISABLED) { if (act) UI_ThemeColor(TH_ACT_MARKER); else UI_ThemeColorShade(TH_DIS_MARKER, 128); } else { if (act) UI_ThemeColor(TH_ACT_MARKER); else UI_ThemeColor(TH_SEL_MARKER); } if ((sc->flag & SC_SHOW_MARKER_SEARCH) && ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) { dx = marker->search_min[0]; dy = marker->search_min[1]; } else if (sc->flag & SC_SHOW_MARKER_PATTERN) { 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; pos[1] = (marker_pos[1] + dy) * height; pos[2] = 0.0f; mul_m4_v3(sc->stabmat, pos); pos[0] = pos[0] * zoomx; pos[1] = pos[1] * zoomy - fontsize; if (marker->flag & MARKER_DISABLED) strcpy(state, "disabled"); else if (marker->framenr != ED_space_clip_get_clip_frame_number(sc)) strcpy(state, "estimated"); else if (marker->flag & MARKER_TRACKED) strcpy(state, "tracked"); else strcpy(state, "keyframed"); if (state[0]) BLI_snprintf(str, sizeof(str), "%s: %s", track->name, state); else BLI_strncpy(str, track->name, sizeof(str)); BLF_position(fontid, pos[0], pos[1], 0.0f); BLF_draw(fontid, str, sizeof(str)); pos[1] -= fontsize; if (track->flag & TRACK_HAS_BUNDLE) { BLI_snprintf(str, sizeof(str), "Average error: %.3f", track->error); BLF_position(fontid, pos[0], pos[1], 0.0f); BLF_draw(fontid, str, sizeof(str)); pos[1] -= fontsize; } if (track->flag & TRACK_LOCKED) { BLF_position(fontid, pos[0], pos[1], 0.0f); BLF_draw(fontid, "locked", 6); } }
static int select_all_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); 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); bool has_selection = false; if (action == SEL_TOGGLE) { action = SEL_SELECT; for (track = tracksbase->first; track; track = track->next) { if (TRACK_VIEW_SELECTED(sc, track)) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { action = SEL_DESELECT; break; } } } for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) { if (PLANE_TRACK_VIEW_SELECTED(plane_track)) { action = SEL_DESELECT; break; } } } for (track = tracksbase->first; track; track = track->next) { if ((track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { switch (action) { case SEL_SELECT: track->flag |= SELECT; track->pat_flag |= SELECT; track->search_flag |= SELECT; break; case SEL_DESELECT: track->flag &= ~SELECT; track->pat_flag &= ~SELECT; track->search_flag &= ~SELECT; break; case SEL_INVERT: track->flag ^= SELECT; track->pat_flag ^= SELECT; track->search_flag ^= SELECT; break; } } } if (TRACK_VIEW_SELECTED(sc, track)) has_selection = true; } 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) sc->flag &= ~SC_LOCK_SELECTION; BKE_tracking_dopesheet_tag_update(tracking); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); return OPERATOR_FINISHED; }