diff options
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/intern/tracking.c | 51 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/tracking_auto.c | 17 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/tracking_util.c | 62 | ||||
-rw-r--r-- | source/blender/blenkernel/tracking_private.h | 11 |
4 files changed, 122 insertions, 19 deletions
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 990d250b854..bfe8dcbb21e 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -974,8 +974,11 @@ static void track_mask_set_pixel_cb(int x, int x_end, int y, void *user_data) } static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height, - MovieTrackingMarker *marker, bGPDlayer *layer, - float *mask, int mask_width, int mask_height) + const float region_min[2], + bGPDlayer *layer, + float *mask, + int mask_width, + int mask_height) { bGPDframe *frame = layer->frames.first; TrackMaskSetPixelData data; @@ -994,8 +997,8 @@ static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height point = mask_points = MEM_callocN(2 * stroke->totpoints * sizeof(int), "track mask rasterization points"); for (int i = 0; i < stroke->totpoints; i++, point += 2) { - point[0] = (stroke_points[i].x - marker->search_min[0]) * frame_width; - point[1] = (stroke_points[i].y - marker->search_min[1]) * frame_height; + point[0] = stroke_points[i].x * frame_width - region_min[0]; + point[1] = stroke_points[i].y * frame_height - region_min[1]; } /* TODO: add an option to control whether AA is enabled or not */ BLI_bitmap_draw_2d_poly_v2i_n( @@ -1010,26 +1013,42 @@ static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height } } -float *BKE_tracking_track_get_mask(int frame_width, int frame_height, - MovieTrackingTrack *track, MovieTrackingMarker *marker) +/* Region is in pixel space, relative to marker's center. */ +float *tracking_track_get_mask_for_region(int frame_width, int frame_height, + const float region_min[2], + const float region_max[2], + MovieTrackingTrack *track) { float *mask = NULL; bGPDlayer *layer = track_mask_gpencil_layer_get(track); - int mask_width, mask_height; - - mask_width = (marker->search_max[0] - marker->search_min[0]) * frame_width; - mask_height = (marker->search_max[1] - marker->search_min[1]) * frame_height; - - if (layer) { + if (layer != NULL) { + const int mask_width = region_max[0] - region_min[0]; + const int mask_height = region_max[1] - region_min[1]; mask = MEM_callocN(mask_width * mask_height * sizeof(float), "track mask"); - - track_mask_gpencil_layer_rasterize(frame_width, frame_height, marker, layer, - mask, mask_width, mask_height); + track_mask_gpencil_layer_rasterize(frame_width, frame_height, + region_min, + layer, + mask, + mask_width, mask_height); } - return mask; } +float *BKE_tracking_track_get_mask(int frame_width, int frame_height, + MovieTrackingTrack *track, + MovieTrackingMarker *marker) +{ + /* Convert normalized space marker's search area to pixel-space region. */ + const float region_min[2] = {marker->search_min[0] * frame_width, + marker->search_min[1] * frame_height}; + const float region_max[2] = {marker->search_max[0] * frame_width, + marker->search_max[1] * frame_height}; + return tracking_track_get_mask_for_region(frame_width, frame_height, + region_min, + region_max, + track); +} + float BKE_tracking_track_get_weight_for_marker(MovieClip *clip, MovieTrackingTrack *track, MovieTrackingMarker *marker) { FCurve *weight_fcurve; diff --git a/source/blender/blenkernel/intern/tracking_auto.c b/source/blender/blenkernel/intern/tracking_auto.c index 3b56ea271d0..9475925cdda 100644 --- a/source/blender/blenkernel/intern/tracking_auto.c +++ b/source/blender/blenkernel/intern/tracking_auto.c @@ -36,8 +36,9 @@ #include "DNA_movieclip_types.h" #include "DNA_object_types.h" /* SELECT */ -#include "BLI_threads.h" #include "BLI_utildefines.h" +#include "BLI_listbase.h" +#include "BLI_threads.h" #include "BLI_math.h" #include "BKE_movieclip.h" @@ -76,6 +77,9 @@ typedef struct AutoTrackContext { int num_tracks; /* Number of tracks being tracked. */ AutoTrackOptions *options; /* Per-tracking track options. */ + /* Array of all tracks, indexed by track_index. */ + MovieTrackingTrack **tracks; + bool backwards; bool sequence; int first_frame; @@ -306,8 +310,15 @@ AutoTrackContext *BKE_autotrack_context_new(MovieClip *clip, BLI_spin_init(&context->spin_lock); + int num_total_tracks = BLI_listbase_count(tracksbase); + context->tracks = + MEM_callocN(sizeof(MovieTrackingTrack*) * num_total_tracks, + "auto track pointers"); + context->image_accessor = - tracking_image_accessor_new(context->clips, 1, user->framenr); + tracking_image_accessor_new(context->clips, 1, + context->tracks, num_total_tracks, + user->framenr); context->autotrack = libmv_autoTrackNew(context->image_accessor->libmv_accessor); @@ -361,6 +372,7 @@ AutoTrackContext *BKE_autotrack_context_new(MovieClip *clip, options->use_keyframe_match = track->pattern_match == TRACK_MATCH_KEYFRAME; } + context->tracks[track_index] = track; ++track_index; } @@ -565,6 +577,7 @@ void BKE_autotrack_context_free(AutoTrackContext *context) libmv_autoTrackDestroy(context->autotrack); tracking_image_accessor_destroy(context->image_accessor); MEM_freeN(context->options); + MEM_freeN(context->tracks); BLI_spin_end(&context->spin_lock); MEM_freeN(context); } diff --git a/source/blender/blenkernel/intern/tracking_util.c b/source/blender/blenkernel/intern/tracking_util.c index 1c056cda68d..a95399562d5 100644 --- a/source/blender/blenkernel/intern/tracking_util.c +++ b/source/blender/blenkernel/intern/tracking_util.c @@ -875,8 +875,64 @@ static void accessor_release_image_callback(libmv_CacheKey cache_key) IMB_freeImBuf(ibuf); } +static libmv_CacheKey accessor_get_mask_for_track_callback( + libmv_FrameAccessorUserData* user_data, + int clip_index, + int frame, + int track_index, + const libmv_Region *region, + float **r_destination, + int *r_width, + int *r_height) +{ + /* Perform sanity checks first. */ + TrackingImageAccessor *accessor = (TrackingImageAccessor *) user_data; + BLI_assert(clip_index < accessor->num_clips); + BLI_assert(track_index < accessor->num_tracks); + MovieTrackingTrack *track = accessor->tracks[track_index]; + /* Early output, track does not use mask. */ + if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) == 0) { + return NULL; + } + MovieClip *clip = accessor->clips[clip_index]; + /* Construct fake user so we can access movie clip. */ + MovieClipUser user; + int scene_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, frame); + BKE_movieclip_user_set_frame(&user, scene_frame); + user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL; + user.render_flag = 0; + /* Get frame width and height so we can convert stroke coordinates + * and other things from normalized to pixel space. + */ + int frame_width, frame_height; + BKE_movieclip_get_size(clip, &user, &frame_width, &frame_height); + /* Actual mask sampling. */ + MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, frame); + const float region_min[2] = {region->min[0] - marker->pos[0] * frame_width, + region->min[1] - marker->pos[1] * frame_height}; + const float region_max[2] = {region->max[0] - marker->pos[0] * frame_width, + region->max[1] - marker->pos[1] * frame_height}; + *r_destination = tracking_track_get_mask_for_region(frame_width, frame_height, + region_min, + region_max, + track); + *r_width = region->max[0] - region->min[0]; + *r_height = region->max[1] - region->min[1]; + return *r_destination; +} + +static void accessor_release_mask_callback(libmv_CacheKey cache_key) +{ + if (cache_key != NULL) { + float *mask = (float *)cache_key; + MEM_freeN(mask); + } +} + TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR_CLIP], int num_clips, + MovieTrackingTrack **tracks, + int num_tracks, int start_frame) { TrackingImageAccessor *accessor = @@ -891,12 +947,16 @@ TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR memcpy(accessor->clips, clips, num_clips * sizeof(MovieClip *)); accessor->num_clips = num_clips; + accessor->tracks = tracks; + accessor->num_tracks = num_tracks; accessor->start_frame = start_frame; accessor->libmv_accessor = libmv_FrameAccessorNew((libmv_FrameAccessorUserData *) accessor, accessor_get_image_callback, - accessor_release_image_callback); + accessor_release_image_callback, + accessor_get_mask_for_track_callback, + accessor_release_mask_callback); return accessor; } diff --git a/source/blender/blenkernel/tracking_private.h b/source/blender/blenkernel/tracking_private.h index 591ee4d0d01..1a68a1cac6a 100644 --- a/source/blender/blenkernel/tracking_private.h +++ b/source/blender/blenkernel/tracking_private.h @@ -105,6 +105,13 @@ struct MovieTrackingMarker *tracking_get_keyframed_marker( int current_frame, bool backwards); +/*********************** Masking *************************/ + +float *tracking_track_get_mask_for_region(int frame_width, int frame_height, + const float region_min[2], + const float region_max[2], + MovieTrackingTrack *track); + /*********************** Frame accessr *************************/ struct libmv_FrameAccessor; @@ -114,12 +121,16 @@ typedef struct TrackingImageAccessor { struct MovieCache *cache; struct MovieClip *clips[MAX_ACCESSOR_CLIP]; int num_clips; + struct MovieTrackingTrack **tracks; + int num_tracks; int start_frame; struct libmv_FrameAccessor *libmv_accessor; } TrackingImageAccessor; TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR_CLIP], int num_clips, + MovieTrackingTrack **tracks, + int num_tracks, int start_frame); void tracking_image_accessor_destroy(TrackingImageAccessor *accessor); |