~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

Viewing changes to source/blender/blenkernel/intern/tracking.c

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 *
21
21
 * Contributor(s): Blender Foundation,
22
22
 *                 Sergey Sharybin
 
23
 *                 Keir Mierle
23
24
 *
24
25
 * ***** END GPL LICENSE BLOCK *****
25
26
 */
38
39
#include "DNA_gpencil_types.h"
39
40
#include "DNA_camera_types.h"
40
41
#include "DNA_movieclip_types.h"
41
 
#include "DNA_object_types.h"   /* SELECT */
 
42
#include "DNA_object_types.h"   /* SELECT */
42
43
#include "DNA_scene_types.h"
43
44
 
44
45
#include "BLI_utildefines.h"
50
51
#include "BLI_string.h"
51
52
#include "BLI_threads.h"
52
53
 
 
54
#include "BLF_translation.h"
 
55
 
53
56
#include "BKE_global.h"
54
57
#include "BKE_tracking.h"
55
58
#include "BKE_movieclip.h"
59
62
#include "IMB_imbuf_types.h"
60
63
#include "IMB_imbuf.h"
61
64
 
 
65
#include "raskter.h"
 
66
 
62
67
#ifdef WITH_LIBMV
63
68
#  include "libmv-capi.h"
64
69
#else
73
78
        ListBase tracks;
74
79
} tracking_clipboard;
75
80
 
76
 
/*********************** common functions *************************/
77
 
 
78
 
void BKE_tracking_init_settings(MovieTracking *tracking)
 
81
/*********************** Common functions  *************************/
 
82
 
 
83
static MovieTrackingTrack *tracking_track_duplicate(MovieTrackingTrack *track)
 
84
{
 
85
        MovieTrackingTrack *new_track;
 
86
 
 
87
        new_track = MEM_callocN(sizeof(MovieTrackingTrack), "tracksMapMerge new_track");
 
88
 
 
89
        *new_track = *track;
 
90
        new_track->next = new_track->prev = NULL;
 
91
 
 
92
        new_track->markers = MEM_dupallocN(new_track->markers);
 
93
 
 
94
        return new_track;
 
95
}
 
96
 
 
97
static void tracking_tracks_free(ListBase *tracks)
 
98
{
 
99
        MovieTrackingTrack *track;
 
100
 
 
101
        for (track = tracks->first; track; track = track->next) {
 
102
                BKE_tracking_track_free(track);
 
103
        }
 
104
 
 
105
        BLI_freelistN(tracks);
 
106
}
 
107
 
 
108
static void tracking_reconstruction_free(MovieTrackingReconstruction *reconstruction)
 
109
{
 
110
        if (reconstruction->cameras)
 
111
                MEM_freeN(reconstruction->cameras);
 
112
}
 
113
 
 
114
static void tracking_object_free(MovieTrackingObject *object)
 
115
{
 
116
        tracking_tracks_free(&object->tracks);
 
117
        tracking_reconstruction_free(&object->reconstruction);
 
118
}
 
119
 
 
120
static void tracking_objects_free(ListBase *objects)
 
121
{
 
122
        MovieTrackingObject *object;
 
123
 
 
124
        for (object = objects->first; object; object = object->next)
 
125
                tracking_object_free(object);
 
126
 
 
127
        BLI_freelistN(objects);
 
128
}
 
129
 
 
130
static void tracking_dopesheet_free(MovieTrackingDopesheet *dopesheet)
 
131
{
 
132
        MovieTrackingDopesheetChannel *channel;
 
133
 
 
134
        channel = dopesheet->channels.first;
 
135
        while (channel) {
 
136
                if (channel->segments) {
 
137
                        MEM_freeN(channel->segments);
 
138
                }
 
139
 
 
140
                channel = channel->next;
 
141
        }
 
142
 
 
143
        BLI_freelistN(&dopesheet->channels);
 
144
 
 
145
        dopesheet->channels.first = dopesheet->channels.last = NULL;
 
146
        dopesheet->tot_channel = 0;
 
147
}
 
148
 
 
149
void BKE_tracking_free(MovieTracking *tracking)
 
150
{
 
151
        tracking_tracks_free(&tracking->tracks);
 
152
        tracking_reconstruction_free(&tracking->reconstruction);
 
153
        tracking_objects_free(&tracking->objects);
 
154
 
 
155
        if (tracking->stabilization.scaleibuf)
 
156
                IMB_freeImBuf(tracking->stabilization.scaleibuf);
 
157
 
 
158
        if (tracking->camera.intrinsics)
 
159
                BKE_tracking_distortion_free(tracking->camera.intrinsics);
 
160
 
 
161
        tracking_dopesheet_free(&tracking->dopesheet);
 
162
}
 
163
 
 
164
void BKE_tracking_settings_init(MovieTracking *tracking)
79
165
{
80
166
        tracking->camera.sensor_width = 35.0f;
81
167
        tracking->camera.pixel_aspect = 1.0f;
82
168
        tracking->camera.units = CAMERA_UNITS_MM;
83
169
 
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;
93
178
 
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;
98
183
 
99
 
        BKE_tracking_new_object(tracking, "Camera");
100
 
}
101
 
 
102
 
void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event)
103
 
{
104
 
        int a;
105
 
        float pat_min[2];
106
 
        float pat_max[2];
107
 
        float max_pyramid_level_factor = 1.0;
108
 
 
109
 
        if (track->tracker == TRACKER_KLT) {
110
 
                max_pyramid_level_factor= 1 << (track->pyramid_levels - 1);
111
 
        }
112
 
 
113
 
        /* sort */
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]);
117
 
 
118
 
                if (track->search_min[a] > track->search_max[a])
119
 
                        SWAP(float, track->search_min[a], track->search_max[a]);
120
 
        }
121
 
 
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];
127
 
        }
128
 
 
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]);
134
 
                }
135
 
        }
136
 
        else if (event == CLAMP_PAT_POS) {
137
 
                float dim[2];
138
 
 
139
 
                sub_v2_v2v2(dim, track->pat_max, track->pat_min);
140
 
 
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];
146
 
                        }
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];
150
 
                        }
151
 
                }
152
 
        }
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]);
158
 
                }
159
 
        }
160
 
        else if (event == CLAMP_SEARCH_POS) {
161
 
                float dim[2];
162
 
 
163
 
                sub_v2_v2v2(dim, track->search_max, track->search_min);
164
 
 
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];
170
 
                        }
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];
174
 
                        }
175
 
                }
176
 
        }
177
 
        else if (event == CLAMP_PYRAMID_LEVELS || (event == CLAMP_SEARCH_DIM && track->tracker == TRACKER_KLT)) {
178
 
                float dim[2];
179
 
                sub_v2_v2v2(dim, track->pat_max, track->pat_min);
180
 
                {
181
 
                        float search_ratio = 2.3f * max_pyramid_level_factor;
182
 
 
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];
188
 
                        }
189
 
                }
190
 
        }
191
 
 
192
 
        /* marker's center should be in center of pattern */
193
 
        if (event == CLAMP_PAT_DIM || event == CLAMP_PAT_POS) {
194
 
                float dim[2];
195
 
 
196
 
                sub_v2_v2v2(dim, track->pat_max, track->pat_min);
197
 
 
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;
201
 
                }
202
 
        }
203
 
}
204
 
 
205
 
void BKE_tracking_track_flag(MovieTrackingTrack *track, int area, int flag, int clear)
206
 
{
207
 
        if (area == TRACK_AREA_NONE)
208
 
                return;
209
 
 
210
 
        if (clear) {
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;
217
 
        }
218
 
        else {
219
 
                if (area & TRACK_AREA_POINT)
220
 
                        track->flag |= flag;
221
 
                if (area & TRACK_AREA_PAT)
222
 
                        track->pat_flag |= flag;
223
 
                if (area & TRACK_AREA_SEARCH)
224
 
                        track->search_flag |= flag;
225
 
        }
226
 
}
227
 
 
228
 
MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, ListBase *tracksbase, float x, float y,
 
184
        BKE_tracking_object_add(tracking, "Camera");
 
185
}
 
186
 
 
187
ListBase *BKE_tracking_get_active_tracks(MovieTracking *tracking)
 
188
{
 
189
        MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
 
190
 
 
191
        if (object && (object->flag & TRACKING_OBJECT_CAMERA) == 0) {
 
192
                return &object->tracks;
 
193
        }
 
194
 
 
195
        return &tracking->tracks;
 
196
}
 
197
 
 
198
MovieTrackingReconstruction *BKE_tracking_get_active_reconstruction(MovieTracking *tracking)
 
199
{
 
200
        MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
 
201
 
 
202
        return BKE_tracking_object_get_reconstruction(tracking, object);
 
203
}
 
204
 
 
205
void BKE_tracking_get_camera_object_matrix(Scene *scene, Object *ob, float mat[4][4])
 
206
{
 
207
        if (!ob) {
 
208
                if (scene->camera)
 
209
                        ob = scene->camera;
 
210
                else
 
211
                        ob = BKE_scene_camera_find(scene);
 
212
        }
 
213
 
 
214
        if (ob)
 
215
                BKE_object_where_is_calc_mat4(scene, ob, mat);
 
216
        else
 
217
                unit_m4(mat);
 
218
}
 
219
 
 
220
void BKE_tracking_get_projection_matrix(MovieTracking *tracking, MovieTrackingObject *object,
 
221
                                        int framenr, int winx, int winy, float mat[4][4])
 
222
{
 
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;
 
226
        float winmat[4][4];
 
227
        float ycor =  1.0f / tracking->camera.pixel_aspect;
 
228
        float shiftx, shifty, winside = (float)min_ii(winx, winy);
 
229
 
 
230
        BKE_tracking_camera_shift_get(tracking, winx, winy, &shiftx, &shifty);
 
231
 
 
232
        clipsta = 0.1f;
 
233
        clipend = 1000.0f;
 
234
 
 
235
        if (winx >= winy)
 
236
                viewfac = (lens * winx) / tracking->camera.sensor_width;
 
237
        else
 
238
                viewfac = (ycor * lens * winy) / tracking->camera.sensor_width;
 
239
 
 
240
        pixsize = clipsta / viewfac;
 
241
 
 
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;
 
246
 
 
247
        left *= pixsize;
 
248
        right *= pixsize;
 
249
        bottom *= pixsize;
 
250
        top *= pixsize;
 
251
 
 
252
        perspective_m4(winmat, left, right, bottom, top, clipsta, clipend);
 
253
 
 
254
        camera = BKE_tracking_camera_get_reconstructed(tracking, object, framenr);
 
255
 
 
256
        if (camera) {
 
257
                float imat[4][4];
 
258
 
 
259
                invert_m4_m4(imat, camera->mat);
 
260
                mult_m4_m4m4(mat, winmat, imat);
 
261
        }
 
262
        else copy_m4_m4(mat, winmat);
 
263
}
 
264
 
 
265
/* **** space transformation functions  **** */
 
266
 
 
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.
 
272
 */
 
273
static void unified_to_pixel(int frame_width, int frame_height,
 
274
                             const float unified_coords[2], float pixel_coords[2])
 
275
{
 
276
        pixel_coords[0] = unified_coords[0] * frame_width;
 
277
        pixel_coords[1] = unified_coords[1] * frame_height;
 
278
}
 
279
 
 
280
static void marker_to_frame_unified(const MovieTrackingMarker *marker, const float marker_unified_coords[2],
 
281
                                    float frame_unified_coords[2])
 
282
{
 
283
        frame_unified_coords[0] = marker_unified_coords[0] + marker->pos[0];
 
284
        frame_unified_coords[1] = marker_unified_coords[1] + marker->pos[1];
 
285
}
 
286
 
 
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])
 
291
{
 
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);
 
294
}
 
295
 
 
296
static void get_search_origin_frame_pixel(int frame_width, int frame_height,
 
297
                                          const MovieTrackingMarker *marker, float frame_pixel[2])
 
298
{
 
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];
 
303
}
 
304
 
 
305
#ifdef WITH_LIBMV
 
306
static void pixel_to_unified(int frame_width, int frame_height, const float pixel_coords[2], float unified_coords[2])
 
307
{
 
308
        unified_coords[0] = pixel_coords[0] / frame_width;
 
309
        unified_coords[1] = pixel_coords[1] / frame_height;
 
310
}
 
311
 
 
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])
 
315
{
 
316
        float frame_pixel[2];
 
317
        float search_origin_frame_pixel[2];
 
318
 
 
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);
 
322
}
 
323
 
 
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])
 
327
{
 
328
        float frame_unified[2];
 
329
        float search_origin_frame_pixel[2];
 
330
 
 
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);
 
334
 
 
335
        /* marker pos is in frame unified */
 
336
        sub_v2_v2v2(marker_unified, frame_unified, marker->pos);
 
337
}
 
338
 
 
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).
 
343
 */
 
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])
 
347
{
 
348
        int i;
 
349
        float unified_coords[2];
 
350
        float pixel_coords[2];
 
351
 
 
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];
 
357
        }
 
358
 
 
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);
 
363
 
 
364
        search_pixel_x[4] = pixel_coords[0];
 
365
        search_pixel_y[4] = pixel_coords[1];
 
366
}
 
367
 
 
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])
 
371
{
 
372
        int i;
 
373
        float marker_unified[2];
 
374
        float search_pixel[2];
 
375
 
 
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]);
 
381
        }
 
382
 
 
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);
 
387
 
 
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.
 
391
         */
 
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];
 
395
        }
 
396
 
 
397
        marker->pos[0] += marker_unified[0];
 
398
        marker->pos[1] += marker_unified[1];
 
399
}
 
400
#endif
 
401
 
 
402
/*********************** clipboard *************************/
 
403
 
 
404
void BKE_tracking_clipboard_free(void)
 
405
{
 
406
        MovieTrackingTrack *track = tracking_clipboard.tracks.first, *next_track;
 
407
 
 
408
        while (track) {
 
409
                next_track = track->next;
 
410
 
 
411
                BKE_tracking_track_free(track);
 
412
                MEM_freeN(track);
 
413
 
 
414
                track = next_track;
 
415
        }
 
416
 
 
417
        tracking_clipboard.tracks.first = tracking_clipboard.tracks.last = NULL;
 
418
}
 
419
 
 
420
void BKE_tracking_clipboard_copy_tracks(MovieTracking *tracking, MovieTrackingObject *object)
 
421
{
 
422
        ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
 
423
        MovieTrackingTrack *track = tracksbase->first;
 
424
 
 
425
        BKE_tracking_clipboard_free();
 
426
 
 
427
        while (track) {
 
428
                if (TRACK_SELECTED(track) && (track->flag & TRACK_HIDDEN) == 0) {
 
429
                        MovieTrackingTrack *new_track = tracking_track_duplicate(track);
 
430
 
 
431
                        BLI_addtail(&tracking_clipboard.tracks, new_track);
 
432
                }
 
433
 
 
434
                track = track->next;
 
435
        }
 
436
}
 
437
 
 
438
int BKE_tracking_clipboard_has_tracks(void)
 
439
{
 
440
        return tracking_clipboard.tracks.first != NULL;
 
441
}
 
442
 
 
443
void BKE_tracking_clipboard_paste_tracks(MovieTracking *tracking, MovieTrackingObject *object)
 
444
{
 
445
        ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
 
446
        MovieTrackingTrack *track = tracking_clipboard.tracks.first;
 
447
 
 
448
        while (track) {
 
449
                MovieTrackingTrack *new_track = tracking_track_duplicate(track);
 
450
 
 
451
                BLI_addtail(tracksbase, new_track);
 
452
                BKE_tracking_track_unique_name(tracksbase, new_track);
 
453
 
 
454
                track = track->next;
 
455
        }
 
456
}
 
457
 
 
458
/*********************** Tracks  *************************/
 
459
 
 
460
static void tracking_marker_insert_disabled(MovieTrackingTrack *track, const MovieTrackingMarker *ref_marker,
 
461
                                            int before, int overwrite)
 
462
{
 
463
        MovieTrackingMarker marker_new;
 
464
 
 
465
        marker_new = *ref_marker;
 
466
        marker_new.flag &= ~MARKER_TRACKED;
 
467
        marker_new.flag |= MARKER_DISABLED;
 
468
 
 
469
        if (before)
 
470
                marker_new.framenr--;
 
471
        else
 
472
                marker_new.framenr++;
 
473
 
 
474
        if (overwrite || !BKE_tracking_track_has_marker_at_frame(track, marker_new.framenr))
 
475
                BKE_tracking_marker_insert(track, &marker_new);
 
476
}
 
477
 
 
478
MovieTrackingTrack *BKE_tracking_track_add(MovieTracking *tracking, ListBase *tracksbase, float x, float y,
229
479
                                           int framenr, int width, int height)
230
480
{
231
481
        MovieTrackingTrack *track;
245
495
        track = MEM_callocN(sizeof(MovieTrackingTrack), "add_marker_exec track");
246
496
        strcpy(track->name, "Track");
247
497
 
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;
255
506
 
256
507
        memset(&marker, 0, sizeof(marker));
257
508
        marker.pos[0] = x;
258
509
        marker.pos[1] = y;
259
510
        marker.framenr = framenr;
260
511
 
261
 
        copy_v2_v2(track->pat_max, pat);
262
 
        negate_v2_v2(track->pat_min, pat);
263
 
 
264
 
        copy_v2_v2(track->search_max, search);
265
 
        negate_v2_v2(track->search_min, search);
266
 
 
267
 
        BKE_tracking_insert_marker(track, &marker);
268
 
 
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];
 
514
 
 
515
        marker.pattern_corners[1][0] = pat[0];
 
516
        marker.pattern_corners[1][1] = -pat[1];
 
517
 
 
518
        negate_v2_v2(marker.pattern_corners[2], marker.pattern_corners[0]);
 
519
        negate_v2_v2(marker.pattern_corners[3], marker.pattern_corners[1]);
 
520
 
 
521
        copy_v2_v2(marker.search_max, search);
 
522
        negate_v2_v2(marker.search_min, search);
 
523
 
 
524
        BKE_tracking_marker_insert(track, &marker);
271
525
 
272
526
        BLI_addtail(tracksbase, track);
273
 
        BKE_track_unique_name(tracksbase, track);
 
527
        BKE_tracking_track_unique_name(tracksbase, track);
274
528
 
275
529
        return track;
276
530
}
277
531
 
278
 
MovieTrackingMarker *BKE_tracking_insert_marker(MovieTrackingTrack *track, MovieTrackingMarker *marker)
279
 
{
280
 
        MovieTrackingMarker *old_marker= NULL;
281
 
 
282
 
        if (track->markersnr)
283
 
                old_marker = BKE_tracking_exact_marker(track, marker->framenr);
284
 
 
285
 
        if (old_marker) {
286
 
                *old_marker = *marker;
287
 
 
288
 
                return old_marker;
289
 
        }
290
 
        else {
291
 
                int a = track->markersnr;
292
 
 
293
 
                while (a--) {
294
 
                        if (track->markers[a].framenr < marker->framenr)
295
 
                                break;
296
 
                }
297
 
 
298
 
                track->markersnr++;
299
 
 
300
 
                if (track->markers)
301
 
                        track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker)*track->markersnr);
302
 
                else
303
 
                        track->markers = MEM_callocN(sizeof(MovieTrackingMarker), "MovieTracking markers");
304
 
 
305
 
                memmove(track->markers+a+2, track->markers+a+1, (track->markersnr-a-2)*sizeof(MovieTrackingMarker));
306
 
                track->markers[a+1] = *marker;
307
 
 
308
 
                track->last_marker = a + 1;
309
 
 
310
 
                return &track->markers[a + 1];
311
 
        }
312
 
}
313
 
 
314
 
void BKE_tracking_delete_marker(MovieTrackingTrack *track, int framenr)
315
 
{
316
 
        int a= 0;
317
 
 
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));
322
 
                                track->markersnr--;
323
 
                                track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker)*track->markersnr);
324
 
                        }
325
 
                        else {
326
 
                                MEM_freeN(track->markers);
327
 
                                track->markers = NULL;
328
 
                                track->markersnr = 0;
329
 
                        }
330
 
 
331
 
                        break;
332
 
                }
333
 
 
334
 
                a++;
335
 
        }
336
 
}
337
 
 
338
 
MovieTrackingMarker *BKE_tracking_get_marker(MovieTrackingTrack *track, int framenr)
339
 
{
340
 
        int a = track->markersnr-1;
341
 
 
342
 
        if (!track->markersnr)
343
 
                return NULL;
344
 
 
345
 
        /* approximate pre-first framenr marker with first marker */
346
 
        if (framenr < track->markers[0].framenr)
347
 
                return &track->markers[0];
348
 
 
349
 
        if (track->last_marker < track->markersnr)
350
 
                a = track->last_marker;
351
 
 
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;
356
 
 
357
 
                                return &track->markers[a];
358
 
                        }
359
 
                        a++;
360
 
                }
361
 
 
362
 
                /* if there's no marker for exact position, use nearest marker from left side */
363
 
                return &track->markers[a-1];
364
 
        }
365
 
        else {
366
 
                while (a >= 0 && track->markers[a].framenr >= framenr) {
367
 
                        if (track->markers[a].framenr == framenr) {
368
 
                                track->last_marker = a;
369
 
 
370
 
                                return &track->markers[a];
371
 
                        }
372
 
 
373
 
                        a--;
374
 
                }
375
 
 
376
 
                /* if there's no marker for exact position, use nearest marker from left side */
377
 
                return &track->markers[a];
378
 
        }
379
 
 
380
 
        return NULL;
381
 
}
382
 
 
383
 
MovieTrackingMarker *BKE_tracking_ensure_marker(MovieTrackingTrack *track, int framenr)
384
 
{
385
 
        MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr);
386
 
 
387
 
        if (marker->framenr != framenr) {
388
 
                MovieTrackingMarker marker_new;
389
 
 
390
 
                marker_new = *marker;
391
 
                marker_new.framenr = framenr;
392
 
 
393
 
                BKE_tracking_insert_marker(track, &marker_new);
394
 
                marker = BKE_tracking_get_marker(track, framenr);
395
 
        }
396
 
 
397
 
        return marker;
398
 
}
399
 
 
400
 
MovieTrackingMarker *BKE_tracking_exact_marker(MovieTrackingTrack *track, int framenr)
401
 
{
402
 
        MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr);
403
 
 
404
 
        if (marker->framenr != framenr)
405
 
                return NULL;
406
 
 
407
 
        return marker;
408
 
}
409
 
 
410
 
int BKE_tracking_has_marker(MovieTrackingTrack *track, int framenr)
411
 
{
412
 
        return BKE_tracking_exact_marker(track, framenr) != 0;
413
 
}
414
 
 
415
 
int BKE_tracking_has_enabled_marker(MovieTrackingTrack *track, int framenr)
416
 
{
417
 
        MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr);
 
532
void BKE_tracking_track_unique_name(ListBase *tracksbase, MovieTrackingTrack *track)
 
533
{
 
534
        BLI_uniquename(tracksbase, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name));
 
535
}
 
536
 
 
537
void BKE_tracking_track_free(MovieTrackingTrack *track)
 
538
{
 
539
        if (track->markers)
 
540
                MEM_freeN(track->markers);
 
541
}
 
542
 
 
543
void BKE_tracking_track_flag_set(MovieTrackingTrack *track, int area, int flag)
 
544
{
 
545
        if (area == TRACK_AREA_NONE)
 
546
                return;
 
547
 
 
548
        if (area & TRACK_AREA_POINT)
 
549
                track->flag |= flag;
 
550
        if (area & TRACK_AREA_PAT)
 
551
                track->pat_flag |= flag;
 
552
        if (area & TRACK_AREA_SEARCH)
 
553
                track->search_flag |= flag;
 
554
}
 
