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 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 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; }