diff options
Diffstat (limited to 'source/blender/editors/space_clip/clip_draw.c')
-rw-r--r-- | source/blender/editors/space_clip/clip_draw.c | 288 |
1 files changed, 148 insertions, 140 deletions
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index e3fa8edd714..80b58954c8f 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -161,7 +161,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc /* cache background */ ED_region_cache_draw_background(ar); - /* cached segments -- could be usefu lto debug caching strategies */ + /* cached segments -- could be useful to debug caching strategies */ BKE_movieclip_get_cache_segments(clip, &sc->user, &totseg, &points); ED_region_cache_draw_cached_segments(ar, totseg, points, sfra, efra); @@ -404,177 +404,185 @@ static void draw_stabilization_border( } } -static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackingTrack *track) -{ -#define MAX_STATIC_PATH 64 - int count = sc->path_length; - int i, a, b, curindex = -1; - float path_static[(MAX_STATIC_PATH + 1) * 2][2]; - float(*path)[2]; - int tiny = sc->flag & SC_SHOW_TINY_MARKER, framenr, start_frame; - MovieTrackingMarker *marker; +enum { + PATH_POINT_FLAG_KEYFRAME = (1 << 0), +}; - if (count == 0) { - return; - } +typedef struct TrachPathPoint { + float co[2]; + uchar flag; +} TrackPathPoint; - 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; - } - - if (count < MAX_STATIC_PATH) { - path = path_static; - } - else { - path = MEM_mallocN(sizeof(*path) * (count + 1) * 2, "path"); +static void marker_to_path_point(SpaceClip *sc, + const MovieTrackingTrack *track, + const MovieTrackingMarker *marker, + TrackPathPoint *point) +{ + add_v2_v2v2(point->co, marker->pos, track->offset); + ED_clip_point_undistorted_pos(sc, point->co, point->co); + point->flag = 0; + if ((marker->flag & MARKER_TRACKED) == 0) { + point->flag |= PATH_POINT_FLAG_KEYFRAME; } +} - a = count; - i = framenr - 1; - while (i >= framenr - count) { - marker = BKE_tracking_marker_get(track, i); - - if (!marker || marker->flag & MARKER_DISABLED) { +static int track_to_path_segment(SpaceClip *sc, + MovieTrackingTrack *track, + int direction, + TrackPathPoint *path) +{ + const int count = sc->path_length; + int current_frame = ED_space_clip_get_clip_frame_number(sc); + const MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, current_frame); + /* Check whether there is marker at exact current frame. + * If not, we don't have anything to be put to path. */ + if (marker == NULL || (marker->flag & MARKER_DISABLED)) { + return 0; + } + /* Index inside of path array where we write data to. */ + int point_index = count; + int path_length = 0; + for (int i = 0; i < count; ++i) { + marker_to_path_point(sc, track, marker, &path[point_index]); + /* Move to the next marker along the path segment. */ + path_length++; + point_index += direction; + current_frame += direction; + marker = BKE_tracking_marker_get_exact(track, current_frame); + if (marker == NULL || (marker->flag & MARKER_DISABLED)) { + /* Reached end of tracked segment. */ break; } + } + return path_length; +} - if (marker->framenr == i) { - add_v2_v2v2(path[--a], marker->pos, track->offset); - ED_clip_point_undistorted_pos(sc, path[a], path[a]); +static void draw_track_path_points(const TrackPathPoint *path, + uint position_attribute, + const int start_point, + const int num_points) +{ + if (num_points == 0) { + return; + } + immBegin(GPU_PRIM_POINTS, num_points); + for (int i = 0; i < num_points; i++) { + const TrackPathPoint *point = &path[i + start_point]; + immVertex2fv(position_attribute, point->co); + } + immEnd(); +} - if (marker->framenr == start_frame) { - curindex = a; - } - } - else { - break; +static void draw_track_path_keyframe_points(const TrackPathPoint *path, + uint position_attribute, + const int start_point, + const int num_points) +{ + immBeginAtMost(GPU_PRIM_POINTS, num_points); + for (int i = 0; i < num_points; i++) { + const TrackPathPoint *point = &path[i + start_point]; + if (point->flag & PATH_POINT_FLAG_KEYFRAME) { + immVertex2fv(position_attribute, point->co); } + } + immEnd(); +} - i--; +static void draw_track_path_lines(const TrackPathPoint *path, + uint position_attribute, + const int start_point, + const int num_points) +{ + if (num_points < 2) { + return; + } + immBegin(GPU_PRIM_LINE_STRIP, num_points); + for (int i = 0; i < num_points; i++) { + const TrackPathPoint *point = &path[i + start_point]; + immVertex2fv(position_attribute, point->co); } + immEnd(); +} - b = count; - i = framenr; - while (i <= framenr + count) { - marker = BKE_tracking_marker_get(track, i); +static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackingTrack *track) +{ +#define MAX_STATIC_PATH 64 - if (!marker || marker->flag & MARKER_DISABLED) { - break; - } + const int count = sc->path_length; + TrackPathPoint path_static[(MAX_STATIC_PATH + 1) * 2]; + TrackPathPoint *path; + const bool tiny = (sc->flag & SC_SHOW_TINY_MARKER) != 0; - if (marker->framenr == i) { - if (marker->framenr == start_frame) { - curindex = b; - } + if (count == 0) { + /* Early output, nothing to bother about here. */ + return; + } - add_v2_v2v2(path[b++], marker->pos, track->offset); - ED_clip_point_undistorted_pos(sc, path[b - 1], path[b - 1]); - } - else { - break; - } + /* Try to use stack allocated memory when possibly, only use heap allocation + * for really long paths. */ + path = (count < MAX_STATIC_PATH) ? path_static : + MEM_mallocN(sizeof(*path) * (count + 1) * 2, "path"); + /* Collect path information. */ + const int num_points_before = track_to_path_segment(sc, track, -1, path); + const int num_points_after = track_to_path_segment(sc, track, 1, path); + if (num_points_before == 0 && num_points_after == 0) { + return; + } - i++; + int num_all_points = num_points_before + num_points_after; + /* If both leading and trailing parts of the path are there the center point is counted twice. */ + if (num_points_before != 0 && num_points_after != 0) { + num_all_points -= 1; } - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const int path_start_index = count - num_points_before + 1; + const int path_center_index = count; + const uint position_attribute = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + /* Draw path outline. */ if (!tiny) { immUniformThemeColor(TH_MARKER_OUTLINE); - if (TRACK_VIEW_SELECTED(sc, track)) { - if ((b - a - 1) >= 1) { - GPU_point_size(5.0f); - - immBegin(GPU_PRIM_POINTS, b - a - 1); - - for (i = a; i < b; i++) { - if (i != curindex) { - immVertex2f(pos, path[i][0], path[i][1]); - } - } - - immEnd(); - } - } - - if ((b - a) >= 2) { - GPU_line_width(3.0f); - - immBegin(GPU_PRIM_LINE_STRIP, b - a); - - for (i = a; i < b; i++) { - immVertex2f(pos, path[i][0], path[i][1]); - } - - immEnd(); + GPU_point_size(5.0f); + draw_track_path_points(path, position_attribute, path_start_index, num_all_points); + GPU_point_size(7.0f); + draw_track_path_keyframe_points(path, position_attribute, path_start_index, num_all_points); } + /* Draw darker outline for actual path, all line segments at once. */ + GPU_line_width(3.0f); + draw_track_path_lines(path, position_attribute, path_start_index, num_all_points); } - if (TRACK_VIEW_SELECTED(sc, track)) { - GPU_point_size(3.0f); - - if ((curindex - a) >= 1) { - immUniformThemeColor(TH_PATH_BEFORE); - - immBegin(GPU_PRIM_POINTS, curindex - a); - - for (i = a; i < curindex; i++) { - immVertex2f(pos, path[i][0], path[i][1]); - } - - immEnd(); - } - - if ((b - curindex - 1) >= 1) { - immUniformThemeColor(TH_PATH_AFTER); - - immBegin(GPU_PRIM_POINTS, b - curindex - 1); - - for (i = curindex + 1; i < b; i++) { - immVertex2f(pos, path[i][0], path[i][1]); - } - - immEnd(); - } - } + /* Draw all points. */ + GPU_point_size(3.0f); + immUniformThemeColor(TH_PATH_BEFORE); + draw_track_path_points(path, position_attribute, path_start_index, num_points_before); + immUniformThemeColor(TH_PATH_AFTER); + draw_track_path_points(path, position_attribute, path_center_index, num_points_after); + /* Connect points with color coded segments. */ GPU_line_width(1); + immUniformThemeColor(TH_PATH_BEFORE); + draw_track_path_lines(path, position_attribute, path_start_index, num_points_before); + immUniformThemeColor(TH_PATH_AFTER); + draw_track_path_lines(path, position_attribute, path_center_index, num_points_after); + + /* Draw all bigger points corresponding to keyframes. */ + GPU_point_size(5.0f); + immUniformThemeColor(TH_PATH_KEYFRAME_BEFORE); + draw_track_path_keyframe_points(path, position_attribute, path_start_index, num_points_before); + immUniformThemeColor(TH_PATH_KEYFRAME_AFTER); + draw_track_path_keyframe_points(path, position_attribute, path_center_index, num_points_after); - if ((curindex - a + 1) >= 2) { - immUniformThemeColor(TH_PATH_BEFORE); - - immBegin(GPU_PRIM_LINE_STRIP, curindex - a + 1); - - for (i = a; i <= curindex; i++) { - immVertex2f(pos, path[i][0], path[i][1]); - } - - immEnd(); - } - - if ((b - curindex) >= 2) { - immUniformThemeColor(TH_PATH_AFTER); - - immBegin(GPU_PRIM_LINE_STRIP, b - curindex); - - for (i = curindex; i < b; i++) { - immVertex2f(pos, path[i][0], path[i][1]); - } - - immEnd(); + if (path != path_static) { + MEM_freeN(path); } immUnbindProgram(); - if (path != path_static) { - MEM_freeN(path); - } #undef MAX_STATIC_PATH } @@ -887,7 +895,7 @@ static float get_shortest_pattern_side(MovieTrackingMarker *marker) } static void draw_marker_slide_square( - float x, float y, float dx, float dy, int outline, float px[2], unsigned int pos) + float x, float y, float dx, float dy, int outline, const float px[2], unsigned int pos) { float tdx, tdy; @@ -903,7 +911,7 @@ static void draw_marker_slide_square( } static void draw_marker_slide_triangle( - float x, float y, float dx, float dy, int outline, float px[2], unsigned int pos) + float x, float y, float dx, float dy, int outline, const float px[2], unsigned int pos) { float tdx, tdy; |