555
 
 
556
void BKE_tracking_track_flag_clear(MovieTrackingTrack *track, int area, int flag)
 
557
{
 
558
        if (area == TRACK_AREA_NONE)
 
559
                return;
 
560
 
 
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;
 
567
}
 
568
 
 
569
int BKE_tracking_track_has_marker_at_frame(MovieTrackingTrack *track, int framenr)
 
570
{
 
571
        return BKE_tracking_marker_get_exact(track, framenr) != 0;
 
572
}
 
573
 
 
574
int BKE_tracking_track_has_enabled_marker_at_frame(MovieTrackingTrack *track, int framenr)
 
575
{
 
576
        MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, framenr);
418
577
 
419
578
        return marker && (marker->flag & MARKER_DISABLED) == 0;
420
579
}
421
580
 
422
 
void BKE_tracking_free_track(MovieTrackingTrack *track)
423
 
{
424
 
        if (track->markers)
425
 
                MEM_freeN(track->markers);
426
 
}
427
 
 
428
 
static void put_disabled_marker(MovieTrackingTrack *track, MovieTrackingMarker *ref_marker, int before, int overwrite)
429
 
{
430
 
        MovieTrackingMarker marker_new;
431
 
 
432
 
        marker_new = *ref_marker;
433
 
        marker_new.flag &= ~MARKER_TRACKED;
434
 
        marker_new.flag |= MARKER_DISABLED;
435
 
 
436
 
        if (before)
437
 
                marker_new.framenr--;
438
 
        else
439
 
                marker_new.framenr++;
440
 
 
441
 
        if (!BKE_tracking_has_marker(track, marker_new.framenr) || overwrite)
442
 
                BKE_tracking_insert_marker(track, &marker_new);
443
 
}
444
 
 
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)
446
582
{
447
583
        int a;
448
584
 
452
588
                while (a < track->markersnr) {
453
589
                        if (track->markers[a].framenr > ref_frame) {
454
590
                                track->markersnr = a;
455
 
                                track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker)*track->markersnr);
 
591
                                track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr);
456
592
 
457
593
                                break;
458
594
                        }
461
597
                }
462
598
 
463
599
                if (track->markersnr)
464
 
                        put_disabled_marker(track, &track->markers[track->markersnr-1], 0, 1);
 
600
                        tracking_marker_insert_disabled(track, &track->markers[track->markersnr - 1], FALSE, TRUE);
465
601
        }
466
602
        else if (action == TRACK_CLEAR_UPTO) {
467
 
                a= track->markersnr-1;
 
603
                a = track->markersnr - 1;
468
604
 
469
605
                while (a >= 0) {
470
606
                        if (track->markers[a].framenr <= ref_frame) {
471
 
                                memmove(track->markers, track->markers+a, (track->markersnr-a)*sizeof(MovieTrackingMarker));
 
607
                                memmove(track->markers, track->markers + a, (track->markersnr - a) * sizeof(MovieTrackingMarker));
472
608
 
473
 
                                track->markersnr = track->markersnr-a;
474
 
                                track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker)*track->markersnr);
 
609
                                track->markersnr = track->markersnr - a;
 
610
                                track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr);
475
611
 
476
612
                                break;
477
613
                        }
480
616
                }
481
617
 
482
618
                if (track->markersnr)
483
 
                        put_disabled_marker(track, &track->markers[0], 1, 1);
 
619
                        tracking_marker_insert_disabled(track, &track->markers[0], TRUE, TRUE);
484
620
        }
485
621
        else if (action == TRACK_CLEAR_ALL) {
486
622
                MovieTrackingMarker *marker, marker_new;
487
623
 
488
 
                marker = BKE_tracking_get_marker(track, ref_frame);
 
624
                marker = BKE_tracking_marker_get(track, ref_frame);
489
625
                marker_new = *marker;
490
626
 
491
627
                MEM_freeN(track->markers);
492
628
                track->markers = NULL;
493
629
                track->markersnr = 0;
494
630
 
495
 
                BKE_tracking_insert_marker(track, &marker_new);
 
631
                BKE_tracking_marker_insert(track, &marker_new);
496
632
 
497
 
                put_disabled_marker(track, &marker_new, 1, 1);
498
 
                put_disabled_marker(track, &marker_new, 0, 1);
 
633
                tracking_marker_insert_disabled(track, &marker_new, TRUE, TRUE);
 
634
                tracking_marker_insert_disabled(track, &marker_new, FALSE, TRUE);
499
635
        }
500
636
}
501
637
 
502
 
void BKE_tracking_join_tracks(MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track)
 
638
void BKE_tracking_tracks_join(MovieTracking *tracking, MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track)
503
639
{
504
640
        int i = 0, a = 0, b = 0, tot;
505
641
        MovieTrackingMarker *markers;
521
657
                        markers[i] = dst_track->markers[b++];
522
658
                }
523
659
                else {
524
 
                        if ((src_track->markers[a].flag & MARKER_DISABLED)==0) {
525
 
                                if ((dst_track->markers[b].flag & MARKER_DISABLED)==0) {
 
660
                        if ((src_track->markers[a].flag & MARKER_DISABLED) == 0) {
 
661
                                if ((dst_track->markers[b].flag & MARKER_DISABLED) == 0) {
526
662
                                        /* both tracks are enabled on this frame, so find the whole segment
527
663
                                         * on which tracks are intersecting and blend tracks using linear
528
 
                                         * interpolation to prevent jumps */
 
664
                                         * interpolation to prevent jumps
 
665
                                         */
529
666
 
530
667
                                        MovieTrackingMarker *marker_a, *marker_b;
531
668
                                        int start_a = a, start_b = b, len = 0, frame = src_track->markers[a].framenr;
532
669
                                        int j, inverse = 0;
533
670
 
534
671
                                        inverse = (b == 0) ||
535
 
                                                  (dst_track->markers[b-1].flag & MARKER_DISABLED) ||
536
 
                                                  (dst_track->markers[b-1].framenr != frame - 1);
 
672
                                                  (dst_track->markers[b - 1].flag & MARKER_DISABLED) ||
 
673
                                                  (dst_track->markers[b - 1].framenr != frame - 1);
537
674
 
538
675
                                        /* find length of intersection */
539
676
                                        while (a < src_track->markersnr && b < dst_track->markersnr) {
578
715
                                        /* this values will be incremented at the end of the loop cycle */
579
716
                                        a--; b--; i--;
580
717
                                }
581
 
                                else markers[i] = src_track->markers[a];
582
 
                        }
583
 
                        else markers[i] = dst_track->markers[b];
 
718
                                else {
 
719
                                        markers[i] = src_track->markers[a];
 
720
                                }
 
721
                        }
 
722
                        else {
 
723
                                markers[i] = dst_track->markers[b];
 
724
                        }
584
725
 
585
726
                        a++;
586
727
                        b++;
591
732
 
592
733
        MEM_freeN(dst_track->markers);
593
734
 
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));
596
737
 
597
738
        dst_track->markersnr = i;
598
739
 
599
740
        MEM_freeN(markers);
600
 
}
601
 
 
602
 
static void tracking_tracks_free(ListBase *tracks)
 
741
 
 
742
        BKE_tracking_dopesheet_tag_update(tracking);
 
743
}
 
744
 
 
745
MovieTrackingTrack *BKE_tracking_track_get_named(MovieTracking *tracking, MovieTrackingObject *object, const char *name)
 
746
{
 
747
        ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
 
748
        MovieTrackingTrack *track = tracksbase->first;
 
749
 
 
750
        while (track) {
 
751
                if (!strcmp(track->name, name))
 
752
                        return track;
 
753
 
 
754
                track = track->next;
 
755
        }
 
756
 
 
757
        return NULL;
 
758
}
 
759
 
 
760
MovieTrackingTrack *BKE_tracking_track_get_indexed(MovieTracking *tracking, int tracknr, ListBase **tracksbase_r)
 
761
{
 
762
        MovieTrackingObject *object;
 
763
        int cur = 1;
 
764
 
 
765
        object = tracking->objects.first;
 
766
        while (object) {
 
767
                ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
 
768
                MovieTrackingTrack *track = tracksbase->first;
 
769
 
 
770
                while (track) {
 
771
                        if (track->flag & TRACK_HAS_BUNDLE) {
 
772
                                if (cur == tracknr) {
 
773
                                        *tracksbase_r = tracksbase;
 
774
                                        return track;
 
775
                                }
 
776
 
 
777
                                cur++;
 
778
                        }
 
779
 
 
780
                        track = track->next;
 
781
                }
 
782
 
 
783
                object = object->next;
 
784
        }
 
785
 
 
786
        *tracksbase_r = NULL;
 
787
 
 
788
        return NULL;
 
789
}
 
790
 
 
791
MovieTrackingTrack *BKE_tracking_track_get_active(MovieTracking *tracking)
 
792
{
 
793
        ListBase *tracksbase;
 
794
 
 
795
        if (!tracking->act_track)
 
796
                return NULL;
 
797
 
 
798
        tracksbase = BKE_tracking_get_active_tracks(tracking);
 
799
 
 
800
        /* check that active track is in current tracks list */
 
801
        if (BLI_findindex(tracksbase, tracking->act_track) >= 0)
 
802
                return tracking->act_track;
 
803
 
 
804
        return NULL;
 
805
}
 
806
 
 
807
static bGPDlayer *track_mask_gpencil_layer_get(MovieTrackingTrack *track)
 
808
{
 
809
        bGPDlayer *layer;
 
810
 
 
811
        if (!track->gpd)
 
812
                return NULL;
 
813
 
 
814
        layer = track->gpd->layers.first;
 
815
 
 
816
        while (layer) {
 
817
                if (layer->flag & GP_LAYER_ACTIVE) {
 
818
                        bGPDframe *frame = layer->frames.first;
 
819
                        int ok = FALSE;
 
820
 
 
821
                        while (frame) {
 
822
                                if (frame->strokes.first) {
 
823
                                        ok = TRUE;
 
824
                                }
 
825
 
 
826
                                frame = frame->next;
 
827
                        }
 
828
 
 
829
                        if (ok)
 
830
                                return layer;
 
831
                }
 
832
 
 
833
                layer = layer->next;
 
834
        }
 
835
 
 
836
        return NULL;
 
837
}
 
838
 
 
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)
 
842
{
 
843
        bGPDframe *frame = layer->frames.first;
 
844
 
 
845
        while (frame) {
 
846
                bGPDstroke *stroke = frame->strokes.first;
 
847
 
 
848
                while (stroke) {
 
849
                        bGPDspoint *stroke_points = stroke->points;
 
850
                        float *mask_points, *fp;
 
851
                        int i;
 
852
 
 
853
                        if (stroke->flag & GP_STROKE_2DSPACE) {
 
854
                                fp = mask_points = MEM_callocN(2 * stroke->totpoints * sizeof(float),
 
855
                                                               "track mask rasterization points");
 
856
 
 
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;
 
860
                                }
 
861
 
 
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);
 
864
 
 
865
                                MEM_freeN(mask_points);
 
866
                        }
 
867
 
 
868
                        stroke = stroke->next;
 
869
                }
 
870
 
 
871
                frame = frame->next;
 
872
        }
 
873
}
 
874
 
 
875
float *BKE_tracking_track_get_mask(int frame_width, int frame_height,
 
876
                                   MovieTrackingTrack *track, MovieTrackingMarker *marker)
 
877
{
 
878
        float *mask = NULL;
 
879
        bGPDlayer *layer = track_mask_gpencil_layer_get(track);
 
880
        int mask_width, mask_height;
 
881
 
 
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;
 
884
 
 
885
        if (layer) {
 
886
                mask = MEM_callocN(mask_width * mask_height * sizeof(float), "track mask");
 
887
 
 
888
                track_mask_gpencil_layer_rasterize(frame_width, frame_height, marker, layer,
 
889
                                                   mask, mask_width, mask_height);
 
890
        }
 
891
 
 
892
        return mask;
 
893
}
 
894
 
 
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)
 
897
{
 
898
        if (extend) {
 
899
                BKE_tracking_track_flag_set(track, area, SELECT);
 
900
        }
 
901
        else {
 
902
                MovieTrackingTrack *cur = tracksbase->first;
 
903
 
 
904
                while (cur) {
 
905
                        if ((cur->flag & TRACK_HIDDEN) == 0) {
 
906
                                if (cur == track) {
 
907
                                        BKE_tracking_track_flag_clear(cur, TRACK_AREA_ALL, SELECT);
 
908
                                        BKE_tracking_track_flag_set(cur, area, SELECT);
 
909
                                }
 
910
                                else {
 
911
                                        BKE_tracking_track_flag_clear(cur, TRACK_AREA_ALL, SELECT);
 
912
                                }
 
913
                        }
 
914
 
 
915
                        cur = cur->next;
 
916
                }
 
917
        }
 
918
}
 
919
 
 
920
void BKE_tracking_track_deselect(MovieTrackingTrack *track, int area)
 
921
{
 
922
        BKE_tracking_track_flag_clear(track, area, SELECT);
 
923
}
 
924
 
 
925
/*********************** Marker *************************/
 
926
 
 
927
MovieTrackingMarker *BKE_tracking_marker_insert(MovieTrackingTrack *track, MovieTrackingMarker *marker)
 
928
{
 
929
        MovieTrackingMarker *old_marker = NULL;
 
930
 
 
931
        if (track->markersnr)
 
932
                old_marker = BKE_tracking_marker_get_exact(track, marker->framenr);
 
933
 
 
934
        if (old_marker) {
 
935
                /* simply replace settings for already allocated marker */
 
936
                *old_marker = *marker;
 
937
 
 
938
                return old_marker;
 
939
        }
 
940
        else {
 
941
                int a = track->markersnr;
 
942
 
 
943
                /* find position in array where to add new marker */
 
944
                while (a--) {
 
945
                        if (track->markers[a].framenr < marker->framenr)
 
946
                                break;
 
947
                }
 
948
 
 
949
                track->markersnr++;
 
950
 
 
951
                if (track->markers)
 
952
                        track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr);
 
953
                else
 
954
                        track->markers = MEM_callocN(sizeof(MovieTrackingMarker), "MovieTracking markers");
 
955
 
 
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));
 
959
 
 
960
                /* put new marker */
 
961
                track->markers[a + 1] = *marker;
 
962
 
 
963
                track->last_marker = a + 1;
 
964
 
 
965
                return &track->markers[a + 1];
 
966
        }
 
967
}
 
968
 
 
969
void BKE_tracking_marker_delete(MovieTrackingTrack *track, int framenr)
 
970
{
 
971
        int a = 0;
 
972
 
 
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));
 
978
                                track->markersnr--;
 
979
                                track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr);
 
980
                        }
 
981
                        else {
 
982
                                MEM_freeN(track->markers);
 
983
                                track->markers = NULL;
 
984
                                track->markersnr = 0;
 
985
                        }
 
986
 
 
987
                        break;
 
988
                }
 
989
 
 
990
                a++;
 
991
        }
 
992
}
 
993
 
 
994
void BKE_tracking_marker_clamp(MovieTrackingMarker *marker, int event)
 
995
{
 
996
        int a;
 
997
        float pat_min[2], pat_max[2];
 
998
 
 
999
        BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
 
1000
 
 
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]);
 
1006
                }
 
1007
        }
 
1008
        else if (event == CLAMP_PAT_POS) {
 
1009
                float dim[2];
 
1010
 
 
1011
                sub_v2_v2v2(dim, pat_max, pat_min);
 
1012
 
 
1013
                for (a = 0; a < 2; a++) {
 
1014
                        int b;
 
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];
 
1019
                        }
 
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];
 
1023
                        }
 
1024
                }
 
1025
        }
 
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]);
 
1031
                }
 
1032
        }
 
1033
        else if (event == CLAMP_SEARCH_POS) {
 
1034
                float dim[2];
 
1035
 
 
1036
                sub_v2_v2v2(dim, marker->search_max, marker->search_min);
 
1037
 
 
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];
 
1043
                        }
 
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];
 
1047
                        }
 
1048
                }
 
1049
        }
 
1050
}
 
1051
 
 
1052
MovieTrackingMarker *BKE_tracking_marker_get(MovieTrackingTrack *track, int framenr)
 
1053
{
 
1054
        int a = track->markersnr - 1;
 
1055
 
 
1056
        if (!track->markersnr)
 
1057
                return NULL;
 
1058
 
 
1059
        /* approximate pre-first framenr marker with first marker */
 
1060
        if (framenr < track->markers[0].framenr)
 
1061
                return &track->markers[0];
 
1062
 
 
1063
        if (track->last_marker < track->markersnr)
 
1064
                a = track->last_marker;
 
1065
 
 
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;
 
1070
 
 
1071
                                return &track->markers[a];
 
1072
                        }
 
1073
                        a++;
 
1074
                }
 
1075
 
 
1076
                /* if there's no marker for exact position, use nearest marker from left side */
 
1077
                return &track->markers[a - 1];
 
1078
        }
 
1079
        else {
 
1080
                while (a >= 0 && track->markers[a].framenr >= framenr) {
 
1081
                        if (track->markers[a].framenr == framenr) {
 
1082
                                track->last_marker = a;
 
1083
 
 
1084
                                return &track->markers[a];
 
1085
                        }
 
1086
 
 
1087
                        a--;
 
1088
                }
 
1089
 
 
1090
                /* if there's no marker for exact position, use nearest marker from left side */
 
1091
                return &track->markers[a];
 
1092
        }
 
1093
 
 
1094
        return NULL;
 
1095
}
 
1096
 
 
1097
MovieTrackingMarker *BKE_tracking_marker_get_exact(MovieTrackingTrack *track, int framenr)
 
1098
{
 
1099
        MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
 
1100
 
 
1101
        if (marker->framenr != framenr)
 
1102
                return NULL;
 
1103
 
 
1104
        return marker;
 
1105
}
 
1106
 
 
1107
MovieTrackingMarker *BKE_tracking_marker_ensure(MovieTrackingTrack *track, int framenr)
 
1108
{
 
1109
        MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
 
1110
 
 
1111
        if (marker->framenr != framenr) {
 
1112
                MovieTrackingMarker marker_new;
 
1113
 
 
1114
                marker_new = *marker;
 
1115
                marker_new.framenr = framenr;
 
1116
 
 
1117
                BKE_tracking_marker_insert(track, &marker_new);
 
1118
                marker = BKE_tracking_marker_get(track, framenr);
 
1119
        }
 
1120
 
 
1121
        return marker;
 
1122
}
 
1123
 
 
1124
void BKE_tracking_marker_pattern_minmax(const MovieTrackingMarker *marker, float min[2], float max[2])
 
1125
{
 
1126
        INIT_MINMAX2(min, max);
 
1127
 
 
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]);
 
1132
}
 
1133
 
 
1134
void BKE_tracking_marker_get_subframe_position(MovieTrackingTrack *track, float framenr, float pos[2])
 
1135
{
 
1136
        MovieTrackingMarker *marker = BKE_tracking_marker_get(track, (int) framenr);
 
1137
        MovieTrackingMarker *marker_last = track->markers + (track->markersnr - 1);
 
1138
 
 
1139
        if (marker != marker_last) {
 
1140
                MovieTrackingMarker *marker_next = marker + 1;
 
1141
 
 
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
 
1145
                         * tracked segments
 
1146
                         */
 
1147
 
 
1148
                        float fac = (framenr - (int) framenr) / (marker_next->framenr - marker->framenr);
 
1149
 
 
1150
                        interp_v2_v2v2(pos, marker->pos, marker_next->pos, fac);
 
1151
                }
 
1152
                else {
 
1153
                        copy_v2_v2(pos, marker->pos);
 
1154
                }
 
1155
        }
 
1156
        else {
 
1157
                copy_v2_v2(pos, marker->pos);
 
1158
        }
 
1159
 
 
1160
        /* currently track offset is always wanted to be applied here, could be made an option later */
 
1161
        add_v2_v2(pos, track->offset);
 
1162
}
 
1163
 
 
1164
/*********************** Object *************************/
 
1165
 
 
1166
MovieTrackingObject *BKE_tracking_object_add(MovieTracking *tracking, const char *name)
 
1167
{
 
1168
        MovieTrackingObject *object = MEM_callocN(sizeof(MovieTrackingObject), "tracking object");
 
1169
 
 
1170
        if (tracking->tot_object == 0) {
 
1171
                /* first object is always camera */
 
1172
                BLI_strncpy(object->name, "Camera", sizeof(object->name));
 
1173
 
 
1174
                object->flag |= TRACKING_OBJECT_CAMERA;
 
1175
        }
 
1176
        else {
 
1177
                BLI_strncpy(object->name, name, sizeof(object->name));
 
1178
        }
 
1179
 
 
1180
        BLI_addtail(&tracking->objects, object);
 
1181
 
 
1182
        tracking->tot_object++;
 
1183
        tracking->objectnr = BLI_countlist(&tracking->objects) - 1;
 
1184
 
 
1185
        object->scale = 1.0f;
 
1186
        object->keyframe1 = 1;
 
1187
        object->keyframe2 = 30;
 
1188
 
 
1189
        BKE_tracking_object_unique_name(tracking, object);
 
1190
 
 
1191
        return object;
 
1192
}
 
1193
 
 
1194
int BKE_tracking_object_delete(MovieTracking *tracking, MovieTrackingObject *object)
603
1195
{
604
1196
        MovieTrackingTrack *track;
605
 
 
606
 
        for (track = tracks->first; track; track = track->next) {
607
 
                BKE_tracking_free_track(track);
608
 
        }
609
 
 
610
 
        BLI_freelistN(tracks);
611
 
}
612
 
 
613
 
static void tracking_reconstruction_free(MovieTrackingReconstruction *reconstruction)
614
 
{
615
 
        if (reconstruction->cameras)
616
 
                MEM_freeN(reconstruction->cameras);
617
 
}
618
 
 
619
 
static void tracking_object_free(MovieTrackingObject *object)
620
 
{
621
 
        tracking_tracks_free(&object->tracks);
622
 
        tracking_reconstruction_free(&object->reconstruction);
623
 
}
624
 
 
625
 
static void tracking_objects_free(ListBase *objects)
626
 
{
627
 
        MovieTrackingObject *object;
628
 
 
629
 
        for (object = objects->first; object; object = object->next)
630
 
                tracking_object_free(object);
631
 
 
632
 
        BLI_freelistN(objects);
633
 
}
634
 
 
635
 
void BKE_tracking_free(MovieTracking *tracking)
636
 
{
637
 
        tracking_tracks_free(&tracking->tracks);
638
 
        tracking_reconstruction_free(&tracking->reconstruction);
639
 
        tracking_objects_free(&tracking->objects);
640
 
 
641
 
        if (tracking->stabilization.scaleibuf)
642
 
                IMB_freeImBuf(tracking->stabilization.scaleibuf);
643
 
 
644
 
        if (tracking->camera.intrinsics)
645
 
                BKE_tracking_distortion_destroy(tracking->camera.intrinsics);
646
 
}
647
 
 
648
 
static MovieTrackingTrack *duplicate_track(MovieTrackingTrack *track)
649
 
{
650
 
        MovieTrackingTrack *new_track;
651
 
 
652
 
        new_track = MEM_callocN(sizeof(MovieTrackingTrack), "tracksMapMerge new_track");
653
 
 
654
 
        *new_track = *track;
655
 
        new_track->next = new_track->prev = NULL;
656
 
 
657
 
        new_track->markers = MEM_dupallocN(new_track->markers);
658
 
 
659
 
        return new_track;
660
 
}
661
 
 
662
 
/*********************** clipboard *************************/
663
 
 
664
 
void BKE_tracking_free_clipboard(void)
665
 
