diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2012-05-03 21:52:34 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2012-05-03 21:52:34 +0400 |
commit | 5821c2973ec6a7cc6abc25ac75e85e84dc176411 (patch) | |
tree | 6dd71544b35d3c42692ebc963a2855cf02927599 | |
parent | 96693d37e602d045a5b2c196a5a3b55174bae1cb (diff) |
Camera tracking: pre-calculate tracked segments for dopesheet channels
-rw-r--r-- | source/blender/blenkernel/intern/tracking.c | 108 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 1 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 1 | ||||
-rw-r--r-- | source/blender/editors/space_clip/clip_dopesheet_draw.c | 56 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_tracking_types.h | 9 |
5 files changed, 118 insertions, 57 deletions
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 25c985b391a..216e3b19672 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -634,7 +634,20 @@ static void tracking_objects_free(ListBase *objects) static void tracking_dopesheet_free(MovieTrackingDopesheet *dopesheet) { + MovieTrackingDopesheetChannel *channel; + + channel = dopesheet->channels.first; + while (channel) { + if (channel->segments) { + MEM_freeN(channel->segments); + } + + channel = channel->next; + } + BLI_freelistN(&dopesheet->channels); + + dopesheet->channels.first = dopesheet->channels.last = NULL; dopesheet->tot_channel = 0; } @@ -3059,32 +3072,101 @@ static int channels_alpha_sort(void *a, void *b) return 0; } +static void channels_segments_calc(MovieTrackingDopesheetChannel *channel) +{ + MovieTrackingTrack *track = channel->track; + int i, segment; + + channel->tot_segment = 0; + channel->max_segment = 0; + channel->total_frames = 0; + + /* count */ + i = 0; + while (i < track->markersnr) { + MovieTrackingMarker *marker = &track->markers[i]; + + if ((marker->flag & MARKER_DISABLED) == 0) { + int prev_fra = marker->framenr, len = 0; + + i++; + while (i < track->markersnr) { + marker = &track->markers[i]; + + if (marker->framenr != prev_fra + 1) + break; + if (marker->flag & MARKER_DISABLED) + break; + + prev_fra = marker->framenr; + len++; + i++; + } + + channel->tot_segment++; + } + + i++; + } + + if (!channel->tot_segment) + return; + + channel->segments = MEM_callocN(2 * sizeof(int) * channel->tot_segment, "tracking channel segments"); + + /* create segments */ + i = 0; + segment = 0; + while (i < track->markersnr) { + MovieTrackingMarker *marker = &track->markers[i]; + + if ((marker->flag & MARKER_DISABLED) == 0) { + MovieTrackingMarker *start_marker = marker; + int prev_fra = marker->framenr, len = 0; + + i++; + while (i < track->markersnr) { + marker = &track->markers[i]; + + if (marker->framenr != prev_fra + 1) + break; + if (marker->flag & MARKER_DISABLED) + break; + + prev_fra = marker->framenr; + channel->total_frames++; + len++; + i++; + } + + channel->segments[2 * segment] = start_marker->framenr; + channel->segments[2 * segment + 1] = start_marker->framenr + len; + + channel->max_segment = MAX2(channel->max_segment, len); + segment++; + } + + i++; + } +} + void BKE_tracking_update_dopesheet(MovieTracking *tracking) { MovieTrackingObject *object = BKE_tracking_active_object(tracking); MovieTrackingDopesheet *dopesheet = &tracking->dopesheet; MovieTrackingTrack *track; ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object); - ListBase old_channels; - old_channels = dopesheet->channels; - dopesheet->channels.first = dopesheet->channels.last = NULL; - dopesheet->tot_channel = 0; + tracking_dopesheet_free(dopesheet); for (track = tracksbase->first; track; track = track->next) { if (TRACK_SELECTED(track) && (track->flag & TRACK_HIDDEN) == 0) { - MovieTrackingDopesheetChannel *channel, *old_channel; + MovieTrackingDopesheetChannel *channel; channel = MEM_callocN(sizeof(MovieTrackingDopesheetChannel), "tracking dopesheet channel"); channel->track = track; - /* copy flags from current dopsheet information to new one */ - for (old_channel = old_channels.first; old_channel; old_channel = old_channel->next) { - if (old_channel->track == track) { - channel->flag = old_channel->flag; - break; - } - } + channels_segments_calc(channel); BLI_addtail(&dopesheet->channels, channel); dopesheet->tot_channel++; @@ -3092,6 +3174,4 @@ void BKE_tracking_update_dopesheet(MovieTracking *tracking) } BLI_sortlist(&dopesheet->channels, channels_alpha_sort); - - BLI_freelistN(&old_channels); } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 6c0ac651f13..afc4989f620 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6179,6 +6179,7 @@ static void direct_link_movieDopesheet(FileData *fd, MovieTrackingDopesheet *dop channel = dopesheet->channels.first; while (channel) { channel->track = newdataadr(fd, channel->track); + channel->segments = newdataadr(fd, channel->segments); channel = channel->next; } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 7947d6f8f71..eb697aad17c 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2686,6 +2686,7 @@ static void write_movieDopesheet(WriteData *wd, MovieTrackingDopesheet *dopeshee channel = dopesheet->channels.first; while (channel) { writestruct(wd, DATA, "MovieTrackingDopesheetChannel", 1, channel); + writedata(wd, DATA, 2 * channel->tot_segment, channel->segments); channel = channel->next; } diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c index d1733cf322b..1814b253def 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_draw.c +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -87,7 +87,7 @@ static void draw_keyframe_shape(float x, float y, float xscale, float yscale, sh {1.0f, 0.0f}, /* mid-right */ {0.0f, -1.0f}, /* bottom vert */ {-1.0f, 0.0f} /* mid-left */ - }; + }; static GLuint displist1 = 0; static GLuint displist2 = 0; int hsize = STRIP_HEIGHT_HALF; @@ -199,45 +199,19 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) alpha = (track->flag & TRACK_LOCKED) ? 0.5f : 1.0f; /* tracked segments */ - i = 0; - while (i < track->markersnr) { - MovieTrackingMarker *marker = &track->markers[i]; - - if ((marker->flag & MARKER_DISABLED) == 0) { - MovieTrackingMarker *start_marker = marker; - int prev_fra = marker->framenr, len = 0; - - i++; - while (i < track->markersnr) { - marker = &track->markers[i]; - - if (marker->framenr != prev_fra + 1) - break; - if (marker->flag & MARKER_DISABLED) - break; - - prev_fra = marker->framenr; - len++; - i++; - } - - if (sel) - glColor4fv(selected_strip); - else - glColor4fv(strip); - - if (len) { - glRectf(start_marker->framenr, (float) y - STRIP_HEIGHT_HALF, - start_marker->framenr + len, (float) y + STRIP_HEIGHT_HALF); - draw_keyframe_shape(start_marker->framenr, y, xscale, yscale, sel, alpha); - draw_keyframe_shape(start_marker->framenr + len, y, xscale, yscale, sel, alpha); - } - else { - draw_keyframe_shape(start_marker->framenr, y, xscale, yscale, sel, alpha); - } + for (i = 0; i < channel->tot_segment; i++) { + int start_frame = channel->segments[2 * i]; + int end_frame = channel->segments[2 * i + 1]; + + if (start_frame != end_frame) { + glRectf(start_frame, (float) y - STRIP_HEIGHT_HALF, + end_frame, (float) y + STRIP_HEIGHT_HALF); + draw_keyframe_shape(start_frame, y, xscale, yscale, sel, alpha); + draw_keyframe_shape(end_frame, y, xscale, yscale, sel, alpha); + } + else { + draw_keyframe_shape(start_frame, y, xscale, yscale, sel, alpha); } - - i++; } /* keyframes */ @@ -286,8 +260,8 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar) height = (dopesheet->tot_channel * CHANNEL_STEP) + (CHANNEL_HEIGHT * 2); if (height > (v2d->mask.ymax - v2d->mask.ymin)) { - /* don't use totrect set, as the width stays the same - * (NOTE: this is ok here, the configuration is pretty straightforward) + /* don't use totrect set, as the width stays the same + * (NOTE: this is ok here, the configuration is pretty straightforward) */ v2d->tot.ymin = (float)(-height); } diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index e8abee36716..db1899ab31b 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -195,8 +195,13 @@ typedef struct MovieTrackingStats { typedef struct MovieTrackingDopesheetChannel { struct MovieTrackingDopesheetChannel *next, *prev; - MovieTrackingTrack *track; - int flag, pad; + + MovieTrackingTrack *track; /* motion track for which channel is created */ + int pad; + + int tot_segment; /* total number of segments */ + int *segments; /* tracked segments */ + int max_segment, total_frames; /* longest segment length and total number of tracked frames */ } MovieTrackingDopesheetChannel; typedef struct MovieTrackingDopesheet { |