diff options
Diffstat (limited to 'source/blender/editors/space_clip/clip_utils.c')
-rw-r--r-- | source/blender/editors/space_clip/clip_utils.c | 149 |
1 files changed, 143 insertions, 6 deletions
diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c index 94badf7fdd6..48f788e2e3a 100644 --- a/source/blender/editors/space_clip/clip_utils.c +++ b/source/blender/editors/space_clip/clip_utils.c @@ -27,6 +27,7 @@ #include "BLI_utildefines.h" #include "BLI_listbase.h" +#include "BLI_math.h" #include "BKE_animsys.h" #include "BKE_context.h" @@ -52,12 +53,28 @@ #include "clip_intern.h" // own include -void clip_graph_tracking_values_iterate_track(SpaceClip *sc, - MovieTrackingTrack *track, - void *userdata, - ClipTrackValueCallback func, - ClipTrackValueSegmentStartCallback segment_start, - ClipTrackValueSegmentEndCallback segment_end) +bool clip_graph_value_visible(SpaceClip *sc, eClipCurveValueSource value_source) +{ + if (ELEM(value_source, CLIP_VALUE_SOURCE_SPEED_X, CLIP_VALUE_SOURCE_SPEED_Y)) { + if ((sc->flag & SC_SHOW_GRAPH_TRACKS_MOTION) == 0) { + return false; + } + } + else if (value_source == CLIP_VALUE_SOURCE_REPROJECTION_ERROR) { + if ((sc->flag & SC_SHOW_GRAPH_TRACKS_ERROR) == 0) { + return false; + } + } + return true; +} + +static void clip_graph_tracking_values_iterate_track_speed_values( + SpaceClip *sc, + MovieTrackingTrack *track, + void *userdata, + ClipTrackValueCallback func, + ClipTrackValueSegmentStartCallback segment_start, + ClipTrackValueSegmentEndCallback segment_end) { MovieClip *clip = ED_space_clip_get_clip(sc); int width, height, coord; @@ -124,6 +141,126 @@ void clip_graph_tracking_values_iterate_track(SpaceClip *sc, } } +static float calculate_reprojection_error_at_marker(MovieClip *clip, + MovieTracking *tracking, + MovieTrackingObject *tracking_object, + MovieTrackingTrack *track, + MovieTrackingMarker *marker, + const int clip_width, + const int clip_height, + const int scene_framenr) +{ + float reprojected_position[4], bundle_position[4], marker_position[2], delta[2]; + float weight = BKE_tracking_track_get_weight_for_marker(clip, track, marker); + const float aspy = 1.0f / tracking->camera.pixel_aspect; + + float projection_matrix[4][4]; + BKE_tracking_get_projection_matrix( + tracking, tracking_object, scene_framenr, clip_width, clip_height, projection_matrix); + + copy_v3_v3(bundle_position, track->bundle_pos); + bundle_position[3] = 1; + + mul_v4_m4v4(reprojected_position, projection_matrix, bundle_position); + reprojected_position[0] = (reprojected_position[0] / (reprojected_position[3] * 2.0f) + 0.5f) * + clip_width; + reprojected_position[1] = (reprojected_position[1] / (reprojected_position[3] * 2.0f) + 0.5f) * + clip_height * aspy; + + BKE_tracking_distort_v2(tracking, reprojected_position, reprojected_position); + + marker_position[0] = (marker->pos[0] + track->offset[0]) * clip_width; + marker_position[1] = (marker->pos[1] + track->offset[1]) * clip_height * aspy; + + sub_v2_v2v2(delta, reprojected_position, marker_position); + return len_v2(delta) * weight; +} + +static void clip_graph_tracking_values_iterate_track_reprojection_error_values( + SpaceClip *sc, + MovieTrackingTrack *track, + void *userdata, + ClipTrackValueCallback func, + ClipTrackValueSegmentStartCallback segment_start, + ClipTrackValueSegmentEndCallback segment_end) +{ + /* Tracks without bundle can not have any reprojection error curve. */ + if ((track->flag & TRACK_HAS_BUNDLE) == 0) { + return; + } + + MovieClip *clip = ED_space_clip_get_clip(sc); + MovieTracking *tracking = &clip->tracking; + MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); + + int clip_width, clip_height; + BKE_movieclip_get_size(clip, &sc->user, &clip_width, &clip_height); + + /* Iterate over segments. */ + bool is_segment_open = false; + for (int marker_index = 0; marker_index < track->markersnr; marker_index++) { + MovieTrackingMarker *marker = &track->markers[marker_index]; + + /* End of tracked segment, no reprojection error can be calculated here since the ground truth + * 2D position is not known. */ + if (marker->flag & MARKER_DISABLED) { + if (is_segment_open) { + if (segment_end != NULL) { + segment_end(userdata, CLIP_VALUE_SOURCE_REPROJECTION_ERROR); + } + is_segment_open = false; + } + continue; + } + + /* Begin new segment if it is not open yet. */ + if (!is_segment_open) { + if (segment_start != NULL) { + if ((marker_index + 1) == track->markersnr) { + segment_start(userdata, track, CLIP_VALUE_SOURCE_REPROJECTION_ERROR, true); + } + else { + segment_start(userdata, + track, + CLIP_VALUE_SOURCE_REPROJECTION_ERROR, + (track->markers[marker_index + 1].flag & MARKER_DISABLED)); + } + } + is_segment_open = true; + } + + if (func != NULL) { + const int scene_framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr); + const float reprojection_error = calculate_reprojection_error_at_marker( + clip, tracking, tracking_object, track, marker, clip_width, clip_height, scene_framenr); + func(userdata, + track, + marker, + CLIP_VALUE_SOURCE_REPROJECTION_ERROR, + scene_framenr, + reprojection_error); + } + } + + if (is_segment_open && segment_end != NULL) { + segment_end(userdata, CLIP_VALUE_SOURCE_REPROJECTION_ERROR); + } +} + +void clip_graph_tracking_values_iterate_track(SpaceClip *sc, + MovieTrackingTrack *track, + void *userdata, + ClipTrackValueCallback func, + ClipTrackValueSegmentStartCallback segment_start, + ClipTrackValueSegmentEndCallback segment_end) +{ + clip_graph_tracking_values_iterate_track_speed_values( + sc, track, userdata, func, segment_start, segment_end); + + clip_graph_tracking_values_iterate_track_reprojection_error_values( + sc, track, userdata, func, segment_start, segment_end); +} + void clip_graph_tracking_values_iterate(SpaceClip *sc, bool selected_only, bool include_hidden, |