{
666
 
        MovieTrackingTrack *track = tracking_clipboard.tracks.first, *next_track;
667
 
 
668
 
        while (track) {
669
 
                next_track = track->next;
670
 
 
671
 
                BKE_tracking_free_track(track);
672
 
                MEM_freeN(track);
673
 
 
674
 
                track = next_track;
675
 
        }
676
 
}
677
 
 
678
 
void BKE_tracking_clipboard_copy_tracks(MovieTracking *tracking, MovieTrackingObject *object)
679
 
{
680
 
        ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object);
681
 
        MovieTrackingTrack *track = tracksbase->first;
682
 
 
683
 
        BKE_tracking_free_clipboard();
684
 
 
685
 
        while (track) {
686
 
                if (TRACK_SELECTED(track) && (track->flag & TRACK_HIDDEN) == 0) {
687
 
                        MovieTrackingTrack *new_track = duplicate_track(track);
688
 
 
689
 
                        BLI_addtail(&tracking_clipboard.tracks, new_track);
690
 
                }
691
 
 
692
 
                track = track->next;
693
 
        }
694
 
}
695
 
 
696
 
int BKE_tracking_clipboard_has_tracks(void)
697
 
{
698
 
        return tracking_clipboard.tracks.first != NULL;
699
 
}
700
 
 
701
 
void BKE_tracking_clipboard_paste_tracks(MovieTracking *tracking, MovieTrackingObject *object)
702
 
{
703
 
        ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object);
704
 
        MovieTrackingTrack *track = tracking_clipboard.tracks.first;
705
 
 
706
 
        while (track) {
707
 
                MovieTrackingTrack *new_track = duplicate_track(track);
708
 
 
709
 
                BLI_addtail(tracksbase, new_track);
710
 
                BKE_track_unique_name(tracksbase, new_track);
711
 
 
712
 
                track = track->next;
713
 
        }
714
 
}
715
 
 
716
 
/*********************** tracks map *************************/
 
1197
        int index = BLI_findindex(&tracking->objects, object);
 
1198
 
 
1199
        if (index == -1)
 
1200
                return FALSE;
 
1201
 
 
1202
        if (object->flag & TRACKING_OBJECT_CAMERA) {
 
1203
                /* object used for camera solving can't be deleted */
 
1204
                return FALSE;
 
1205
        }
 
1206
 
 
1207
        track = object->tracks.first;
 
1208
        while (track) {
 
1209
                if (track == tracking->act_track)
 
1210
                        tracking->act_track = NULL;
 
1211
 
 
1212
                track = track->next;
 
1213
        }
 
1214
 
 
1215
        tracking_object_free(object);
 
1216
        BLI_freelinkN(&tracking->objects, object);
 
1217
 
 
1218
        tracking->tot_object--;
 
1219
 
 
1220
        if (index != 0)
 
1221
                tracking->objectnr = index - 1;
 
1222
        else
 
1223
                tracking->objectnr = 0;
 
1224
        return TRUE;
 
1225
}
 
1226
 
 
1227
void BKE_tracking_object_unique_name(MovieTracking *tracking, MovieTrackingObject *object)
 
1228
{
 
1229
        BLI_uniquename(&tracking->objects, object, "Object", '.',
 
1230
                       offsetof(MovieTrackingObject, name), sizeof(object->name));
 
1231
}
 
1232
 
 
1233
MovieTrackingObject *BKE_tracking_object_get_named(MovieTracking *tracking, const char *name)
 
1234
{
 
1235
        MovieTrackingObject *object = tracking->objects.first;
 
1236
 
 
1237
        while (object) {
 
1238
                if (!strcmp(object->name, name))
 
1239
                        return object;
 
1240
 
 
1241
                object = object->next;
 
1242
        }
 
1243
 
 
1244
        return NULL;
 
1245
}
 
1246
 
 
1247
MovieTrackingObject *BKE_tracking_object_get_active(MovieTracking *tracking)
 
1248
{
 
1249
        return BLI_findlink(&tracking->objects, tracking->objectnr);
 
1250
}
 
1251
 
 
1252
MovieTrackingObject *BKE_tracking_object_get_camera(MovieTracking *tracking)
 
1253
{
 
1254
        MovieTrackingObject *object = tracking->objects.first;
 
1255
 
 
1256
        while (object) {
 
1257
                if (object->flag & TRACKING_OBJECT_CAMERA)
 
1258
                        return object;
 
1259
 
 
1260
                object = object->next;
 
1261
        }
 
1262
 
 
1263
        return NULL;
 
1264
}
 
1265
 
 
1266
ListBase *BKE_tracking_object_get_tracks(MovieTracking *tracking, MovieTrackingObject *object)
 
1267
{
 
1268
        if (object->flag & TRACKING_OBJECT_CAMERA) {
 
1269
                return &tracking->tracks;
 
1270
        }
 
1271
 
 
1272
        return &object->tracks;
 
1273
}
 
1274
 
 
1275
MovieTrackingReconstruction *BKE_tracking_object_get_reconstruction(MovieTracking *tracking,
 
1276
                                                                    MovieTrackingObject *object)
 
1277
{
 
1278
        if (object->flag & TRACKING_OBJECT_CAMERA) {
 
1279
                return &tracking->reconstruction;
 
1280
        }
 
1281
 
 
1282
        return &object->reconstruction;
 
1283
}
 
1284
 
 
1285
/*********************** Camera *************************/
 
1286
 
 
1287
static int reconstructed_camera_index_get(MovieTrackingReconstruction *reconstruction, int framenr, int nearest)
 
1288
{
 
1289
        MovieReconstructedCamera *cameras = reconstruction->cameras;
 
1290
        int a = 0, d = 1;
 
1291
 
 
1292
        if (!reconstruction->camnr)
 
1293
                return -1;
 
1294
 
 
1295
        if (framenr < cameras[0].framenr) {
 
1296
                if (nearest)
 
1297
                        return 0;
 
1298
                else
 
1299
                        return -1;
 
1300
        }
 
1301
 
 
1302
        if (framenr > cameras[reconstruction->camnr - 1].framenr) {
 
1303
                if (nearest)
 
1304
                        return reconstruction->camnr - 1;
 
1305
                else
 
1306
                        return -1;
 
1307
        }
 
1308
 
 
1309
        if (reconstruction->last_camera < reconstruction->camnr)
 
1310
                a = reconstruction->last_camera;
 
1311
 
 
1312
        if (cameras[a].framenr >= framenr)
 
1313
                d = -1;
 
1314
 
 
1315
        while (a >= 0 && a < reconstruction->camnr) {
 
1316
                int cfra = cameras[a].framenr;
 
1317
 
 
1318
                /* check if needed framenr was "skipped" -- no data for requested frame */
 
1319
 
 
1320
                if (d > 0 && cfra > framenr) {
 
1321
                        /* interpolate with previous position */
 
1322
                        if (nearest)
 
1323
                                return a - 1;
 
1324
                        else
 
1325
                                break;
 
1326
                }
 
1327
 
 
1328
                if (d < 0 && cfra < framenr) {
 
1329
                        /* interpolate with next position */
 
1330
                        if (nearest)
 
1331
                                return a;
 
1332
                        else
 
1333
                                break;
 
1334
                }
 
1335
 
 
1336
                if (cfra == framenr) {
 
1337
                        reconstruction->last_camera = a;
 
1338
 
 
1339
                        return a;
 
1340
                }
 
1341
 
 
1342
                a += d;
 
1343
        }
 
1344
 
 
1345
        return -1;
 
1346
}
 
1347
 
 
1348
static void reconstructed_camera_scale_set(MovieTrackingObject *object, float mat[4][4])
 
1349
{
 
1350
        if ((object->flag & TRACKING_OBJECT_CAMERA) == 0) {
 
1351
                float smat[4][4];
 
1352
 
 
1353
                scale_m4_fl(smat, 1.0f / object->scale);
 
1354
                mult_m4_m4m4(mat, mat, smat);
 
1355
        }
 
1356
}
 
1357
 
 
1358
 
 
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)
 
1361
{
 
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;
 
1365
}
 
1366
 
 
1367
void BKE_tracking_camera_to_blender(MovieTracking *tracking, Scene *scene, Camera *camera, int width, int height)
 
1368
{
 
1369
        float focal = tracking->camera.focal;
 
1370
 
 
1371
        camera->sensor_x = tracking->camera.sensor_width;
 
1372
        camera->sensor_fit = CAMERA_SENSOR_FIT_AUTO;
 
1373
        camera->lens = focal * camera->sensor_x / width;
 
1374
 
 
1375
        scene->r.xsch = width * tracking->camera.pixel_aspect;
 
1376
        scene->r.ysch = height;
 
1377
 
 
1378
        scene->r.xasp = 1.0f;
 
1379
        scene->r.yasp = 1.0f;
 
1380
 
 
1381
        BKE_tracking_camera_shift_get(tracking, width, height, &camera->shiftx, &camera->shifty);
 
1382
}
 
1383
 
 
1384
MovieReconstructedCamera *BKE_tracking_camera_get_reconstructed(MovieTracking *tracking,
 
1385
                                                                MovieTrackingObject *object, int framenr)
 
1386
{
 
1387
        MovieTrackingReconstruction *reconstruction;
 
1388
        int a;
 
1389
 
 
1390
        reconstruction = BKE_tracking_object_get_reconstruction(tracking, object);
 
1391
        a = reconstructed_camera_index_get(reconstruction, framenr, FALSE);
 
1392
 
 
1393
        if (a == -1)
 
1394
                return NULL;
 
1395
 
 
1396
        return &reconstruction->cameras[a];
 
1397
}
 
1398
 
 
1399
void BKE_tracking_camera_get_reconstructed_interpolate(MovieTracking *tracking, MovieTrackingObject *object,
 
1400
                                                       int framenr, float mat[4][4])
 
1401
{
 
1402
        MovieTrackingReconstruction *reconstruction;
 
1403
        MovieReconstructedCamera *cameras;
 
1404
        int a;
 
1405
 
 
1406
        reconstruction = BKE_tracking_object_get_reconstruction(tracking, object);
 
1407
        cameras = reconstruction->cameras;
 
1408
        a = reconstructed_camera_index_get(reconstruction, framenr, 1);
 
1409
 
 
1410
        if (a == -1) {
 
1411
                unit_m4(mat);
 
1412
 
 
1413
                return;
 
1414
        }
 
1415
 
 
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);
 
1418
 
 
1419
                blend_m4_m4m4(mat, cameras[a].mat, cameras[a + 1].mat, t);
 
1420
        }
 
1421
        else {
 
1422
                copy_m4_m4(mat, cameras[a].mat);
 
1423
        }
 
1424
 
 
1425
        reconstructed_camera_scale_set(object, mat);
 
1426
}
 
1427
 
 
1428
/*********************** Distortion/Undistortion *************************/
 
1429
 
 
1430
MovieDistortion *BKE_tracking_distortion_new(void)
 
1431
{
 
1432
        MovieDistortion *distortion;
 
1433
 
 
1434
        distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
 
1435
 
 
1436
        return distortion;
 
1437
}
 
1438
 
 
1439
void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *tracking,
 
1440
                                    int calibration_width, int calibration_height)
 
1441
{
 
1442
        MovieTrackingCamera *camera = &tracking->camera;
 
1443
        float aspy = 1.0f / tracking->camera.pixel_aspect;
 
1444
 
 
1445
#ifdef WITH_LIBMV
 
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);
 
1451
        }
 
1452
        else {
 
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);
 
1457
        }
 
1458
#else
 
1459
        (void) distortion;
 
1460
        (void) calibration_width;
 
1461
        (void) calibration_height;
 
1462
        (void) camera;
 
1463
        (void) aspy;
 
1464
#endif
 
1465
}
 
1466
 
 
1467
MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion)
 
1468
{
 
1469
        MovieDistortion *new_distortion;
 
1470
 
 
1471
        new_distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
 
1472
 
 
1473
#ifdef WITH_LIBMV
 
1474
        new_distortion->intrinsics = libmv_CameraIntrinsicsCopy(distortion->intrinsics);
 
1475
#else
 
1476
        (void) distortion;
 
1477
#endif
 
1478
 
 
1479
        return new_distortion;
 
1480
}
 
1481
 
 
1482
ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *tracking, ImBuf *ibuf,
 
1483
                                    int calibration_width, int calibration_height, float overscan, int undistort)
 
1484
{
 
1485
        ImBuf *resibuf;
 
1486
 
 
1487
        BKE_tracking_distortion_update(distortion, tracking, calibration_width, calibration_height);
 
1488
 
 
1489
        resibuf = IMB_dupImBuf(ibuf);
 
1490
 
 
1491
#ifdef WITH_LIBMV
 
1492
        if (ibuf->rect_float) {
 
1493
                if (undistort) {
 
1494
                        libmv_CameraIntrinsicsUndistortFloat(distortion->intrinsics,
 
1495
                                                             ibuf->rect_float, resibuf->rect_float,
 
1496
                                                             ibuf->x, ibuf->y, overscan, ibuf->channels);
 
1497
                }
 
1498
                else {
 
1499
                        libmv_CameraIntrinsicsDistortFloat(distortion->intrinsics,
 
1500
                                                           ibuf->rect_float, resibuf->rect_float,
 
1501
                                                           ibuf->x, ibuf->y, overscan, ibuf->channels);
 
1502
                }
 
1503
 
 
1504
                if (ibuf->rect)
 
1505
                        imb_freerectImBuf(ibuf);
 
1506
        }
 
1507
        else {
 
1508
                if (undistort) {
 
1509
                        libmv_CameraIntrinsicsUndistortByte(distortion->intrinsics,
 
1510
                                                            (unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect,
 
1511
                                                            ibuf->x, ibuf->y, overscan, ibuf->channels);
 
1512
                }
 
1513
                else {
 
1514
                        libmv_CameraIntrinsicsDistortByte(distortion->intrinsics,
 
1515
                                                          (unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect,
 
1516
                                                          ibuf->x, ibuf->y, overscan, ibuf->channels);
 
1517
                }
 
1518
        }
 
1519
#else
 
1520
        (void) overscan;
 
1521
        (void) undistort;
 
1522
 
 
1523
        if (ibuf->rect_float && ibuf->rect)
 
1524
                imb_freerectImBuf(ibuf);
 
1525
#endif
 
1526
 
 
1527
        return resibuf;
 
1528
}
 
1529
 
 
1530
void BKE_tracking_distortion_free(MovieDistortion *distortion)
 
1531
{
 
1532
#ifdef WITH_LIBMV
 
1533
        libmv_CameraIntrinsicsDestroy(distortion->intrinsics);
 
1534
#endif
 
1535
 
 
1536
        MEM_freeN(distortion);
 
1537
}
 
1538
 
 
1539
void BKE_tracking_distort_v2(MovieTracking *tracking, const float co[2], float r_co[2])
 
1540
{
 
1541
        MovieTrackingCamera *camera = &tracking->camera;
 
1542
 
 
1543
#ifdef WITH_LIBMV
 
1544
        double x, y;
 
1545
        float aspy = 1.0f / tracking->camera.pixel_aspect;
 
1546
 
 
1547
        /* normalize coords */
 
1548
        x = (co[0] - camera->principal[0]) / camera->focal;
 
1549
        y = (co[1] - camera->principal[1] * aspy) / camera->focal;
 
1550
 
 
1551
        libmv_applyCameraIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy,
 
1552
                                    camera->k1, camera->k2, camera->k3, x, y, &x, &y);
 
1553
 
 
1554
        /* result is in image coords already */
 
1555
        r_co[0] = x;
 
1556
        r_co[1] = y;
 
1557
#else
 
1558
        (void) camera;
 
1559
        (void) co;
 
1560
        zero_v2(r_co);
 
1561
#endif
 
1562
}
 
1563
 
 
1564
void BKE_tracking_undistort_v2(MovieTracking *tracking, const float co[2], float r_co[2])
 
1565
{
 
1566
        MovieTrackingCamera *camera = &tracking->camera;
 
1567
 
 
1568
#ifdef WITH_LIBMV
 
1569
        double x = co[0], y = co[1];
 
1570
        float aspy = 1.0f / tracking->camera.pixel_aspect;
 
1571
 
 
1572
        libmv_InvertIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy,
 
1573
                               camera->k1, camera->k2, camera->k3, x, y, &x, &y);
 
1574
 
 
1575
        r_co[0] = x * camera->focal + camera->principal[0];
 
1576
        r_co[1] = y * camera->focal + camera->principal[1] * aspy;
 
1577
#else
 
1578
        (void) camera;
 
1579
        (void) co;
 
1580
        zero_v2(r_co);
 
1581
#endif
 
1582
}
 
1583
 
 
1584
ImBuf *BKE_tracking_undistort_frame(MovieTracking *tracking, ImBuf *ibuf, int calibration_width,
 
1585
                                    int calibration_height, float overscan)
 
1586
{
 
1587
        MovieTrackingCamera *camera = &tracking->camera;
 
1588
 
 
1589
        if (camera->intrinsics == NULL)
 
1590
                camera->intrinsics = BKE_tracking_distortion_new();
 
1591
 
 
1592
        return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, calibration_width,
 
1593
                                            calibration_height, overscan, TRUE);
 
1594
}
 
1595
 
 
1596
ImBuf *BKE_tracking_distort_frame(MovieTracking *tracking, ImBuf *ibuf, int calibration_width,
 
1597
                                  int calibration_height, float overscan)
 
1598
{
 
1599
        MovieTrackingCamera *camera = &tracking->camera;
 
1600
 
 
1601
        if (camera->intrinsics == NULL)
 
1602
                camera->intrinsics = BKE_tracking_distortion_new();
 
1603
 
 
1604
        return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, calibration_width,
 
1605
                                            calibration_height, overscan, FALSE);
 
1606
}
 
1607
 
 
1608
void BKE_tracking_max_undistortion_delta_across_bound(MovieTracking *tracking, rcti *rect, float delta[2])
 
1609
{
 
1610
        int a;
 
1611
        float pos[2], warped_pos[2];
 
1612
        const int coord_delta = 5;
 
1613
 
 
1614
        delta[0] = delta[1] = -FLT_MAX;
 
1615
 
 
1616
        for (a = rect->xmin; a <= rect->xmax + coord_delta; a += coord_delta) {
 
1617
                if (a > rect->xmax)
 
1618
                        a = rect->xmax;
 
1619
 
 
1620
                /* bottom edge */
 
1621
                pos[0] = a;
 
1622
                pos[1] = rect->ymin;
 
1623
 
 
1624
                BKE_tracking_undistort_v2(tracking, pos, warped_pos);
 
1625
 
 
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]));
 
1628
 
 
1629
                /* top edge */
 
1630
                pos[0] = a;
 
1631
                pos[1] = rect->ymax;
 
1632
 
 
1633
                BKE_tracking_undistort_v2(tracking, pos, warped_pos);
 
1634
 
 
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]));
 
1637
 
 
1638
                if (a >= rect->xmax)
 
1639
                        break;
 
1640
        }
 
1641
 
 
1642
        for (a = rect->ymin; a <= rect->ymax + coord_delta; a += coord_delta) {
 
1643
                if (a > rect->ymax)
 
1644
                        a = rect->ymax;
 
1645
 
 
1646
                /* left edge */
 
1647
                pos[0] = rect->xmin;
 
1648
                pos[1] = a;
 
1649
 
 
1650
                BKE_tracking_undistort_v2(tracking, pos, warped_pos);
 
1651
 
 
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]));
 
1654
 
 
1655
                /* right edge */
 
1656
                pos[0] = rect->xmax;
 
1657
                pos[1] = a;
 
1658
 
 
1659
                BKE_tracking_undistort_v2(tracking, pos, warped_pos);
 
1660
 
 
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]));
 
1663
 
 
1664
                if (a >= rect->ymax)
 
1665
                        break;
 
1666
        }
 
1667
}
 
1668
 
 
1669
/*********************** Image sampling *************************/
 
1670
 
 
1671
static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int grayscale)
 
1672
{
 
1673
        BKE_tracking_disable_channels(ibuf, track->flag & TRACK_DISABLE_RED,
 
1674
                                      track->flag & TRACK_DISABLE_GREEN,
 
1675
                                      track->flag & TRACK_DISABLE_BLUE, grayscale);
 
1676
}
 
1677
 
 
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,
 
1681
                                   float pos[2])
 
1682
{
 
1683
#ifdef WITH_LIBMV
 
1684
        ImBuf *pattern_ibuf;
 
1685
        double src_pixel_x[5], src_pixel_y[5];
 
1686
        double warped_position_x, warped_position_y;
 
1687
        float *mask = NULL;
 
1688
 
 
1689
        if (num_samples_x <= 0 || num_samples_y <= 0)
 
1690
                return NULL;
 
1691
 
 
1692
        pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y, 32, IB_rectfloat);
 
1693
 
 
1694
        if (!search_ibuf->rect_float) {
 
1695
                IMB_float_from_rect(search_ibuf);
 
1696
        }
 
1697
 
 
1698
        get_marker_coords_for_tracking(frame_width, frame_height, marker, src_pixel_x, src_pixel_y);
 
1699
 
 
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)
 
1703
         *
 
1704
         * in this case we need to alter coordinates a bit, to compensate rounded
 
1705
         * fractional part of offset
 
1706
         */
 
1707
        if (from_anchor) {
 
1708
                int a;
 
1709
 
 
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)));
 
1713
 
 
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;
 
1719
                }
 
1720
        }
 
1721
 
 
1722
        if (use_mask) {
 
1723
                mask = BKE_tracking_track_get_mask(frame_width, frame_height, track, marker);
 
1724
        }
 
1725
 
 
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);
 
1730
 
 
1731
        if (pos) {
 
1732
                pos[0] = warped_position_x;
 
1733
                pos[1] = warped_position_y;
 
1734
        }
 
1735
 
 
1736
        if (mask) {
 
1737
                MEM_freeN(mask);
 
1738
        }
 
1739
 
 
1740
        return pattern_ibuf;
 
1741
#else
 
1742
        ImBuf *pattern_ibuf;
 
1743
 
 
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
 
1748
         */
 
1749
 
 
1750
        (void) frame_width;
 
1751
        (void) frame_height;
 
1752
        (void) search_ibuf;
 
1753
        (void) marker;
 
1754
        (void) track;
 
1755
        (void) use_mask;
 
1756
 
 
1757
        pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y, 32, IB_rectfloat);
 
1758
 
 
1759
        pos[0] = num_samples_x / 2.0f;
 
1760
        pos[1] = num_samples_y / 2.0f;
 
1761
 
 
1762
        return pattern_ibuf;
 
1763
#endif
 
1764
}
 
1765
 
 
1766
ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
 
1767
                                      int anchored, int disable_channels)
 
1768
{
 
1769
        ImBuf *pattern_ibuf, *search_ibuf;
 
1770
        float pat_min[2], pat_max[2];
 
1771
        int num_samples_x, num_samples_y;
 
1772
 
 
1773
        BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
 
1774
 
 
1775
        num_samples_x = (pat_max[0] - pat_min[0]) * ibuf->x;
 
1776
        num_samples_y = (pat_max[1] - pat_min[1]) * ibuf->y;
 
1777
 
 
1778
        search_ibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, anchored, disable_channels);
 
1779
 
 
1780
        if (search_ibuf) {
 
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);
 
1783
 
 
1784
                IMB_freeImBuf(search_ibuf);
 
1785
        }
 
1786
        else {
 
1787
                pattern_ibuf = NULL;
 
1788
        }
 
1789
 
 
1790
        return pattern_ibuf;
 
1791
}
 
1792
 
 
1793
ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
 
1794
                                     int anchored, int disable_channels)
 
