74
79
} tracking_clipboard;
76
/*********************** common functions *************************/
78
void BKE_tracking_init_settings(MovieTracking *tracking)
81
/*********************** Common functions *************************/
83
static MovieTrackingTrack *tracking_track_duplicate(MovieTrackingTrack *track)
85
MovieTrackingTrack *new_track;
87
new_track = MEM_callocN(sizeof(MovieTrackingTrack), "tracksMapMerge new_track");
90
new_track->next = new_track->prev = NULL;
92
new_track->markers = MEM_dupallocN(new_track->markers);
97
static void tracking_tracks_free(ListBase *tracks)
99
MovieTrackingTrack *track;
101
for (track = tracks->first; track; track = track->next) {
102
BKE_tracking_track_free(track);
105
BLI_freelistN(tracks);
108
static void tracking_reconstruction_free(MovieTrackingReconstruction *reconstruction)
110
if (reconstruction->cameras)
111
MEM_freeN(reconstruction->cameras);
114
static void tracking_object_free(MovieTrackingObject *object)
116
tracking_tracks_free(&object->tracks);
117
tracking_reconstruction_free(&object->reconstruction);
120
static void tracking_objects_free(ListBase *objects)
122
MovieTrackingObject *object;
124
for (object = objects->first; object; object = object->next)
125
tracking_object_free(object);
127
BLI_freelistN(objects);
130
static void tracking_dopesheet_free(MovieTrackingDopesheet *dopesheet)
132
MovieTrackingDopesheetChannel *channel;
134
channel = dopesheet->channels.first;
136
if (channel->segments) {
137
MEM_freeN(channel->segments);
140
channel = channel->next;
143
BLI_freelistN(&dopesheet->channels);
145
dopesheet->channels.first = dopesheet->channels.last = NULL;
146
dopesheet->tot_channel = 0;
149
void BKE_tracking_free(MovieTracking *tracking)
151
tracking_tracks_free(&tracking->tracks);
152
tracking_reconstruction_free(&tracking->reconstruction);
153
tracking_objects_free(&tracking->objects);
155
if (tracking->stabilization.scaleibuf)
156
IMB_freeImBuf(tracking->stabilization.scaleibuf);
158
if (tracking->camera.intrinsics)
159
BKE_tracking_distortion_free(tracking->camera.intrinsics);
161
tracking_dopesheet_free(&tracking->dopesheet);
164
void BKE_tracking_settings_init(MovieTracking *tracking)
80
166
tracking->camera.sensor_width = 35.0f;
81
167
tracking->camera.pixel_aspect = 1.0f;
82
168
tracking->camera.units = CAMERA_UNITS_MM;
84
tracking->settings.default_tracker = TRACKER_HYBRID;
170
tracking->settings.default_motion_model = TRACK_MOTION_MODEL_TRANSLATION;
85
171
tracking->settings.default_minimum_correlation = 0.75;
86
tracking->settings.default_pattern_size = 11;
172
tracking->settings.default_pattern_size = 15;
87
173
tracking->settings.default_search_size = 61;
88
tracking->settings.default_pyramid_levels = 2;
89
tracking->settings.keyframe1 = 1;
90
tracking->settings.keyframe2 = 30;
174
tracking->settings.default_algorithm_flag |= TRACK_ALGORITHM_FLAG_USE_BRUTE;
91
175
tracking->settings.dist = 1;
92
176
tracking->settings.object_distance = 1;
177
tracking->settings.reconstruction_success_threshold = 1e-3;
94
179
tracking->stabilization.scaleinf = 1.0f;
95
180
tracking->stabilization.locinf = 1.0f;
96
181
tracking->stabilization.rotinf = 1.0f;
97
182
tracking->stabilization.maxscale = 2.0f;
99
BKE_tracking_new_object(tracking, "Camera");
102
void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event)
107
float max_pyramid_level_factor = 1.0;
109
if (track->tracker == TRACKER_KLT) {
110
max_pyramid_level_factor= 1 << (track->pyramid_levels - 1);
114
for (a = 0; a < 2; a++) {
115
if (track->pat_min[a] > track->pat_max[a])
116
SWAP(float, track->pat_min[a], track->pat_max[a]);
118
if (track->search_min[a] > track->search_max[a])
119
SWAP(float, track->search_min[a], track->search_max[a]);
122
/* compute the effective pattern size, which differs from the fine resolution
123
* pattern size for the pyramid KLT tracker */
124
for (a = 0; a < 2; a++) {
125
pat_min[a] = max_pyramid_level_factor * track->pat_min[a];
126
pat_max[a] = max_pyramid_level_factor * track->pat_max[a];
129
if (event == CLAMP_PAT_DIM) {
130
for (a = 0; a < 2; a++) {
131
/* search shouldn't be resized smaller than pattern */
132
track->search_min[a] = MIN2(pat_min[a], track->search_min[a]);
133
track->search_max[a] = MAX2(pat_max[a], track->search_max[a]);
136
else if (event == CLAMP_PAT_POS) {
139
sub_v2_v2v2(dim, track->pat_max, track->pat_min);
141
for (a = 0; a < 2; a++) {
142
/* pattern shouldn't be moved outside of search */
143
if (pat_min[a] < track->search_min[a]) {
144
track->pat_min[a] = track->search_min[a] - (pat_min[a] - track->pat_min[a]);
145
track->pat_max[a] = track->pat_min[a] + dim[a];
147
if (track->pat_max[a] > track->search_max[a]) {
148
track->pat_max[a] = track->search_max[a] - (pat_max[a] - track->pat_max[a]);
149
track->pat_min[a] = track->pat_max[a] - dim[a];
153
else if (event == CLAMP_SEARCH_DIM) {
154
for (a = 0; a < 2; a++) {
155
/* search shouldn't be resized smaller than pattern */
156
track->search_min[a] = MIN2(pat_min[a], track->search_min[a]);
157
track->search_max[a] = MAX2(pat_max[a], track->search_max[a]);
160
else if (event == CLAMP_SEARCH_POS) {
163
sub_v2_v2v2(dim, track->search_max, track->search_min);
165
for (a = 0; a < 2; a++) {
166
/* search shouldn't be moved inside pattern */
167
if (track->search_min[a] > pat_min[a]) {
168
track->search_min[a] = pat_min[a];
169
track->search_max[a] = track->search_min[a]+dim[a];
171
if (track->search_max[a] < pat_max[a]) {
172
track->search_max[a] = pat_max[a];
173
track->search_min[a] = track->search_max[a]-dim[a];
177
else if (event == CLAMP_PYRAMID_LEVELS || (event == CLAMP_SEARCH_DIM && track->tracker == TRACKER_KLT)) {
179
sub_v2_v2v2(dim, track->pat_max, track->pat_min);
181
float search_ratio = 2.3f * max_pyramid_level_factor;
183
/* resize the search area to something sensible based
184
* on the number of pyramid levels */
185
for (a = 0; a < 2; a++) {
186
track->search_min[a] = search_ratio * track->pat_min[a];
187
track->search_max[a] = search_ratio * track->pat_max[a];
192
/* marker's center should be in center of pattern */
193
if (event == CLAMP_PAT_DIM || event == CLAMP_PAT_POS) {
196
sub_v2_v2v2(dim, track->pat_max, track->pat_min);
198
for (a = 0; a < 2; a++) {
199
track->pat_min[a] = -dim[a]/2.0f;
200
track->pat_max[a] = dim[a]/2.0f;
205
void BKE_tracking_track_flag(MovieTrackingTrack *track, int area, int flag, int clear)
207
if (area == TRACK_AREA_NONE)
211
if (area & TRACK_AREA_POINT)
212
track->flag &= ~flag;
213
if (area & TRACK_AREA_PAT)
214
track->pat_flag &= ~flag;
215
if (area & TRACK_AREA_SEARCH)
216
track->search_flag &= ~flag;
219
if (area & TRACK_AREA_POINT)
221
if (area & TRACK_AREA_PAT)
222
track->pat_flag |= flag;
223
if (area & TRACK_AREA_SEARCH)
224
track->search_flag |= flag;
228
MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, ListBase *tracksbase, float x, float y,
184
BKE_tracking_object_add(tracking, "Camera");
187
ListBase *BKE_tracking_get_active_tracks(MovieTracking *tracking)
189
MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
191
if (object && (object->flag & TRACKING_OBJECT_CAMERA) == 0) {
192
return &object->tracks;
195
return &tracking->tracks;
198
MovieTrackingReconstruction *BKE_tracking_get_active_reconstruction(MovieTracking *tracking)
200
MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
202
return BKE_tracking_object_get_reconstruction(tracking, object);
205
void BKE_tracking_get_camera_object_matrix(Scene *scene, Object *ob, float mat[4][4])
211
ob = BKE_scene_camera_find(scene);
215
BKE_object_where_is_calc_mat4(scene, ob, mat);
220
void BKE_tracking_get_projection_matrix(MovieTracking *tracking, MovieTrackingObject *object,
221
int framenr, int winx, int winy, float mat[4][4])
223
MovieReconstructedCamera *camera;
224
float lens = tracking->camera.focal * tracking->camera.sensor_width / (float)winx;
225
float viewfac, pixsize, left, right, bottom, top, clipsta, clipend;
227
float ycor = 1.0f / tracking->camera.pixel_aspect;
228
float shiftx, shifty, winside = (float)min_ii(winx, winy);
230
BKE_tracking_camera_shift_get(tracking, winx, winy, &shiftx, &shifty);
236
viewfac = (lens * winx) / tracking->camera.sensor_width;
238
viewfac = (ycor * lens * winy) / tracking->camera.sensor_width;
240
pixsize = clipsta / viewfac;
242
left = -0.5f * (float)winx + shiftx * winside;
243
bottom = -0.5f * (ycor) * (float)winy + shifty * winside;
244
right = 0.5f * (float)winx + shiftx * winside;
245
top = 0.5f * (ycor) * (float)winy + shifty * winside;
252
perspective_m4(winmat, left, right, bottom, top, clipsta, clipend);
254
camera = BKE_tracking_camera_get_reconstructed(tracking, object, framenr);
259
invert_m4_m4(imat, camera->mat);
260
mult_m4_m4m4(mat, winmat, imat);
262
else copy_m4_m4(mat, winmat);
265
/* **** space transformation functions **** */
267
/* Three coordinate frames: Frame, Search, and Marker
268
* Two units: Pixels, Unified
269
* Notation: {coordinate frame}_{unit}; for example, "search_pixel" are search
270
* window relative coordinates in pixels, and "frame_unified" are unified 0..1
271
* coordinates relative to the entire frame.
273
static void unified_to_pixel(int frame_width, int frame_height,
274
const float unified_coords[2], float pixel_coords[2])
276
pixel_coords[0] = unified_coords[0] * frame_width;
277
pixel_coords[1] = unified_coords[1] * frame_height;
280
static void marker_to_frame_unified(const MovieTrackingMarker *marker, const float marker_unified_coords[2],
281
float frame_unified_coords[2])
283
frame_unified_coords[0] = marker_unified_coords[0] + marker->pos[0];
284
frame_unified_coords[1] = marker_unified_coords[1] + marker->pos[1];
287
static void marker_unified_to_frame_pixel_coordinates(int frame_width, int frame_height,
288
const MovieTrackingMarker *marker,
289
const float marker_unified_coords[2],
290
float frame_pixel_coords[2])
292
marker_to_frame_unified(marker, marker_unified_coords, frame_pixel_coords);
293
unified_to_pixel(frame_width, frame_height, frame_pixel_coords, frame_pixel_coords);
296
static void get_search_origin_frame_pixel(int frame_width, int frame_height,
297
const MovieTrackingMarker *marker, float frame_pixel[2])
299
/* Get the lower left coordinate of the search window and snap to pixel coordinates */
300
marker_unified_to_frame_pixel_coordinates(frame_width, frame_height, marker, marker->search_min, frame_pixel);
301
frame_pixel[0] = (int)frame_pixel[0];
302
frame_pixel[1] = (int)frame_pixel[1];
306
static void pixel_to_unified(int frame_width, int frame_height, const float pixel_coords[2], float unified_coords[2])
308
unified_coords[0] = pixel_coords[0] / frame_width;
309
unified_coords[1] = pixel_coords[1] / frame_height;
312
static void marker_unified_to_search_pixel(int frame_width, int frame_height,
313
const MovieTrackingMarker *marker,
314
const float marker_unified[2], float search_pixel[2])
316
float frame_pixel[2];
317
float search_origin_frame_pixel[2];
319
marker_unified_to_frame_pixel_coordinates(frame_width, frame_height, marker, marker_unified, frame_pixel);
320
get_search_origin_frame_pixel(frame_width, frame_height, marker, search_origin_frame_pixel);
321
sub_v2_v2v2(search_pixel, frame_pixel, search_origin_frame_pixel);
324
static void search_pixel_to_marker_unified(int frame_width, int frame_height,
325
const MovieTrackingMarker *marker,
326
const float search_pixel[2], float marker_unified[2])
328
float frame_unified[2];
329
float search_origin_frame_pixel[2];
331
get_search_origin_frame_pixel(frame_width, frame_height, marker, search_origin_frame_pixel);
332
add_v2_v2v2(frame_unified, search_pixel, search_origin_frame_pixel);
333
pixel_to_unified(frame_width, frame_height, frame_unified, frame_unified);
335
/* marker pos is in frame unified */
336
sub_v2_v2v2(marker_unified, frame_unified, marker->pos);
339
/* Each marker has 5 coordinates associated with it that get warped with
340
* tracking: the four corners ("pattern_corners"), and the center ("pos").
341
* This function puts those 5 points into the appropriate frame for tracking
342
* (the "search" coordinate frame).
344
static void get_marker_coords_for_tracking(int frame_width, int frame_height,
345
const MovieTrackingMarker *marker,
346
double search_pixel_x[5], double search_pixel_y[5])
349
float unified_coords[2];
350
float pixel_coords[2];
352
/* Convert the corners into search space coordinates. */
353
for (i = 0; i < 4; i++) {
354
marker_unified_to_search_pixel(frame_width, frame_height, marker, marker->pattern_corners[i], pixel_coords);
355
search_pixel_x[i] = pixel_coords[0];
356
search_pixel_y[i] = pixel_coords[1];
359
/* Convert the center position (aka "pos"); this is the origin */
360
unified_coords[0] = 0.0;
361
unified_coords[1] = 0.0;
362
marker_unified_to_search_pixel(frame_width, frame_height, marker, unified_coords, pixel_coords);
364
search_pixel_x[4] = pixel_coords[0];
365
search_pixel_y[4] = pixel_coords[1];
368
/* Inverse of above. */
369
static void set_marker_coords_from_tracking(int frame_width, int frame_height, MovieTrackingMarker *marker,
370
const double search_pixel_x[5], const double search_pixel_y[5])
373
float marker_unified[2];
374
float search_pixel[2];
376
/* Convert the corners into search space coordinates. */
377
for (i = 0; i < 4; i++) {
378
search_pixel[0] = search_pixel_x[i];
379
search_pixel[1] = search_pixel_y[i];
380
search_pixel_to_marker_unified(frame_width, frame_height, marker, search_pixel, marker->pattern_corners[i]);
383
/* Convert the center position (aka "pos"); this is the origin */
384
search_pixel[0] = search_pixel_x[4];
385
search_pixel[1] = search_pixel_y[4];
386
search_pixel_to_marker_unified(frame_width, frame_height, marker, search_pixel, marker_unified);
388
/* If the tracker tracked nothing, then "marker_unified" would be zero.
389
* Otherwise, the entire patch shifted, and that delta should be applied to
390
* all the coordinates.
392
for (i = 0; i < 4; i++) {
393
marker->pattern_corners[i][0] -= marker_unified[0];
394
marker->pattern_corners[i][1] -= marker_unified[1];
397
marker->pos[0] += marker_unified[0];
398
marker->pos[1] += marker_unified[1];
402
/*********************** clipboard *************************/
404
void BKE_tracking_clipboard_free(void)
406
MovieTrackingTrack *track = tracking_clipboard.tracks.first, *next_track;
409
next_track = track->next;
411
BKE_tracking_track_free(track);
417
tracking_clipboard.tracks.first = tracking_clipboard.tracks.last = NULL;
420
void BKE_tracking_clipboard_copy_tracks(MovieTracking *tracking, MovieTrackingObject *object)
422
ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
423
MovieTrackingTrack *track = tracksbase->first;
425
BKE_tracking_clipboard_free();
428
if (TRACK_SELECTED(track) && (track->flag & TRACK_HIDDEN) == 0) {
429
MovieTrackingTrack *new_track = tracking_track_duplicate(track);
431
BLI_addtail(&tracking_clipboard.tracks, new_track);
438
int BKE_tracking_clipboard_has_tracks(void)
440
return tracking_clipboard.tracks.first != NULL;
443
void BKE_tracking_clipboard_paste_tracks(MovieTracking *tracking, MovieTrackingObject *object)
445
ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
446
MovieTrackingTrack *track = tracking_clipboard.tracks.first;
449
MovieTrackingTrack *new_track = tracking_track_duplicate(track);
451
BLI_addtail(tracksbase, new_track);
452
BKE_tracking_track_unique_name(tracksbase, new_track);
458
/*********************** Tracks *************************/
460
static void tracking_marker_insert_disabled(MovieTrackingTrack *track, const MovieTrackingMarker *ref_marker,
461
int before, int overwrite)
463
MovieTrackingMarker marker_new;
465
marker_new = *ref_marker;
466
marker_new.flag &= ~MARKER_TRACKED;
467
marker_new.flag |= MARKER_DISABLED;
470
marker_new.framenr--;
472
marker_new.framenr++;
474
if (overwrite || !BKE_tracking_track_has_marker_at_frame(track, marker_new.framenr))
475
BKE_tracking_marker_insert(track, &marker_new);
478
MovieTrackingTrack *BKE_tracking_track_add(MovieTracking *tracking, ListBase *tracksbase, float x, float y,
229
479
int framenr, int width, int height)
231
481
MovieTrackingTrack *track;
245
495
track = MEM_callocN(sizeof(MovieTrackingTrack), "add_marker_exec track");
246
496
strcpy(track->name, "Track");
248
track->tracker = settings->default_tracker;
249
track->pyramid_levels = settings->default_pyramid_levels;
498
/* fill track's settings from default settings */
499
track->motion_model = settings->default_motion_model;
250
500
track->minimum_correlation = settings->default_minimum_correlation;
251
501
track->margin = settings->default_margin;
252
502
track->pattern_match = settings->default_pattern_match;
253
503
track->frames_limit = settings->default_frames_limit;
254
504
track->flag = settings->default_flag;
505
track->algorithm_flag = settings->default_algorithm_flag;
256
507
memset(&marker, 0, sizeof(marker));
257
508
marker.pos[0] = x;
258
509
marker.pos[1] = y;
259
510
marker.framenr = framenr;
261
copy_v2_v2(track->pat_max, pat);
262
negate_v2_v2(track->pat_min, pat);
264
copy_v2_v2(track->search_max, search);
265
negate_v2_v2(track->search_min, search);
267
BKE_tracking_insert_marker(track, &marker);
269
if (track->tracker == TRACKER_KLT)
270
BKE_tracking_clamp_track(track, CLAMP_PYRAMID_LEVELS);
512
marker.pattern_corners[0][0] = -pat[0];
513
marker.pattern_corners[0][1] = -pat[1];
515
marker.pattern_corners[1][0] = pat[0];
516
marker.pattern_corners[1][1] = -pat[1];
518
negate_v2_v2(marker.pattern_corners[2], marker.pattern_corners[0]);
519
negate_v2_v2(marker.pattern_corners[3], marker.pattern_corners[1]);
521
copy_v2_v2(marker.search_max, search);
522
negate_v2_v2(marker.search_min, search);
524
BKE_tracking_marker_insert(track, &marker);
272
526
BLI_addtail(tracksbase, track);
273
BKE_track_unique_name(tracksbase, track);
527
BKE_tracking_track_unique_name(tracksbase, track);
278
MovieTrackingMarker *BKE_tracking_insert_marker(MovieTrackingTrack *track, MovieTrackingMarker *marker)
280
MovieTrackingMarker *old_marker= NULL;
282
if (track->markersnr)
283
old_marker = BKE_tracking_exact_marker(track, marker->framenr);
286
*old_marker = *marker;
291
int a = track->markersnr;
294
if (track->markers[a].framenr < marker->framenr)
301
track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker)*track->markersnr);
303
track->markers = MEM_callocN(sizeof(MovieTrackingMarker), "MovieTracking markers");
305
memmove(track->markers+a+2, track->markers+a+1, (track->markersnr-a-2)*sizeof(MovieTrackingMarker));
306
track->markers[a+1] = *marker;
308
track->last_marker = a + 1;
310
return &track->markers[a + 1];
314
void BKE_tracking_delete_marker(MovieTrackingTrack *track, int framenr)
318
while (a<track->markersnr) {
319
if (track->markers[a].framenr == framenr) {
320
if (track->markersnr > 1) {
321
memmove(track->markers+a, track->markers+a+1, (track->markersnr-a-1)*sizeof(MovieTrackingMarker));
323
track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker)*track->markersnr);
326
MEM_freeN(track->markers);
327
track->markers = NULL;
328
track->markersnr = 0;
338
MovieTrackingMarker *BKE_tracking_get_marker(MovieTrackingTrack *track, int framenr)
340
int a = track->markersnr-1;
342
if (!track->markersnr)
345
/* approximate pre-first framenr marker with first marker */
346
if (framenr < track->markers[0].framenr)
347
return &track->markers[0];
349
if (track->last_marker < track->markersnr)
350
a = track->last_marker;
352
if (track->markers[a].framenr <= framenr) {
353
while (a < track->markersnr && track->markers[a].framenr <= framenr) {
354
if (track->markers[a].framenr == framenr) {
355
track->last_marker = a;
357
return &track->markers[a];
362
/* if there's no marker for exact position, use nearest marker from left side */
363
return &track->markers[a-1];
366
while (a >= 0 && track->markers[a].framenr >= framenr) {
367
if (track->markers[a].framenr == framenr) {
368
track->last_marker = a;
370
return &track->markers[a];
376
/* if there's no marker for exact position, use nearest marker from left side */
377
return &track->markers[a];
383
MovieTrackingMarker *BKE_tracking_ensure_marker(MovieTrackingTrack *track, int framenr)
385
MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr);
387
if (marker->framenr != framenr) {
388
MovieTrackingMarker marker_new;
390
marker_new = *marker;
391
marker_new.framenr = framenr;
393
BKE_tracking_insert_marker(track, &marker_new);
394
marker = BKE_tracking_get_marker(track, framenr);
400
MovieTrackingMarker *BKE_tracking_exact_marker(MovieTrackingTrack *track, int framenr)
402
MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr);
404
if (marker->framenr != framenr)
410
int BKE_tracking_has_marker(MovieTrackingTrack *track, int framenr)
412
return BKE_tracking_exact_marker(track, framenr) != 0;
415
int BKE_tracking_has_enabled_marker(MovieTrackingTrack *track, int framenr)
417
MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr);
532
void BKE_tracking_track_unique_name(ListBase *tracksbase, MovieTrackingTrack *track)
534
BLI_uniquename(tracksbase, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name));
537
void BKE_tracking_track_free(MovieTrackingTrack *track)
540
MEM_freeN(track->markers);
543
void BKE_tracking_track_flag_set(MovieTrackingTrack *track, int area, int flag)
545
if (area == TRACK_AREA_NONE)
548
if (area & TRACK_AREA_POINT)
550
if (area & TRACK_AREA_PAT)
551
track->pat_flag |= flag;
552
if (area & TRACK_AREA_SEARCH)
553
track->search_flag |= flag;
556
void BKE_tracking_track_flag_clear(MovieTrackingTrack *track, int area, int flag)
558
if (area == TRACK_AREA_NONE)
561
if (area & TRACK_AREA_POINT)
562
track->flag &= ~flag;
563
if (area & TRACK_AREA_PAT)
564
track->pat_flag &= ~flag;
565
if (area & TRACK_AREA_SEARCH)
566
track->search_flag &= ~flag;
569
int BKE_tracking_track_has_marker_at_frame(MovieTrackingTrack *track, int framenr)
571
return BKE_tracking_marker_get_exact(track, framenr) != 0;
574
int BKE_tracking_track_has_enabled_marker_at_frame(MovieTrackingTrack *track, int framenr)
576
MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, framenr);
419
578
return marker && (marker->flag & MARKER_DISABLED) == 0;
422
void BKE_tracking_free_track(MovieTrackingTrack *track)
425
MEM_freeN(track->markers);
428
static void put_disabled_marker(MovieTrackingTrack *track, MovieTrackingMarker *ref_marker, int before, int overwrite)
430
MovieTrackingMarker marker_new;
432
marker_new = *ref_marker;
433
marker_new.flag &= ~MARKER_TRACKED;
434
marker_new.flag |= MARKER_DISABLED;
437
marker_new.framenr--;
439
marker_new.framenr++;
441
if (!BKE_tracking_has_marker(track, marker_new.framenr) || overwrite)
442
BKE_tracking_insert_marker(track, &marker_new);
445
void BKE_tracking_clear_path(MovieTrackingTrack *track, int ref_frame, int action)
581
void BKE_tracking_track_path_clear(MovieTrackingTrack *track, int ref_frame, int action)
592
733
MEM_freeN(dst_track->markers);
594
dst_track->markers = MEM_callocN(i*sizeof(MovieTrackingMarker), "tracking joined tracks");
595
memcpy(dst_track->markers, markers, i*sizeof(MovieTrackingMarker));
735
dst_track->markers = MEM_callocN(i * sizeof(MovieTrackingMarker), "tracking joined tracks");
736
memcpy(dst_track->markers, markers, i * sizeof(MovieTrackingMarker));
597
738
dst_track->markersnr = i;
599
740
MEM_freeN(markers);
602
static void tracking_tracks_free(ListBase *tracks)
742
BKE_tracking_dopesheet_tag_update(tracking);
745
MovieTrackingTrack *BKE_tracking_track_get_named(MovieTracking *tracking, MovieTrackingObject *object, const char *name)
747
ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
748
MovieTrackingTrack *track = tracksbase->first;
751
if (!strcmp(track->name, name))
760
MovieTrackingTrack *BKE_tracking_track_get_indexed(MovieTracking *tracking, int tracknr, ListBase **tracksbase_r)
762
MovieTrackingObject *object;
765
object = tracking->objects.first;
767
ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
768
MovieTrackingTrack *track = tracksbase->first;
771
if (track->flag & TRACK_HAS_BUNDLE) {
772
if (cur == tracknr) {
773
*tracksbase_r = tracksbase;
783
object = object->next;
786
*tracksbase_r = NULL;
791
MovieTrackingTrack *BKE_tracking_track_get_active(MovieTracking *tracking)
793
ListBase *tracksbase;
795
if (!tracking->act_track)
798
tracksbase = BKE_tracking_get_active_tracks(tracking);
800
/* check that active track is in current tracks list */
801
if (BLI_findindex(tracksbase, tracking->act_track) >= 0)
802
return tracking->act_track;
807
static bGPDlayer *track_mask_gpencil_layer_get(MovieTrackingTrack *track)
814
layer = track->gpd->layers.first;
817
if (layer->flag & GP_LAYER_ACTIVE) {
818
bGPDframe *frame = layer->frames.first;
822
if (frame->strokes.first) {
839
static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height,
840
MovieTrackingMarker *marker, bGPDlayer *layer,
841
float *mask, int mask_width, int mask_height)
843
bGPDframe *frame = layer->frames.first;
846
bGPDstroke *stroke = frame->strokes.first;
849
bGPDspoint *stroke_points = stroke->points;
850
float *mask_points, *fp;
853
if (stroke->flag & GP_STROKE_2DSPACE) {
854
fp = mask_points = MEM_callocN(2 * stroke->totpoints * sizeof(float),
855
"track mask rasterization points");
857
for (i = 0; i < stroke->totpoints; i++, fp += 2) {
858
fp[0] = (stroke_points[i].x - marker->search_min[0]) * frame_width / mask_width;
859
fp[1] = (stroke_points[i].y - marker->search_min[1]) * frame_height / mask_height;
862
/* TODO: add an option to control whether AA is enabled or not */
863
PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, mask_width, mask_height);
865
MEM_freeN(mask_points);
868
stroke = stroke->next;
875
float *BKE_tracking_track_get_mask(int frame_width, int frame_height,
876
MovieTrackingTrack *track, MovieTrackingMarker *marker)
879
bGPDlayer *layer = track_mask_gpencil_layer_get(track);
880
int mask_width, mask_height;
882
mask_width = (marker->search_max[0] - marker->search_min[0]) * frame_width;
883
mask_height = (marker->search_max[1] - marker->search_min[1]) * frame_height;
886
mask = MEM_callocN(mask_width * mask_height * sizeof(float), "track mask");
888
track_mask_gpencil_layer_rasterize(frame_width, frame_height, marker, layer,
889
mask, mask_width, mask_height);
895
/* area - which part of marker should be selected. see TRACK_AREA_* constants */
896
void BKE_tracking_track_select(ListBase *tracksbase, MovieTrackingTrack *track, int area, int extend)
899
BKE_tracking_track_flag_set(track, area, SELECT);
902
MovieTrackingTrack *cur = tracksbase->first;
905
if ((cur->flag & TRACK_HIDDEN) == 0) {
907
BKE_tracking_track_flag_clear(cur, TRACK_AREA_ALL, SELECT);
908
BKE_tracking_track_flag_set(cur, area, SELECT);
911
BKE_tracking_track_flag_clear(cur, TRACK_AREA_ALL, SELECT);
920
void BKE_tracking_track_deselect(MovieTrackingTrack *track, int area)
922
BKE_tracking_track_flag_clear(track, area, SELECT);
925
/*********************** Marker *************************/
927
MovieTrackingMarker *BKE_tracking_marker_insert(MovieTrackingTrack *track, MovieTrackingMarker *marker)
929
MovieTrackingMarker *old_marker = NULL;
931
if (track->markersnr)
932
old_marker = BKE_tracking_marker_get_exact(track, marker->framenr);
935
/* simply replace settings for already allocated marker */
936
*old_marker = *marker;
941
int a = track->markersnr;
943
/* find position in array where to add new marker */
945
if (track->markers[a].framenr < marker->framenr)
952
track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr);
954
track->markers = MEM_callocN(sizeof(MovieTrackingMarker), "MovieTracking markers");
956
/* shift array to "free" space for new marker */
957
memmove(track->markers + a + 2, track->markers + a + 1,
958
(track->markersnr - a - 2) * sizeof(MovieTrackingMarker));
961
track->markers[a + 1] = *marker;
963
track->last_marker = a + 1;
965
return &track->markers[a + 1];
969
void BKE_tracking_marker_delete(MovieTrackingTrack *track, int framenr)
973
while (a < track->markersnr) {
974
if (track->markers[a].framenr == framenr) {
975
if (track->markersnr > 1) {
976
memmove(track->markers + a, track->markers + a + 1,
977
(track->markersnr - a - 1) * sizeof(MovieTrackingMarker));
979
track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr);
982
MEM_freeN(track->markers);
983
track->markers = NULL;
984
track->markersnr = 0;
994
void BKE_tracking_marker_clamp(MovieTrackingMarker *marker, int event)
997
float pat_min[2], pat_max[2];
999
BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
1001
if (event == CLAMP_PAT_DIM) {
1002
for (a = 0; a < 2; a++) {
1003
/* search shouldn't be resized smaller than pattern */
1004
marker->search_min[a] = min_ff(pat_min[a], marker->search_min[a]);
1005
marker->search_max[a] = max_ff(pat_max[a], marker->search_max[a]);
1008
else if (event == CLAMP_PAT_POS) {
1011
sub_v2_v2v2(dim, pat_max, pat_min);
1013
for (a = 0; a < 2; a++) {
1015
/* pattern shouldn't be moved outside of search */
1016
if (pat_min[a] < marker->search_min[a]) {
1017
for (b = 0; b < 4; b++)
1018
marker->pattern_corners[b][a] += marker->search_min[a] - pat_min[a];
1020
if (pat_max[a] > marker->search_max[a]) {
1021
for (b = 0; b < 4; b++)
1022
marker->pattern_corners[b][a] -= pat_max[a] - marker->search_max[a];
1026
else if (event == CLAMP_SEARCH_DIM) {
1027
for (a = 0; a < 2; a++) {
1028
/* search shouldn't be resized smaller than pattern */
1029
marker->search_min[a] = min_ff(pat_min[a], marker->search_min[a]);
1030
marker->search_max[a] = max_ff(pat_max[a], marker->search_max[a]);
1033
else if (event == CLAMP_SEARCH_POS) {
1036
sub_v2_v2v2(dim, marker->search_max, marker->search_min);
1038
for (a = 0; a < 2; a++) {
1039
/* search shouldn't be moved inside pattern */
1040
if (marker->search_min[a] > pat_min[a]) {
1041
marker->search_min[a] = pat_min[a];
1042
marker->search_max[a] = marker->search_min[a] + dim[a];
1044
if (marker->search_max[a] < pat_max[a]) {
1045
marker->search_max[a] = pat_max[a];
1046
marker->search_min[a] = marker->search_max[a] - dim[a];
1052
MovieTrackingMarker *BKE_tracking_marker_get(MovieTrackingTrack *track, int framenr)
1054
int a = track->markersnr - 1;
1056
if (!track->markersnr)
1059
/* approximate pre-first framenr marker with first marker */
1060
if (framenr < track->markers[0].framenr)
1061
return &track->markers[0];
1063
if (track->last_marker < track->markersnr)
1064
a = track->last_marker;
1066
if (track->markers[a].framenr <= framenr) {
1067
while (a < track->markersnr && track->markers[a].framenr <= framenr) {
1068
if (track->markers[a].framenr == framenr) {
1069
track->last_marker = a;
1071
return &track->markers[a];
1076
/* if there's no marker for exact position, use nearest marker from left side */
1077
return &track->markers[a - 1];
1080
while (a >= 0 && track->markers[a].framenr >= framenr) {
1081
if (track->markers[a].framenr == framenr) {
1082
track->last_marker = a;
1084
return &track->markers[a];
1090
/* if there's no marker for exact position, use nearest marker from left side */
1091
return &track->markers[a];
1097
MovieTrackingMarker *BKE_tracking_marker_get_exact(MovieTrackingTrack *track, int framenr)
1099
MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
1101
if (marker->framenr != framenr)
1107
MovieTrackingMarker *BKE_tracking_marker_ensure(MovieTrackingTrack *track, int framenr)
1109
MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
1111
if (marker->framenr != framenr) {
1112
MovieTrackingMarker marker_new;
1114
marker_new = *marker;
1115
marker_new.framenr = framenr;
1117
BKE_tracking_marker_insert(track, &marker_new);
1118
marker = BKE_tracking_marker_get(track, framenr);
1124
void BKE_tracking_marker_pattern_minmax(const MovieTrackingMarker *marker, float min[2], float max[2])
1126
INIT_MINMAX2(min, max);
1128
minmax_v2v2_v2(min, max, marker->pattern_corners[0]);
1129
minmax_v2v2_v2(min, max, marker->pattern_corners[1]);
1130
minmax_v2v2_v2(min, max, marker->pattern_corners[2]);
1131
minmax_v2v2_v2(min, max, marker->pattern_corners[3]);
1134
void BKE_tracking_marker_get_subframe_position(MovieTrackingTrack *track, float framenr, float pos[2])
1136
MovieTrackingMarker *marker = BKE_tracking_marker_get(track, (int) framenr);
1137
MovieTrackingMarker *marker_last = track->markers + (track->markersnr - 1);
1139
if (marker != marker_last) {
1140
MovieTrackingMarker *marker_next = marker + 1;
1142
if (marker_next->framenr == marker->framenr + 1) {
1143
/* currently only do subframing inside tracked ranges, do not extrapolate tracked segments
1144
* could be changed when / if mask parent would be interpolating position in-between
1148
float fac = (framenr - (int) framenr) / (marker_next->framenr - marker->framenr);
1150
interp_v2_v2v2(pos, marker->pos, marker_next->pos, fac);
1153
copy_v2_v2(pos, marker->pos);
1157
copy_v2_v2(pos, marker->pos);
1160
/* currently track offset is always wanted to be applied here, could be made an option later */
1161
add_v2_v2(pos, track->offset);
1164
/*********************** Object *************************/
1166
MovieTrackingObject *BKE_tracking_object_add(MovieTracking *tracking, const char *name)
1168
MovieTrackingObject *object = MEM_callocN(sizeof(MovieTrackingObject), "tracking object");
1170
if (tracking->tot_object == 0) {
1171
/* first object is always camera */
1172
BLI_strncpy(object->name, "Camera", sizeof(object->name));
1174
object->flag |= TRACKING_OBJECT_CAMERA;
1177
BLI_strncpy(object->name, name, sizeof(object->name));
1180
BLI_addtail(&tracking->objects, object);
1182
tracking->tot_object++;
1183
tracking->objectnr = BLI_countlist(&tracking->objects) - 1;
1185
object->scale = 1.0f;
1186
object->keyframe1 = 1;
1187
object->keyframe2 = 30;
1189
BKE_tracking_object_unique_name(tracking, object);
1194
int BKE_tracking_object_delete(MovieTracking *tracking, MovieTrackingObject *object)
604
1196
MovieTrackingTrack *track;
606
for (track = tracks->first; track; track = track->next) {
607
BKE_tracking_free_track(track);
610
BLI_freelistN(tracks);
613
static void tracking_reconstruction_free(MovieTrackingReconstruction *reconstruction)
615
if (reconstruction->cameras)
616
MEM_freeN(reconstruction->cameras);
619
static void tracking_object_free(MovieTrackingObject *object)
621
tracking_tracks_free(&object->tracks);
622
tracking_reconstruction_free(&object->reconstruction);
625
static void tracking_objects_free(ListBase *objects)
627
MovieTrackingObject *object;
629
for (object = objects->first; object; object = object->next)
630
tracking_object_free(object);
632
BLI_freelistN(objects);
635
void BKE_tracking_free(MovieTracking *tracking)
637
tracking_tracks_free(&tracking->tracks);
638
tracking_reconstruction_free(&tracking->reconstruction);
639
tracking_objects_free(&tracking->objects);
641
if (tracking->stabilization.scaleibuf)
642
IMB_freeImBuf(tracking->stabilization.scaleibuf);
644
if (tracking->camera.intrinsics)
645
BKE_tracking_distortion_destroy(tracking->camera.intrinsics);
648
static MovieTrackingTrack *duplicate_track(MovieTrackingTrack *track)
650
MovieTrackingTrack *new_track;
652
new_track = MEM_callocN(sizeof(MovieTrackingTrack), "tracksMapMerge new_track");
655
new_track->next = new_track->prev = NULL;
657
new_track->markers = MEM_dupallocN(new_track->markers);
662
/*********************** clipboard *************************/
664
void BKE_tracking_free_clipboard(void)
666
MovieTrackingTrack *track = tracking_clipboard.tracks.first, *next_track;
669
next_track = track->next;
671
BKE_tracking_free_track(track);
678
void BKE_tracking_clipboard_copy_tracks(MovieTracking *tracking, MovieTrackingObject *object)
680
ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object);
681
MovieTrackingTrack *track = tracksbase->first;
683
BKE_tracking_free_clipboard();
686
if (TRACK_SELECTED(track) && (track->flag & TRACK_HIDDEN) == 0) {
687
MovieTrackingTrack *new_track = duplicate_track(track);
689
BLI_addtail(&tracking_clipboard.tracks, new_track);
696
int BKE_tracking_clipboard_has_tracks(void)
698
return tracking_clipboard.tracks.first != NULL;
701
void BKE_tracking_clipboard_paste_tracks(MovieTracking *tracking, MovieTrackingObject *object)
703
ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object);
704
MovieTrackingTrack *track = tracking_clipboard.tracks.first;
707
MovieTrackingTrack *new_track = duplicate_track(track);
709
BLI_addtail(tracksbase, new_track);
710
BKE_track_unique_name(tracksbase, new_track);
716
/*********************** tracks map *************************/
1197
int index = BLI_findindex(&tracking->objects, object);
1202
if (object->flag & TRACKING_OBJECT_CAMERA) {
1203
/* object used for camera solving can't be deleted */
1207
track = object->tracks.first;
1209
if (track == tracking->act_track)
1210
tracking->act_track = NULL;
1212
track = track->next;
1215
tracking_object_free(object);
1216
BLI_freelinkN(&tracking->objects, object);
1218
tracking->tot_object--;
1221
tracking->objectnr = index - 1;
1223
tracking->objectnr = 0;
1227
void BKE_tracking_object_unique_name(MovieTracking *tracking, MovieTrackingObject *object)
1229
BLI_uniquename(&tracking->objects, object, "Object", '.',
1230
offsetof(MovieTrackingObject, name), sizeof(object->name));
1233
MovieTrackingObject *BKE_tracking_object_get_named(MovieTracking *tracking, const char *name)
1235
MovieTrackingObject *object = tracking->objects.first;
1238
if (!strcmp(object->name, name))
1241
object = object->next;
1247
MovieTrackingObject *BKE_tracking_object_get_active(MovieTracking *tracking)
1249
return BLI_findlink(&tracking->objects, tracking->objectnr);
1252
MovieTrackingObject *BKE_tracking_object_get_camera(MovieTracking *tracking)
1254
MovieTrackingObject *object = tracking->objects.first;
1257
if (object->flag & TRACKING_OBJECT_CAMERA)
1260
object = object->next;
1266
ListBase *BKE_tracking_object_get_tracks(MovieTracking *tracking, MovieTrackingObject *object)
1268
if (object->flag & TRACKING_OBJECT_CAMERA) {
1269
return &tracking->tracks;
1272
return &object->tracks;
1275
MovieTrackingReconstruction *BKE_tracking_object_get_reconstruction(MovieTracking *tracking,
1276
MovieTrackingObject *object)
1278
if (object->flag & TRACKING_OBJECT_CAMERA) {
1279
return &tracking->reconstruction;
1282
return &object->reconstruction;
1285
/*********************** Camera *************************/
1287
static int reconstructed_camera_index_get(MovieTrackingReconstruction *reconstruction, int framenr, int nearest)
1289
MovieReconstructedCamera *cameras = reconstruction->cameras;
1292
if (!reconstruction->camnr)
1295
if (framenr < cameras[0].framenr) {
1302
if (framenr > cameras[reconstruction->camnr - 1].framenr) {
1304
return reconstruction->camnr - 1;
1309
if (reconstruction->last_camera < reconstruction->camnr)
1310
a = reconstruction->last_camera;
1312
if (cameras[a].framenr >= framenr)
1315
while (a >= 0 && a < reconstruction->camnr) {
1316
int cfra = cameras[a].framenr;
1318
/* check if needed framenr was "skipped" -- no data for requested frame */
1320
if (d > 0 && cfra > framenr) {
1321
/* interpolate with previous position */
1328
if (d < 0 && cfra < framenr) {
1329
/* interpolate with next position */
1336
if (cfra == framenr) {
1337
reconstruction->last_camera = a;
1348
static void reconstructed_camera_scale_set(MovieTrackingObject *object, float mat[4][4])
1350
if ((object->flag & TRACKING_OBJECT_CAMERA) == 0) {
1353
scale_m4_fl(smat, 1.0f / object->scale);
1354
mult_m4_m4m4(mat, mat, smat);
1359
/* converts principal offset from center to offset of blender's camera */
1360
void BKE_tracking_camera_shift_get(MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty)
1362
/* indeed in both of cases it should be winx -- it's just how camera shift works for blender's camera */
1363
*shiftx = (0.5f * winx - tracking->camera.principal[0]) / winx;
1364
*shifty = (0.5f * winy - tracking->camera.principal[1]) / winx;
1367
void BKE_tracking_camera_to_blender(MovieTracking *tracking, Scene *scene, Camera *camera, int width, int height)
1369
float focal = tracking->camera.focal;
1371
camera->sensor_x = tracking->camera.sensor_width;
1372
camera->sensor_fit = CAMERA_SENSOR_FIT_AUTO;
1373
camera->lens = focal * camera->sensor_x / width;
1375
scene->r.xsch = width * tracking->camera.pixel_aspect;
1376
scene->r.ysch = height;
1378
scene->r.xasp = 1.0f;
1379
scene->r.yasp = 1.0f;
1381
BKE_tracking_camera_shift_get(tracking, width, height, &camera->shiftx, &camera->shifty);
1384
MovieReconstructedCamera *BKE_tracking_camera_get_reconstructed(MovieTracking *tracking,
1385
MovieTrackingObject *object, int framenr)
1387
MovieTrackingReconstruction *reconstruction;
1390
reconstruction = BKE_tracking_object_get_reconstruction(tracking, object);
1391
a = reconstructed_camera_index_get(reconstruction, framenr, FALSE);
1396
return &reconstruction->cameras[a];
1399
void BKE_tracking_camera_get_reconstructed_interpolate(MovieTracking *tracking, MovieTrackingObject *object,
1400
int framenr, float mat[4][4])
1402
MovieTrackingReconstruction *reconstruction;
1403
MovieReconstructedCamera *cameras;
1406
reconstruction = BKE_tracking_object_get_reconstruction(tracking, object);
1407
cameras = reconstruction->cameras;
1408
a = reconstructed_camera_index_get(reconstruction, framenr, 1);
1416
if (cameras[a].framenr != framenr && a > 0 && a < reconstruction->camnr - 1) {
1417
float t = ((float)framenr - cameras[a].framenr) / (cameras[a + 1].framenr - cameras[a].framenr);
1419
blend_m4_m4m4(mat, cameras[a].mat, cameras[a + 1].mat, t);
1422
copy_m4_m4(mat, cameras[a].mat);
1425
reconstructed_camera_scale_set(object, mat);
1428
/*********************** Distortion/Undistortion *************************/
1430
MovieDistortion *BKE_tracking_distortion_new(void)
1432
MovieDistortion *distortion;
1434
distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
1439
void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *tracking,
1440
int calibration_width, int calibration_height)
1442
MovieTrackingCamera *camera = &tracking->camera;
1443
float aspy = 1.0f / tracking->camera.pixel_aspect;
1446
if (!distortion->intrinsics) {
1447
distortion->intrinsics = libmv_CameraIntrinsicsNew(camera->focal,
1448
camera->principal[0], camera->principal[1] * aspy,
1449
camera->k1, camera->k2, camera->k3,
1450
calibration_width, calibration_height * aspy);
1453
libmv_CameraIntrinsicsUpdate(distortion->intrinsics, camera->focal,
1454
camera->principal[0], camera->principal[1] * aspy,
1455
camera->k1, camera->k2, camera->k3,
1456
calibration_width, calibration_height * aspy);
1460
(void) calibration_width;
1461
(void) calibration_height;
1467
MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion)
1469
MovieDistortion *new_distortion;
1471
new_distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
1474
new_distortion->intrinsics = libmv_CameraIntrinsicsCopy(distortion->intrinsics);
1479
return new_distortion;
1482
ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *tracking, ImBuf *ibuf,
1483
int calibration_width, int calibration_height, float overscan, int undistort)
1487
BKE_tracking_distortion_update(distortion, tracking, calibration_width, calibration_height);
1489
resibuf = IMB_dupImBuf(ibuf);
1492
if (ibuf->rect_float) {
1494
libmv_CameraIntrinsicsUndistortFloat(distortion->intrinsics,
1495
ibuf->rect_float, resibuf->rect_float,
1496
ibuf->x, ibuf->y, overscan, ibuf->channels);
1499
libmv_CameraIntrinsicsDistortFloat(distortion->intrinsics,
1500
ibuf->rect_float, resibuf->rect_float,
1501
ibuf->x, ibuf->y, overscan, ibuf->channels);
1505
imb_freerectImBuf(ibuf);
1509
libmv_CameraIntrinsicsUndistortByte(distortion->intrinsics,
1510
(unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect,
1511
ibuf->x, ibuf->y, overscan, ibuf->channels);
1514
libmv_CameraIntrinsicsDistortByte(distortion->intrinsics,
1515
(unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect,
1516
ibuf->x, ibuf->y, overscan, ibuf->channels);
1523
if (ibuf->rect_float && ibuf->rect)
1524
imb_freerectImBuf(ibuf);
1530
void BKE_tracking_distortion_free(MovieDistortion *distortion)
1533
libmv_CameraIntrinsicsDestroy(distortion->intrinsics);
1536
MEM_freeN(distortion);
1539
void BKE_tracking_distort_v2(MovieTracking *tracking, const float co[2], float r_co[2])
1541
MovieTrackingCamera *camera = &tracking->camera;
1545
float aspy = 1.0f / tracking->camera.pixel_aspect;
1547
/* normalize coords */
1548
x = (co[0] - camera->principal[0]) / camera->focal;
1549
y = (co[1] - camera->principal[1] * aspy) / camera->focal;
1551
libmv_applyCameraIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy,
1552
camera->k1, camera->k2, camera->k3, x, y, &x, &y);
1554
/* result is in image coords already */
1564
void BKE_tracking_undistort_v2(MovieTracking *tracking, const float co[2], float r_co[2])
1566
MovieTrackingCamera *camera = &tracking->camera;
1569
double x = co[0], y = co[1];
1570
float aspy = 1.0f / tracking->camera.pixel_aspect;
1572
libmv_InvertIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy,
1573
camera->k1, camera->k2, camera->k3, x, y, &x, &y);
1575
r_co[0] = x * camera->focal + camera->principal[0];
1576
r_co[1] = y * camera->focal + camera->principal[1] * aspy;
1584
ImBuf *BKE_tracking_undistort_frame(MovieTracking *tracking, ImBuf *ibuf, int calibration_width,
1585
int calibration_height, float overscan)
1587
MovieTrackingCamera *camera = &tracking->camera;
1589
if (camera->intrinsics == NULL)
1590
camera->intrinsics = BKE_tracking_distortion_new();
1592
return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, calibration_width,
1593
calibration_height, overscan, TRUE);
1596
ImBuf *BKE_tracking_distort_frame(MovieTracking *tracking, ImBuf *ibuf, int calibration_width,
1597
int calibration_height, float overscan)
1599
MovieTrackingCamera *camera = &tracking->camera;
1601
if (camera->intrinsics == NULL)
1602
camera->intrinsics = BKE_tracking_distortion_new();
1604
return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, calibration_width,
1605
calibration_height, overscan, FALSE);
1608
void BKE_tracking_max_undistortion_delta_across_bound(MovieTracking *tracking, rcti *rect, float delta[2])
1611
float pos[2], warped_pos[2];
1612
const int coord_delta = 5;
1614
delta[0] = delta[1] = -FLT_MAX;
1616
for (a = rect->xmin; a <= rect->xmax + coord_delta; a += coord_delta) {
1622
pos[1] = rect->ymin;
1624
BKE_tracking_undistort_v2(tracking, pos, warped_pos);
1626
delta[0] = max_ff(delta[0], fabs(pos[0] - warped_pos[0]));
1627
delta[1] = max_ff(delta[1], fabs(pos[1] - warped_pos[1]));
1631
pos[1] = rect->ymax;
1633
BKE_tracking_undistort_v2(tracking, pos, warped_pos);
1635
delta[0] = max_ff(delta[0], fabs(pos[0] - warped_pos[0]));
1636
delta[1] = max_ff(delta[1], fabs(pos[1] - warped_pos[1]));
1638
if (a >= rect->xmax)
1642
for (a = rect->ymin; a <= rect->ymax + coord_delta; a += coord_delta) {
1647
pos[0] = rect->xmin;
1650
BKE_tracking_undistort_v2(tracking, pos, warped_pos);
1652
delta[0] = max_ff(delta[0], fabs(pos[0] - warped_pos[0]));
1653
delta[1] = max_ff(delta[1], fabs(pos[1] - warped_pos[1]));
1656
pos[0] = rect->xmax;
1659
BKE_tracking_undistort_v2(tracking, pos, warped_pos);
1661
delta[0] = max_ff(delta[0], fabs(pos[0] - warped_pos[0]));
1662
delta[1] = max_ff(delta[1], fabs(pos[1] - warped_pos[1]));
1664
if (a >= rect->ymax)
1669
/*********************** Image sampling *************************/
1671
static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int grayscale)
1673
BKE_tracking_disable_channels(ibuf, track->flag & TRACK_DISABLE_RED,
1674
track->flag & TRACK_DISABLE_GREEN,
1675
track->flag & TRACK_DISABLE_BLUE, grayscale);
1678
ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *search_ibuf,
1679
MovieTrackingTrack *track, MovieTrackingMarker *marker,
1680
int from_anchor, int use_mask, int num_samples_x, int num_samples_y,
1684
ImBuf *pattern_ibuf;
1685
double src_pixel_x[5], src_pixel_y[5];
1686
double warped_position_x, warped_position_y;
1689
if (num_samples_x <= 0 || num_samples_y <= 0)
1692
pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y, 32, IB_rectfloat);
1694
if (!search_ibuf->rect_float) {
1695
IMB_float_from_rect(search_ibuf);
1698
get_marker_coords_for_tracking(frame_width, frame_height, marker, src_pixel_x, src_pixel_y);
1700
/* from_anchor means search buffer was obtained for an anchored position,
1701
* which means applying track offset rounded to pixel space (we could not
1702
* store search buffer with sub-pixel precision)
1704
* in this case we need to alter coordinates a bit, to compensate rounded
1705
* fractional part of offset
1710
for (a = 0; a < 5; a++) {
1711
src_pixel_x[a] += ((track->offset[0] * frame_width) - ((int) (track->offset[0] * frame_width)));
1712
src_pixel_y[a] += ((track->offset[1] * frame_height) - ((int) (track->offset[1] * frame_height)));
1714
/* when offset is negative, rounding happens in opposite direction */
1715
if (track->offset[0] < 0.0f)
1716
src_pixel_x[a] += 1.0f;
1717
if (track->offset[1] < 0.0f)
1718
src_pixel_y[a] += 1.0f;
1723
mask = BKE_tracking_track_get_mask(frame_width, frame_height, track, marker);
1726
libmv_samplePlanarPatch(search_ibuf->rect_float, search_ibuf->x, search_ibuf->y, 4,
1727
src_pixel_x, src_pixel_y, num_samples_x,
1728
num_samples_y, mask, pattern_ibuf->rect_float,
1729
&warped_position_x, &warped_position_y);
1732
pos[0] = warped_position_x;
1733
pos[1] = warped_position_y;
1740
return pattern_ibuf;
1742
ImBuf *pattern_ibuf;
1744
/* real sampling requires libmv, but areas are supposing pattern would be
1745
* sampled if search area does exists, so we'll need to create empty
1746
* pattern area here to prevent adding NULL-checks all over just to deal
1747
* with situation when libmv is disabled
1751
(void) frame_height;
1757
pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y, 32, IB_rectfloat);
1759
pos[0] = num_samples_x / 2.0f;
1760
pos[1] = num_samples_y / 2.0f;
1762
return pattern_ibuf;
1766
ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
1767
int anchored, int disable_channels)
1769
ImBuf *pattern_ibuf, *search_ibuf;
1770
float pat_min[2], pat_max[2];
1771
int num_samples_x, num_samples_y;
1773
BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
1775
num_samples_x = (pat_max[0] - pat_min[0]) * ibuf->x;
1776
num_samples_y = (pat_max[1] - pat_min[1]) * ibuf->y;
1778
search_ibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, anchored, disable_channels);
1781
pattern_ibuf = BKE_tracking_sample_pattern(ibuf->x, ibuf->y, search_ibuf, track, marker,
1782
anchored, FALSE, num_samples_x, num_samples_y, NULL);
1784
IMB_freeImBuf(search_ibuf);
1787
pattern_ibuf = NULL;
1790
return pattern_ibuf;
1793
ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
1794
int anchored, int disable_channels)
1798
float search_origin[2];
1800
get_search_origin_frame_pixel(ibuf->x, ibuf->y, marker, search_origin);
1802
x = search_origin[0];
1803
y = search_origin[1];
1806
x += track->offset[0] * ibuf->x;
1807
y += track->offset[1] * ibuf->y;
1810
w = (marker->search_max[0] - marker->search_min[0]) * ibuf->x;
1811
h = (marker->search_max[1] - marker->search_min[1]) * ibuf->y;
1813
if (w <= 0 || h <= 0)
1816
searchibuf = IMB_allocImBuf(w, h, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
1818
IMB_rectcpy(searchibuf, ibuf, 0, 0, x, y, w, h);
1820
if (disable_channels) {
1821
if ((track->flag & TRACK_PREVIEW_GRAYSCALE) ||
1822
(track->flag & TRACK_DISABLE_RED) ||
1823
(track->flag & TRACK_DISABLE_GREEN) ||
1824
(track->flag & TRACK_DISABLE_BLUE))
1826
disable_imbuf_channels(searchibuf, track, TRUE);
1833
/* zap channels from the imbuf that are disabled by the user. this can lead to
1834
* better tracks sometimes. however, instead of simply zeroing the channels
1835
* out, do a partial grayscale conversion so the display is better.
1837
void BKE_tracking_disable_channels(ImBuf *ibuf, int disable_red, int disable_green, int disable_blue,
1843
if (!disable_red && !disable_green && !disable_blue && !grayscale)
1846
/* if only some components are selected, it's important to rescale the result
1847
* appropriately so that e.g. if only blue is selected, it's not zeroed out.
1849
scale = (disable_red ? 0.0f : 0.2126f) +
1850
(disable_green ? 0.0f : 0.7152f) +
1851
(disable_blue ? 0.0f : 0.0722f);
1853
for (y = 0; y < ibuf->y; y++) {
1854
for (x = 0; x < ibuf->x; x++) {
1855
int pixel = ibuf->x * y + x;
1857
if (ibuf->rect_float) {
1858
float *rrgbf = ibuf->rect_float + pixel * 4;
1859
float r = disable_red ? 0.0f : rrgbf[0];
1860
float g = disable_green ? 0.0f : rrgbf[1];
1861
float b = disable_blue ? 0.0f : rrgbf[2];
1864
float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale;
1866
rrgbf[0] = rrgbf[1] = rrgbf[2] = gray;
1875
char *rrgb = (char *)ibuf->rect + pixel * 4;
1876
char r = disable_red ? 0 : rrgb[0];
1877
char g = disable_green ? 0 : rrgb[1];
1878
char b = disable_blue ? 0 : rrgb[2];
1881
float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale;
1883
rrgb[0] = rrgb[1] = rrgb[2] = gray;
1894
if (ibuf->rect_float)
1895
ibuf->userflags |= IB_RECT_INVALID;
1898
/*********************** Tracks map *************************/
718
1900
typedef struct TracksMap {
719
1901
char object_name[MAX_NAME];
1070
2223
MEM_freeN(context);
1073
/* zap channels from the imbuf that are disabled by the user. this can lead to
1074
* better tracks sometimes. however, instead of simply zeroing the channels
1075
* out, do a partial grayscale conversion so the display is better. */
1076
void BKE_tracking_disable_imbuf_channels(ImBuf *ibuf, int disable_red, int disable_green, int disable_blue, int grayscale)
1081
if (!disable_red && !disable_green && !disable_blue && !grayscale)
1084
/* If only some components are selected, it's important to rescale the result
1085
* appropriately so that e.g. if only blue is selected, it's not zeroed out. */
1086
scale = (disable_red ? 0.0f : 0.2126f) +
1087
(disable_green ? 0.0f : 0.7152f) +
1088
(disable_blue ? 0.0f : 0.0722f);
1090
for (y = 0; y < ibuf->y; y++) {
1091
for (x = 0; x < ibuf->x; x++) {
1092
int pixel = ibuf->x*y + x;
1094
if (ibuf->rect_float) {
1095
float *rrgbf = ibuf->rect_float + pixel*4;
1096
float r = disable_red ? 0.0f : rrgbf[0];
1097
float g = disable_green ? 0.0f : rrgbf[1];
1098
float b = disable_blue ? 0.0f : rrgbf[2];
1101
float gray = (0.2126f*r + 0.7152f*g + 0.0722f*b) / scale;
1103
rrgbf[0] = rrgbf[1] = rrgbf[2] = gray;
1112
char *rrgb = (char*)ibuf->rect + pixel*4;
1113
char r = disable_red ? 0 : rrgb[0];
1114
char g = disable_green ? 0 : rrgb[1];
1115
char b = disable_blue ? 0 : rrgb[2];
1118
float gray = (0.2126f*r + 0.7152f*g + 0.0722f*b) / scale;
1120
rrgb[0] = rrgb[1] = rrgb[2] = gray;
1131
if (ibuf->rect_float)
1132
ibuf->userflags |= IB_RECT_INVALID;
1135
static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int grayscale)
1137
BKE_tracking_disable_imbuf_channels(ibuf, track->flag & TRACK_DISABLE_RED,
1138
track->flag & TRACK_DISABLE_GREEN, track->flag & TRACK_DISABLE_BLUE, grayscale);
1141
static ImBuf *get_area_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
1142
float min[2], float max[2], int margin, int anchored, float pos[2], int origin[2])
1149
copy_v2_v2(mpos, marker->pos);
1151
add_v2_v2(mpos, track->offset);
1156
x = mpos[0]*ibuf->x;
1157
y = mpos[1]*ibuf->y;
1159
w = (max[0] - min[0]) * ibuf->x;
1160
h = (max[1] - min[1]) * ibuf->y;
1162
/* dimensions should be odd */
1166
x1 = x-(int)(w * (-min[0] / (max[0] - min[0])));
1167
y1 = y-(int)(h * (-min[1] / (max[1] - min[1])));
1169
if (ibuf->rect_float)
1170
tmpibuf = IMB_allocImBuf(w + margin * 2, h + margin * 2, 32, IB_rectfloat);
2226
void BKE_tracking_context_sync(MovieTrackingContext *context)
2228
MovieTracking *tracking = &context->clip->tracking;
2231
tracks_map_merge(context->tracks_map, tracking);
2233
if (context->backwards)
2234
newframe = context->user.framenr + 1;
1172
tmpibuf = IMB_allocImBuf(w + margin * 2, h + margin * 2, 32, IB_rect);
1174
tmpibuf->profile = ibuf->profile;
1176
IMB_rectcpy(tmpibuf, ibuf, 0, 0, x1 - margin, y1 - margin, w + margin * 2, h + margin * 2);
1179
pos[0] = mpos[0] * ibuf->x - x1 + margin;
1180
pos[1] = mpos[1] * ibuf->y - y1 + margin;
1183
if (origin != NULL) {
1184
origin[0] = x1 - margin;
1185
origin[1] = y1 - margin;
1188
if ((track->flag & TRACK_PREVIEW_GRAYSCALE) ||
1189
(track->flag & TRACK_DISABLE_RED) ||
1190
(track->flag & TRACK_DISABLE_GREEN) ||
1191
(track->flag & TRACK_DISABLE_BLUE))
1193
disable_imbuf_channels(tmpibuf, track, TRUE /* grayscale */);
1199
ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
1200
int margin, int anchored, float pos[2], int origin[2])
1202
return get_area_imbuf(ibuf, track, marker, track->pat_min, track->pat_max, margin, anchored, pos, origin);
1205
ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
1206
int margin, int anchored, float pos[2], int origin[2])
1208
return get_area_imbuf(ibuf, track, marker, track->search_min, track->search_max, margin, anchored, pos, origin);
2236
newframe = context->user.framenr - 1;
2238
context->sync_frame = newframe;
2240
BKE_tracking_dopesheet_tag_update(tracking);
2243
void BKE_tracking_context_sync_user(const MovieTrackingContext *context, MovieClipUser *user)
2245
user->framenr = context->sync_frame;
1211
2248
#ifdef WITH_LIBMV
1212
static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
1213
int *width_r, int *height_r, float pos[2], int origin[2])
1217
int x, y, width, height;
1219
width = (track->search_max[0] - track->search_min[0]) * ibuf->x;
1220
height = (track->search_max[1] - track->search_min[1]) * ibuf->y;
1222
tmpibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, 0, 0, pos, origin);
1223
disable_imbuf_channels(tmpibuf, track, FALSE /* don't grayscale */);
2249
/* **** utility functions for tracking **** */
2251
/* convert from float and byte RGBA to grayscale. Supports different coefficients for RGB. */
2252
static void float_rgba_to_gray(const float *rgba, float *gray, int num_pixels,
2253
float weight_red, float weight_green, float weight_blue)
2257
for (i = 0; i < num_pixels; i++) {
2258
const float *pixel = rgba + 4 * i;
2260
gray[i] = weight_red * pixel[0] + weight_green * pixel[1] + weight_blue * pixel[2];
2264
static void uint8_rgba_to_float_gray(const unsigned char *rgba, float *gray, int num_pixels,
2265
float weight_red, float weight_green, float weight_blue)
2269
for (i = 0; i < num_pixels; i++) {
2270
const unsigned char *pixel = rgba + i * 4;
2272
gray[i] = (weight_red * pixel[0] + weight_green * pixel[1] + weight_blue * pixel[2]) / 255.0f;
2276
static float *track_get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
2277
int *width_r, int *height_r)
2283
searchibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, FALSE, TRUE);
2291
width = searchibuf->x;
2292
height = searchibuf->y;
2294
gray_pixels = MEM_callocN(width * height * sizeof(float), "tracking floatBuf");
2296
if (searchibuf->rect_float) {
2297
float_rgba_to_gray(searchibuf->rect_float, gray_pixels, width * height,
2298
0.2126f, 0.7152f, 0.0722f);
2301
uint8_rgba_to_float_gray((unsigned char *)searchibuf->rect, gray_pixels, width * height,
2302
0.2126f, 0.7152f, 0.0722f);
2305
IMB_freeImBuf(searchibuf);
1225
2307
*width_r = width;
1226
2308
*height_r = height;
1228
fp = pixels = MEM_callocN(width * height * sizeof(float), "tracking floatBuf");
1229
for (y = 0; y < (int)height; y++) {
1230
for (x = 0; x < (int)width; x++) {
1231
int pixel = tmpibuf->x * y + x;
1233
if (tmpibuf->rect_float) {
1234
float *rrgbf = tmpibuf->rect_float + pixel * 4;
1236
*fp = 0.2126 * rrgbf[0] + 0.7152 * rrgbf[1] + 0.0722 * rrgbf[2];
1239
unsigned char *rrgb = (unsigned char*)tmpibuf->rect + pixel * 4;
1241
*fp = (0.2126 * rrgb[0] + 0.7152 * rrgb[1] + 0.0722 * rrgb[2]) / 255.0f;
1248
IMB_freeImBuf(tmpibuf);
1253
static unsigned char *get_ucharbuf(ImBuf *ibuf)
1256
unsigned char *pixels, *cp;
1258
cp = pixels = MEM_callocN(ibuf->x * ibuf->y * sizeof(unsigned char), "tracking ucharBuf");
1259
for (y = 0; y < ibuf->y; y++) {
1260
for (x = 0; x < ibuf->x; x++) {
1261
int pixel = ibuf->x * y + x;
1263
if (ibuf->rect_float) {
1264
const float *rrgbf = ibuf->rect_float + pixel*4;
1265
const float grey_f = 0.2126f * rrgbf[0] + 0.7152f * rrgbf[1] + 0.0722f * rrgbf[2];
1267
*cp = FTOCHAR(grey_f);
1270
const unsigned char *rrgb = (unsigned char*)ibuf->rect + pixel * 4;
1272
*cp = 0.2126f * rrgb[0] + 0.7152f * rrgb[1] + 0.0722f * rrgb[2];
1282
static ImBuf *get_frame_ibuf(MovieTrackingContext *context, int framenr)
2313
static ImBuf *tracking_context_get_frame_ibuf(MovieTrackingContext *context, int framenr)
1285
2316
MovieClipUser user = context->user;
1287
user.framenr = framenr;
2318
user.framenr = BKE_movieclip_remap_clip_to_scene_frame(context->clip, framenr);
1289
2320
ibuf = BKE_movieclip_get_ibuf_flag(context->clip, &user, context->clip_flag, MOVIECLIP_CACHE_SKIP);
1294
static ImBuf *get_keyframed_ibuf(MovieTrackingContext *context, MovieTrackingTrack *track,
1295
MovieTrackingMarker *marker, MovieTrackingMarker **marker_keyed)
2325
static MovieTrackingMarker *tracking_context_get_keyframed_marker(MovieTrackingContext *context, MovieTrackingTrack *track,
2326
MovieTrackingMarker *marker)
1297
int framenr = marker->framenr;
1298
int a = marker-track->markers;
1300
*marker_keyed = marker;
2328
int a = marker - track->markers;
2329
MovieTrackingMarker *marker_keyed = marker;
1302
2331
while (a >= 0 && a < track->markersnr) {
1303
int next = (context->backwards) ? a+1 : a-1;
2332
int next = (context->backwards) ? a + 1 : a - 1;
1304
2333
int is_keyframed = FALSE;
1305
2334
MovieTrackingMarker *cur_marker = &track->markers[a];
1306
2335
MovieTrackingMarker *next_marker = NULL;
1308
if (next>=0 && next<track->markersnr)
1309
next_marker= &track->markers[next];
2337
if (next >= 0 && next < track->markersnr)
2338
next_marker = &track->markers[next];
1311
2340
/* if next mrker is disabled, stop searching keyframe and use current frame as keyframe */
1312
2341
if (next_marker && next_marker->flag & MARKER_DISABLED)
2391
static int track_context_update_reference(MovieTrackingContext *context, TrackContext *track_context,
2392
MovieTrackingTrack *track, MovieTrackingMarker *marker, int curfra,
2393
int frame_width, int frame_height)
2395
MovieTrackingMarker *marker_keyed = NULL;
2396
ImBuf *reference_ibuf = NULL;
2399
/* calculate patch for keyframed position */
2400
reference_ibuf = tracking_context_get_reference_ibuf(context, track, marker, curfra, &marker_keyed);
2402
if (!reference_ibuf)
2405
track_context->marker = *marker_keyed;
2407
if (track_context->search_area) {
2408
MEM_freeN(track_context->search_area);
2411
track_context->search_area = track_get_search_floatbuf(reference_ibuf, track, marker_keyed, &width, &height);
2412
track_context->search_area_height = height;
2413
track_context->search_area_width = width;
2415
if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0) {
2416
if (track_context->mask)
2417
MEM_freeN(track_context->mask);
2419
track_context->mask = BKE_tracking_track_get_mask(frame_width, frame_height, track, marker);
2422
IMB_freeImBuf(reference_ibuf);
2427
static void tracking_configure_tracker(TrackContext *track_context, MovieTrackingTrack *track,
2428
struct libmv_trackRegionOptions *options)
2430
options->motion_model = track->motion_model;
2432
options->use_brute = ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_BRUTE) != 0);
2434
options->use_normalization = ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_NORMALIZATION) != 0);
2436
options->num_iterations = 50;
2437
options->minimum_correlation = track->minimum_correlation;
2438
options->sigma = 0.9;
2440
if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0)
2441
options->image1_mask = track_context->mask;
2444
/* returns FALSE if marker crossed margin area from frame bounds */
2445
static int tracking_check_marker_margin(MovieTrackingTrack *track, MovieTrackingMarker *marker,
2446
int frame_width, int frame_height)
2448
float pat_min[2], pat_max[2], dim[2], margin[2];
2450
/* margin from frame boundaries */
2451
BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
2452
sub_v2_v2v2(dim, pat_max, pat_min);
2453
margin[0] = margin[1] = max_ff(dim[0], dim[1]) / 2.0f;
2455
margin[0] = max_ff(margin[0], (float)track->margin / frame_width);
2456
margin[1] = max_ff(margin[1], (float)track->margin / frame_height);
2458
/* do not track markers which are too close to boundary */
2459
if (marker->pos[0] < margin[0] || marker->pos[0] > 1.0f - margin[0] ||
2460
marker->pos[1] < margin[1] || marker->pos[1] > 1.0f - margin[1])
2468
static void tracking_scale_marker_search(const MovieTrackingMarker *old_marker, MovieTrackingMarker *new_marker)
2470
float old_pat_min[2], old_pat_max[2];
2471
float new_pat_min[2], new_pat_max[2];
2472
float scale_x, scale_y;
2474
BKE_tracking_marker_pattern_minmax(old_marker, old_pat_min, old_pat_max);
2475
BKE_tracking_marker_pattern_minmax(new_marker, new_pat_min, new_pat_max);
2477
scale_x = (new_pat_max[0] - new_pat_min[0]) / (old_pat_max[0] - old_pat_min[0]);
2478
scale_y = (new_pat_max[1] - new_pat_min[1]) / (old_pat_max[1] - old_pat_min[1]);
2480
new_marker->search_min[0] *= scale_x;
2481
new_marker->search_min[1] *= scale_y;
2483
new_marker->search_max[0] *= scale_x;
2484
new_marker->search_max[1] *= scale_y;
2487
static void tracking_insert_new_marker(MovieTrackingContext *context, MovieTrackingTrack *track,
2488
const MovieTrackingMarker *old_marker, int curfra, int tracked,
2489
int frame_width, int frame_height,
2490
double dst_pixel_x[5], double dst_pixel_y[5])
2492
MovieTrackingMarker new_marker;
2493
int frame_delta = context->backwards ? -1 : 1;
2494
int nextfra = curfra + frame_delta;
2496
new_marker = *old_marker;
2499
set_marker_coords_from_tracking(frame_width, frame_height, &new_marker, dst_pixel_x, dst_pixel_y);
2500
new_marker.flag |= MARKER_TRACKED;
2501
new_marker.framenr = nextfra;
2503
tracking_scale_marker_search(old_marker, &new_marker);
2505
if (context->first_time) {
2506
/* check if there's no keyframe/tracked markers before tracking marker.
2507
* if so -- create disabled marker before currently tracking "segment"
2510
tracking_marker_insert_disabled(track, old_marker, !context->backwards, FALSE);
2513
/* insert currently tracked marker */
2514
BKE_tracking_marker_insert(track, &new_marker);
2516
/* make currently tracked segment be finished with disabled marker */
2517
tracking_marker_insert_disabled(track, &new_marker, context->backwards, FALSE);
2520
new_marker.framenr = nextfra;
2521
new_marker.flag |= MARKER_DISABLED;
2523
BKE_tracking_marker_insert(track, &new_marker);
1350
void BKE_tracking_sync(MovieTrackingContext *context)
1352
MovieTracking *tracking = &context->clip->tracking;
1355
tracks_map_merge(context->tracks_map, tracking);
1357
if (context->backwards)
1358
newframe = context->user.framenr + 1;
1360
newframe = context->user.framenr - 1;
1362
context->sync_frame = newframe;
1365
void BKE_tracking_sync_user(MovieClipUser *user, MovieTrackingContext *context)
1367
user->framenr = context->sync_frame;
1370
int BKE_tracking_next(MovieTrackingContext *context)
1373
int curfra = context->user.framenr;
2529
int BKE_tracking_context_step(MovieTrackingContext *context)
2531
ImBuf *destination_ibuf;
2532
int frame_delta = context->backwards ? -1 : 1;
2533
int curfra = BKE_movieclip_remap_scene_to_clip_frame(context->clip, context->user.framenr);
2534
/* int nextfra; */ /* UNUSED */
1374
2535
int a, ok = FALSE, map_size;
1376
map_size = tracks_map_size(context->tracks_map);
2537
int frame_width, frame_height;
2539
map_size = tracks_map_get_size(context->tracks_map);
1378
2541
/* nothing to track, avoid unneeded frames reading to save time and memory */
1382
if (context->backwards)
1383
context->user.framenr--;
1385
context->user.framenr++;
2545
context->user.framenr += frame_delta;
1387
ibuf_new = BKE_movieclip_get_ibuf_flag(context->clip, &context->user, context->clip_flag, MOVIECLIP_CACHE_SKIP);
2547
destination_ibuf = BKE_movieclip_get_ibuf_flag(context->clip, &context->user,
2548
context->clip_flag, MOVIECLIP_CACHE_SKIP);
2549
if (!destination_ibuf)
1391
#pragma omp parallel for private(a) shared(ibuf_new, ok) if (map_size>1)
2552
/* nextfra = curfra + frame_delta; */ /* UNUSED */
2554
frame_width = destination_ibuf->x;
2555
frame_height = destination_ibuf->y;
2557
#pragma omp parallel for private(a) shared(destination_ibuf, ok) if (map_size > 1)
1392
2558
for (a = 0; a < map_size; a++) {
1393
2559
TrackContext *track_context = NULL;
1394
2560
MovieTrackingTrack *track;
1395
2561
MovieTrackingMarker *marker;
1397
tracks_map_get(context->tracks_map, a, &track, (void**)&track_context);
2563
tracks_map_get_indexed_element(context->tracks_map, a, &track, (void **)&track_context);
1399
marker = BKE_tracking_exact_marker(track, curfra);
2565
marker = BKE_tracking_marker_get_exact(track, curfra);
1401
2567
if (marker && (marker->flag & MARKER_DISABLED) == 0) {
1402
2568
#ifdef WITH_LIBMV
1403
int width, height, origin[2], tracked = 0, need_readjust = 0;
1404
float pos[2], margin[2], dim[2];
1405
double x1, y1, x2, y2;
1407
MovieTrackingMarker marker_new, *marker_keyed;
1408
int onbound = FALSE, nextfra;
2569
int width, height, tracked = FALSE, need_readjust;
2570
double dst_pixel_x[5], dst_pixel_y[5];
1410
2572
if (track->pattern_match == TRACK_MATCH_KEYFRAME)
1411
2573
need_readjust = context->first_time;
1413
2575
need_readjust = TRUE;
1415
if (context->backwards)
1416
nextfra = curfra - 1;
1418
nextfra = curfra + 1;
1420
/* margin from frame boundaries */
1421
sub_v2_v2v2(dim, track->pat_max, track->pat_min);
1422
margin[0] = margin[1] = MAX2(dim[0], dim[1]) / 2.0f;
1424
margin[0] = MAX2(margin[0], (float)track->margin / ibuf_new->x);
1425
margin[1] = MAX2(margin[1], (float)track->margin / ibuf_new->y);
1427
2577
/* do not track markers which are too close to boundary */
1428
if (marker->pos[0]<margin[0] || marker->pos[0]>1.0f-margin[0] ||
1429
marker->pos[1]<margin[1] || marker->pos[1]>1.0f-margin[1])
2578
if (tracking_check_marker_margin(track, marker, frame_width, frame_height)) {
2579
/* to convert to the x/y split array format for libmv. */
2580
double src_pixel_x[5], src_pixel_y[5];
2582
/* settings for the tracker */
2583
struct libmv_trackRegionOptions options = {0};
2584
struct libmv_trackRegionResult result;
1434
2586
float *patch_new;
1436
2588
if (need_readjust) {
1437
/* calculate patch for keyframed position */
1438
ibuf = get_adjust_ibuf(context, track, marker, curfra, &marker_keyed);
1440
if (track_context->patch)
1441
MEM_freeN(track_context->patch);
1443
track_context->patch = get_search_floatbuf(ibuf, track, marker_keyed, &width, &height,
1444
track_context->keyframed_pos, origin);
1446
IMB_freeImBuf(ibuf);
2589
if (track_context_update_reference(context, track_context, track, marker,
2590
curfra, frame_width, frame_height) == FALSE)
2592
/* happens when reference frame fails to be loaded */
1449
patch_new = get_search_floatbuf(ibuf_new, track, marker, &width, &height, pos, origin);
1451
x1 = track_context->keyframed_pos[0];
1452
y1 = track_context->keyframed_pos[1];
1457
tracked = libmv_regionTrackerTrack(track_context->region_tracker, track_context->patch, patch_new,
1458
width, height, x1, y1, &x2, &y2);
2597
/* for now track to the same search area dimension as marker has got for current frame
2598
* will make all tracked markers in currently tracked segment have the same search area
2599
* size, but it's quite close to what is actually needed
2601
patch_new = track_get_search_floatbuf(destination_ibuf, track, marker, &width, &height);
2603
/* configure the tracker */
2604
tracking_configure_tracker(track_context, track, &options);
2606
/* convert the marker corners and center into pixel coordinates in the search/destination images. */
2607
get_marker_coords_for_tracking(frame_width, frame_height, &track_context->marker, src_pixel_x, src_pixel_y);
2608
get_marker_coords_for_tracking(frame_width, frame_height, marker, dst_pixel_x, dst_pixel_y);
2610
if (!patch_new || !track_context->search_area)
2613
/* run the tracker! */
2614
tracked = libmv_trackRegion(&options,
2615
track_context->search_area,
2616
track_context->search_area_width,
2617
track_context->search_area_height,
2618
patch_new, width, height,
2619
src_pixel_x, src_pixel_y,
2621
dst_pixel_x, dst_pixel_y);
1460
2622
MEM_freeN(patch_new);
1463
if (tracked && !onbound && finite(x2) && finite(y2)) {
1464
if (context->first_time) {
1465
#pragma omp critical
1467
/* check if there's no keyframe/tracked markers before tracking marker.
1468
* if so -- create disabled marker before currently tracking "segment" */
1469
put_disabled_marker(track, marker, !context->backwards, 0);
1473
memset(&marker_new, 0, sizeof(marker_new));
1476
marker_new.pos[0] = (origin[0] + x2) / ibuf_new->x;
1477
marker_new.pos[1] = (origin[1] + y2) / ibuf_new->y;
1480
copy_v2_v2(marker_new.pos, marker->pos);
1483
marker_new.flag |= MARKER_TRACKED;
1484
marker_new.framenr= nextfra;
1486
#pragma omp critical
1488
BKE_tracking_insert_marker(track, &marker_new);
1491
/* make currently tracked segment be finished with disabled marker */
1492
#pragma omp critical
1494
put_disabled_marker(track, &marker_new, context->backwards, 0);
1498
marker_new = *marker;
1500
marker_new.framenr = nextfra;
1501
marker_new.flag |= MARKER_DISABLED;
1503
#pragma omp critical
1505
BKE_tracking_insert_marker(track, &marker_new);
2625
#pragma omp critical
2627
tracking_insert_new_marker(context, track, marker, curfra, tracked,
2628
frame_width, frame_height, dst_pixel_x, dst_pixel_y);
1514
IMB_freeImBuf(ibuf_new);
2639
IMB_freeImBuf(destination_ibuf);
1516
2641
context->first_time = FALSE;
1517
2642
context->frames++;
1943
3089
reconstruction->flag |= TRACKING_RECONSTRUCTED;
1945
3091
#ifdef WITH_LIBMV
1946
if (!retrieve_libmv_reconstruct(context, tracking))
3092
if (!reconstruct_retrieve_libmv(context, tracking))
1953
void BKE_track_unique_name(ListBase *tracksbase, MovieTrackingTrack *track)
1955
BLI_uniquename(tracksbase, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name));
1958
MovieTrackingTrack *BKE_tracking_named_track(MovieTracking *tracking, MovieTrackingObject *object, const char *name)
1960
ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object);
1961
MovieTrackingTrack *track = tracksbase->first;
1964
if (!strcmp(track->name, name))
1967
track = track->next;
1973
static int reconstruction_camera_index(MovieTrackingReconstruction *reconstruction, int framenr, int nearest)
1975
MovieReconstructedCamera *cameras= reconstruction->cameras;
1978
if (!reconstruction->camnr)
1981
if (framenr<cameras[0].framenr) {
1988
if (framenr>cameras[reconstruction->camnr - 1].framenr) {
1990
return reconstruction->camnr - 1;
1995
if (reconstruction->last_camera<reconstruction->camnr)
1996
a = reconstruction->last_camera;
1998
if (cameras[a].framenr >= framenr)
2001
while (a >= 0 && a < reconstruction->camnr) {
2002
int cfra = cameras[a].framenr;
2004
/* check if needed framenr was "skipped" -- no data for requested frame */
2006
if (d > 0 && cfra > framenr) {
2007
/* interpolate with previous position */
2014
if (d < 0 && cfra < framenr) {
2015
/* interpolate with next position */
2022
if (cfra == framenr) {
2023
reconstruction->last_camera = a;
2034
static void scale_reconstructed_camera(MovieTrackingObject *object, float mat[4][4])
2036
if ((object->flag & TRACKING_OBJECT_CAMERA) == 0) {
2039
scale_m4_fl(smat, 1.0f / object->scale);
2040
mult_m4_m4m4(mat, mat, smat);
2044
MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(MovieTracking *tracking,
2045
MovieTrackingObject *object, int framenr)
2047
MovieTrackingReconstruction *reconstruction;
2050
reconstruction = BKE_tracking_object_reconstruction(tracking, object);
2051
a = reconstruction_camera_index(reconstruction, framenr, FALSE);
2056
return &reconstruction->cameras[a];
2059
void BKE_tracking_get_interpolated_camera(MovieTracking *tracking, MovieTrackingObject *object,
2060
int framenr, float mat[4][4])
2062
MovieTrackingReconstruction *reconstruction;
2063
MovieReconstructedCamera *cameras;
2066
reconstruction = BKE_tracking_object_reconstruction(tracking, object);
2067
cameras = reconstruction->cameras;
2068
a = reconstruction_camera_index(reconstruction, framenr, 1);
2076
if (cameras[a].framenr != framenr && a > 0 && a < reconstruction->camnr - 1) {
2077
float t = ((float)framenr-cameras[a].framenr) / (cameras[a + 1].framenr-cameras[a].framenr);
2079
blend_m4_m4m4(mat, cameras[a].mat, cameras[a+1].mat, t);
2082
copy_m4_m4(mat, cameras[a].mat);
2085
scale_reconstructed_camera(object, mat);
2088
void BKE_get_tracking_mat(Scene *scene, Object *ob, float mat[4][4])
2094
ob = scene_find_camera(scene);
2098
where_is_object_mat(scene, ob, mat);
2103
void BKE_tracking_camera_shift(MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty)
2105
/* indeed in both of cases it should be winx -- it's just how camera shift works for blender's camera */
2106
*shiftx = (0.5f * winx-tracking->camera.principal[0]) / winx;
2107
*shifty = (0.5f * winy-tracking->camera.principal[1]) / winx;
2110
void BKE_tracking_camera_to_blender(MovieTracking *tracking, Scene *scene, Camera *camera, int width, int height)
2112
float focal = tracking->camera.focal;
2114
camera->sensor_x = tracking->camera.sensor_width;
2115
camera->sensor_fit = CAMERA_SENSOR_FIT_AUTO;
2116
camera->lens = focal*camera->sensor_x/width;
2118
scene->r.xsch = width*tracking->camera.pixel_aspect;
2119
scene->r.ysch = height;
2121
scene->r.xasp = 1.0f;
2122
scene->r.yasp = 1.0f;
2124
BKE_tracking_camera_shift(tracking, width, height, &camera->shiftx, &camera->shifty);
2127
void BKE_tracking_projection_matrix(MovieTracking *tracking, MovieTrackingObject *object,
2128
int framenr, int winx, int winy, float mat[4][4])
2130
MovieReconstructedCamera *camera;
2131
float lens = tracking->camera.focal*tracking->camera.sensor_width/(float)winx;
2132
float viewfac, pixsize, left, right, bottom, top, clipsta, clipend;
2134
float ycor = 1.0f / tracking->camera.pixel_aspect;
2135
float shiftx, shifty, winside = MAX2(winx, winy);
2137
BKE_tracking_camera_shift(tracking, winx, winy, &shiftx, &shifty);
2143
viewfac = (lens*winx)/tracking->camera.sensor_width;
2145
viewfac = (ycor*lens*winy)/tracking->camera.sensor_width;
2147
pixsize = clipsta/viewfac;
2149
left = -0.5f * (float)winx + shiftx * winside;
2150
bottom = -0.5f * (ycor) * (float)winy + shifty * winside;
2151
right = 0.5f * (float)winx + shiftx * winside;
2152
top = 0.5f * (ycor) * (float)winy + shifty * winside;
2159
perspective_m4(winmat, left, right, bottom, top, clipsta, clipend);
2161
camera = BKE_tracking_get_reconstructed_camera(tracking, object, framenr);
2166
invert_m4_m4(imat, camera->mat);
2167
mult_m4_m4m4(mat, winmat, imat);
2169
else copy_m4_m4(mat, winmat);
2172
ListBase *BKE_tracking_get_tracks(MovieTracking *tracking)
2174
MovieTrackingObject *object = BKE_tracking_active_object(tracking);
2176
if (object && (object->flag & TRACKING_OBJECT_CAMERA) == 0) {
2177
return &object->tracks;
2180
return &tracking->tracks;
2183
MovieTrackingTrack *BKE_tracking_active_track(MovieTracking *tracking)
2185
ListBase *tracksbase;
2187
if (!tracking->act_track)
2190
tracksbase = BKE_tracking_get_tracks(tracking);
2192
/* check that active track is in current tracks list */
2193
if (BLI_findindex(tracksbase, tracking->act_track) >= 0)
2194
return tracking->act_track;
2199
MovieTrackingObject *BKE_tracking_active_object(MovieTracking *tracking)
2201
return BLI_findlink(&tracking->objects, tracking->objectnr);
2204
MovieTrackingObject *BKE_tracking_get_camera_object(MovieTracking *tracking)
2206
MovieTrackingObject *object = tracking->objects.first;
2209
if (object->flag & TRACKING_OBJECT_CAMERA)
2212
object= object->next;
2218
ListBase *BKE_tracking_object_tracks(MovieTracking *tracking, MovieTrackingObject *object)
2220
if (object->flag & TRACKING_OBJECT_CAMERA) {
2221
return &tracking->tracks;
2224
return &object->tracks;
2227
MovieTrackingReconstruction *BKE_tracking_object_reconstruction(MovieTracking *tracking, MovieTrackingObject *object)
2229
if (object->flag & TRACKING_OBJECT_CAMERA) {
2230
return &tracking->reconstruction;
2233
return &object->reconstruction;
2236
MovieTrackingReconstruction *BKE_tracking_get_reconstruction(MovieTracking *tracking)
2238
MovieTrackingObject *object = BKE_tracking_active_object(tracking);
2240
return BKE_tracking_object_reconstruction(tracking, object);
2243
void BKE_tracking_apply_intrinsics(MovieTracking *tracking, float co[2], float nco[2])
2245
MovieTrackingCamera *camera= &tracking->camera;
2249
float aspy = 1.0f/tracking->camera.pixel_aspect;
2251
/* normalize coords */
2252
x = (co[0] - camera->principal[0]) / camera->focal;
2253
y = (co[1] - camera->principal[1] * aspy) / camera->focal;
2255
libmv_applyCameraIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy,
2256
camera->k1, camera->k2, camera->k3, x, y, &x, &y);
2258
/* result is in image coords already */
2268
void BKE_tracking_invert_intrinsics(MovieTracking *tracking, float co[2], float nco[2])
2270
MovieTrackingCamera *camera = &tracking->camera;
2273
double x = co[0], y = co[1];
2274
float aspy = 1.0f / tracking->camera.pixel_aspect;
2276
libmv_InvertIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy,
2277
camera->k1, camera->k2, camera->k3, x, y, &x, &y);
2279
nco[0] = x * camera->focal + camera->principal[0];
2280
nco[1] = y * camera->focal + camera->principal[1] * aspy;
2289
static int point_in_stroke(bGPDstroke *stroke, float x, float y)
3099
/*********************** Feature detection *************************/
3102
static int check_point_in_stroke(bGPDstroke *stroke, float x, float y)
2786
3605
cmat[3][1] = (float)height / 2.0f;
2787
3606
invert_m4_m4(icmat, cmat);
2789
size_to_mat4(smat, svec); /* scale matrix */
2790
add_v2_v2(lmat[3], loc); /* translation matrix */
2791
rotate_m4(rmat, 'Z', angle); /* rotation matrix */
3608
size_to_mat4(smat, svec); /* scale matrix */
3609
add_v2_v2(lmat[3], loc); /* translation matrix */
3610
rotate_m4(rmat, 'Z', angle); /* rotation matrix */
2793
3612
/* compose transformation matrix */
2794
3613
mul_serie_m4(mat, lmat, cmat, amat, rmat, iamat, smat, icmat, NULL);
2797
MovieDistortion *BKE_tracking_distortion_create(void)
2799
MovieDistortion *distortion;
2801
distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
2806
MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion)
2808
MovieDistortion *new_distortion;
2810
new_distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
2813
new_distortion->intrinsics = libmv_CameraIntrinsicsCopy(distortion->intrinsics);
2818
return new_distortion;
2821
void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *tracking, int width, int height)
2823
MovieTrackingCamera *camera = &tracking->camera;
2824
float aspy = 1.0f / tracking->camera.pixel_aspect;
2827
if (!distortion->intrinsics) {
2828
distortion->intrinsics = libmv_CameraIntrinsicsNew(camera->focal,
2829
camera->principal[0], camera->principal[1] * aspy,
2830
camera->k1, camera->k2, camera->k3, width, height * aspy);
2833
libmv_CameraIntrinsicsUpdate(distortion->intrinsics, camera->focal,
2834
camera->principal[0], camera->principal[1] * aspy,
2835
camera->k1, camera->k2, camera->k3, width, height * aspy);
2846
ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *tracking,
2847
ImBuf *ibuf, int width, int height, float overscan, int undistort)
2851
BKE_tracking_distortion_update(distortion, tracking, width, height);
2853
resibuf = IMB_dupImBuf(ibuf);
2855
if (ibuf->rect_float) {
2858
libmv_CameraIntrinsicsUndistortFloat(distortion->intrinsics,
2859
ibuf->rect_float, resibuf->rect_float,
2860
ibuf->x, ibuf->y, overscan, ibuf->channels);
2863
libmv_CameraIntrinsicsDistortFloat(distortion->intrinsics,
2864
ibuf->rect_float, resibuf->rect_float,
2865
ibuf->x, ibuf->y, overscan, ibuf->channels);
2869
ibuf->userflags |= IB_RECT_INVALID;
2874
libmv_CameraIntrinsicsUndistortByte(distortion->intrinsics,
2875
(unsigned char*)ibuf->rect, (unsigned char*)resibuf->rect,
2876
ibuf->x, ibuf->y, overscan, ibuf->channels);
2879
libmv_CameraIntrinsicsDistortByte(distortion->intrinsics,
2880
(unsigned char*)ibuf->rect, (unsigned char*)resibuf->rect,
2881
ibuf->x, ibuf->y, overscan, ibuf->channels);
2894
void BKE_tracking_distortion_destroy(MovieDistortion *distortion)
2897
libmv_CameraIntrinsicsDestroy(distortion->intrinsics);
2900
MEM_freeN(distortion);
2903
ImBuf *BKE_tracking_undistort(MovieTracking *tracking, ImBuf *ibuf, int width, int height, float overscan)
2905
MovieTrackingCamera *camera = &tracking->camera;
2907
if (camera->intrinsics == NULL)
2908
camera->intrinsics = BKE_tracking_distortion_create();
2910
return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, width, height, overscan, 1);
2913
ImBuf *BKE_tracking_distort(MovieTracking *tracking, ImBuf *ibuf, int width, int height, float overscan)
2915
MovieTrackingCamera *camera = &tracking->camera;
2917
if (camera->intrinsics == NULL)
2918
camera->intrinsics = BKE_tracking_distortion_create();
2920
return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, width, height, overscan, 0);
2923
/* area - which part of marker should be selected. see TRACK_AREA_* constants */
2924
void BKE_tracking_select_track(ListBase *tracksbase, MovieTrackingTrack *track, int area, int extend)
2927
BKE_tracking_track_flag(track, area, SELECT, 0);
2930
MovieTrackingTrack *cur = tracksbase->first;
2933
if ((cur->flag & TRACK_HIDDEN) == 0) {
2935
BKE_tracking_track_flag(cur, TRACK_AREA_ALL, SELECT, 1);
2936
BKE_tracking_track_flag(cur, area, SELECT, 0);
2939
BKE_tracking_track_flag(cur, TRACK_AREA_ALL, SELECT, 1);
2948
void BKE_tracking_deselect_track(MovieTrackingTrack *track, int area)
2950
BKE_tracking_track_flag(track, area, SELECT, 1);
2953
MovieTrackingObject *BKE_tracking_new_object(MovieTracking *tracking, const char *name)
2955
MovieTrackingObject *object = MEM_callocN(sizeof(MovieTrackingObject), "tracking object");
2957
if (tracking->tot_object == 0) {
2958
/* first object is always camera */
2959
BLI_strncpy(object->name, "Camera", sizeof(object->name));
2961
object->flag |= TRACKING_OBJECT_CAMERA;
2964
BLI_strncpy(object->name, name, sizeof(object->name));
2967
BLI_addtail(&tracking->objects, object);
2969
tracking->tot_object++;
2970
tracking->objectnr = BLI_countlist(&tracking->objects) - 1;
2972
object->scale = 1.0f;
2974
BKE_tracking_object_unique_name(tracking, object);
2979
void BKE_tracking_remove_object(MovieTracking *tracking, MovieTrackingObject *object)
3616
/*********************** Dopesheet functions *************************/
3618
static int channels_alpha_sort(void *a, void *b)
3620
MovieTrackingDopesheetChannel *channel_a = a;
3621
MovieTrackingDopesheetChannel *channel_b = b;
3623
if (BLI_strcasecmp(channel_a->track->name, channel_b->track->name) > 0)
3629
static int channels_total_track_sort(void *a, void *b)
3631
MovieTrackingDopesheetChannel *channel_a = a;
3632
MovieTrackingDopesheetChannel *channel_b = b;
3634
if (channel_a->total_frames > channel_b->total_frames)
3640
static int channels_longest_segment_sort(void *a, void *b)
3642
MovieTrackingDopesheetChannel *channel_a = a;
3643
MovieTrackingDopesheetChannel *channel_b = b;
3645
if (channel_a->max_segment > channel_b->max_segment)
3651
static int channels_average_error_sort(void *a, void *b)
3653
MovieTrackingDopesheetChannel *channel_a = a;
3654
MovieTrackingDopesheetChannel *channel_b = b;
3656
if (channel_a->track->error > channel_b->track->error)
3662
static int channels_alpha_inverse_sort(void *a, void *b)
3664
if (channels_alpha_sort(a, b))
3670
static int channels_total_track_inverse_sort(void *a, void *b)
3672
if (channels_total_track_sort(a, b))
3678
static int channels_longest_segment_inverse_sort(void *a, void *b)
3680
if (channels_longest_segment_sort(a, b))
3686
static int channels_average_error_inverse_sort(void *a, void *b)
3688
MovieTrackingDopesheetChannel *channel_a = a;
3689
MovieTrackingDopesheetChannel *channel_b = b;
3691
if (channel_a->track->error < channel_b->track->error)
3697
static void channels_segments_calc(MovieTrackingDopesheetChannel *channel)
3699
MovieTrackingTrack *track = channel->track;
3702
channel->tot_segment = 0;
3703
channel->max_segment = 0;
3704
channel->total_frames = 0;
3708
while (i < track->markersnr) {
3709
MovieTrackingMarker *marker = &track->markers[i];
3711
if ((marker->flag & MARKER_DISABLED) == 0) {
3712
int prev_fra = marker->framenr, len = 0;
3715
while (i < track->markersnr) {
3716
marker = &track->markers[i];
3718
if (marker->framenr != prev_fra + 1)
3720
if (marker->flag & MARKER_DISABLED)
3723
prev_fra = marker->framenr;
3728
channel->tot_segment++;
3734
if (!channel->tot_segment)
3737
channel->segments = MEM_callocN(2 * sizeof(int) * channel->tot_segment, "tracking channel segments");
3739
/* create segments */
3742
while (i < track->markersnr) {
3743
MovieTrackingMarker *marker = &track->markers[i];
3745
if ((marker->flag & MARKER_DISABLED) == 0) {
3746
MovieTrackingMarker *start_marker = marker;
3747
int prev_fra = marker->framenr, len = 0;
3750
while (i < track->markersnr) {
3751
marker = &track->markers[i];
3753
if (marker->framenr != prev_fra + 1)
3755
if (marker->flag & MARKER_DISABLED)
3758
prev_fra = marker->framenr;
3759
channel->total_frames++;
3764
channel->segments[2 * segment] = start_marker->framenr;
3765
channel->segments[2 * segment + 1] = start_marker->framenr + len;
3767
channel->max_segment = max_ii(channel->max_segment, len);
3775
static void tracking_dopesheet_sort(MovieTracking *tracking, int sort_method, int inverse)
3777
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
3780
if (sort_method == TRACKING_DOPE_SORT_NAME) {
3781
BLI_sortlist(&dopesheet->channels, channels_alpha_inverse_sort);
3783
else if (sort_method == TRACKING_DOPE_SORT_LONGEST) {
3784
BLI_sortlist(&dopesheet->channels, channels_longest_segment_inverse_sort);
3786
else if (sort_method == TRACKING_DOPE_SORT_TOTAL) {
3787
BLI_sortlist(&dopesheet->channels, channels_total_track_inverse_sort);
3789
else if (sort_method == TRACKING_DOPE_SORT_AVERAGE_ERROR) {
3790
BLI_sortlist(&dopesheet->channels, channels_average_error_inverse_sort);
3794
if (sort_method == TRACKING_DOPE_SORT_NAME) {
3795
BLI_sortlist(&dopesheet->channels, channels_alpha_sort);
3797
else if (sort_method == TRACKING_DOPE_SORT_LONGEST) {
3798
BLI_sortlist(&dopesheet->channels, channels_longest_segment_sort);
3800
else if (sort_method == TRACKING_DOPE_SORT_TOTAL) {
3801
BLI_sortlist(&dopesheet->channels, channels_total_track_sort);
3803
else if (sort_method == TRACKING_DOPE_SORT_AVERAGE_ERROR) {
3804
BLI_sortlist(&dopesheet->channels, channels_average_error_sort);
3809
void BKE_tracking_dopesheet_tag_update(MovieTracking *tracking)
3811
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
3813
dopesheet->ok = FALSE;
3816
void BKE_tracking_dopesheet_update(MovieTracking *tracking)
3818
MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
3819
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
2981
3820
MovieTrackingTrack *track;
2982
int index = BLI_findindex(&tracking->objects, object);
2987
if (object->flag & TRACKING_OBJECT_CAMERA) {
2988
/* object used for camera solving can't be deleted */
2992
track = object->tracks.first;
2994
if (track == tracking->act_track)
2995
tracking->act_track = NULL;
3000
tracking_object_free(object);
3001
BLI_freelinkN(&tracking->objects, object);
3003
tracking->tot_object--;
3006
tracking->objectnr = index - 1;
3008
tracking->objectnr = 0;
3011
void BKE_tracking_object_unique_name(MovieTracking *tracking, MovieTrackingObject *object)
3013
BLI_uniquename(&tracking->objects, object, "Object", '.', offsetof(MovieTrackingObject, name), sizeof(object->name));
3016
MovieTrackingObject *BKE_tracking_named_object(MovieTracking *tracking, const char *name)
3018
MovieTrackingObject *object = tracking->objects.first;
3021
if (!strcmp(object->name, name))
3024
object = object->next;
3821
MovieTrackingReconstruction *reconstruction;
3822
ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
3824
short sort_method = dopesheet->sort_method;
3825
short inverse = dopesheet->flag & TRACKING_DOPE_SORT_INVERSE;
3826
short sel_only = dopesheet->flag & TRACKING_DOPE_SELECTED_ONLY;
3827
short show_hidden = dopesheet->flag & TRACKING_DOPE_SHOW_HIDDEN;
3832
tracking_dopesheet_free(dopesheet);
3834
reconstruction = BKE_tracking_object_get_reconstruction(tracking, object);
3836
for (track = tracksbase->first; track; track = track->next) {
3837
MovieTrackingDopesheetChannel *channel;
3839
if (!show_hidden && (track->flag & TRACK_HIDDEN) != 0)
3842
if (sel_only && !TRACK_SELECTED(track))
3845
channel = MEM_callocN(sizeof(MovieTrackingDopesheetChannel), "tracking dopesheet channel");
3846
channel->track = track;
3848
if (reconstruction->flag & TRACKING_RECONSTRUCTED) {
3849
BLI_snprintf(channel->name, sizeof(channel->name), "%s (%.4f)", track->name, track->error);
3852
BLI_strncpy(channel->name, track->name, sizeof(channel->name));
3855
channels_segments_calc(channel);
3857
BLI_addtail(&dopesheet->channels, channel);
3858
dopesheet->tot_channel++;
3861
tracking_dopesheet_sort(tracking, sort_method, inverse);
3863
dopesheet->ok = TRUE;