static void draw_tracks_error_curves(SpaceClip *sc) { MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; TrackErrorCurveUserData data; data.clip = clip; data.tracking = tracking; data.tracking_object = BKE_tracking_object_get_active(tracking); data.active_track = BKE_tracking_track_get_active(tracking); data.matrix_initialized = false; BKE_movieclip_get_size(clip, &sc->user, &data.width, &data.height); data.aspy = 1.0f / tracking->camera.pixel_aspect; if (!data.width || !data.height) { return; } clip_graph_tracking_values_iterate(sc, (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0, (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0, &data, tracking_error_segment_point_cb, tracking_error_segment_start_cb, tracking_error_segment_end_cb); }
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 bool apply_solution_scale_poll(bContext *C) { SpaceClip *sc = CTX_wm_space_clip(C); if (sc != NULL) { MovieClip *clip = ED_space_clip_get_clip(sc); if (clip != NULL) { MovieTracking *tracking = &clip->tracking; MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); return (tracking_object->flag & TRACKING_OBJECT_CAMERA) != 0; } } return 0; }
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; }
static bool mouse_select_curve(bContext *C, float co[2], bool extend) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); MouseSelectUserData userdata; mouse_select_init_data(&userdata, co); clip_graph_tracking_values_iterate(sc, (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0, (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0, &userdata, find_nearest_tracking_segment_cb, NULL, find_nearest_tracking_segment_end_cb); if (userdata.track) { if (extend) { if (act_track == userdata.track) { /* currently only single curve can be selected (selected curve represents active track) */ act_track = NULL; } } else if (act_track != userdata.track) { SelectUserData selectdata = {SEL_DESELECT}; MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); tracking->act_track = userdata.track; if ((sc->flag & SC_SHOW_GRAPH_SEL_ONLY) == 0) { ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); BKE_tracking_track_select(tracksbase, userdata.track, TRACK_AREA_ALL, false); } /* deselect all knots on newly selected curve */ clip_graph_tracking_iterate(sc, (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0, (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0, &selectdata, toggle_selection_cb); } return true; } return false; }
static int dopesheet_select_channel_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 *object = BKE_tracking_object_get_active(tracking); MovieTrackingDopesheet *dopesheet = &tracking->dopesheet; MovieTrackingDopesheetChannel *channel; ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); float location[2]; const bool extend = RNA_boolean_get(op->ptr, "extend"); int current_channel_index = 0, channel_index; const bool show_selected_only = (dopesheet->flag & TRACKING_DOPE_SELECTED_ONLY) != 0; RNA_float_get_array(op->ptr, "location", location); channel_index = -(location[1] - (CHANNEL_FIRST + CHANNEL_HEIGHT_HALF)) / CHANNEL_STEP; for (channel = dopesheet->channels.first; channel; channel = channel->next) { MovieTrackingTrack *track = channel->track; if (current_channel_index == channel_index) { if (extend) track->flag ^= TRACK_DOPE_SEL; else track->flag |= TRACK_DOPE_SEL; if (track->flag & TRACK_DOPE_SEL) { tracking->act_track = track; BKE_tracking_track_select(tracksbase, track, TRACK_AREA_ALL, true); } else if (show_selected_only == false) { BKE_tracking_track_deselect(track, TRACK_AREA_ALL); } } else if (!extend) track->flag &= ~TRACK_DOPE_SEL; current_channel_index++; } WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); return OPERATOR_FINISHED; }
static bool set_orientation_poll(bContext *C) { SpaceClip *sc = CTX_wm_space_clip(C); if (sc != NULL) { ViewLayer *view_layer = CTX_data_view_layer(C); MovieClip *clip = ED_space_clip_get_clip(sc); if (clip != NULL) { MovieTracking *tracking = &clip->tracking; MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { return true; } else { return OBACT(view_layer) != NULL; } } } return false; }
static Object *get_orientation_object(bContext *C) { Scene *scene = CTX_data_scene(C); 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); Object *object = NULL; if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { object = get_camera_with_movieclip(scene, clip); } else { object = OBACT; } if (object != NULL && object->parent != NULL) { object = object->parent; } return object; }
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 void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Scene *scene) { float x; int *points, totseg, i, a; float sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1); MovieTracking *tracking = &clip->tracking; MovieTrackingObject *act_object = BKE_tracking_object_get_active(tracking); MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking); MovieTrackingPlaneTrack *act_plane_track = BKE_tracking_plane_track_get_active(&clip->tracking); MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* cache background */ ED_region_cache_draw_background(ar); /* cached segments -- could be usefu lto debug caching strategies */ BKE_movieclip_get_cache_segments(clip, &sc->user, &totseg, &points); ED_region_cache_draw_cached_segments(ar, totseg, points, sfra, efra); /* track */ if (act_track || act_plane_track) { for (i = sfra - clip->start_frame + 1, a = 0; i <= efra - clip->start_frame + 1; i++) { int framenr; int markersnr = generic_track_get_markersnr(act_track, act_plane_track); while (a < markersnr) { int marker_framenr = generic_track_get_marker_framenr(act_track, act_plane_track, a); if (marker_framenr >= i) break; if (a < markersnr - 1 && generic_track_get_marker_framenr(act_track, act_plane_track, a + 1) > i) break; a++; } a = min_ii(a, markersnr - 1); if (generic_track_is_marker_enabled(act_track, act_plane_track, a)) { framenr = generic_track_get_marker_framenr(act_track, act_plane_track, a); if (framenr != i) glColor4ub(128, 128, 0, 96); else if (generic_track_is_marker_keyframed(act_track, act_plane_track, a)) glColor4ub(255, 255, 0, 196); else glColor4ub(255, 255, 0, 96); glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 4 * UI_DPI_FAC); } } } /* failed frames */ if (reconstruction->flag & TRACKING_RECONSTRUCTED) { int n = reconstruction->camnr; MovieReconstructedCamera *cameras = reconstruction->cameras; glColor4ub(255, 0, 0, 96); for (i = sfra, a = 0; i <= efra; i++) { bool ok = false; while (a < n) { if (cameras[a].framenr == i) { ok = true; break; } else if (cameras[a].framenr > i) { break; } a++; } if (!ok) glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 8 * UI_DPI_FAC); } } glDisable(GL_BLEND); /* current frame */ x = (sc->user.framenr - sfra) / (efra - sfra + 1) * ar->winx; UI_ThemeColor(TH_CFRAME); glRecti(x, 0, x + ceilf(framelen), 8 * UI_DPI_FAC); ED_region_cache_draw_curfra_label(sc->user.framenr, x, 8.0f * UI_DPI_FAC); /* solver keyframes */ glColor4ub(175, 255, 0, 255); draw_keyframe(act_object->keyframe1 + clip->start_frame - 1, CFRA, sfra, framelen, 2); draw_keyframe(act_object->keyframe2 + clip->start_frame - 1, CFRA, sfra, framelen, 2); /* movie clip animation */ if ((sc->mode == SC_MODE_MASKEDIT) && sc->mask_info.mask) { ED_mask_draw_frames(sc->mask_info.mask, ar, CFRA, sfra, efra); } }
/* Draw all kind of tracks. */ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, MovieClip *clip, int width, int height, float zoomx, float zoomy) { float x, y; MovieTracking *tracking = &clip->tracking; ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); MovieTrackingTrack *track, *act_track; MovieTrackingPlaneTrack *plane_track, *active_plane_track; MovieTrackingMarker *marker; int framenr = ED_space_clip_get_clip_frame_number(sc); int undistort = sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT; float *marker_pos = NULL, *fp, *active_pos = NULL, cur_pos[2]; /* ** find window pixel coordinates of origin ** */ /* UI_view2d_view_to_region_no_clip return integer values, this could * lead to 1px flickering when view is locked to selection during playbeck. * to avoid this flickering, calculate base point in the same way as it happens * in UI_view2d_view_to_region_no_clip, but do it in floats here */ UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y); glPushMatrix(); glTranslatef(x, y, 0); glPushMatrix(); glScalef(zoomx, zoomy, 0); glMultMatrixf(sc->stabmat); glScalef(width, height, 0); act_track = BKE_tracking_track_get_active(tracking); /* Draw plane tracks */ active_plane_track = BKE_tracking_plane_track_get_active(tracking); for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) { if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) { draw_plane_track(sc, scene, plane_track, framenr, plane_track == active_plane_track, width, height); } } if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) { int count = 0; /* count */ track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) count++; } track = track->next; } /* undistort */ if (count) { marker_pos = MEM_callocN(2 * sizeof(float) * count, "draw_tracking_tracks marker_pos"); track = tracksbase->first; fp = marker_pos; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { ED_clip_point_undistorted_pos(sc, marker->pos, fp); if (track == act_track) active_pos = fp; fp += 2; } } track = track->next; } } } if (sc->flag & SC_SHOW_TRACK_PATH) { track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) draw_track_path(sc, clip, track); track = track->next; } } /* markers outline and non-selected areas */ track = tracksbase->first; fp = marker_pos; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { copy_v2_v2(cur_pos, fp ? fp : marker->pos); draw_marker_outline(sc, track, marker, cur_pos, width, height); draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 0); draw_marker_slide_zones(sc, track, marker, cur_pos, 1, 0, 0, width, height); draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 0, 0, width, height); if (fp) fp += 2; } } track = track->next; } /* selected areas only, so selection wouldn't be overlapped by * non-selected areas */ track = tracksbase->first; fp = marker_pos; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { int act = track == act_track; marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { if (!act) { copy_v2_v2(cur_pos, fp ? fp : marker->pos); draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 1); draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 1, 0, width, height); } if (fp) fp += 2; } } track = track->next; } /* active marker would be displayed on top of everything else */ if (act_track) { if ((act_track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(act_track, framenr); if (MARKER_VISIBLE(sc, act_track, marker)) { copy_v2_v2(cur_pos, active_pos ? active_pos : marker->pos); draw_marker_areas(sc, act_track, marker, cur_pos, width, height, 1, 1); draw_marker_slide_zones(sc, act_track, marker, cur_pos, 0, 1, 1, width, height); } } } if (sc->flag & SC_SHOW_BUNDLES) { MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); float pos[4], vec[4], mat[4][4], aspy; glEnable(GL_POINT_SMOOTH); glPointSize(3.0f); aspy = 1.0f / clip->tracking.camera.pixel_aspect; BKE_tracking_get_projection_matrix(tracking, object, framenr, width, height, mat); track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0 && track->flag & TRACK_HAS_BUNDLE) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { float npos[2]; copy_v3_v3(vec, track->bundle_pos); vec[3] = 1; mul_v4_m4v4(pos, mat, vec); pos[0] = (pos[0] / (pos[3] * 2.0f) + 0.5f) * width; pos[1] = (pos[1] / (pos[3] * 2.0f) + 0.5f) * height * aspy; BKE_tracking_distort_v2(tracking, pos, npos); if (npos[0] >= 0.0f && npos[1] >= 0.0f && npos[0] <= width && npos[1] <= height * aspy) { vec[0] = (marker->pos[0] + track->offset[0]) * width; vec[1] = (marker->pos[1] + track->offset[1]) * height * aspy; sub_v2_v2(vec, npos); if (len_squared_v2(vec) < (3.0f * 3.0f)) glColor3f(0.0f, 1.0f, 0.0f); else glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_POINTS); if (undistort) glVertex3f(pos[0] / width, pos[1] / (height * aspy), 0); else glVertex3f(npos[0] / width, npos[1] / (height * aspy), 0); glEnd(); } } } track = track->next; } glPointSize(1.0f); glDisable(GL_POINT_SMOOTH); } glPopMatrix(); if (sc->flag & SC_SHOW_NAMES) { /* scaling should be cleared before drawing texts, otherwise font would also be scaled */ track = tracksbase->first; fp = marker_pos; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { int act = track == act_track; copy_v2_v2(cur_pos, fp ? fp : marker->pos); draw_marker_texts(sc, track, marker, cur_pos, act, width, height, zoomx, zoomy); if (fp) fp += 2; } } track = track->next; } } glPopMatrix(); if (marker_pos) MEM_freeN(marker_pos); }
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; }