1795
{
 
1796
        ImBuf *searchibuf;
 
1797
        int x, y, w, h;
 
1798
        float search_origin[2];
 
1799
 
 
1800
        get_search_origin_frame_pixel(ibuf->x, ibuf->y, marker, search_origin);
 
1801
 
 
1802
        x = search_origin[0];
 
1803
        y = search_origin[1];
 
1804
 
 
1805
        if (anchored) {
 
1806
                x += track->offset[0] * ibuf->x;
 
1807
                y += track->offset[1] * ibuf->y;
 
1808
        }
 
1809
 
 
1810
        w = (marker->search_max[0] - marker->search_min[0]) * ibuf->x;
 
1811
        h = (marker->search_max[1] - marker->search_min[1]) * ibuf->y;
 
1812
 
 
1813
        if (w <= 0 || h <= 0)
 
1814
                return NULL;
 
1815
 
 
1816
        searchibuf = IMB_allocImBuf(w, h, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
 
1817
 
 
1818
        IMB_rectcpy(searchibuf, ibuf, 0, 0, x, y, w, h);
 
1819
 
 
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))
 
1825
                {
 
1826
                        disable_imbuf_channels(searchibuf, track, TRUE);
 
1827
                }
 
1828
        }
 
1829
 
 
1830
        return searchibuf;
 
1831
}
 
1832
 
 
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.
 
1836
 */
 
1837
void BKE_tracking_disable_channels(ImBuf *ibuf, int disable_red, int disable_green, int disable_blue,
 
1838
                                   int grayscale)
 
1839
{
 
1840
        int x, y;
 
1841
        float scale;
 
1842
 
 
1843
        if (!disable_red && !disable_green && !disable_blue && !grayscale)
 
1844
                return;
 
1845
 
 
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.
 
1848
         */
 
1849
        scale = (disable_red   ? 0.0f : 0.2126f) +
 
1850
                (disable_green ? 0.0f : 0.7152f) +
 
1851
                (disable_blue  ? 0.0f : 0.0722f);
 
1852
 
 
1853
        for (y = 0; y < ibuf->y; y++) {
 
1854
                for (x = 0; x < ibuf->x; x++) {
 
1855
                        int pixel = ibuf->x * y + x;
 
1856
 
 
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];
 
1862
 
 
1863
                                if (grayscale) {
 
1864
                                        float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale;
 
1865
 
 
1866
                                        rrgbf[0] = rrgbf[1] = rrgbf[2] = gray;
 
1867
                                }
 
1868
                                else {
 
1869
                                        rrgbf[0] = r;
 
1870
                                        rrgbf[1] = g;
 
1871
                                        rrgbf[2] = b;
 
1872
                                }
 
1873
                        }
 
1874
                        else {
 
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];
 
1879
 
 
1880
                                if (grayscale) {
 
1881
                                        float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale;
 
1882
 
 
1883
                                        rrgb[0] = rrgb[1] = rrgb[2] = gray;
 
1884
                                }
 
1885
                                else {
 
1886
                                        rrgb[0] = r;
 
1887
                                        rrgb[1] = g;
 
1888
                                        rrgb[2] = b;
 
1889
                                }
 
1890
                        }
 
1891
                }
 
1892
        }
 
1893
 
 
1894
        if (ibuf->rect_float)
 
1895
                ibuf->userflags |= IB_RECT_INVALID;
 
1896
}
 
1897
 
 
1898
/*********************** Tracks map *************************/
717
1899
 
718
1900
typedef struct TracksMap {
719
1901
        char object_name[MAX_NAME];
740
1922
        map->num_tracks = num_tracks;
741
1923
        map->customdata_size = customdata_size;
742
1924
 
743
 
        map->tracks = MEM_callocN(sizeof(MovieTrackingTrack)*num_tracks, "TrackingsMap tracks");
 
1925
        map->tracks = MEM_callocN(sizeof(MovieTrackingTrack) * num_tracks, "TrackingsMap tracks");
744
1926
 
745
1927
        if (customdata_size)
746
 
                map->customdata = MEM_callocN(customdata_size*num_tracks, "TracksMap customdata");
 
1928
                map->customdata = MEM_callocN(customdata_size * num_tracks, "TracksMap customdata");
747
1929
 
748
 
        map->hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "TracksMap hash");
 
1930
        map->hash = BLI_ghash_ptr_new("TracksMap hash");
749
1931
 
750
1932
        return map;
751
1933
}
752
1934
 
753
 
static int tracks_map_size(TracksMap *map)
 
1935
static int tracks_map_get_size(TracksMap *map)
754
1936
{
755
1937
        return map->num_tracks;
756
1938
}
757
1939
 
758
 
static void tracks_map_get(TracksMap *map, int index, MovieTrackingTrack **track, void **customdata)
 
1940
static void tracks_map_get_indexed_element(TracksMap *map, int index, MovieTrackingTrack **track, void **customdata)
759
1941
{
760
1942
        *track = &map->tracks[index];
761
1943
 
762
1944
        if (map->customdata)
763
 
                *customdata = &map->customdata[index*map->customdata_size];
 
1945
                *customdata = &map->customdata[index * map->customdata_size];
764
1946
}
765
1947
 
766
1948
static void tracks_map_insert(TracksMap *map, MovieTrackingTrack *track, void *customdata)
767
1949
{
768
 
        MovieTrackingTrack new_track= *track;
 
1950
        MovieTrackingTrack new_track = *track;
769
1951
 
770
1952
        new_track.markers = MEM_dupallocN(new_track.markers);
771
1953
 
772
1954
        map->tracks[map->ptr] = new_track;
773
1955
 
774
1956
        if (customdata)
775
 
                memcpy(&map->customdata[map->ptr*map->customdata_size], customdata, map->customdata_size);
 
1957
                memcpy(&map->customdata[map->ptr * map->customdata_size], customdata, map->customdata_size);
776
1958
 
777
1959
        BLI_ghash_insert(map->hash, &map->tracks[map->ptr], track);
778
1960
 
782
1964
static void tracks_map_merge(TracksMap *map, MovieTracking *tracking)
783
1965
{
784
1966
        MovieTrackingTrack *track;
785
 
        MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking);
 
1967
        MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
786
1968
        MovieTrackingTrack *rot_track = tracking->stabilization.rot_track;
787
1969
        ListBase tracks = {NULL, NULL}, new_tracks = {NULL, NULL};
788
1970
        ListBase *old_tracks;
792
1974
                old_tracks = &tracking->tracks;
793
1975
        }
794
1976
        else {
795
 
                MovieTrackingObject *object = BKE_tracking_named_object(tracking, map->object_name);
 
1977
                MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, map->object_name);
796
1978
 
797
1979
                if (!object) {
798
1980
                        /* object was deleted by user, create new one */
799
 
                        object = BKE_tracking_new_object(tracking, map->object_name);
 
1981
                        object = BKE_tracking_object_add(tracking, map->object_name);
800
1982
                }
801
1983
 
802
1984
                old_tracks = &object->tracks;
804
1986
 
805
1987
        /* duplicate currently operating tracks to temporary list.
806
1988
         * this is needed to keep names in unique state and it's faster to change names
807
 
         * of currently operating tracks (if needed) */
 
1989
         * of currently operating tracks (if needed)
 
1990
         */
808
1991
        for (a = 0; a < map->num_tracks; a++) {
809
1992
                int replace_sel = 0, replace_rot = 0;
810
1993
                MovieTrackingTrack *new_track, *old;
834
2017
                                track->pat_flag = cur->pat_flag;
835
2018
                                track->search_flag = cur->search_flag;
836
2019
 
837
 
                                BKE_tracking_free_track(cur);
 
2020
                                BKE_tracking_track_free(cur);
838
2021
                                BLI_freelinkN(old_tracks, cur);
839
2022
                        }
840
2023
                }
841
2024
 
842
 
                new_track = duplicate_track(track);
 
2025
                new_track = tracking_track_duplicate(track);
843
2026
 
844
2027
                BLI_ghash_remove(map->hash, track, NULL, NULL); /* XXX: are we actually need this */
845
2028
                BLI_ghash_insert(map->hash, track, new_track);
846
2029
 
847
 
                if (replace_sel)                /* update current selection in clip */
848
 
                        tracking->act_track= new_track;
 
2030
                if (replace_sel)  /* update current selection in clip */
 
2031
                        tracking->act_track = new_track;
849
2032
 
850
 
                if (replace_rot)                /* update track used for rotation stabilization */
851
 
                        tracking->stabilization.rot_track= new_track;
 
2033
                if (replace_rot)  /* update track used for rotation stabilization */
 
2034
                        tracking->stabilization.rot_track = new_track;
852
2035
 
853
2036
                BLI_addtail(&tracks, new_track);
854
2037
        }
861
2044
                track->next = track->prev = NULL;
862
2045
                BLI_addtail(&new_tracks, track);
863
2046
 
864
 
                track= next;
 
2047
                track = next;
865
2048
        }
866
2049
 
867
2050
        /* now move all tracks which are currently operating and keep their names unique */
876
2059
 
877
2060
                BLI_uniquename(&new_tracks, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name));
878
2061
 
879
 
                track= next;
 
2062
                track = next;
880
2063
        }
881
2064
 
882
 
        *old_tracks= new_tracks;
 
2065
        *old_tracks = new_tracks;
883
2066
}
884
2067
 
885
 
static void tracks_map_free(TracksMap *map, void (*customdata_free) (void *customdata))
 
2068
static void tracks_map_free(TracksMap *map, void (*customdata_free)(void *customdata))
886
2069
{
887
 
        int i= 0;
 
2070
        int i = 0;
888
2071
 
889
2072
        BLI_ghash_free(map->hash, NULL, NULL);
890
2073
 
891
2074
        for (i = 0; i < map->num_tracks; i++) {
892
2075
                if (map->customdata && customdata_free)
893
 
                        customdata_free(&map->customdata[i*map->customdata_size]);
 
2076
                        customdata_free(&map->customdata[i * map->customdata_size]);
894
2077
 
895
 
                BKE_tracking_free_track(&map->tracks[i]);
 
2078
                BKE_tracking_track_free(&map->tracks[i]);
896
2079
        }
897
2080
 
898
2081
        if (map->customdata)
902
2085
        MEM_freeN(map);
903
2086
}
904
2087
 
905
 
/*********************** tracking *************************/
 
2088
/*********************** 2D tracking *************************/
906
2089
 
907
2090
typedef struct TrackContext {
908
2091
#ifdef WITH_LIBMV
909
 
        float keyframed_pos[2];
910
 
 
911
 
        struct libmv_RegionTracker *region_tracker;
912
 
        float *patch;                   /* keyframed patch */
 
2092
        /* the reference marker and cutout search area */
 
2093
        MovieTrackingMarker marker;
 
2094
 
 
2095
        /* keyframed patch. This is the search area */
 
2096
        float *search_area;
 
2097
        int search_area_height;
 
2098
        int search_area_width;
 
2099
        int framenr;
 
2100
 
 
2101
        float *mask;
913
2102
#else
914
2103
        int pad;
915
2104
#endif
929
2118
        int sync_frame;
930
2119
} MovieTrackingContext;
931
2120
 
 
2121
static void track_context_free(void *customdata)
 
2122
{
 
2123
        TrackContext *track_context = (TrackContext *)customdata;
 
2124
 
 
2125
#ifdef WITH_LIBMV
 
2126
        if (track_context->search_area)
 
2127
                MEM_freeN(track_context->search_area);
 
2128
 
 
2129
        if (track_context->mask)
 
2130
                MEM_freeN(track_context->mask);
 
2131
 
 
2132
#else
 
2133
        (void)track_context;
 
2134
#endif
 
2135
}
 
2136
 
932
2137
MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *user, short backwards, short sequence)
933
2138
{
934
2139
        MovieTrackingContext *context = MEM_callocN(sizeof(MovieTrackingContext), "trackingContext");
935
2140
        MovieTracking *tracking = &clip->tracking;
936
2141
        MovieTrackingSettings *settings = &tracking->settings;
937
 
        ListBase *tracksbase = BKE_tracking_get_tracks(tracking);
 
2142
        ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
938
2143
        MovieTrackingTrack *track;
939
 
        MovieTrackingObject *object = BKE_tracking_active_object(tracking);
 
2144
        MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
940
2145
        int num_tracks = 0;
941
2146
 
 
2147
        context->clip = clip;
942
2148
        context->settings = *settings;
943
2149
        context->backwards = backwards;
944
2150
        context->sync_frame = user->framenr;
948
2154
        /* count */
949
2155
        track = tracksbase->first;
950
2156
        while (track) {
951
 
                if (TRACK_SELECTED(track) && (track->flag & (TRACK_LOCKED | TRACK_HIDDEN))==0) {
952
 
                        MovieTrackingMarker *marker = BKE_tracking_get_marker(track, user->framenr);
 
2157
                if (TRACK_SELECTED(track) && (track->flag & (TRACK_LOCKED | TRACK_HIDDEN)) == 0) {
 
2158
                        int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr);
 
2159
                        MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
953
2160
 
954
2161
                        if ((marker->flag & MARKER_DISABLED) == 0)
955
2162
                                num_tracks++;
958
2165
                track = track->next;
959
2166
        }
960
2167
 
 
2168
        /* create tracking contextx for all tracks which would be tracked */
961
2169
        if (num_tracks) {
962
2170
                int width, height;
963
2171
 
970
2178
                track = tracksbase->first;
971
2179
                while (track) {
972
2180
                        if (TRACK_SELECTED(track) && (track->flag & (TRACK_HIDDEN | TRACK_LOCKED)) == 0) {
973
 
                                MovieTrackingMarker *marker = BKE_tracking_get_marker(track, user->framenr);
 
2181
                                int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr);
 
2182
                                MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
974
2183
 
975
2184
                                if ((marker->flag & MARKER_DISABLED) == 0) {
976
2185
                                        TrackContext track_context;
977
 
 
978
2186
                                        memset(&track_context, 0, sizeof(TrackContext));
979
 
 
980
 
#ifdef WITH_LIBMV
981
 
                                        {
982
 
                                                float patx = (int)((track->pat_max[0]-track->pat_min[0])*width),
983
 
                                                      paty = (int)((track->pat_max[1]-track->pat_min[1])*height);
984
 
 
985
 
                                                float search_size_x = (track->search_max[0]-track->search_min[0])*width;
986
 
                                                float search_size_y = (track->search_max[1]-track->search_min[1])*height;
987
 
                                                float pattern_size_x = (track->pat_max[0]-track->pat_min[0])*width;
988
 
                                                float pattern_size_y = (track->pat_max[1]-track->pat_min[1])*height;
989
 
                                                int wndx = (int)patx / 2, wndy = (int)paty / 2;
990
 
                                                int half_wnd = MAX2(wndx, wndy);
991
 
 
992
 
                                                        /* compute the maximum pyramid size */
993
 
                                                float search_to_pattern_ratio = MIN2(search_size_x,  search_size_y)
994
 
                                                        / MAX2(pattern_size_x, pattern_size_y);
995
 
                                                float log2_search_to_pattern_ratio = log(floor(search_to_pattern_ratio)) / M_LN2;
996
 
                                                int max_pyramid_levels = floor(log2_search_to_pattern_ratio + 1);
997
 
 
998
 
                                                /* try to accommodate the user's choice of pyramid level in a way
999
 
                                                 * that doesn't cause the coarsest pyramid pattern to be larger
1000
 
                                                 * than the search size */
1001
 
                                                int level = MIN2(track->pyramid_levels, max_pyramid_levels);
1002
 
 
1003
 
                                                if (track->tracker==TRACKER_KLT) {
1004
 
                                                        track_context.region_tracker =
1005
 
                                                                libmv_pyramidRegionTrackerNew(100, level, half_wnd, track->minimum_correlation);
1006
 
                                                }
1007
 
                                                else if (track->tracker == TRACKER_HYBRID) {
1008
 
                                                        track_context.region_tracker =
1009
 
                                                                libmv_hybridRegionTrackerNew(100, half_wnd, track->minimum_correlation);
1010
 
                                                }
1011
 
                                                else if (track->tracker == TRACKER_SAD) {
1012
 
                                                        track_context.region_tracker= libmv_bruteRegionTrackerNew(MAX2(wndx, wndy), track->minimum_correlation);
1013
 
                                                }
1014
 
                                        }
1015
 
#endif
1016
 
 
1017
2187
                                        tracks_map_insert(context->tracks_map, track, &track_context);
1018
2188
                                }
1019
2189
                        }
1022
2192
                }
1023
2193
        }
1024
2194
 
1025
 
        context->clip = clip;
1026
 
 
1027
2195
        /* store needed clip flags passing to get_buffer functions
1028
2196
         * - MCLIP_USE_PROXY is needed to because timecode affects on movie clip
1029
2197
         *   only in case Proxy/Timecode flag is set, so store this flag to use
1031
2199
         *   would be used for images
1032
2200
         * - MCLIP_USE_PROXY_CUSTOM_DIR is needed because proxy/timecode files might
1033
2201
         *   be stored in a different location
1034
 
         * ignore all the rest possible flags for now */
1035
 
        context->clip_flag = clip->flag&MCLIP_TIMECODE_FLAGS;
 
2202
         * ignore all the rest possible flags for now
 
2203
         */
 
2204
        context->clip_flag = clip->flag & MCLIP_TIMECODE_FLAGS;
1036
2205
 
1037
2206
        context->user = *user;
1038
2207
        context->user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
1044
2213
        return context;
1045
2214
}
1046
2215
 
1047
 
static void track_context_free(void *customdata)
1048
 
{
1049
 
        TrackContext *track_context = (TrackContext *)customdata;
1050
 
 
1051
 
#if WITH_LIBMV
1052
 
        if (track_context->region_tracker)
1053
 
                libmv_regionTrackerDestroy(track_context->region_tracker);
1054
 
 
1055
 
        if (track_context->patch)
1056
 
                MEM_freeN(track_context->patch);
1057
 
 
1058
 
#else
1059
 
                (void) track_context;
1060
 
#endif
1061
 
}
1062
 
 
1063
2216
void BKE_tracking_context_free(MovieTrackingContext *context)
1064
2217
{
1065
2218
        if (!context->sequence)
1070
2223
        MEM_freeN(context);
1071
2224
}
1072
2225
 
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)
1077
 
{
1078
 
        int x, y;
1079
 
        float scale;
1080
 
 
1081
 
        if (!disable_red && !disable_green && !disable_blue && !grayscale)
1082
 
                return;
1083
 
 
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);
1089
 
 
1090
 
        for (y = 0; y < ibuf->y; y++) {
1091
 
                for (x = 0; x < ibuf->x; x++) {
1092
 
                        int pixel = ibuf->x*y + x;
1093
 
 
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];
1099
 
 
1100
 
                                if (grayscale) {
1101
 
                                        float gray = (0.2126f*r + 0.7152f*g + 0.0722f*b) / scale;
1102
 
 
1103
 
                                        rrgbf[0] = rrgbf[1] = rrgbf[2] = gray;
1104
 
                                }
1105
 
                                else {
1106
 
                                        rrgbf[0] = r;
1107
 
                                        rrgbf[1] = g;
1108
 
                                        rrgbf[2] = b;
1109
 
                                }
1110
 
                        }
1111
 
                        else {
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];
1116
 
 
1117
 
                                if (grayscale) {
1118
 
                                        float gray = (0.2126f*r + 0.7152f*g + 0.0722f*b) / scale;
1119
 
 
1120
 
                                        rrgb[0] = rrgb[1] = rrgb[2] = gray;
1121
 
                                }
1122
 
                                else {
1123
 
                                        rrgb[0] = r;
1124
 
                                        rrgb[1] = g;
1125
 
                                        rrgb[2] = b;
1126
 
                                }
1127
 
                        }
1128
 
                }
1129
 
        }
1130
 
 
1131
 
        if (ibuf->rect_float)
1132
 
                ibuf->userflags |= IB_RECT_INVALID;
1133
 
}
1134
 
 
1135
 
static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int grayscale)
1136
 
{
1137
 
        BKE_tracking_disable_imbuf_channels(ibuf, track->flag & TRACK_DISABLE_RED,
1138
 
                        track->flag & TRACK_DISABLE_GREEN, track->flag & TRACK_DISABLE_BLUE, grayscale);
1139
 
}
1140
 
 
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])
1143
 
{
1144
 
        ImBuf *tmpibuf;
1145
 
        int x, y;
1146
 
        int x1, y1, w, h;
1147
 
        float mpos[2];
1148
 
 
1149
 
        copy_v2_v2(mpos, marker->pos);
1150
 
        if (anchored)
1151
 
                add_v2_v2(mpos, track->offset);
1152
 
 
1153
 
        if (pos)
1154
 
                zero_v2(pos);
1155
 
 
1156
 
        x = mpos[0]*ibuf->x;
1157
 
        y = mpos[1]*ibuf->y;
1158
 
 
1159
 
        w = (max[0] - min[0]) * ibuf->x;
1160
 
        h = (max[1] - min[1]) * ibuf->y;
1161
 
 
1162
 
        /* dimensions should be odd */
1163
 
        w = w|1;
1164
 
        h = h|1;
1165
 
 
1166
 
        x1 = x-(int)(w * (-min[0] / (max[0] - min[0])));
1167
 
        y1 = y-(int)(h * (-min[1] / (max[1] - min[1])));
1168
 
 
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)
 
2227
{
 
2228
        MovieTracking *tracking = &context->clip->tracking;
 
2229
        int newframe;
 
2230
 
 
2231
        tracks_map_merge(context->tracks_map, tracking);
 
2232
 
 
2233
        if (context->backwards)
 
2234
                newframe = context->user.framenr + 1;
1171
2235
        else
1172
 
                tmpibuf = IMB_allocImBuf(w + margin * 2, h + margin * 2, 32, IB_rect);
1173
 
 
1174
 
        tmpibuf->profile = ibuf->profile;
1175
 
 
1176
 
        IMB_rectcpy(tmpibuf, ibuf, 0, 0, x1 - margin, y1 - margin, w + margin * 2, h + margin * 2);
1177
 
 
1178
 
        if (pos != NULL) {
1179
 
                pos[0] = mpos[0] * ibuf->x - x1 + margin;
1180
 
                pos[1] = mpos[1] * ibuf->y - y1 + margin;
1181
 
        }
1182
 
 
1183
 
        if (origin != NULL) {
1184
 
                origin[0] = x1 - margin;
1185
 
                origin[1] = y1 - margin;
1186
 
        }
1187
 
 
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))
1192
 
        {
1193
 
                disable_imbuf_channels(tmpibuf, track, TRUE /* grayscale */);
1194
 
        }
1195
 
 
1196
 
        return tmpibuf;
1197
 
}
1198
 
 
1199
 
ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
1200
 
                                      int margin, int anchored, float pos[2], int origin[2])
1201
 
{
1202
 
        return get_area_imbuf(ibuf, track, marker, track->pat_min, track->pat_max, margin, anchored, pos, origin);
1203
 
}
1204
 
 
1205
 
ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
1206
 
                                     int margin, int anchored, float pos[2], int origin[2])
1207
 
{
1208
 
        return get_area_imbuf(ibuf, track, marker, track->search_min, track->search_max, margin, anchored, pos, origin);
 
2236
                newframe = context->user.framenr - 1;
 
2237
 
 
2238
        context->sync_frame = newframe;
 
2239
 
 
2240
        BKE_tracking_dopesheet_tag_update(tracking);
 
2241
}
 
2242
 
 
2243
void BKE_tracking_context_sync_user(const MovieTrackingContext *context, MovieClipUser *user)
 
2244
{
 
2245
        user->framenr = context->sync_frame;
1209
2246
}
1210
2247
 
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])
1214
 
{
1215
 
        ImBuf *tmpibuf;
1216
 
        float *pixels, *fp;
1217
 
        int x, y, width, height;
1218
 
 
1219
 
        width = (track->search_max[0] - track->search_min[0]) * ibuf->x;
1220
 
        height = (track->search_max[1] - track->search_min[1]) * ibuf->y;
1221
 
 
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 **** */
 
2250
 
 
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)
 
2254
{
 
2255
        int i;
 
2256
 
 
2257
        for (i = 0; i < num_pixels; i++) {
 
2258
                const float *pixel = rgba + 4 * i;
 
2259
 
 
2260
                gray[i] = weight_red * pixel[0] + weight_green * pixel[1] + weight_blue * pixel[2];
 
2261
        }
 
2262
}
 
2263
 
 
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)
 
2266
{
 
2267
        int i;
 
2268
 
 
2269
        for (i = 0; i < num_pixels; i++) {
 
2270
                const unsigned char *pixel = rgba + i * 4;
 
2271
 
 
2272
                gray[i] = (weight_red * pixel[0] + weight_green * pixel[1] + weight_blue * pixel[2]) / 255.0f;
 
2273
        }
 
2274
}
 
2275
 
 
2276
static float *track_get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
 
2277
                                        int *width_r, int *height_r)
 
2278
{
 
2279
        ImBuf *searchibuf;
 
2280
        float *gray_pixels;
 
2281
        int width, height;
 
2282
 
 
2283
        searchibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, FALSE, TRUE);
 
2284
 
 
2285
        if (!searchibuf) {
 
2286
                *width_r = 0;
 
2287
                *height_r = 0;
 
2288
                return NULL;
 
2289
        }
 
2290
 
 
2291
        width = searchibuf->x;
 
2292
        height = searchibuf->y;
 
2293
 
 
2294
        gray_pixels = MEM_callocN(width * height * sizeof(float), "tracking floatBuf");
 
2295
 
 
2296
        if (searchibuf->rect_float) {
 
2297
                float_rgba_to_gray(searchibuf->rect_float, gray_pixels, width * height,
 
2298
                                   0.2126f, 0.7152f, 0.0722f);
 
2299
        }
 
2300
        else {
 
2301
                uint8_rgba_to_float_gray((unsigned char *)searchibuf->rect, gray_pixels, width * height,
 
2302
                                         0.2126f, 0.7152f, 0.0722f);
 
2303
        }
 
2304
 
 
2305
        IMB_freeImBuf(searchibuf);
1224
2306
 
1225
2307
        *width_r = width;
1226
2308
        *height_r = height;
1227
2309
 
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;
1232
 
 
1233
 
                        if (tmpibuf->rect_float) {
1234
 
                                float *rrgbf = tmpibuf->rect_float + pixel * 4;
1235
 
 
1236
 
                                *fp = 0.2126 * rrgbf[0] + 0.7152 * rrgbf[1] + 0.0722 * rrgbf[2];
1237
 
                        }
1238
 
                        else {
1239
 
                                unsigned char *rrgb = (unsigned char*)tmpibuf->rect + pixel * 4;
1240
 
 
1241
 
                                *fp = (0.2126 * rrgb[0] + 0.7152 * rrgb[1] + 0.0722 * rrgb[2]) / 255.0f;
1242
 
                        }
1243
 
 
1244
 
                        fp++;
1245
 
                }
1246
 
        }
1247
 
 
1248
 
        IMB_freeImBuf(tmpibuf);
1249
 
 
1250
 
        return pixels;
1251
 
}
1252
 
 
1253
 
static unsigned char *get_ucharbuf(ImBuf *ibuf)
1254
 
{
1255
 
        int x, y;
1256
 
        unsigned char *pixels, *cp;
1257
 
 
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;
1262
 
 
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];
1266
 
 
1267
 
                                *cp = FTOCHAR(grey_f);
1268
 
                        }
1269
 
                        else {
1270
 
                                const unsigned char *rrgb = (unsigned char*)ibuf->rect + pixel * 4;
1271
 
 
1272
 
                                *cp = 0.2126f * rrgb[0] + 0.7152f * rrgb[1] + 0.0722f * rrgb[2];
1273
 
                        }
1274
 
 
1275
 
                        cp++;
1276
 
                }
1277
 
        }
1278
 
 
1279
 
        return pixels;
1280
 
}
1281
 
 
1282
 
static ImBuf *get_frame_ibuf(MovieTrackingContext *context, int framenr)
 
2310
        return gray_pixels;
 
2311
}
 
2312
 
 
2313
static ImBuf *tracking_context_get_frame_ibuf(MovieTrackingContext *context, int framenr)
1283
2314
{
1284
2315
        ImBuf *ibuf;
1285
2316
        MovieClipUser user = context->user;
1286
2317
 
1287
 
        user.framenr = framenr;
 
2318
        user.framenr = BKE_movieclip_remap_clip_to_scene_frame(context->clip, framenr);
1288
2319
 
1289
2320
        ibuf = BKE_movieclip_get_ibuf_flag(context->clip, &user, context->clip_flag, MOVIECLIP_CACHE_SKIP);
1290
2321
 
1291
2322
        return ibuf;
1292
2323
}
1293
2324
 
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)
1296
2327
{
1297
 
        int framenr = marker->framenr;
1298
 
        int a = marker-track->markers;
1299
 
 
1300
 
        *marker_keyed = marker;
 
2328
        int a = marker - track->markers;
 
2329
        MovieTrackingMarker *marker_keyed = marker;
1301
2330
 
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;
1307
2336
 
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];
1310
2339
 
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)
1315
2344
                is_keyframed |= (cur_marker->flag & MARKER_TRACKED) == 0;
1316
2345
 
1317
2346
                if (is_keyframed) {
1318
 
                        framenr = cur_marker->framenr;
1319
 
                        *marker_keyed = cur_marker;
 
2347
                        marker_keyed = cur_marker;
1320
2348
 
1321
2349
                        break;
1322
2350
                }
1324
2352
                a = next;
1325
2353
        }
1326
2354
 
1327
 
        return get_frame_ibuf(context, framenr);
1328
 
}
1329
 
 
1330
 
static ImBuf *get_adjust_ibuf(MovieTrackingContext *context, MovieTrackingTrack *track, MovieTrackingMarker *marker,
1331
 
                              int curfra, MovieTrackingMarker **marker_keyed)
 
2355
        return marker_keyed;
 
2356
}
 
2357
 
 
2358
static ImBuf *tracking_context_get_keyframed_ibuf(MovieTrackingContext *context, MovieTrackingTrack *track,
 
2359
                                                  MovieTrackingMarker *marker, MovieTrackingMarker **marker_keyed_r)
 
2360
{
 
2361
        MovieTrackingMarker *marker_keyed;
 
2362
        int keyed_framenr;
 
2363
 
 
2364
        marker_keyed = tracking_context_get_keyframed_marker(context, track, marker);
 
2365
        keyed_framenr = marker_keyed->framenr;
 
2366
 
 
2367
        *marker_keyed_r = marker_keyed;
 
2368
 
 
2369
        return tracking_context_get_frame_ibuf(context, keyed_framenr);
 
2370
}
 
2371
 
 
2372
static ImBuf *tracking_context_get_reference_ibuf(MovieTrackingContext *context, MovieTrackingTrack *track,
 
2373
                                                  MovieTrackingMarker *marker, int curfra,
 
2374
                                                  MovieTrackingMarker **marker_keyed)
1332
2375
{
1333
2376
        ImBuf *ibuf = NULL;
1334
2377
 
1335
2378
        if (track->pattern_match == TRACK_MATCH_KEYFRAME) {
1336
 
                ibuf = get_keyframed_ibuf(context, track, marker, marker_keyed);
 
2379
                ibuf = tracking_context_get_keyframed_ibuf(context, track, marker, marker_keyed);
1337
2380
        }
1338
2381
        else {
1339
 
                ibuf = get_frame_ibuf(context, curfra);
 
2382
                ibuf = tracking_context_get_frame_ibuf(context, curfra);
1340
2383
 
1341
2384
                /* use current marker as keyframed position */
1342
2385
                *marker_keyed = marker;
1345
2388
        return ibuf;
1346
2389
}
1347
2390
 
 
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)
 
2394
{
 
2395
        MovieTrackingMarker *marker_keyed = NULL;
 
2396
        ImBuf *reference_ibuf = NULL;
 
2397
        int width, height;
 
2398
 
 
2399
        /* calculate patch for keyframed position */
 
2400
        reference_ibuf = tracking_context_get_reference_ibuf(context, track, marker, curfra, &marker_keyed);
 
2401
 
 
2402
        if (!reference_ibuf)
 
2403
                return FALSE;
 
2404
 
 
2405
        track_context->marker = *marker_keyed;
 
2406
 
 
2407
        if (track_context->search_area) {
 
2408
                MEM_freeN(track_context->search_area);
 
2409
        }
 
2410
 
 
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;
 
2414
 
 
2415
        if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0) {
 
2416
                if (track_context->mask)
 
2417
                        MEM_freeN(track_context->mask);
 
2418
 
 
2419
                track_context->mask = BKE_tracking_track_get_mask(frame_width, frame_height, track, marker);
 
2420
        }
 
2421
 
 
2422
        IMB_freeImBuf(reference_ibuf);
 
2423
 
 
2424
        return TRUE;
 
2425
}
 
2426
 
 
2427
static void tracking_configure_tracker(TrackContext *track_context, MovieTrackingTrack *track,
 
2428
                                       struct libmv_trackRegionOptions *options)
 
2429
{
 
2430
        options->motion_model = track->motion_model;
 
2431
 
 
2432
        options->use_brute = ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_BRUTE) != 0);
 
2433
 
 
2434
        options->use_normalization = ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_NORMALIZATION) != 0);
 
2435
 
 
2436
        options->num_iterations = 50;
 
2437
        options->minimum_correlation = track->minimum_correlation;
 
2438
        options->sigma = 0.9;
 
2439
 
 
2440
        if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0)
 
2441
                options->image1_mask = track_context->mask;
 
2442
}
 
2443
 
 
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)
 
2447
{
 
2448
        float pat_min[2], pat_max[2], dim[2], margin[2];
 
2449
 
 
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;
 
2454
 
 
2455
        margin[0] = max_ff(margin[0], (float)track->margin / frame_width);
 
2456
        margin[1] = max_ff(margin[1], (float)track->margin / frame_height);
 
2457
 
 
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])
 
2461
        {
 
2462
                return FALSE;
 
2463
        }
 
2464
 
 
2465
        return TRUE;
 
2466
}
 
2467
 
 
2468
static void tracking_scale_marker_search(const MovieTrackingMarker *old_marker, MovieTrackingMarker *new_marker)
 
2469
{
 
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;
 
2473
 
 
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);
 
2476
 
 
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]);
 
2479
 
 
2480
        new_marker->search_min[0] *= scale_x;
 
2481
        new_marker->search_min[1] *= scale_y;
 
2482
 
 
2483
        new_marker->search_max[0] *= scale_x;
 
2484
        new_marker->search_max[1] *= scale_y;
 
2485
}
 
2486
 
 
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])
 
2491
{
 
2492
        MovieTrackingMarker new_marker;
 
2493
        int frame_delta = context->backwards ? -1 : 1;
 
2494
        int nextfra = curfra + frame_delta;
 
2495
 
 
2496
        new_marker = *old_marker;
 
2497
 
 
2498
        if (tracked) {
 
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;
 
2502
 
 
2503
                tracking_scale_marker_search(old_marker, &new_marker);
 
2504
 
 
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"
 
2508
                         */
 
2509
 
 
2510
                        tracking_marker_insert_disabled(track, old_marker, !context->backwards, FALSE);
 
2511
                }
 
2512
 
 
2513
                /* insert currently tracked marker */
 
2514
                BKE_tracking_marker_insert(track, &new_marker);
 
2515
 
 
2516
                /* make currently tracked segment be finished with disabled marker */
 
2517
                tracking_marker_insert_disabled(track, &new_marker, context->backwards, FALSE);
 
2518
        }
 
2519
        else {
 
2520
                new_marker.framenr = nextfra;
 
2521
                new_marker.flag |= MARKER_DISABLED;
 
2522
 
 
2523
                BKE_tracking_marker_insert(track, &new_marker);
 
2524
        }
 
2525
}
 
2526
 
1348
2527
#endif
1349
2528
 
1350
 
void BKE_tracking_sync(MovieTrackingContext *context)
1351
 
{
1352
 
        MovieTracking *tracking = &context->clip->tracking;
1353
 
        int newframe;
1354
 
 
1355
 
        tracks_map_merge(context->tracks_map, tracking);
1356
 
 
1357
 
        if (context->backwards)
1358
 
                newframe = context->user.framenr + 1;
1359
 
        else
1360
 
                newframe = context->user.framenr - 1;
1361
 
 
1362
 
        context->sync_frame = newframe;
1363
 
}
1364
 
 
1365
 
void BKE_tracking_sync_user(MovieClipUser *user, MovieTrackingContext *context)
1366
 
{
1367
 
        user->framenr = context->sync_frame;
1368
 
}
1369
 
 
1370
 
int BKE_tracking_next(MovieTrackingContext *context)
1371
 
{
1372
 
        ImBuf *ibuf_new;
1373
 
        int curfra = context->user.framenr;
 
2529
int BKE_tracking_context_step(MovieTrackingContext *context)
 
2530
{
 
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;
1375
2536
 
1376
 
        map_size = tracks_map_size(context->tracks_map);
 
2537
        int frame_width, frame_height;
 
2538
 
 
2539
        map_size = tracks_map_get_size(context->tracks_map);
1377
2540
 
1378
2541
        /* nothing to track, avoid unneeded frames reading to save time and memory */
1379
2542
        if (!map_size)
1380
2543
                return FALSE;
1381
2544
 
1382
 
        if (context->backwards)
1383
 
                context->user.framenr--;
1384
 
        else
1385
 
                context->user.framenr++;
 
2545
        context->user.framenr += frame_delta;
1386
2546
 
1387
 
        ibuf_new = BKE_movieclip_get_ibuf_flag(context->clip, &context->user, context->clip_flag, MOVIECLIP_CACHE_SKIP);
1388
 
        if (!ibuf_new)
 
2547
        destination_ibuf = BKE_movieclip_get_ibuf_flag(context->clip, &context->user,
 
2548
                                                       context->clip_flag, MOVIECLIP_CACHE_SKIP);
 
2549
        if (!destination_ibuf)
1389
2550
                return FALSE;
1390
2551
 
1391
 
        #pragma omp parallel for private(a) shared(ibuf_new, ok) if (map_size>1)
 
2552
        /* nextfra = curfra + frame_delta; */ /* UNUSED */
 
2553
 
 
2554
        frame_width = destination_ibuf->x;
 
2555
        frame_height = destination_ibuf->y;
 
2556
 
 
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;
1396
2562
 
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);
1398
2564
 
1399
 
                marker = BKE_tracking_exact_marker(track, curfra);
 
2565
                marker = BKE_tracking_marker_get_exact(track, curfra);
1400
2566
 
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;
1406
 
                        ImBuf *ibuf = NULL;
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];
1409
2571
 
1410
2572
                        if (track->pattern_match == TRACK_MATCH_KEYFRAME)
1411
2573
                                need_readjust = context->first_time;
1412
2574
                        else
1413
2575
                                need_readjust = TRUE;
1414
2576
 
1415
 
                        if (context->backwards)
1416
 
                                nextfra = curfra - 1;
1417
 
                        else
1418
 
                                nextfra = curfra + 1;
1419
 
 
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;
1423
 
 
1424
 
                        margin[0] = MAX2(margin[0], (float)track->margin / ibuf_new->x);
1425
 
                        margin[1] = MAX2(margin[1], (float)track->margin / ibuf_new->y);
1426
 
 
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])
1430
 
                        {
1431
 
                                onbound = TRUE;
1432
 
                        }
1433
 
                        else {
 
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];
 
2581
 
 
2582
                                /* settings for the tracker */
 
2583
                                struct libmv_trackRegionOptions options = {0};
 
2584
                                struct libmv_trackRegionResult result;
 
2585
 
1434
2586
                                float *patch_new;
1435
2587
 
1436
2588
                                if (need_readjust) {
1437
 
                                        /* calculate patch for keyframed position */
1438
 
                                        ibuf = get_adjust_ibuf(context, track, marker, curfra, &marker_keyed);
1439
 
 
1440
 
                                        if (track_context->patch)
1441
 
                                                MEM_freeN(track_context->patch);
1442
 
 
1443
 
                                        track_context->patch = get_search_floatbuf(ibuf, track, marker_keyed, &width, &height,
1444
 
                                                                                   track_context->keyframed_pos, origin);
1445
 
 
1446
 
                                        IMB_freeImBuf(ibuf);
 
2589
                                        if (track_context_update_reference(context, track_context, track, marker,
 
2590
                                                                           curfra, frame_width, frame_height) == FALSE)
 
2591
                                        {
 
2592
                                                /* happens when reference frame fails to be loaded */
 
2593
                                                continue;
 
2594
                                        }
1447
2595
                                }
1448
2596
 
1449
 
                                patch_new = get_search_floatbuf(ibuf_new, track, marker, &width, &height, pos, origin);
1450
 
 
1451
 
                                x1 = track_context->keyframed_pos[0];
1452
 
                                y1 = track_context->keyframed_pos[1];
1453
 
 
1454
 
                                x2 = pos[0];
1455
 
                                y2 = pos[1];
1456
 
 
1457
 
                                tracked = libmv_regionTrackerTrack(track_context->region_tracker, track_context->patch, patch_new,
1458
 
                                                        width, height, x1, y1, &x2, &y2);
1459
 
 
 
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
 
2600
                                 */
 
2601
                                patch_new = track_get_search_floatbuf(destination_ibuf, track, marker, &width, &height);
 
2602
 
 
2603
                                /* configure the tracker */
 
2604
                                tracking_configure_tracker(track_context, track, &options);
 
2605
 
 
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);
 
2609
 
 
2610
                                if (!patch_new || !track_context->search_area)
 
2611
                                        continue;
 
2612
 
 
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,
 
2620
                                                            &result,
 
2621
                                                            dst_pixel_x, dst_pixel_y);
1460
2622
                                MEM_freeN(patch_new);
1461
2623
                        }
1462
2624
 
1463
 
                        if (tracked && !onbound && finite(x2) && finite(y2)) {
1464
 
                                if (context->first_time) {
1465
 
                                        #pragma omp critical
1466
 
                                        {
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);
1470
 
                                        }
1471
 
                                }
1472
 
 
1473
 
                                memset(&marker_new, 0, sizeof(marker_new));
1474
 
 
1475
 
                                if (!onbound) {
1476
 
                                        marker_new.pos[0] = (origin[0] + x2) / ibuf_new->x;
1477
 
                                        marker_new.pos[1] = (origin[1] + y2) / ibuf_new->y;
1478
 
                                }
1479
 
                                else {
1480
 
                                        copy_v2_v2(marker_new.pos, marker->pos);
1481
 
                                }
1482
 
 
1483
 
                                marker_new.flag |= MARKER_TRACKED;
1484
 
                                marker_new.framenr= nextfra;
1485
 
 
1486
 
                                #pragma omp critical
1487
 
                                {
1488
 
                                        BKE_tracking_insert_marker(track, &marker_new);
1489
 
                                }
1490
 
 
1491
 
                                /* make currently tracked segment be finished with disabled marker */
1492
 
                                #pragma omp critical
1493
 
                                {
1494
 
                                        put_disabled_marker(track, &marker_new, context->backwards, 0);
1495
 
                                }
1496
 
                        }
1497
 
                        else {
1498
 
                                marker_new = *marker;
1499
 
 
1500
 
                                marker_new.framenr = nextfra;
1501
 
                                marker_new.flag |= MARKER_DISABLED;
1502
 
 
1503
 
                                #pragma omp critical
1504
 
                                {
1505
 
                                        BKE_tracking_insert_marker(track, &marker_new);
1506
 
                                }
 
2625
                        #pragma omp critical
 
2626
                        {
 
2627
                                tracking_insert_new_marker(context, track, marker, curfra, tracked,
 
2628
                                                           frame_width, frame_height, dst_pixel_x, dst_pixel_y);
1507
2629
                        }
1508
2630
 
1509
2631
                        ok = TRUE;
 
2632
#else
 
2633
                        (void)frame_height;
 
2634
                        (void)frame_width;
1510
2635
#endif
1511
2636
                }
1512
2637
        }
1513
2638
 
1514
 
        IMB_freeImBuf(ibuf_new);
 
2639
        IMB_freeImBuf(destination_ibuf);
1515
2640
 
1516
2641
        context->first_time = FALSE;
1517
2642
        context->frames++;
1519
2644
        return ok;
1520
2645
}
1521
2646
 
1522
 
/*********************** camera solving *************************/
 
2647
/*********************** Camera solving *************************/
1523
2648
 
1524
2649
typedef struct MovieReconstructContext {
1525
2650
#ifdef WITH_LIBMV
1531
2656
#endif
1532
2657
        char object_name[MAX_NAME];
1533
2658
        int is_camera;
 
2659
        short motion_flag;
1534
2660
 
1535
2661
        float focal_length;
1536
2662
        float principal_point[2];
1540
2666
 
1541
2667
        TracksMap *tracks_map;
1542
2668
 
 
2669
        float success_threshold;
 
2670
        int use_fallback_reconstruction;
 
2671
 
1543
2672
        int sfra, efra;
1544
2673
} MovieReconstructContext;
1545
2674
 
1551
2680
        int message_size;
1552
2681
} ReconstructProgressData;
1553
2682
 
1554
 
#if WITH_LIBMV
1555
 
static struct libmv_Tracks *create_libmv_tracks(ListBase *tracksbase, int width, int height)
 
2683
#ifdef WITH_LIBMV
 
2684
static struct libmv_Tracks *libmv_tracks_new(ListBase *tracksbase, int width, int height)
1556
2685
{
1557
2686
        int tracknr = 0;
1558
2687
        MovieTrackingTrack *track;
1567
2696
 
1568
2697
                        if ((marker->flag & MARKER_DISABLED) == 0) {
1569
2698
                                libmv_tracksInsert(tracks, marker->framenr, tracknr,
1570
 
                                                        marker->pos[0] * width, marker->pos[1] * height);
 
2699
                                                   (marker->pos[0] + track->offset[0]) * width,
 
2700
                                                   (marker->pos[1] + track->offset[1]) * height);
1571
2701
                        }
1572
2702
                }
1573
2703
 
1578
2708
        return tracks;
1579
2709
}
1580
2710
 
1581
 
static void retrieve_libmv_reconstruct_intrinscis(MovieReconstructContext *context, MovieTracking *tracking)
 
2711
static void reconstruct_retrieve_libmv_intrinscis(MovieReconstructContext *context, MovieTracking *tracking)
1582
2712
{
1583
2713
        struct libmv_Reconstruction *libmv_reconstruction = context->reconstruction;
1584
2714
        struct libmv_CameraIntrinsics *libmv_intrinsics = libmv_ReconstructionExtractIntrinsics(libmv_reconstruction);
1599
2729
        tracking->camera.k2 = k2;
1600
2730
}
1601
2731
 
1602
 
static int retrieve_libmv_reconstruct_tracks(MovieReconstructContext *context, MovieTracking *tracking)
 
2732
static int reconstruct_retrieve_libmv_tracks(MovieReconstructContext *context, MovieTracking *tracking)
1603
2733
{
1604
2734
        struct libmv_Reconstruction *libmv_reconstruction = context->reconstruction;
1605
2735
        MovieTrackingReconstruction *reconstruction = NULL;
1615
2745
                reconstruction = &tracking->reconstruction;
1616
2746
        }
1617
2747
        else {
1618
 
                MovieTrackingObject *object = BKE_tracking_named_object(tracking, context->object_name);
 
2748
                MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, context->object_name);
1619
2749
 
1620
2750
                tracksbase = &object->tracks;
1621
2751
                reconstruction = &object->reconstruction;
1651
2781
 
1652
2782
        reconstruction->camnr = 0;
1653
2783
        reconstruction->cameras = NULL;
1654
 
        reconstructed = MEM_callocN((efra-sfra+1)*sizeof(MovieReconstructedCamera), "temp reconstructed camera");
 
2784
        reconstructed = MEM_callocN((efra - sfra + 1) * sizeof(MovieReconstructedCamera),
 
2785
                                    "temp reconstructed camera");
1655
2786
 
1656
2787
        for (a = sfra; a <= efra; a++) {
1657
2788
                double matd[4][4];
1686
2817
        }
1687
2818
 
1688
2819
        if (reconstruction->camnr) {
1689
 
                reconstruction->cameras = MEM_callocN(reconstruction->camnr * sizeof(MovieReconstructedCamera), "reconstructed camera");
1690
 
                memcpy(reconstruction->cameras, reconstructed, reconstruction->camnr * sizeof(MovieReconstructedCamera));
 
2820
                int size = reconstruction->camnr * sizeof(MovieReconstructedCamera);
 
2821
                reconstruction->cameras = MEM_callocN(size, "reconstructed camera");
 
2822
                memcpy(reconstruction->cameras, reconstructed, size);
1691
2823
        }
1692
2824
 
1693
2825
        if (origin_set) {
1705
2837
        return ok;
1706
2838
}
1707
2839
 
1708
 
static int retrieve_libmv_reconstruct(MovieReconstructContext *context, MovieTracking *tracking)
 
2840
static int reconstruct_retrieve_libmv(MovieReconstructContext *context, MovieTracking *tracking)
1709
2841
{
1710
2842
        /* take the intrinscis back from libmv */
1711
 
        retrieve_libmv_reconstruct_intrinscis(context, tracking);
 
2843
        reconstruct_retrieve_libmv_intrinscis(context, tracking);
1712
2844
 
1713
 
        return retrieve_libmv_reconstruct_tracks(context, tracking);
 
2845
        return reconstruct_retrieve_libmv_tracks(context, tracking);
1714
2846
}
1715
2847
 
1716
 
static int get_refine_intrinsics_flags(MovieTracking *tracking, MovieTrackingObject *object)
 
2848
static int reconstruct_refine_intrinsics_get_flags(MovieTracking *tracking, MovieTrackingObject *object)
1717
2849
{
1718
2850
        int refine = tracking->settings.refine_camera_intrinsics;
1719
2851
        int flags = 0;
1736
2868
        return flags;
1737
2869
}
1738
2870
 
1739
 
static int count_tracks_on_both_keyframes(MovieTracking *tracking, ListBase *tracksbase)
 
2871
static int reconstruct_count_tracks_on_both_keyframes(MovieTracking *tracking, MovieTrackingObject *object)
1740
2872
{
 
2873
        ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
1741
2874
        int tot = 0;
1742
 
        int frame1 = tracking->settings.keyframe1, frame2= tracking->settings.keyframe2;
 
2875
        int frame1 = object->keyframe1, frame2 = object->keyframe2;
1743
2876
        MovieTrackingTrack *track;
1744
2877
 
1745
2878
        track = tracksbase->first;
1746
2879
        while (track) {
1747
 
                if (BKE_tracking_has_enabled_marker(track, frame1))
1748
 
                        if (BKE_tracking_has_enabled_marker(track, frame2))
 
2880
                if (BKE_tracking_track_has_enabled_marker_at_frame(track, frame1)) {
 
2881
                        if (BKE_tracking_track_has_enabled_marker_at_frame(track, frame2)) {
1749
2882
                                tot++;
 
2883
                        }
 
2884
                }
1750
2885
 
1751
2886
                track = track->next;
1752
2887
        }
1755
2890
}
1756
2891
#endif
1757
2892
 
1758
 
int BKE_tracking_can_reconstruct(MovieTracking *tracking, MovieTrackingObject *object, char *error_msg, int error_size)
 
2893
int BKE_tracking_reconstruction_check(MovieTracking *tracking, MovieTrackingObject *object, char *error_msg, int error_size)
1759
2894
{
1760
 
#if WITH_LIBMV
1761
 
        ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object);
1762
 
 
1763
 
        if (count_tracks_on_both_keyframes(tracking, tracksbase)<8) {
1764
 
                BLI_strncpy(error_msg, "At least 8 common tracks on both of keyframes are needed for reconstruction", error_size);
 
2895
#ifdef WITH_LIBMV
 
2896
        if (tracking->settings.motion_flag & TRACKING_MOTION_MODAL) {
 
2897
                /* TODO: check for number of tracks? */
 
2898
                return TRUE;
 
2899
        }
 
2900
        else if (reconstruct_count_tracks_on_both_keyframes(tracking, object) < 8) {
 
2901
                BLI_strncpy(error_msg, N_("At least 8 common tracks on both of keyframes are needed for reconstruction"),
 
2902
                            error_size);
1765
2903
 
1766
2904
                return FALSE;
1767
2905
        }
1768
2906
 
1769
2907
        return TRUE;
1770
2908
#else
1771
 
        BLI_strncpy(error_msg, "Blender is compiled without motion tracking library", error_size);
 
2909
        BLI_strncpy(error_msg, N_("Blender is compiled without motion tracking library"), error_size);
1772
2910
 
1773
2911
        (void) tracking;
1774
2912
        (void) object;
1777
2915
#endif
1778
2916
}
1779
2917
 
1780
 
MovieReconstructContext* BKE_tracking_reconstruction_context_new(MovieTracking *tracking, MovieTrackingObject *object,
 
2918
MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieTracking *tracking, MovieTrackingObject *object,
1781
2919
                                                                 int keyframe1, int keyframe2, int width, int height)
1782
2920
{
1783
2921
        MovieReconstructContext *context = MEM_callocN(sizeof(MovieReconstructContext), "MovieReconstructContext data");
1784
2922
        MovieTrackingCamera *camera = &tracking->camera;
1785
 
        ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object);
 
2923
        ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
1786
2924
        float aspy = 1.0f / tracking->camera.pixel_aspect;
1787
2925
        int num_tracks = BLI_countlist(tracksbase);
1788
2926
        int sfra = INT_MAX, efra = INT_MIN;
1789
2927
        MovieTrackingTrack *track;
1790
2928
 
1791
2929
        BLI_strncpy(context->object_name, object->name, sizeof(context->object_name));
1792
 
        context->is_camera = object->flag&TRACKING_OBJECT_CAMERA;
 
2930
        context->is_camera = object->flag & TRACKING_OBJECT_CAMERA;
 
2931
        context->motion_flag = tracking->settings.motion_flag;
 
2932
 
 
2933
        context->focal_length = camera->focal;
 
2934
        context->principal_point[0] = camera->principal[0];
 
2935
        context->principal_point[1] = camera->principal[1] * aspy;
 
2936
 
 
2937
        context->k1 = camera->k1;
 
2938
        context->k2 = camera->k2;
 
2939
        context->k3 = camera->k3;
 
2940
 
 
2941
        context->success_threshold = tracking->settings.reconstruction_success_threshold;
 
2942
        context->use_fallback_reconstruction = tracking->settings.reconstruction_flag & TRACKING_USE_FALLBACK_RECONSTRUCTION;
1793
2943
 
1794
2944
        context->tracks_map = tracks_map_new(context->object_name, context->is_camera, num_tracks, 0);
1795
2945
 
1796
2946
        track = tracksbase->first;
1797
2947
        while (track) {
1798
 
                int first = 0, last = track->markersnr-1;
 
2948
                int first = 0, last = track->markersnr - 1;
1799
2949
                MovieTrackingMarker *first_marker = &track->markers[0];
1800
2950
                MovieTrackingMarker *last_marker = &track->markers[track->markersnr - 1];
1801
2951
 
1811
2961
                        last_marker--;
1812
2962
                }
1813
2963
 
1814
 
                if (first<track->markersnr - 1)
1815
 
                        sfra = MIN2(sfra, first_marker->framenr);
 
2964
                if (first < track->markersnr - 1)
 
2965
                        sfra = min_ii(sfra, first_marker->framenr);
1816
2966
 
1817
2967
                if (last >= 0)
1818
 
                        efra = MAX2(efra, last_marker->framenr);
 
2968
                        efra = max_ii(efra, last_marker->framenr);
1819
2969
 
1820
2970
                tracks_map_insert(context->tracks_map, track, NULL);
1821
2971
 
1826
2976
        context->efra = efra;
1827
2977
 
1828
2978
#ifdef WITH_LIBMV
1829
 
        context->tracks = create_libmv_tracks(tracksbase, width, height*aspy);
 
2979
        context->tracks = libmv_tracks_new(tracksbase, width, height * aspy);
1830
2980
        context->keyframe1 = keyframe1;
1831
2981
        context->keyframe2 = keyframe2;
1832
 
        context->refine_flags = get_refine_intrinsics_flags(tracking, object);
 
2982
        context->refine_flags = reconstruct_refine_intrinsics_get_flags(tracking, object);
1833
2983
#else
1834
2984
        (void) width;
1835
2985
        (void) height;
1837
2987
        (void) keyframe2;
1838
2988
#endif
1839
2989
 
1840
 
        context->focal_length = camera->focal;
1841
 
        context->principal_point[0] = camera->principal[0];
1842
 
        context->principal_point[1] = camera->principal[1] * aspy;
1843
 
 
1844
 
        context->k1 = camera->k1;
1845
 
        context->k2 = camera->k2;
1846
 
        context->k3 = camera->k3;
1847
 
 
1848
2990
        return context;
1849
2991
}
1850
2992
 
1852
2994
{
1853
2995
#ifdef WITH_LIBMV
1854
2996
        if (context->reconstruction)
1855
 
                        libmv_destroyReconstruction(context->reconstruction);
 
2997
                libmv_destroyReconstruction(context->reconstruction);
1856
2998
 
1857
2999
        libmv_tracksDestroy(context->tracks);
1858
3000
#endif
1863
3005
}
1864
3006
 
1865
3007
#ifdef WITH_LIBMV
1866
 
static void solve_reconstruction_update_cb(void *customdata, double progress, const char *message)
 
3008
static void reconstruct_update_solve_cb(void *customdata, double progress, const char *message)
1867
3009
{
1868
 
        ReconstructProgressData *progressdata= customdata;
 
3010
        ReconstructProgressData *progressdata = customdata;
1869
3011
 
1870
3012
        if (progressdata->progress) {
1871
3013
                *progressdata->progress = progress;
1876
3018
}
1877
3019
#endif
1878
3020
 
1879
 
#if 0
1880
 
static int solve_reconstruction_testbreak_cb(void *customdata)
1881
 
{
1882
 
        ReconstructProgressData *progressdata = customdata;
1883
 
 
1884
 
        if (progressdata->stop && *progressdata->stop)
1885
 
                return TRUE;
1886
 
 
1887
 
        return G.afbreek;
1888
 
}
1889
 
#endif
1890
 
 
1891
 
void BKE_tracking_solve_reconstruction(MovieReconstructContext *context, short *stop, short *do_update,
 
3021
void BKE_tracking_reconstruction_solve(MovieReconstructContext *context, short *stop, short *do_update,
1892
3022
                                       float *progress, char *stats_message, int message_size)
1893
3023
{
1894
3024
#ifdef WITH_LIBMV
1902
3032
        progressdata.stats_message = stats_message;
1903
3033
        progressdata.message_size = message_size;
1904
3034
 
1905
 
        context->reconstruction = libmv_solveReconstruction(context->tracks,
1906
 
                context->keyframe1, context->keyframe2,
1907
 
                context->refine_flags,
1908
 
                context->focal_length,
1909
 
                context->principal_point[0], context->principal_point[1],
1910
 
                context->k1, context->k2, context->k3,
1911
 
                solve_reconstruction_update_cb, &progressdata);
 
3035
        if (context->motion_flag & TRACKING_MOTION_MODAL) {
 
3036
                context->reconstruction = libmv_solveModal(context->tracks,
 
3037
                                                           context->focal_length,
 
3038
                                                           context->principal_point[0], context->principal_point[1],
 
3039
                                                           context->k1, context->k2, context->k3,
 
3040
                                                           reconstruct_update_solve_cb, &progressdata);
 
3041
        }
 
3042
        else {
 
3043
                struct libmv_reconstructionOptions options;
 
3044
 
 
3045
                options.success_threshold = context->success_threshold;
 
3046
                options.use_fallback_reconstruction = context->use_fallback_reconstruction;
 
3047
 
 
3048
                context->reconstruction = libmv_solveReconstruction(context->tracks,
 
3049
                                                                    context->keyframe1, context->keyframe2,
 
3050
                                                                    context->refine_flags,
 
3051
                                                                    context->focal_length,
 
3052
                                                                    context->principal_point[0], context->principal_point[1],
 
3053
                                                                    context->k1, context->k2, context->k3,
 
3054
                                                                    &options,
 
3055
                                                                    reconstruct_update_solve_cb, &progressdata);
 
3056
        }
1912
3057
 
1913
3058
        error = libmv_reprojectionError(context->reconstruction);
1914
3059
 
1923
3068
#endif
1924
3069
}
1925
3070
 
1926
 
int BKE_tracking_finish_reconstruction(MovieReconstructContext *context, MovieTracking *tracking)
 
3071
int BKE_tracking_reconstruction_finish(MovieReconstructContext *context, MovieTracking *tracking)
1927
3072
{
1928
3073
        MovieTrackingReconstruction *reconstruction;
1929
3074
 
1930
3075
        tracks_map_merge(context->tracks_map, tracking);
 
3076
        BKE_tracking_dopesheet_tag_update(tracking);
1931
3077
 
1932
3078
        if (context->is_camera) {
1933
3079
                reconstruction = &tracking->reconstruction;
1935
3081
        else {
1936
3082
                MovieTrackingObject *object;
1937
3083
 
1938
 
                object = BKE_tracking_named_object(tracking, context->object_name);
 
3084
                object = BKE_tracking_object_get_named(tracking, context->object_name);
1939
3085
                reconstruction = &object->reconstruction;
1940
3086
        }
1941
3087
 
1943
3089
        reconstruction->flag |= TRACKING_RECONSTRUCTED;
1944
3090
 
1945
3091
#ifdef WITH_LIBMV
1946
 
        if (!retrieve_libmv_reconstruct(context, tracking))
 
3092
        if (!reconstruct_retrieve_libmv(context, tracking))
1947
3093
                return FALSE;
1948
3094
#endif
1949
3095
 
1950
3096
        return TRUE;
1951
3097
}
1952
3098
 
1953
 
void BKE_track_unique_name(ListBase *tracksbase, MovieTrackingTrack *track)
1954
 
{
1955
 
        BLI_uniquename(tracksbase, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name));
1956
 
}
1957
 
 
1958
 
MovieTrackingTrack *BKE_tracking_named_track(MovieTracking *tracking, MovieTrackingObject *object, const char *name)
1959
 
{
1960
 
        ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object);
1961
 
        MovieTrackingTrack *track = tracksbase->first;
1962
 
 
1963
 
        while (track) {
1964
 
                if (!strcmp(track->name, name))
1965
 
                        return track;
1966
 
 
1967
 
                track = track->next;
1968
 
        }
1969
 
 
1970
 
        return NULL;
1971
 
}
1972
 
 
1973
 
static int reconstruction_camera_index(MovieTrackingReconstruction *reconstruction, int framenr, int nearest)
1974
 
{
1975
 
        MovieReconstructedCamera *cameras= reconstruction->cameras;
1976
 
        int a = 0, d = 1;
1977
 
 
1978
 
        if (!reconstruction->camnr)
1979
 
                return -1;
1980
 
 
1981
 
        if (framenr<cameras[0].framenr) {
1982
 
                if (nearest)
1983
 
                        return 0;
1984
 
                else
1985
 
                        return -1;
1986
 
        }
1987
 
 
1988
 
        if (framenr>cameras[reconstruction->camnr - 1].framenr) {
1989
 
                if (nearest)
1990
 
                        return reconstruction->camnr - 1;
1991
 
                else
1992
 
                        return -1;
1993
 
        }
1994
 
 
1995
 
        if (reconstruction->last_camera<reconstruction->camnr)
1996
 
                a = reconstruction->last_camera;
1997
 
 
1998
 
        if (cameras[a].framenr >= framenr)
1999
 
                d = -1;
2000
 
 
2001
 
        while (a >= 0 && a < reconstruction->camnr) {
2002
 
                int cfra = cameras[a].framenr;
2003
 
 
2004
 
                /* check if needed framenr was "skipped" -- no data for requested frame */
2005
 
 
2006
 
                if (d > 0 && cfra > framenr) {
2007
 
                        /* interpolate with previous position */
2008
 
                        if (nearest)
2009
 
                                return a - 1;
2010
 
                        else
2011
 
                                break;
2012
 
                }
2013
 
 
2014
 
                if (d < 0 && cfra < framenr) {
2015
 
                        /* interpolate with next position */
2016
 
                        if (nearest)
2017
 
                                return a;
2018
 
                        else
2019
 
                                break;
2020
 
                }
2021
 
 
2022
 
                if (cfra == framenr) {
2023
 
                        reconstruction->last_camera = a;
2024
 
 
2025
 
                        return a;
2026
 
                }
2027
 
 
2028
 
                a += d;
2029
 
        }
2030
 
 
2031
 
        return -1;
2032
 
}
2033
 
 
2034
 
static void scale_reconstructed_camera(MovieTrackingObject *object, float mat[4][4])
2035
 
{
2036
 
        if ((object->flag & TRACKING_OBJECT_CAMERA) == 0) {
2037
 
                float smat[4][4];
2038
 
 
2039
 
                scale_m4_fl(smat, 1.0f / object->scale);
2040
 
                mult_m4_m4m4(mat, mat, smat);
2041
 
        }
2042
 
}
2043
 
 
2044
 
MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(MovieTracking *tracking,
2045
 
                                                                MovieTrackingObject *object, int framenr)
2046
 
{
2047
 
        MovieTrackingReconstruction *reconstruction;
2048
 
        int a;
2049
 
 
2050
 
        reconstruction = BKE_tracking_object_reconstruction(tracking, object);
2051
 
        a = reconstruction_camera_index(reconstruction, framenr, FALSE);
2052
 
 
2053
 
        if (a ==-1)
2054
 
                return NULL;
2055
 
 
2056
 
        return &reconstruction->cameras[a];
2057
 
}
2058
 
 
2059
 
void BKE_tracking_get_interpolated_camera(MovieTracking *tracking, MovieTrackingObject *object,
2060
 
                                          int framenr, float mat[4][4])
2061
 
{
2062
 
        MovieTrackingReconstruction *reconstruction;
2063
 
        MovieReconstructedCamera *cameras;
2064
 
        int a;
2065
 
 
2066
 
        reconstruction = BKE_tracking_object_reconstruction(tracking, object);
2067
 
        cameras = reconstruction->cameras;
2068
 
        a = reconstruction_camera_index(reconstruction, framenr, 1);
2069
 
 
2070
 
        if (a == -1) {
2071
 
                unit_m4(mat);
2072
 
 
2073
 
                return;
2074
 
        }
2075
 
 
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);
2078
 
 
2079
 
                blend_m4_m4m4(mat, cameras[a].mat, cameras[a+1].mat, t);
2080
 
        }
2081
 
        else {
2082
 
                copy_m4_m4(mat, cameras[a].mat);
2083
 
        }
2084
 
 
2085
 
        scale_reconstructed_camera(object, mat);
2086
 
}
2087
 
 
2088
 
void BKE_get_tracking_mat(Scene *scene, Object *ob, float mat[4][4])
2089
 
{
2090
 
        if (!ob) {
2091
 
                if (scene->camera)
2092
 
                        ob = scene->camera;
2093
 
                else
2094
 
                        ob = scene_find_camera(scene);
2095
 
        }
2096
 
 
2097
 
        if (ob)
2098
 
                where_is_object_mat(scene, ob, mat);
2099
 
        else
2100
 
                unit_m4(mat);
2101
 
}
2102
 
 
2103
 
void BKE_tracking_camera_shift(MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty)
2104
 
{
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;
2108
 
}
2109
 
 
2110
 
void BKE_tracking_camera_to_blender(MovieTracking *tracking, Scene *scene, Camera *camera, int width, int height)
2111
 
{
2112
 
        float focal = tracking->camera.focal;
2113
 
 
2114
 
        camera->sensor_x = tracking->camera.sensor_width;
2115
 
        camera->sensor_fit = CAMERA_SENSOR_FIT_AUTO;
2116
 
        camera->lens = focal*camera->sensor_x/width;
2117
 
 
2118
 
        scene->r.xsch = width*tracking->camera.pixel_aspect;
2119
 
        scene->r.ysch = height;
2120
 
 
2121
 
        scene->r.xasp = 1.0f;
2122
 
        scene->r.yasp = 1.0f;
2123
 
 
2124
 
        BKE_tracking_camera_shift(tracking, width, height, &camera->shiftx, &camera->shifty);
2125
 
}
2126
 
 
2127
 
void BKE_tracking_projection_matrix(MovieTracking *tracking, MovieTrackingObject *object,
2128
 
                                    int framenr, int winx, int winy, float mat[4][4])
2129
 
{
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;
2133
 
        float winmat[4][4];
2134
 
        float ycor =  1.0f / tracking->camera.pixel_aspect;
2135
 
        float shiftx, shifty, winside = MAX2(winx, winy);
2136
 
 
2137
 
        BKE_tracking_camera_shift(tracking, winx, winy, &shiftx, &shifty);
2138
 
 
2139
 
        clipsta = 0.1f;
2140
 
        clipend = 1000.0f;
2141
 
 
2142
 
        if (winx >= winy)
2143
 
                viewfac = (lens*winx)/tracking->camera.sensor_width;
2144
 
        else
2145
 
                viewfac = (ycor*lens*winy)/tracking->camera.sensor_width;
2146
 
 
2147
 
        pixsize = clipsta/viewfac;
2148
 
 
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;
2153
 
 
2154
 
        left *= pixsize;
2155
 
        right *= pixsize;
2156
 
        bottom *= pixsize;
2157
 
        top *= pixsize;
2158
 
 
2159
 
        perspective_m4(winmat, left, right, bottom, top, clipsta, clipend);
2160
 
 
2161
 
        camera = BKE_tracking_get_reconstructed_camera(tracking, object, framenr);
2162
 
 
2163
 
        if (camera) {
2164
 
                float imat[4][4];
2165
 
 
2166
 
                invert_m4_m4(imat, camera->mat);
2167
 
                mult_m4_m4m4(mat, winmat, imat);
2168
 
        }
2169
 
        else copy_m4_m4(mat, winmat);
2170
 
}
2171
 
 
2172
 
ListBase *BKE_tracking_get_tracks(MovieTracking *tracking)
2173
 
{
2174
 
        MovieTrackingObject *object = BKE_tracking_active_object(tracking);
2175
 
 
2176
 
        if (object && (object->flag & TRACKING_OBJECT_CAMERA) == 0) {
2177
 
                return &object->tracks;
2178
 
        }
2179
 
 
2180
 
        return &tracking->tracks;
2181
 
}
2182
 
 
2183
 
MovieTrackingTrack *BKE_tracking_active_track(MovieTracking *tracking)
2184
 
{
2185
 
        ListBase *tracksbase;
2186
 
 
2187
 
        if (!tracking->act_track)
2188
 
                return NULL;
2189
 
 
2190
 
        tracksbase = BKE_tracking_get_tracks(tracking);
2191
 
 
2192
 
        /* check that active track is in current tracks list */
2193
 
        if (BLI_findindex(tracksbase, tracking->act_track) >= 0)
2194
 
                return tracking->act_track;
2195
 
 
2196
 
        return NULL;
2197
 
}
2198
 
 
2199
 
MovieTrackingObject *BKE_tracking_active_object(MovieTracking *tracking)
2200
 
{
2201
 
        return BLI_findlink(&tracking->objects, tracking->objectnr);
2202
 
}
2203
 
 
2204
 
MovieTrackingObject *BKE_tracking_get_camera_object(MovieTracking *tracking)
2205
 
{
2206
 
        MovieTrackingObject *object = tracking->objects.first;
2207
 
 
2208
 
        while (object) {
2209
 
                if (object->flag & TRACKING_OBJECT_CAMERA)
2210
 
                        return object;
2211
 
 
2212
 
                object= object->next;
2213
 
        }
2214
 
 
2215
 
        return NULL;
2216
 
}
2217
 
 
2218
 
ListBase *BKE_tracking_object_tracks(MovieTracking *tracking, MovieTrackingObject *object)
2219
 
{
2220
 
        if (object->flag & TRACKING_OBJECT_CAMERA) {
2221
 
                return &tracking->tracks;
2222
 
        }
2223
 
 
2224
 
        return &object->tracks;
2225
 
}
2226
 
 
2227
 
MovieTrackingReconstruction *BKE_tracking_object_reconstruction(MovieTracking *tracking, MovieTrackingObject *object)
2228
 
{
2229
 
        if (object->flag & TRACKING_OBJECT_CAMERA) {
2230
 
                return &tracking->reconstruction;
2231
 
        }
2232
 
 
2233
 
        return &object->reconstruction;
2234
 
}
2235
 
 
2236
 
MovieTrackingReconstruction *BKE_tracking_get_reconstruction(MovieTracking *tracking)
2237
 
{
2238
 
        MovieTrackingObject *object = BKE_tracking_active_object(tracking);
2239
 
 
2240
 
        return BKE_tracking_object_reconstruction(tracking, object);
2241
 
}
2242
 
 
2243
 
void BKE_tracking_apply_intrinsics(MovieTracking *tracking, float co[2], float nco[2])
2244
 
{
2245
 
        MovieTrackingCamera *camera= &tracking->camera;
2246
 
 
2247
 
#ifdef WITH_LIBMV
2248
 
        double x, y;
2249
 
        float aspy = 1.0f/tracking->camera.pixel_aspect;
2250
 
 
2251
 
        /* normalize coords */
2252
 
        x = (co[0] - camera->principal[0]) / camera->focal;
2253
 
        y = (co[1] - camera->principal[1] * aspy) / camera->focal;
2254
 
 
2255
 
        libmv_applyCameraIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy,
2256
 
                                    camera->k1, camera->k2, camera->k3, x, y, &x, &y);
2257
 
 
2258
 
        /* result is in image coords already */
2259
 
        nco[0] = x;
2260
 
        nco[1] = y;
2261
 
#else
2262
 
        (void) camera;
2263
 
        (void) co;
2264
 
        (void) nco;
2265
 
#endif
2266
 
}
2267
 
 
2268
 
void BKE_tracking_invert_intrinsics(MovieTracking *tracking, float co[2], float nco[2])
2269
 
{
2270
 
        MovieTrackingCamera *camera = &tracking->camera;
2271
 
 
2272
 
#ifdef WITH_LIBMV
2273
 
        double x = co[0], y = co[1];
2274
 
        float aspy = 1.0f / tracking->camera.pixel_aspect;
2275
 
 
2276
 
        libmv_InvertIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy,
2277
 
                               camera->k1, camera->k2, camera->k3, x, y, &x, &y);
2278
 
 
2279
 
        nco[0] = x * camera->focal + camera->principal[0];
2280
 
        nco[1] = y * camera->focal + camera->principal[1] * aspy;
2281
 
#else
2282
 
        (void) camera;
2283
 
        (void) co;
2284
 
        (void) nco;
2285
 
#endif
2286
 
}
2287
 
 
2288
 
#ifdef WITH_LIBMV
2289
 
static int point_in_stroke(bGPDstroke *stroke, float x, float y)
 
3099
/*********************** Feature detection *************************/
 
3100
 
 
3101
#ifdef WITH_LIBMV
 
3102
static int check_point_in_stroke(bGPDstroke *stroke, float x, float y)
2290
3103
{
2291
3104
        int i, prev;
2292
3105
        int count = 0;
2294
3107
 
2295
3108
        prev = stroke->totpoints - 1;
2296
3109
 
2297
 
        for (i = 0; i<stroke->totpoints; i++) {
 
3110
        for (i = 0; i < stroke->totpoints; i++) {
2298
3111
                if ((points[i].y < y && points[prev].y >= y) || (points[prev].y < y && points[i].y >= y)) {
2299
3112
                        float fac = (y - points[i].y) / (points[prev].y - points[i].y);
2300
3113
 
2302
3115
                                count++;
2303
3116
                }
2304
3117
 
2305
 
                prev= i;
 
3118
                prev = i;
2306
3119
        }
2307
3120
 
2308
3121
        return count % 2;
2309
3122
}
2310
3123
 
2311
 
static int point_in_layer(bGPDlayer *layer, float x, float y)
 
3124
static int check_point_in_layer(bGPDlayer *layer, float x, float y)
2312
3125
{
2313
3126
        bGPDframe *frame = layer->frames.first;
2314
3127
 
2316
3129
                bGPDstroke *stroke = frame->strokes.first;
2317
3130
 
2318
3131
                while (stroke) {
2319
 
                        if (point_in_stroke(stroke, x, y))
 
3132
                        if (check_point_in_stroke(stroke, x, y))
2320
3133
                                return TRUE;
2321
3134
 
2322
3135
                        stroke = stroke->next;
2327
3140
        return FALSE;
2328
3141
}
2329
3142
 
2330
 
static void retrieve_libmv_features(MovieTracking *tracking, ListBase *tracksbase,
2331
 
                                    struct libmv_Features *features, int framenr, int width, int height,
2332
 
                                    bGPDlayer *layer, int place_outside_layer)
 
3143
static void detect_retrieve_libmv_features(MovieTracking *tracking, ListBase *tracksbase,
 
3144
                                           struct libmv_Features *features, int framenr, int width, int height,
 
3145
                                           bGPDlayer *layer, int place_outside_layer)
2333
3146
{
2334
3147
        int a;
2335
3148
 
2346
3159
                yu = y / height;
2347
3160
 
2348
3161
                if (layer)
2349
 
                        ok = point_in_layer(layer, xu, yu) != place_outside_layer;
 
3162
                        ok = check_point_in_layer(layer, xu, yu) != place_outside_layer;
2350
3163
 
2351
3164
                if (ok) {
2352
 
                        track = BKE_tracking_add_track(tracking, tracksbase, xu, yu, framenr, width, height);
 
3165
                        track = BKE_tracking_track_add(tracking, tracksbase, xu, yu, framenr, width, height);
2353
3166
                        track->flag |= SELECT;
2354
3167
                        track->pat_flag |= SELECT;
2355
3168
                        track->search_flag |= SELECT;
2356
3169
                }
2357
3170
        }
2358
3171
}
 
3172
 
 
3173
static unsigned char *detect_get_frame_ucharbuf(ImBuf *ibuf)
 
3174
{
 
3175
        int x, y;
 
3176
        unsigned char *pixels, *cp;
 
3177
 
 
3178
        cp = pixels = MEM_callocN(ibuf->x * ibuf->y * sizeof(unsigned char), "tracking ucharBuf");
 
3179
        for (y = 0; y < ibuf->y; y++) {
 
3180
                for (x = 0; x < ibuf->x; x++) {
 
3181
                        int pixel = ibuf->x * y + x;
 
3182
 
 
3183
                        if (ibuf->rect_float) {
 
3184
                                const float *rrgbf = ibuf->rect_float + pixel * 4;
 
3185
                                const float gray_f = 0.2126f * rrgbf[0] + 0.7152f * rrgbf[1] + 0.0722f * rrgbf[2];
 
3186
 
 
3187
                                *cp = FTOCHAR(gray_f);
 
3188
                        }
 
3189
                        else {
 
3190
                                const unsigned char *rrgb = (unsigned char *)ibuf->rect + pixel * 4;
 
3191
 
 
3192
                                *cp = 0.2126f * rrgb[0] + 0.7152f * rrgb[1] + 0.0722f * rrgb[2];
 
3193
                        }
 
3194
 
 
3195
                        cp++;
 
3196
                }
 
3197
        }
 
3198
 
 
3199
        return pixels;
 
3200
}
2359
3201
#endif
2360
3202
 
2361
3203
void BKE_tracking_detect_fast(MovieTracking *tracking, ListBase *tracksbase, ImBuf *ibuf,
2364
3206
{
2365
3207
#ifdef WITH_LIBMV
2366
3208
        struct libmv_Features *features;
2367
 
        unsigned char *pixels = get_ucharbuf(ibuf);
 
3209
        unsigned char *pixels = detect_get_frame_ucharbuf(ibuf);
2368
3210
 
2369
3211
        features = libmv_detectFeaturesFAST(pixels, ibuf->x, ibuf->y, ibuf->x,
2370
3212
                                            margin, min_trackness, min_distance);
2371
3213
 
2372
3214
        MEM_freeN(pixels);
2373
3215
 
2374
 
        retrieve_libmv_features(tracking, tracksbase, features, framenr,
2375
 
                                ibuf->x, ibuf->y, layer, place_outside_layer);
 
3216
        detect_retrieve_libmv_features(tracking, tracksbase, features, framenr,
 
3217
                                       ibuf->x, ibuf->y, layer, place_outside_layer);
2376
3218
 
2377
3219
        libmv_destroyFeatures(features);
2378
3220
#else
2388
3230
#endif
2389
3231
}
2390
3232
 
2391
 
MovieTrackingTrack *BKE_tracking_indexed_track(MovieTracking *tracking, int tracknr, ListBase **tracksbase_r)
2392
 
{
2393
 
        MovieTrackingObject *object;
2394
 
        int cur = 1;
2395
 
 
2396
 
        object = tracking->objects.first;
2397
 
        while (object) {
2398
 
                ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object);
2399
 
                MovieTrackingTrack *track = tracksbase->first;
2400
 
 
2401
 
                while (track) {
2402
 
                        if (track->flag & TRACK_HAS_BUNDLE) {
2403
 
                                if (cur == tracknr) {
2404
 
                                        *tracksbase_r = tracksbase;
2405
 
                                        return track;
2406
 
                                }
2407
 
 
2408
 
                                cur++;
2409
 
                        }
2410
 
 
2411
 
                        track = track->next;
2412
 
                }
2413
 
 
2414
 
                object= object->next;
2415
 
        }
2416
 
 
2417
 
        *tracksbase_r= NULL;
2418
 
 
2419
 
        return NULL;
2420
 
}
2421
 
 
2422
 
static int stabilization_median_point(MovieTracking *tracking, int framenr, float median[2])
 
3233
/*********************** 2D stabilization *************************/
 
3234
 
 
3235
static int stabilization_median_point_get(MovieTracking *tracking, int framenr, float median[2])
2423
3236
{
2424
3237
        int ok = FALSE;
2425
3238
        float min[2], max[2];
2430
3243
        track = tracking->tracks.first;
2431
3244
        while (track) {
2432
3245
                if (track->flag & TRACK_USE_2D_STAB) {
2433
 
                        MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr);
 
3246
                        MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
2434
3247
 
2435
 
                        DO_MINMAX2(marker->pos, min, max);
 
3248
                        minmax_v2v2_v2(min, max, marker->pos);
2436
3249
 
2437
3250
                        ok = TRUE;
2438
3251
                }
2446
3259
        return ok;
2447
3260
}
2448
3261
 
2449
 
static void calculate_stabdata(MovieTracking *tracking, int framenr, float width, float height,
2450
 
                               float firstmedian[2], float median[2], float loc[2], float *scale, float *angle)
 
3262
static void stabilization_calculate_data(MovieTracking *tracking, int framenr, float width, float height,
 
3263
                                         float firstmedian[2], float median[2], float loc[2],
 
3264
                                         float *scale, float *angle)
2451
3265
{
2452
3266
        MovieTrackingStabilization *stab = &tracking->stabilization;
2453
3267
 
2454
3268
        *scale = (stab->scale - 1.0f) * stab->scaleinf + 1.0f;
2455
3269
        *angle = 0.0f;
2456
3270
 
2457
 
        loc[0] = (firstmedian[0] - median[0]) *width * (*scale);
2458
 
        loc[1] = (firstmedian[1] - median[1]) *height * (*scale);
 
3271
        loc[0] = (firstmedian[0] - median[0]) * width * (*scale);
 
3272
        loc[1] = (firstmedian[1] - median[1]) * height * (*scale);
2459
3273
 
2460
3274
        mul_v2_fl(loc, stab->locinf);
2461
3275
 
2465
3279
                float x0 = (float)width / 2.0f, y0 = (float)height / 2.0f;
2466
3280
                float x = median[0] * width, y = median[1] * height;
2467
3281
 
2468
 
                marker = BKE_tracking_get_marker(stab->rot_track, 1);
 
3282
                marker = BKE_tracking_marker_get(stab->rot_track, 1);
2469
3283
                sub_v2_v2v2(a, marker->pos, firstmedian);
2470
3284
                a[0] *= width;
2471
3285
                a[1] *= height;
2472
3286
 
2473
 
                marker = BKE_tracking_get_marker(stab->rot_track, framenr);
 
3287
                marker = BKE_tracking_marker_get(stab->rot_track, framenr);
2474
3288
                sub_v2_v2v2(b, marker->pos, median);
2475
3289
                b[0] *= width;
2476
3290
                b[1] *= height;
2477
3291
 
2478
 
                *angle = -atan2(a[0]*b[1]-a[1]*b[0], a[0]*b[0]+a[1]*b[1]);
 
3292
                *angle = -atan2(a[0] * b[1] - a[1] * b[0], a[0] * b[0] + a[1] * b[1]);
2479
3293
                *angle *= stab->rotinf;
2480
3294
 
2481
3295
                /* convert to rotation around image center */
2484
3298
        }
2485
3299
}
2486
3300
 
2487
 
static float stabilization_auto_scale_factor(MovieTracking *tracking, int width, int height)
 
3301
static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, int width, int height)
2488
3302
{
2489
3303
        float firstmedian[2];
2490
3304
        MovieTrackingStabilization *stab = &tracking->stabilization;
2493
3307
        if (stab->ok)
2494
3308
                return stab->scale;
2495
3309
 
2496
 
        if (stabilization_median_point(tracking, 1, firstmedian)) {
 
3310
        if (stabilization_median_point_get(tracking, 1, firstmedian)) {
2497
3311
                int sfra = INT_MAX, efra = INT_MIN, cfra;
2498
3312
                float scale = 1.0f;
2499
3313
                MovieTrackingTrack *track;
2503
3317
                track = tracking->tracks.first;
2504
3318
                while (track) {
2505
3319
                        if (track->flag & TRACK_USE_2D_STAB ||
2506
 
                           ((stab->flag & TRACKING_STABILIZE_ROTATION) && track == stab->rot_track))
 
3320
                            ((stab->flag & TRACKING_STABILIZE_ROTATION) && track == stab->rot_track))
2507
3321
                        {
2508
 
                                sfra = MIN2(sfra, track->markers[0].framenr);
2509
 
                                efra = MAX2(efra, track->markers[track->markersnr - 1].framenr);
 
3322
                                sfra = min_ii(sfra, track->markers[0].framenr);
 
3323
                                efra = max_ii(efra, track->markers[track->markersnr - 1].framenr);
2510
3324
                        }
2511
3325
 
2512
3326
                        track = track->next;
2520
3334
                        float points[4][2] = {{0.0f, 0.0f}, {0.0f, height}, {width, height}, {width, 0.0f}};
2521
3335
                        float si, co;
2522
3336
 
2523
 
                        stabilization_median_point(tracking, cfra, median);
2524
 
 
2525
 
                        calculate_stabdata(tracking, cfra, width, height, firstmedian, median, loc, &tmp_scale, &angle);
2526
 
 
2527
 
                        BKE_tracking_stabdata_to_mat4(width, height, aspect, loc, 1.0f, angle, mat);
 
3337
                        stabilization_median_point_get(tracking, cfra, median);
 
3338
 
 
3339
                        stabilization_calculate_data(tracking, cfra, width, height, firstmedian, median, loc, &tmp_scale, &angle);
 
3340
 
 
3341
                        BKE_tracking_stabilization_data_to_mat4(width, height, aspect, loc, 1.0f, angle, mat);
2528
3342
 
2529
3343
                        si = sin(angle);
2530
3344
                        co = cos(angle);
2531
3345
 
2532
3346
                        for (i = 0; i < 4; i++) {
2533
3347
                                int j;
2534
 
                                float a[3] = {0.0f, 0.0f, 0.0f}, b[3]= {0.0f, 0.0f, 0.0f};
 
3348
                                float a[3] = {0.0f, 0.0f, 0.0f}, b[3] = {0.0f, 0.0f, 0.0f};
2535
3349
 
2536
3350
                                copy_v3_v3(a, points[i]);
2537
 
                                copy_v3_v3(b, points[(i+1)%4]);
 
3351
                                copy_v3_v3(b, points[(i + 1) % 4]);
2538
3352
 
2539
3353
                                mul_m4_v3(mat, a);
2540
3354
                                mul_m4_v3(mat, b);
2564
3378
                                                        h = (float)height / 2.0f;
2565
3379
                                                }
2566
3380
 
2567
 
                                                E = -w*co + h*si;
2568
 
                                                F = -h*co - w*si;
 
3381
                                                E = -w * co + h * si;
 
3382
                                                F = -h * co - w * si;
2569
3383
 
2570
3384
                                                if ((i % 2) == (j % 2)) {
2571
 
                                                        G = -w*co - h*si;
2572
 
                                                        H = h*co - w*si;
 
3385
                                                        G = -w * co - h * si;
 
3386
                                                        H = h * co - w * si;
2573
3387
                                                }
2574
3388
                                                else {
2575
 
                                                        G = w*co + h*si;
2576
 
                                                        H = -h*co + w*si;
 
3389
                                                        G = w * co + h * si;
 
3390
                                                        H = -h * co + w * si;
2577
3391
                                                }
2578
3392
 
2579
3393
                                                I = F - H;
2580
3394
                                                J = G - E;
2581
 
                                                K = G*F - E*H;
2582
 
 
2583
 
                                                S = (-w*I - h*J) / (dx*I + dy*J + K);
2584
 
 
2585
 
                                                scale = MAX2(scale, S);
 
3395
                                                K = G * F - E * H;
 
3396
 
 
3397
                                                S = (-w * I - h * J) / (dx * I + dy * J + K);
 
3398
 
 
3399
                                                scale = max_ff(scale, S);
2586
3400
                                        }
2587
3401
                                }
2588
3402
                        }
2590
3404
 
2591
3405
                stab->scale = scale;
2592
3406
 
2593
 
                if (stab->maxscale>0.0f)
2594
 
                        stab->scale = MIN2(stab->scale, stab->maxscale);
 
3407
                if (stab->maxscale > 0.0f)
 
3408
                        stab->scale = min_ff(stab->scale, stab->maxscale);
2595
3409
        }
2596
3410
        else {
2597
3411
                stab->scale = 1.0f;
2602
3416
        return stab->scale;
2603
3417
}
2604
3418
 
2605
 
static ImBuf* stabilize_alloc_ibuf(ImBuf *cacheibuf, ImBuf *srcibuf, int fill)
 
3419
static ImBuf *stabilization_allocate_ibuf(ImBuf *cacheibuf, ImBuf *srcibuf, int fill)
2606
3420
{
2607
3421
        int flags;
2608
3422
 
2625
3439
        }
2626
3440
        else {
2627
3441
                cacheibuf = IMB_allocImBuf(srcibuf->x, srcibuf->y, srcibuf->planes, flags);
2628
 
                cacheibuf->profile = srcibuf->profile;
2629
3442
        }
2630
3443
 
2631
3444
        return cacheibuf;
2632
3445
}
2633
3446
 
2634
 
void BKE_tracking_stabilization_data(MovieTracking *tracking, int framenr, int width, int height, float loc[2], float *scale, float *angle)
 
3447
/* NOTE: frame number should be in clip space, not scene space */
 
3448
void BKE_tracking_stabilization_data_get(MovieTracking *tracking, int framenr, int width, int height,
 
3449
                                         float loc[2], float *scale, float *angle)
2635
3450
{
2636
3451
        float firstmedian[2], median[2];
2637
3452
        MovieTrackingStabilization *stab = &tracking->stabilization;
2638
3453
 
2639
3454
        if ((stab->flag & TRACKING_2D_STABILIZATION) == 0) {
2640
3455
                zero_v2(loc);
2641
 
                *scale= 1.0f;
2642
 
                *angle= 0.0f;
 
3456
                *scale = 1.0f;
 
3457
                *angle = 0.0f;
2643
3458
 
2644
3459
                return;
2645
3460
        }
2646
3461
 
2647
 
        if (stabilization_median_point(tracking, 1, firstmedian)) {
2648
 
                stabilization_median_point(tracking, framenr, median);
 
3462
        if (stabilization_median_point_get(tracking, 1, firstmedian)) {
 
3463
                stabilization_median_point_get(tracking, framenr, median);
2649
3464
 
2650
3465
                if ((stab->flag & TRACKING_AUTOSCALE) == 0)
2651
3466
                        stab->scale = 1.0f;
2652
3467
 
2653
3468
                if (!stab->ok) {
2654
3469
                        if (stab->flag & TRACKING_AUTOSCALE)
2655
 
                                stabilization_auto_scale_factor(tracking, width, height);
 
3470
                                stabilization_calculate_autoscale_factor(tracking, width, height);
2656
3471
 
2657
 
                        calculate_stabdata(tracking, framenr, width, height, firstmedian, median, loc, scale, angle);
 
3472
                        stabilization_calculate_data(tracking, framenr, width, height, firstmedian, median, loc, scale, angle);
2658
3473
 
2659
3474
                        stab->ok = TRUE;
2660
3475
                }
2661
3476
                else {
2662
 
                        calculate_stabdata(tracking, framenr, width, height, firstmedian, median, loc, scale, angle);
 
3477
                        stabilization_calculate_data(tracking, framenr, width, height, firstmedian, median, loc, scale, angle);
2663
3478
                }
2664
3479
        }
2665
3480
        else {
2669
3484
        }
2670
3485
}
2671
3486
 
2672
 
ImBuf *BKE_tracking_stabilize(MovieTracking *tracking, int framenr, ImBuf *ibuf, float loc[2], float *scale, float *angle)
 
3487
/* NOTE: frame number should be in clip space, not scene space */
 
3488
ImBuf *BKE_tracking_stabilize_frame(MovieTracking *tracking, int framenr, ImBuf *ibuf,
 
3489
                                    float loc[2], float *scale, float *angle)
2673
3490
{
2674
3491
        float tloc[2], tscale, tangle;
2675
3492
        MovieTrackingStabilization *stab = &tracking->stabilization;
2693
3510
                return ibuf;
2694
3511
        }
2695
3512
 
2696
 
        BKE_tracking_stabilization_data(tracking, framenr, width, height, tloc, &tscale, &tangle);
 
3513
        BKE_tracking_stabilization_data_get(tracking, framenr, width, height, tloc, &tscale, &tangle);
2697
3514
 
2698
 
        tmpibuf = stabilize_alloc_ibuf(NULL, ibuf, TRUE);
 
3515
        tmpibuf = stabilization_allocate_ibuf(NULL, ibuf, TRUE);
2699
3516
 
2700
3517
        /* scale would be handled by matrix transformation when angle is non-zero */
2701
3518
        if (tscale != 1.0f && tangle == 0.0f) {
2702
3519
                ImBuf *scaleibuf;
2703
3520
 
2704
 
                stabilization_auto_scale_factor(tracking, width, height);
 
3521
                stabilization_calculate_autoscale_factor(tracking, width, height);
2705
3522
 
2706
 
                scaleibuf = stabilize_alloc_ibuf(stab->scaleibuf, ibuf, 0);
 
3523
                scaleibuf = stabilization_allocate_ibuf(stab->scaleibuf, ibuf, 0);
2707
3524
                stab->scaleibuf = scaleibuf;
2708
3525
 
2709
3526
                IMB_rectcpy(scaleibuf, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y);
2710
 
                IMB_scalefastImBuf(scaleibuf, ibuf->x*tscale, ibuf->y*tscale);
 
3527
                IMB_scalefastImBuf(scaleibuf, ibuf->x * tscale, ibuf->y * tscale);
2711
3528
 
2712
3529
                ibuf = scaleibuf;
2713
3530
        }
2714
3531
 
2715
3532
        if (tangle == 0.0f) {
2716
3533
                /* if angle is zero, then it's much faster to use rect copy
2717
 
                 * but could be issues with subpixel precisions */
 
3534
                 * but could be issues with subpixel precisions
 
3535
                 */
2718
3536
                IMB_rectcpy(tmpibuf, ibuf,
2719
3537
                            tloc[0] - (tscale - 1.0f) * width / 2.0f,
2720
3538
                            tloc[1] - (tscale - 1.0f) * height / 2.0f,
2723
3541
        else {
2724
3542
                float mat[4][4];
2725
3543
                int i, j, filter = tracking->stabilization.filter;
2726
 
                void (*interpolation) (struct ImBuf*, struct ImBuf*, float, float, int, int) = NULL;
 
3544
                void (*interpolation)(struct ImBuf *, struct ImBuf *, float, float, int, int) = NULL;
2727
3545
 
2728
 
                BKE_tracking_stabdata_to_mat4(ibuf->x, ibuf->y, aspect, tloc, tscale, tangle, mat);
 
3546
                BKE_tracking_stabilization_data_to_mat4(ibuf->x, ibuf->y, aspect, tloc, tscale, tangle, mat);
2729
3547
                invert_m4(mat);
2730
3548
 
2731
 
                if (filter == TRACKING_FILTER_NEAREAST)
2732
 
                        interpolation = neareast_interpolation;
 
3549
                if (filter == TRACKING_FILTER_NEAREST)
 
3550
                        interpolation = nearest_interpolation;
2733
3551
                else if (filter == TRACKING_FILTER_BILINEAR)
2734
3552
                        interpolation = bilinear_interpolation;
2735
3553
                else if (filter == TRACKING_FILTER_BICUBIC)
2736
3554
                        interpolation = bicubic_interpolation;
2737
3555
                else
2738
3556
                        /* fallback to default interpolation method */
2739
 
                        interpolation = neareast_interpolation;
 
3557
                        interpolation = nearest_interpolation;
2740
3558
 
2741
3559
                for (j = 0; j < tmpibuf->y; j++) {
2742
 
                        for (i = 0; i < tmpibuf->x;i++) {
 
3560
                        for (i = 0; i < tmpibuf->x; i++) {
2743
3561
                                float vec[3] = {i, j, 0};
2744
3562
 
2745
3563
                                mul_v3_m4v3(vec, mat, vec);
2758
3576
                copy_v2_v2(loc, tloc);
2759
3577
 
2760
3578
        if (scale)
2761
 
                *scale= tscale;
 
3579
                *scale = tscale;
2762
3580
 
2763
3581
        if (angle)
2764
 
                *angle= tangle;
 
3582
                *angle = tangle;
2765
3583
 
2766
3584
        return tmpibuf;
2767
3585
}
2768
3586
 
2769
 
void BKE_tracking_stabdata_to_mat4(int width, int height, float aspect, float loc[2], float scale, float angle, float mat[4][4])
 
3587
void BKE_tracking_stabilization_data_to_mat4(int width, int height, float aspect, float loc[2],
 
3588
                                             float scale, float angle, float mat[4][4])
2770
3589
{
2771
3590
        float lmat[4][4], rmat[4][4], smat[4][4], cmat[4][4], icmat[4][4], amat[4][4], iamat[4][4];
2772
 
        float svec[3]= {scale, scale, scale};
 
3591
        float svec[3] = {scale, scale, scale};
2773
3592
 
2774
3593
        unit_m4(rmat);
2775
3594
        unit_m4(lmat);
2786
3605
        cmat[3][1] = (float)height / 2.0f;
2787
3606
        invert_m4_m4(icmat, cmat);
2788
3607
 
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 */
2792
3611
 
2793
3612
        /* compose transformation matrix */
2794
3613
        mul_serie_m4(mat, lmat, cmat, amat, rmat, iamat, smat, icmat, NULL);
2795
3614
}
2796
3615
 
2797
 
MovieDistortion *BKE_tracking_distortion_create(void)
2798
 
{
2799
 
        MovieDistortion *distortion;
2800
 
 
2801
 
        distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
2802
 
 
2803
 
        return distortion;
2804
 
}
2805
 
 
2806
 
MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion)
2807
 
{
2808
 
        MovieDistortion *new_distortion;
2809
 
 
2810
 
        new_distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
2811
 
 
2812
 
#ifdef WITH_LIBMV
2813
 
        new_distortion->intrinsics = libmv_CameraIntrinsicsCopy(distortion->intrinsics);
2814
 
#else
2815
 
        (void) distortion;
2816
 
#endif
2817
 
 
2818
 
        return new_distortion;
2819
 
}
2820
 
 
2821
 
void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *tracking, int width, int height)
2822
 
{
2823
 
        MovieTrackingCamera *camera = &tracking->camera;
2824
 
        float aspy = 1.0f / tracking->camera.pixel_aspect;
2825
 
 
2826
 
#ifdef WITH_LIBMV
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);
2831
 
        }
2832
 
        else {
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);
2836
 
        }
2837
 
#else
2838
 
        (void) distortion;
2839
 
        (void) width;
2840
 
        (void) height;
2841
 
        (void) camera;
2842
 
        (void) aspy;
2843
 
#endif
2844
 
}
2845
 
 
2846
 
ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *tracking,
2847
 
                                    ImBuf *ibuf, int width, int height, float overscan, int undistort)
2848
 
{
2849
 
        ImBuf *resibuf;
2850
 
 
2851
 
        BKE_tracking_distortion_update(distortion, tracking, width, height);
2852
 
 
2853
 
        resibuf = IMB_dupImBuf(ibuf);
2854
 
 
2855
 
        if (ibuf->rect_float) {
2856
 
#ifdef WITH_LIBMV
2857
 
                if (undistort) {
2858
 
                        libmv_CameraIntrinsicsUndistortFloat(distortion->intrinsics,
2859
 
                                                ibuf->rect_float, resibuf->rect_float,
2860
 
                                                ibuf->x, ibuf->y, overscan, ibuf->channels);
2861
 
                }
2862
 
                else {
2863
 
                        libmv_CameraIntrinsicsDistortFloat(distortion->intrinsics,
2864
 
                                                ibuf->rect_float, resibuf->rect_float,
2865
 
                                                ibuf->x, ibuf->y, overscan, ibuf->channels);
2866
 
                }
2867
 
#endif
2868
 
 
2869
 
                ibuf->userflags |= IB_RECT_INVALID;
2870
 
        }
2871
 
        else {
2872
 
#ifdef WITH_LIBMV
2873
 
                if (undistort) {
2874
 
                                libmv_CameraIntrinsicsUndistortByte(distortion->intrinsics,
2875
 
                                                        (unsigned char*)ibuf->rect, (unsigned char*)resibuf->rect,
2876
 
                                                        ibuf->x, ibuf->y, overscan, ibuf->channels);
2877
 
                }
2878
 
                else {
2879
 
                        libmv_CameraIntrinsicsDistortByte(distortion->intrinsics,
2880
 
                                                (unsigned char*)ibuf->rect, (unsigned char*)resibuf->rect,
2881
 
                                                ibuf->x, ibuf->y, overscan, ibuf->channels);
2882
 
                }
2883
 
#endif
2884
 
        }
2885
 
 
2886
 
#ifndef WITH_LIBMV
2887
 
        (void) overscan;
2888
 
        (void) undistort;
2889
 
#endif
2890
 
 
2891
 
        return resibuf;
2892
 
}
2893
 
 
2894
 
void BKE_tracking_distortion_destroy(MovieDistortion *distortion)
2895
 
{
2896
 
#ifdef WITH_LIBMV
2897
 
        libmv_CameraIntrinsicsDestroy(distortion->intrinsics);
2898
 
#endif
2899
 
 
2900
 
        MEM_freeN(distortion);
2901
 
}
2902
 
 
2903
 
ImBuf *BKE_tracking_undistort(MovieTracking *tracking, ImBuf *ibuf, int width, int height, float overscan)
2904
 
{
2905
 
        MovieTrackingCamera *camera = &tracking->camera;
2906
 
 
2907
 
        if (camera->intrinsics == NULL)
2908
 
                camera->intrinsics = BKE_tracking_distortion_create();
2909
 
 
2910
 
        return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, width, height, overscan, 1);
2911
 
}
2912
 
 
2913
 
ImBuf *BKE_tracking_distort(MovieTracking *tracking, ImBuf *ibuf, int width, int height, float overscan)
2914
 
{
2915
 
        MovieTrackingCamera *camera = &tracking->camera;
2916
 
 
2917
 
        if (camera->intrinsics == NULL)
2918
 
                camera->intrinsics = BKE_tracking_distortion_create();
2919
 
 
2920
 
        return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, width, height, overscan, 0);
2921
 
}
2922
 
 
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)
2925
 
{
2926
 
        if (extend) {
2927
 
                BKE_tracking_track_flag(track, area, SELECT, 0);
2928
 
        }
2929
 
        else {
2930
 
                MovieTrackingTrack *cur = tracksbase->first;
2931
 
 
2932
 
                while (cur) {
2933
 
                        if ((cur->flag & TRACK_HIDDEN) == 0) {
2934
 
                                if (cur == track) {
2935
 
                                        BKE_tracking_track_flag(cur, TRACK_AREA_ALL, SELECT, 1);
2936
 
                                        BKE_tracking_track_flag(cur, area, SELECT, 0);
2937
 
                                }
2938
 
                                else {
2939
 
                                        BKE_tracking_track_flag(cur, TRACK_AREA_ALL, SELECT, 1);
2940
 
                                }
2941
 
                        }
2942
 
 
2943
 
                        cur = cur->next;
2944
 
                }
2945
 
        }
2946
 
}
2947
 
 
2948
 
void BKE_tracking_deselect_track(MovieTrackingTrack *track, int area)
2949
 
{
2950
 
        BKE_tracking_track_flag(track, area, SELECT, 1);
2951
 
}
2952
 
 
2953
 
MovieTrackingObject *BKE_tracking_new_object(MovieTracking *tracking, const char *name)
2954
 
{
2955
 
        MovieTrackingObject *object = MEM_callocN(sizeof(MovieTrackingObject), "tracking object");
2956
 
 
2957
 
        if (tracking->tot_object == 0) {
2958
 
                /* first object is always camera */
2959
 
                BLI_strncpy(object->name, "Camera", sizeof(object->name));
2960
 
 
2961
 
                object->flag |= TRACKING_OBJECT_CAMERA;
2962
 
        }
2963
 
        else {
2964
 
                BLI_strncpy(object->name, name, sizeof(object->name));
2965
 
        }
2966
 
 
2967
 
        BLI_addtail(&tracking->objects, object);
2968
 
 
2969
 
        tracking->tot_object++;
2970
 
        tracking->objectnr = BLI_countlist(&tracking->objects) - 1;
2971
 
 
2972
 
        object->scale = 1.0f;
2973
 
 
2974
 
        BKE_tracking_object_unique_name(tracking, object);
2975
 
 
2976
 
        return object;
2977
 
}
2978
 
 
2979
 
void BKE_tracking_remove_object(MovieTracking *tracking, MovieTrackingObject *object)
2980
 
{
 
3616
/*********************** Dopesheet functions *************************/
 
3617
 
 
3618
static int channels_alpha_sort(void *a, void *b)
 
3619
{
 
3620
        MovieTrackingDopesheetChannel *channel_a = a;
 
3621
        MovieTrackingDopesheetChannel *channel_b = b;
 
3622
 
 
3623
        if (BLI_strcasecmp(channel_a->track->name, channel_b->track->name) > 0)
 
3624
                return 1;
 
3625
        else
 
3626
                return 0;
 
3627
}
 
3628
 
 
3629
static int channels_total_track_sort(void *a, void *b)
 
3630
{
 
3631
        MovieTrackingDopesheetChannel *channel_a = a;
 
3632
        MovieTrackingDopesheetChannel *channel_b = b;
 
3633
 
 
3634
        if (channel_a->total_frames > channel_b->total_frames)
 
3635
                return 1;
 
3636
        else
 
3637
                return 0;
 
3638
}
 
3639
 
 
3640
static int channels_longest_segment_sort(void *a, void *b)
 
3641
{
 
3642
        MovieTrackingDopesheetChannel *channel_a = a;
 
3643
        MovieTrackingDopesheetChannel *channel_b = b;
 
3644
 
 
3645
        if (channel_a->max_segment > channel_b->max_segment)
 
3646
                return 1;
 
3647
        else
 
3648
                return 0;
 
3649
}
 
3650
 
 
3651
static int channels_average_error_sort(void *a, void *b)
 
3652
{
 
3653
        MovieTrackingDopesheetChannel *channel_a = a;
 
3654
        MovieTrackingDopesheetChannel *channel_b = b;
 
3655
 
 
3656
        if (channel_a->track->error > channel_b->track->error)
 
3657
                return 1;
 
3658
        else
 
3659
                return 0;
 
3660
}
 
3661
 
 
3662
static int channels_alpha_inverse_sort(void *a, void *b)
 
3663
{
 
3664
        if (channels_alpha_sort(a, b))
 
3665
                return 0;
 
3666
        else
 
3667
                return 1;
 
3668
}
 
3669
 
 
3670
static int channels_total_track_inverse_sort(void *a, void *b)
 
3671
{
 
3672
        if (channels_total_track_sort(a, b))
 
3673
                return 0;
 
3674
        else
 
3675
                return 1;
 
3676
}
 
3677
 
 
3678
static int channels_longest_segment_inverse_sort(void *a, void *b)
 
3679
{
 
3680
        if (channels_longest_segment_sort(a, b))
 
3681
                return 0;
 
3682
        else
 
3683
                return 1;
 
3684
}
 
3685
 
 
3686
static int channels_average_error_inverse_sort(void *a, void *b)
 
3687
{
 
3688
        MovieTrackingDopesheetChannel *channel_a = a;
 
3689
        MovieTrackingDopesheetChannel *channel_b = b;
 
3690
 
 
3691
        if (channel_a->track->error < channel_b->track->error)
 
3692
                return 1;
 
3693
        else
 
3694
                return 0;
 
3695
}
 
3696
 
 
3697
static void channels_segments_calc(MovieTrackingDopesheetChannel *channel)
 
3698
{
 
3699
        MovieTrackingTrack *track = channel->track;
 
3700
        int i, segment;
 
3701
 
 
3702
        channel->tot_segment = 0;
 
3703
        channel->max_segment = 0;
 
3704
        channel->total_frames = 0;
 
3705
 
 
3706
        /* count */
 
3707
        i = 0;
 
3708
        while (i < track->markersnr) {
 
3709
                MovieTrackingMarker *marker = &track->markers[i];
 
3710
 
 
3711
                if ((marker->flag & MARKER_DISABLED) == 0) {
 
3712
                        int prev_fra = marker->framenr, len = 0;
 
3713
 
 
3714
                        i++;
 
3715
                        while (i < track->markersnr) {
 
3716
                                marker = &track->markers[i];
 
3717
 
 
3718
                                if (marker->framenr != prev_fra + 1)
 
3719
                                        break;
 
3720
                                if (marker->flag & MARKER_DISABLED)
 
3721
                                        break;
 
3722
 
 
3723
                                prev_fra = marker->framenr;
 
3724
                                len++;
 
3725
                                i++;
 
3726
                        }
 
3727
 
 
3728
                        channel->tot_segment++;
 
3729
                }
 
3730
 
 
3731
                i++;
 
3732
        }
 
3733
 
 
3734
        if (!channel->tot_segment)
 
3735
                return;
 
3736
 
 
3737
        channel->segments = MEM_callocN(2 * sizeof(int) * channel->tot_segment, "tracking channel segments");
 
3738
 
 
3739
        /* create segments */
 
3740
        i = 0;
 
3741
        segment = 0;
 
3742
        while (i < track->markersnr) {
 
3743
                MovieTrackingMarker *marker = &track->markers[i];
 
3744
 
 
3745
                if ((marker->flag & MARKER_DISABLED) == 0) {
 
3746
                        MovieTrackingMarker *start_marker = marker;
 
3747
                        int prev_fra = marker->framenr, len = 0;
 
3748
 
 
3749
                        i++;
 
3750
                        while (i < track->markersnr) {
 
3751
                                marker = &track->markers[i];
 
3752
 
 
3753
                                if (marker->framenr != prev_fra + 1)
 
3754
                                        break;
 
3755
                                if (marker->flag & MARKER_DISABLED)
 
3756
                                        break;
 
3757
 
 
3758
                                prev_fra = marker->framenr;
 
3759
                                channel->total_frames++;
 
3760
                                len++;
 
3761
                                i++;
 
3762
                        }
 
3763
 
 
3764
                        channel->segments[2 * segment] = start_marker->framenr;
 
3765
                        channel->segments[2 * segment + 1] = start_marker->framenr + len;
 
3766
 
 
3767
                        channel->max_segment = max_ii(channel->max_segment, len);
 
3768
                        segment++;
 
3769
                }
 
3770
 
 
3771
                i++;
 
3772
        }
 
3773
}
 
3774
 
 
3775
static void tracking_dopesheet_sort(MovieTracking *tracking, int sort_method, int inverse)
 
3776
{
 
3777
        MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
 
3778
 
 
3779
        if (inverse) {
 
3780
                if (sort_method == TRACKING_DOPE_SORT_NAME) {
 
3781
                        BLI_sortlist(&dopesheet->channels, channels_alpha_inverse_sort);
 
3782
                }
 
3783
                else if (sort_method == TRACKING_DOPE_SORT_LONGEST) {
 
3784
                        BLI_sortlist(&dopesheet->channels, channels_longest_segment_inverse_sort);
 
3785
                }
 
3786
                else if (sort_method == TRACKING_DOPE_SORT_TOTAL) {
 
3787
                        BLI_sortlist(&dopesheet->channels, channels_total_track_inverse_sort);
 
3788
                }
 
3789
                else if (sort_method == TRACKING_DOPE_SORT_AVERAGE_ERROR) {
 
3790
                        BLI_sortlist(&dopesheet->channels, channels_average_error_inverse_sort);
 
3791
                }
 
3792
        }
 
3793
        else {
 
3794
                if (sort_method == TRACKING_DOPE_SORT_NAME) {
 
3795
                        BLI_sortlist(&dopesheet->channels, channels_alpha_sort);
 
3796
                }
 
3797
                else if (sort_method == TRACKING_DOPE_SORT_LONGEST) {
 
3798
                        BLI_sortlist(&dopesheet->channels, channels_longest_segment_sort);
 
3799
                }
 
3800
                else if (sort_method == TRACKING_DOPE_SORT_TOTAL) {
 
3801
                        BLI_sortlist(&dopesheet->channels, channels_total_track_sort);
 
3802
                }
 
3803
                else if (sort_method == TRACKING_DOPE_SORT_AVERAGE_ERROR) {
 
3804
                        BLI_sortlist(&dopesheet->channels, channels_average_error_sort);
 
3805
                }
 
3806
        }
 
3807
}
 
3808
 
 
3809
void BKE_tracking_dopesheet_tag_update(MovieTracking *tracking)
 
3810
{
 
3811
        MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
 
3812
 
 
3813
        dopesheet->ok = FALSE;
 
3814
}
 
3815
 
 
3816
void BKE_tracking_dopesheet_update(MovieTracking *tracking)
 
3817
{
 
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);
2983
 
 
2984
 
        if (index<0)
2985
 
                return;
2986
 
 
2987
 
        if (object->flag & TRACKING_OBJECT_CAMERA) {
2988
 
                /* object used for camera solving can't be deleted */
2989
 
                return;
2990
 
        }
2991
 
 
2992
 
        track = object->tracks.first;
2993
 
        while (track) {
2994
 
                if (track == tracking->act_track)
2995
 
                        tracking->act_track = NULL;
2996
 
 
2997
 
                track= track->next;
2998
 
        }
2999
 
 
3000
 
        tracking_object_free(object);
3001
 
        BLI_freelinkN(&tracking->objects, object);
3002
 
 
3003
 
        tracking->tot_object--;
3004
 
 
3005
 
        if (index>0)
3006
 
                tracking->objectnr = index - 1;
3007
 
        else
3008
 
                tracking->objectnr = 0;
3009
 
}
3010
 
 
3011
 
void BKE_tracking_object_unique_name(MovieTracking *tracking, MovieTrackingObject *object)
3012
 
{
3013
 
        BLI_uniquename(&tracking->objects, object, "Object", '.', offsetof(MovieTrackingObject, name), sizeof(object->name));
3014
 
}
3015
 
 
3016
 
MovieTrackingObject *BKE_tracking_named_object(MovieTracking *tracking, const char *name)
3017
 
{
3018
 
        MovieTrackingObject *object = tracking->objects.first;
3019
 
 
3020
 
        while (object) {
3021
 
                if (!strcmp(object->name, name))
3022
 
                        return object;
3023
 
 
3024
 
                object = object->next;
3025
 
        }
3026
 
 
3027
 
        return NULL;
 
3821
        MovieTrackingReconstruction *reconstruction;
 
3822
        ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
 
3823
 
 
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;
 
3828
 
 
3829
        if (dopesheet->ok)
 
3830
                return;
 
3831
 
 
3832
        tracking_dopesheet_free(dopesheet);
 
3833
 
 
3834
        reconstruction = BKE_tracking_object_get_reconstruction(tracking, object);
 
3835
 
 
3836
        for (track = tracksbase->first; track; track = track->next) {
 
3837
                MovieTrackingDopesheetChannel *channel;
 
3838
 
 
3839
                if (!show_hidden && (track->flag & TRACK_HIDDEN) != 0)
 
3840
                        continue;
 
3841
 
 
3842
                if (sel_only && !TRACK_SELECTED(track))
 
3843
                        continue;
 
3844
 
 
3845
                channel = MEM_callocN(sizeof(MovieTrackingDopesheetChannel), "tracking dopesheet channel");
 
3846
                channel->track = track;
 
3847
 
 
3848
                if (reconstruction->flag & TRACKING_RECONSTRUCTED) {
 
3849
                        BLI_snprintf(channel->name, sizeof(channel->name), "%s (%.4f)", track->name, track->error);
 
3850
                }
 
3851
                else {
 
3852
                        BLI_strncpy(channel->name, track->name, sizeof(channel->name));
 
3853
                }
 
3854
 
 
3855
                channels_segments_calc(channel);
 
3856
 
 
3857
                BLI_addtail(&dopesheet->channels, channel);
 
3858
                dopesheet->tot_channel++;
 
3859
        }
 
3860
 
 
3861
        tracking_dopesheet_sort(tracking, sort_method, inverse);
 
3862
 
 
3863
        dopesheet->ok = TRUE;
3028
3864
}