Math Lib: rename mul_serie_m3 to mul_m3_series & reorder args
[blender-staging.git] / source / blender / editors / space_clip / clip_draw.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2011 Blender Foundation.
19  * All rights reserved.
20  *
21  *
22  * Contributor(s): Blender Foundation,
23  *                 Sergey Sharybin
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/space_clip/clip_draw.c
29  *  \ingroup spclip
30  */
31
32 #include "DNA_gpencil_types.h"
33 #include "DNA_movieclip_types.h"
34 #include "DNA_scene_types.h"
35
36 #include "MEM_guardedalloc.h"
37
38 #include "IMB_colormanagement.h"
39 #include "IMB_imbuf_types.h"
40 #include "IMB_imbuf.h"
41
42 #include "BLI_utildefines.h"
43 #include "BLI_math.h"
44 #include "BLI_string.h"
45 #include "BLI_math_base.h"
46
47 #include "BKE_context.h"
48 #include "BKE_image.h"
49 #include "BKE_movieclip.h"
50 #include "BKE_tracking.h"
51
52 #include "ED_screen.h"
53 #include "ED_clip.h"
54 #include "ED_mask.h"
55 #include "ED_gpencil.h"
56
57 #include "BIF_gl.h"
58 #include "BIF_glutil.h"
59
60 #include "WM_types.h"
61
62 #include "UI_interface.h"
63 #include "UI_resources.h"
64 #include "UI_view2d.h"
65
66 #include "RNA_access.h"
67
68 #include "BLF_api.h"
69
70 #include "clip_intern.h"    // own include
71
72 /*********************** main area drawing *************************/
73
74 static void draw_keyframe(int frame, int cfra, int sfra, float framelen, int width)
75 {
76         int height = (frame == cfra) ? 22 : 10;
77         int x = (frame - sfra) * framelen;
78
79         if (width == 1) {
80                 glBegin(GL_LINES);
81                 glVertex2i(x, 0);
82                 glVertex2i(x, height * UI_DPI_FAC);
83                 glEnd();
84         }
85         else {
86                 glRecti(x, 0, x + width, height * UI_DPI_FAC);
87         }
88 }
89
90 static int generic_track_get_markersnr(MovieTrackingTrack *track, MovieTrackingPlaneTrack *plane_track)
91 {
92         if (track) {
93                 return track->markersnr;
94         }
95         else if (plane_track) {
96                 return plane_track->markersnr;
97         }
98
99         return 0;
100 }
101
102 static int generic_track_get_marker_framenr(MovieTrackingTrack *track, MovieTrackingPlaneTrack *plane_track,
103                                             int marker_index)
104 {
105         if (track) {
106                 BLI_assert(marker_index < track->markersnr);
107                 return track->markers[marker_index].framenr;
108         }
109         else if (plane_track) {
110                 BLI_assert(marker_index < plane_track->markersnr);
111                 return plane_track->markers[marker_index].framenr;
112         }
113
114         return 0;
115 }
116
117 static bool generic_track_is_marker_enabled(MovieTrackingTrack *track, MovieTrackingPlaneTrack *plane_track,
118                                             int marker_index)
119 {
120         if (track) {
121                 BLI_assert(marker_index < track->markersnr);
122                 return (track->markers[marker_index].flag & MARKER_DISABLED) == 0;
123         }
124         else if (plane_track) {
125                 return true;
126         }
127
128         return false;
129 }
130
131 static bool generic_track_is_marker_keyframed(MovieTrackingTrack *track, MovieTrackingPlaneTrack *plane_track,
132                                               int marker_index)
133 {
134         if (track) {
135                 BLI_assert(marker_index < track->markersnr);
136                 return (track->markers[marker_index].flag & MARKER_TRACKED) == 0;
137         }
138         else if (plane_track) {
139                 BLI_assert(marker_index < plane_track->markersnr);
140                 return (plane_track->markers[marker_index].flag & PLANE_MARKER_TRACKED) == 0;
141         }
142
143         return false;
144 }
145
146 static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Scene *scene)
147 {
148         float x;
149         int *points, totseg, i, a;
150         float sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1);
151         MovieTracking *tracking = &clip->tracking;
152         MovieTrackingObject *act_object = BKE_tracking_object_get_active(tracking);
153         MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking);
154         MovieTrackingPlaneTrack *act_plane_track = BKE_tracking_plane_track_get_active(&clip->tracking);
155         MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking);
156
157         glEnable(GL_BLEND);
158         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
159
160         /* cache background */
161         ED_region_cache_draw_background(ar);
162
163         /* cached segments -- could be usefu lto debug caching strategies */
164         BKE_movieclip_get_cache_segments(clip, &sc->user, &totseg, &points);
165         ED_region_cache_draw_cached_segments(ar, totseg, points, sfra, efra);
166
167         /* track */
168         if (act_track || act_plane_track) {
169                 for (i = sfra - clip->start_frame + 1, a = 0; i <= efra - clip->start_frame + 1; i++) {
170                         int framenr;
171                         int markersnr = generic_track_get_markersnr(act_track, act_plane_track);
172
173                         while (a < markersnr) {
174                                 int marker_framenr = generic_track_get_marker_framenr(act_track, act_plane_track, a);
175
176                                 if (marker_framenr >= i)
177                                         break;
178
179                                 if (a < markersnr - 1 && generic_track_get_marker_framenr(act_track, act_plane_track, a + 1) > i)
180                                         break;
181
182                                 a++;
183                         }
184
185                         a = min_ii(a, markersnr - 1);
186
187                         if (generic_track_is_marker_enabled(act_track, act_plane_track, a)) {
188                                 framenr = generic_track_get_marker_framenr(act_track, act_plane_track, a);
189
190                                 if (framenr != i)
191                                         glColor4ub(128, 128, 0, 96);
192                                 else if (generic_track_is_marker_keyframed(act_track, act_plane_track, a))
193                                         glColor4ub(255, 255, 0, 196);
194                                 else
195                                         glColor4ub(255, 255, 0, 96);
196
197                                 glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 4 * UI_DPI_FAC);
198                         }
199                 }
200         }
201
202         /* failed frames */
203         if (reconstruction->flag & TRACKING_RECONSTRUCTED) {
204                 int n = reconstruction->camnr;
205                 MovieReconstructedCamera *cameras = reconstruction->cameras;
206
207                 glColor4ub(255, 0, 0, 96);
208
209                 for (i = sfra, a = 0; i <= efra; i++) {
210                         bool ok = false;
211
212                         while (a < n) {
213                                 if (cameras[a].framenr == i) {
214                                         ok = true;
215                                         break;
216                                 }
217                                 else if (cameras[a].framenr > i) {
218                                         break;
219                                 }
220
221                                 a++;
222                         }
223
224                         if (!ok)
225                                 glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 8 * UI_DPI_FAC);
226                 }
227         }
228
229         glDisable(GL_BLEND);
230
231         /* current frame */
232         x = (sc->user.framenr - sfra) / (efra - sfra + 1) * ar->winx;
233
234         UI_ThemeColor(TH_CFRAME);
235         glRecti(x, 0, x + ceilf(framelen), 8 * UI_DPI_FAC);
236
237         ED_region_cache_draw_curfra_label(sc->user.framenr, x, 8.0f * UI_DPI_FAC);
238
239         /* solver keyframes */
240         glColor4ub(175, 255, 0, 255);
241         draw_keyframe(act_object->keyframe1 + clip->start_frame - 1, CFRA, sfra, framelen, 2);
242         draw_keyframe(act_object->keyframe2 + clip->start_frame - 1, CFRA, sfra, framelen, 2);
243
244         /* movie clip animation */
245         if ((sc->mode == SC_MODE_MASKEDIT) && sc->mask_info.mask) {
246                 ED_mask_draw_frames(sc->mask_info.mask, ar, CFRA, sfra, efra);
247         }
248 }
249
250 static void draw_movieclip_notes(SpaceClip *sc, ARegion *ar)
251 {
252         MovieClip *clip = ED_space_clip_get_clip(sc);
253         MovieTracking *tracking = &clip->tracking;
254         char str[256] = {0};
255         bool block = false;
256
257         if (tracking->stats) {
258                 BLI_strncpy(str, tracking->stats->message, sizeof(str));
259                 block = true;
260         }
261         else {
262                 if (sc->flag & SC_LOCK_SELECTION)
263                         strcpy(str, "Locked");
264         }
265
266         if (str[0]) {
267                 float fill_color[4] = {0.0f, 0.0f, 0.0f, 0.6f};
268                 ED_region_info_draw(ar, str, block, fill_color);
269         }
270 }
271
272 static void draw_movieclip_muted(ARegion *ar, int width, int height, float zoomx, float zoomy)
273 {
274         int x, y;
275
276         /* find window pixel coordinates of origin */
277         UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y);
278
279         glColor3f(0.0f, 0.0f, 0.0f);
280         glRectf(x, y, x + zoomx * width, y + zoomy * height);
281 }
282
283 static void draw_movieclip_buffer(const bContext *C, SpaceClip *sc, ARegion *ar, ImBuf *ibuf,
284                                   int width, int height, float zoomx, float zoomy)
285 {
286         MovieClip *clip = ED_space_clip_get_clip(sc);
287         int filter = GL_LINEAR;
288         int x, y;
289
290         /* find window pixel coordinates of origin */
291         UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y);
292
293         /* checkerboard for case alpha */
294         if (ibuf->planes == 32) {
295                 glEnable(GL_BLEND);
296                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
297
298                 fdrawcheckerboard(x, y, x + zoomx * ibuf->x, y + zoomy * ibuf->y);
299         }
300
301         /* non-scaled proxy shouldn't use filtering */
302         if ((clip->flag & MCLIP_USE_PROXY) == 0 ||
303             ELEM(sc->user.render_size, MCLIP_PROXY_RENDER_SIZE_FULL, MCLIP_PROXY_RENDER_SIZE_100))
304         {
305                 filter = GL_NEAREST;
306         }
307
308         /* set zoom */
309         glPixelZoom(zoomx * width / ibuf->x, zoomy * height / ibuf->y);
310
311         glaDrawImBuf_glsl_ctx(C, ibuf, x, y, filter);
312
313         /* reset zoom */
314         glPixelZoom(1.0f, 1.0f);
315
316         if (ibuf->planes == 32)
317                 glDisable(GL_BLEND);
318 }
319
320 static void draw_stabilization_border(SpaceClip *sc, ARegion *ar, int width, int height, float zoomx, float zoomy)
321 {
322         int x, y;
323         MovieClip *clip = ED_space_clip_get_clip(sc);
324
325         /* find window pixel coordinates of origin */
326         UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y);
327
328         /* draw boundary border for frame if stabilization is enabled */
329         if (sc->flag & SC_SHOW_STABLE && clip->tracking.stabilization.flag & TRACKING_2D_STABILIZATION) {
330                 glColor3f(0.0f, 0.0f, 0.0f);
331                 glLineStipple(3, 0xaaaa);
332                 glEnable(GL_LINE_STIPPLE);
333                 glEnable(GL_COLOR_LOGIC_OP);
334                 glLogicOp(GL_NOR);
335
336                 glPushMatrix();
337                 glTranslatef(x, y, 0.0f);
338
339                 glScalef(zoomx, zoomy, 1.0f);
340                 glMultMatrixf(sc->stabmat);
341
342                 glBegin(GL_LINE_LOOP);
343                 glVertex2f(0.0f, 0.0f);
344                 glVertex2f(width, 0.0f);
345                 glVertex2f(width, height);
346                 glVertex2f(0.0f, height);
347                 glEnd();
348
349                 glPopMatrix();
350
351                 glDisable(GL_COLOR_LOGIC_OP);
352                 glDisable(GL_LINE_STIPPLE);
353         }
354 }
355
356 static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackingTrack *track)
357 {
358         int count = sc->path_length;
359         int i, a, b, curindex = -1;
360         float path[102][2];
361         int tiny = sc->flag & SC_SHOW_TINY_MARKER, framenr, start_frame;
362         MovieTrackingMarker *marker;
363
364         if (count == 0)
365                 return;
366
367         start_frame = framenr = ED_space_clip_get_clip_frame_number(sc);
368
369         marker = BKE_tracking_marker_get(track, framenr);
370         if (marker->framenr != framenr || marker->flag & MARKER_DISABLED)
371                 return;
372
373         a = count;
374         i = framenr - 1;
375         while (i >= framenr - count) {
376                 marker = BKE_tracking_marker_get(track, i);
377
378                 if (!marker || marker->flag & MARKER_DISABLED)
379                         break;
380
381                 if (marker->framenr == i) {
382                         add_v2_v2v2(path[--a], marker->pos, track->offset);
383                         ED_clip_point_undistorted_pos(sc, path[a], path[a]);
384
385                         if (marker->framenr == start_frame)
386                                 curindex = a;
387                 }
388                 else {
389                         break;
390                 }
391
392                 i--;
393         }
394
395         b = count;
396         i = framenr;
397         while (i <= framenr + count) {
398                 marker = BKE_tracking_marker_get(track, i);
399
400                 if (!marker || marker->flag & MARKER_DISABLED)
401                         break;
402
403                 if (marker->framenr == i) {
404                         if (marker->framenr == start_frame)
405                                 curindex = b;
406
407                         add_v2_v2v2(path[b++], marker->pos, track->offset);
408                         ED_clip_point_undistorted_pos(sc, path[b - 1], path[b - 1]);
409                 }
410                 else
411                         break;
412
413                 i++;
414         }
415
416         if (!tiny) {
417                 UI_ThemeColor(TH_MARKER_OUTLINE);
418
419                 if (TRACK_VIEW_SELECTED(sc, track)) {
420                         glPointSize(5.0f);
421                         glBegin(GL_POINTS);
422                         for (i = a; i < b; i++) {
423                                 if (i != curindex)
424                                         glVertex2f(path[i][0], path[i][1]);
425                         }
426                         glEnd();
427                 }
428
429                 glLineWidth(3.0f);
430                 glBegin(GL_LINE_STRIP);
431                 for (i = a; i < b; i++)
432                         glVertex2f(path[i][0], path[i][1]);
433                 glEnd();
434                 glLineWidth(1.0f);
435         }
436
437         UI_ThemeColor(TH_PATH_BEFORE);
438
439         if (TRACK_VIEW_SELECTED(sc, track)) {
440                 glPointSize(3.0f);
441                 glBegin(GL_POINTS);
442                 for (i = a; i < b; i++) {
443                         if (i == count + 1)
444                                 UI_ThemeColor(TH_PATH_AFTER);
445
446                         if (i != curindex)
447                                 glVertex2f(path[i][0], path[i][1]);
448                 }
449                 glEnd();
450         }
451
452         UI_ThemeColor(TH_PATH_BEFORE);
453
454         glBegin(GL_LINE_STRIP);
455         for (i = a; i < b; i++) {
456                 if (i == count + 1)
457                         UI_ThemeColor(TH_PATH_AFTER);
458
459                 glVertex2f(path[i][0], path[i][1]);
460         }
461         glEnd();
462         glPointSize(1.0f);
463 }
464
465 static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
466                                 const float marker_pos[2], int width, int height)
467 {
468         int tiny = sc->flag & SC_SHOW_TINY_MARKER;
469         bool show_search = false;
470         float px[2];
471
472         UI_ThemeColor(TH_MARKER_OUTLINE);
473
474         px[0] = 1.0f / width / sc->zoom;
475         px[1] = 1.0f / height / sc->zoom;
476
477         if ((marker->flag & MARKER_DISABLED) == 0) {
478                 float pos[2];
479                 float p[2];
480
481                 add_v2_v2v2(pos, marker->pos, track->offset);
482
483                 ED_clip_point_undistorted_pos(sc, pos, pos);
484
485                 sub_v2_v2v2(p, pos, marker_pos);
486
487                 if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1],
488                                         marker->pattern_corners[2], marker->pattern_corners[3]))
489                 {
490                         if (tiny) glPointSize(3.0f);
491                         else glPointSize(4.0f);
492                         glBegin(GL_POINTS);
493                         glVertex2f(pos[0], pos[1]);
494                         glEnd();
495                         glPointSize(1.0f);
496                 }
497                 else {
498                         if (!tiny) glLineWidth(3.0f);
499                         glBegin(GL_LINES);
500                         glVertex2f(pos[0] + px[0] * 2, pos[1]);
501                         glVertex2f(pos[0] + px[0] * 8, pos[1]);
502
503                         glVertex2f(pos[0] - px[0] * 2, pos[1]);
504                         glVertex2f(pos[0] - px[0] * 8, pos[1]);
505
506                         glVertex2f(pos[0], pos[1] - px[1] * 2);
507                         glVertex2f(pos[0], pos[1] - px[1] * 8);
508
509                         glVertex2f(pos[0], pos[1] + px[1] * 2);
510                         glVertex2f(pos[0], pos[1] + px[1] * 8);
511                         glEnd();
512                         if (!tiny) glLineWidth(1.0f);
513                 }
514         }
515
516         /* pattern and search outline */
517         glPushMatrix();
518         glTranslatef(marker_pos[0], marker_pos[1], 0);
519
520         if (!tiny)
521                 glLineWidth(3.0f);
522
523         if (sc->flag & SC_SHOW_MARKER_PATTERN) {
524                 glBegin(GL_LINE_LOOP);
525                 glVertex2fv(marker->pattern_corners[0]);
526                 glVertex2fv(marker->pattern_corners[1]);
527                 glVertex2fv(marker->pattern_corners[2]);
528                 glVertex2fv(marker->pattern_corners[3]);
529                 glEnd();
530         }
531
532         show_search = (TRACK_VIEW_SELECTED(sc, track) &&
533                        ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) != 0;
534         if (sc->flag & SC_SHOW_MARKER_SEARCH && show_search) {
535                 glBegin(GL_LINE_LOOP);
536                 glVertex2f(marker->search_min[0], marker->search_min[1]);
537                 glVertex2f(marker->search_max[0], marker->search_min[1]);
538                 glVertex2f(marker->search_max[0], marker->search_max[1]);
539                 glVertex2f(marker->search_min[0], marker->search_max[1]);
540                 glEnd();
541         }
542         glPopMatrix();
543
544         if (!tiny)
545                 glLineWidth(1.0f);
546 }
547
548 static void track_colors(MovieTrackingTrack *track, int act, float col[3], float scol[3])
549 {
550         if (track->flag & TRACK_CUSTOMCOLOR) {
551                 if (act)
552                         UI_GetThemeColor3fv(TH_ACT_MARKER, scol);
553                 else
554                         copy_v3_v3(scol, track->color);
555
556                 mul_v3_v3fl(col, track->color, 0.5f);
557         }
558         else {
559                 UI_GetThemeColor3fv(TH_MARKER, col);
560
561                 if (act)
562                         UI_GetThemeColor3fv(TH_ACT_MARKER, scol);
563                 else
564                         UI_GetThemeColor3fv(TH_SEL_MARKER, scol);
565         }
566 }
567
568 static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
569                               const float marker_pos[2], int width, int height, int act, int sel)
570 {
571         int tiny = sc->flag & SC_SHOW_TINY_MARKER;
572         bool show_search = false;
573         float col[3], scol[3], px[2];
574
575         track_colors(track, act, col, scol);
576
577         px[0] = 1.0f / width / sc->zoom;
578         px[1] = 1.0f / height / sc->zoom;
579
580         /* marker position and offset position */
581         if ((track->flag & SELECT) == sel && (marker->flag & MARKER_DISABLED) == 0) {
582                 float pos[2], p[2];
583
584                 if (track->flag & TRACK_LOCKED) {
585                         if (act)
586                                 UI_ThemeColor(TH_ACT_MARKER);
587                         else if (track->flag & SELECT)
588                                 UI_ThemeColorShade(TH_LOCK_MARKER, 64);
589                         else
590                                 UI_ThemeColor(TH_LOCK_MARKER);
591                 }
592                 else {
593                         if (track->flag & SELECT)
594                                 glColor3fv(scol);
595                         else
596                                 glColor3fv(col);
597                 }
598
599                 add_v2_v2v2(pos, marker->pos, track->offset);
600                 ED_clip_point_undistorted_pos(sc, pos, pos);
601
602                 sub_v2_v2v2(p, pos, marker_pos);
603
604                 if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1],
605                                         marker->pattern_corners[2], marker->pattern_corners[3]))
606                 {
607                         if (!tiny)
608                                 glPointSize(2.0f);
609
610                         glBegin(GL_POINTS);
611                         glVertex2f(pos[0], pos[1]);
612                         glEnd();
613
614                         if (!tiny)
615                                 glPointSize(1.0f);
616                 }
617                 else {
618                         glBegin(GL_LINES);
619                         glVertex2f(pos[0] + px[0] * 3, pos[1]);
620                         glVertex2f(pos[0] + px[0] * 7, pos[1]);
621
622                         glVertex2f(pos[0] - px[0] * 3, pos[1]);
623                         glVertex2f(pos[0] - px[0] * 7, pos[1]);
624
625                         glVertex2f(pos[0], pos[1] - px[1] * 3);
626                         glVertex2f(pos[0], pos[1] - px[1] * 7);
627
628                         glVertex2f(pos[0], pos[1] + px[1] * 3);
629                         glVertex2f(pos[0], pos[1] + px[1] * 7);
630                         glEnd();
631
632                         glColor3f(0.0f, 0.0f, 0.0f);
633                         glLineStipple(3, 0xaaaa);
634                         glEnable(GL_LINE_STIPPLE);
635                         glEnable(GL_COLOR_LOGIC_OP);
636                         glLogicOp(GL_NOR);
637
638                         glBegin(GL_LINES);
639                         glVertex2fv(pos);
640                         glVertex2fv(marker_pos);
641                         glEnd();
642
643                         glDisable(GL_COLOR_LOGIC_OP);
644                         glDisable(GL_LINE_STIPPLE);
645                 }
646         }
647
648         /* pattern */
649         glPushMatrix();
650         glTranslatef(marker_pos[0], marker_pos[1], 0);
651
652         if (tiny) {
653                 glLineStipple(3, 0xaaaa);
654                 glEnable(GL_LINE_STIPPLE);
655         }
656
657         if ((track->pat_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_PATTERN)) {
658                 if (track->flag & TRACK_LOCKED) {
659                         if (act)
660                                 UI_ThemeColor(TH_ACT_MARKER);
661                         else if (track->pat_flag & SELECT)
662                                 UI_ThemeColorShade(TH_LOCK_MARKER, 64);
663                         else UI_ThemeColor(TH_LOCK_MARKER);
664                 }
665                 else if (marker->flag & MARKER_DISABLED) {
666                         if (act)
667                                 UI_ThemeColor(TH_ACT_MARKER);
668                         else if (track->pat_flag & SELECT)
669                                 UI_ThemeColorShade(TH_DIS_MARKER, 128);
670                         else UI_ThemeColor(TH_DIS_MARKER);
671                 }
672                 else {
673                         if (track->pat_flag & SELECT)
674                                 glColor3fv(scol);
675                         else glColor3fv(col);
676                 }
677
678                 glBegin(GL_LINE_LOOP);
679                 glVertex2fv(marker->pattern_corners[0]);
680                 glVertex2fv(marker->pattern_corners[1]);
681                 glVertex2fv(marker->pattern_corners[2]);
682                 glVertex2fv(marker->pattern_corners[3]);
683                 glEnd();
684         }
685
686         /* search */
687         show_search = (TRACK_VIEW_SELECTED(sc, track) &&
688                        ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) != 0;
689         if ((track->search_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_SEARCH) && show_search) {
690                 if (track->flag & TRACK_LOCKED) {
691                         if (act)
692                                 UI_ThemeColor(TH_ACT_MARKER);
693                         else if (track->search_flag & SELECT)
694                                 UI_ThemeColorShade(TH_LOCK_MARKER, 64);
695                         else UI_ThemeColor(TH_LOCK_MARKER);
696                 }
697                 else if (marker->flag & MARKER_DISABLED) {
698                         if (act)
699                                 UI_ThemeColor(TH_ACT_MARKER);
700                         else if (track->search_flag & SELECT)
701                                 UI_ThemeColorShade(TH_DIS_MARKER, 128);
702                         else UI_ThemeColor(TH_DIS_MARKER);
703                 }
704                 else {
705                         if (track->search_flag & SELECT)
706                                 glColor3fv(scol);
707                         else
708                                 glColor3fv(col);
709                 }
710
711                 glBegin(GL_LINE_LOOP);
712                 glVertex2f(marker->search_min[0], marker->search_min[1]);
713                 glVertex2f(marker->search_max[0], marker->search_min[1]);
714                 glVertex2f(marker->search_max[0], marker->search_max[1]);
715                 glVertex2f(marker->search_min[0], marker->search_max[1]);
716                 glEnd();
717         }
718
719         if (tiny)
720                 glDisable(GL_LINE_STIPPLE);
721
722         glPopMatrix();
723 }
724
725 static float get_shortest_pattern_side(MovieTrackingMarker *marker)
726 {
727         int i, next;
728         float len_sq = FLT_MAX;
729
730         for (i = 0; i < 4; i++) {
731                 float cur_len;
732
733                 next = (i + 1) % 4;
734
735                 cur_len = len_squared_v2v2(marker->pattern_corners[i], marker->pattern_corners[next]);
736
737                 len_sq = min_ff(cur_len, len_sq);
738         }
739
740         return sqrtf(len_sq);
741 }
742
743 static void draw_marker_slide_square(float x, float y, float dx, float dy, int outline, float px[2])
744 {
745         float tdx, tdy;
746
747         tdx = dx;
748         tdy = dy;
749
750         if (outline) {
751                 tdx += px[0];
752                 tdy += px[1];
753         }
754
755         glBegin(GL_QUADS);
756         glVertex3f(x - tdx, y + tdy, 0.0f);
757         glVertex3f(x + tdx, y + tdy, 0.0f);
758         glVertex3f(x + tdx, y - tdy, 0.0f);
759         glVertex3f(x - tdx, y - tdy, 0.0f);
760         glEnd();
761 }
762
763 static void draw_marker_slide_triangle(float x, float y, float dx, float dy, int outline, float px[2])
764 {
765         float tdx, tdy;
766
767         tdx = dx * 2.0f;
768         tdy = dy * 2.0f;
769
770         if (outline) {
771                 tdx += px[0];
772                 tdy += px[1];
773         }
774
775         glBegin(GL_TRIANGLES);
776         glVertex3f(x,       y,       0.0f);
777         glVertex3f(x - tdx, y,       0.0f);
778         glVertex3f(x,       y + tdy, 0.0f);
779         glEnd();
780 }
781
782 static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
783                                     const float marker_pos[2], int outline, int sel, int act, int width, int height)
784 {
785         float dx, dy, patdx, patdy, searchdx, searchdy;
786         int tiny = sc->flag & SC_SHOW_TINY_MARKER;
787         float col[3], scol[3], px[2], side;
788
789         if ((tiny && outline) || (marker->flag & MARKER_DISABLED))
790                 return;
791
792         if (!TRACK_VIEW_SELECTED(sc, track) || track->flag & TRACK_LOCKED)
793                 return;
794
795         track_colors(track, act, col, scol);
796
797         if (outline) {
798                 glLineWidth(3.0f);
799                 UI_ThemeColor(TH_MARKER_OUTLINE);
800         }
801
802         glPushMatrix();
803         glTranslatef(marker_pos[0], marker_pos[1], 0);
804
805         dx = 6.0f / width / sc->zoom;
806         dy = 6.0f / height / sc->zoom;
807
808         side = get_shortest_pattern_side(marker);
809         patdx = min_ff(dx * 2.0f / 3.0f, side / 6.0f) * UI_DPI_FAC;
810         patdy = min_ff(dy * 2.0f / 3.0f, side * width / height / 6.0f) * UI_DPI_FAC;
811
812         searchdx = min_ff(dx, (marker->search_max[0] - marker->search_min[0]) / 6.0f) * UI_DPI_FAC;
813         searchdy = min_ff(dy, (marker->search_max[1] - marker->search_min[1]) / 6.0f) * UI_DPI_FAC;
814
815         px[0] = 1.0f / sc->zoom / width / sc->scale;
816         px[1] = 1.0f / sc->zoom / height / sc->scale;
817
818         if ((sc->flag & SC_SHOW_MARKER_SEARCH) && ((track->search_flag & SELECT) == sel || outline)) {
819                 if (!outline) {
820                         if (track->search_flag & SELECT)
821                                 glColor3fv(scol);
822                         else
823                                 glColor3fv(col);
824                 }
825
826                 /* search offset square */
827                 draw_marker_slide_square(marker->search_min[0], marker->search_max[1], searchdx, searchdy, outline, px);
828
829                 /* search re-sizing triangle */
830                 draw_marker_slide_triangle(marker->search_max[0], marker->search_min[1], searchdx, searchdy, outline, px);
831         }
832
833         if ((sc->flag & SC_SHOW_MARKER_PATTERN) && ((track->pat_flag & SELECT) == sel || outline)) {
834                 int i;
835                 float pat_min[2], pat_max[2];
836 /*              float dx = 12.0f / width, dy = 12.0f / height;*/ /* XXX UNUSED */
837                 float tilt_ctrl[2];
838
839                 if (!outline) {
840                         if (track->pat_flag & SELECT)
841                                 glColor3fv(scol);
842                         else
843                                 glColor3fv(col);
844                 }
845
846                 /* pattern's corners sliding squares */
847                 for (i = 0; i < 4; i++) {
848                         draw_marker_slide_square(marker->pattern_corners[i][0], marker->pattern_corners[i][1],
849                                                  patdx / 1.5f, patdy / 1.5f, outline, px);
850                 }
851
852                 /* ** sliders to control overall pattern  ** */
853                 add_v2_v2v2(tilt_ctrl, marker->pattern_corners[1], marker->pattern_corners[2]);
854
855                 BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
856
857                 glEnable(GL_LINE_STIPPLE);
858                 glLineStipple(3, 0xaaaa);
859
860 #if 0
861                 /* TODO: disable for now, needs better approach visualizing this */
862
863                 glBegin(GL_LINE_LOOP);
864                 glVertex2f(pat_min[0] - dx, pat_min[1] - dy);
865                 glVertex2f(pat_max[0] + dx, pat_min[1] - dy);
866                 glVertex2f(pat_max[0] + dx, pat_max[1] + dy);
867                 glVertex2f(pat_min[0] - dx, pat_max[1] + dy);
868                 glEnd();
869
870                 /* marker's offset slider */
871                 draw_marker_slide_square(pat_min[0] - dx, pat_max[1] + dy, patdx, patdy, outline, px);
872
873                 /* pattern re-sizing triangle */
874                 draw_marker_slide_triangle(pat_max[0] + dx, pat_min[1] - dy, patdx, patdy, outline, px);
875 #endif
876
877                 glBegin(GL_LINES);
878                 glVertex2f(0.0f, 0.0f);
879                 glVertex2fv(tilt_ctrl);
880                 glEnd();
881
882                 glDisable(GL_LINE_STIPPLE);
883
884
885                 /* slider to control pattern tilt */
886                 draw_marker_slide_square(tilt_ctrl[0], tilt_ctrl[1], patdx, patdy, outline, px);
887         }
888
889         glPopMatrix();
890
891         if (outline)
892                 glLineWidth(1.0f);
893 }
894
895 static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
896                               const float marker_pos[2], int act, int width, int height, float zoomx, float zoomy)
897 {
898         char str[128] = {0}, state[64] = {0};
899         float dx = 0.0f, dy = 0.0f, fontsize, pos[3];
900         uiStyle *style = U.uistyles.first;
901         int fontid = style->widget.uifont_id;
902
903         if (!TRACK_VIEW_SELECTED(sc, track))
904                 return;
905
906         BLF_size(fontid, 11.0f * U.pixelsize, U.dpi);
907         fontsize = BLF_height_max(fontid);
908
909         if (marker->flag & MARKER_DISABLED) {
910                 if (act)
911                         UI_ThemeColor(TH_ACT_MARKER);
912                 else
913                         UI_ThemeColorShade(TH_DIS_MARKER, 128);
914         }
915         else {
916                 if (act)
917                         UI_ThemeColor(TH_ACT_MARKER);
918                 else
919                         UI_ThemeColor(TH_SEL_MARKER);
920         }
921
922         if ((sc->flag & SC_SHOW_MARKER_SEARCH) &&
923             ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0))
924         {
925                 dx = marker->search_min[0];
926                 dy = marker->search_min[1];
927         }
928         else if (sc->flag & SC_SHOW_MARKER_PATTERN) {
929                 float pat_min[2], pat_max[2];
930
931                 BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
932                 dx = pat_min[0];
933                 dy = pat_min[1];
934         }
935
936         pos[0] = (marker_pos[0] + dx) * width;
937         pos[1] = (marker_pos[1] + dy) * height;
938         pos[2] = 0.0f;
939
940         mul_m4_v3(sc->stabmat, pos);
941
942         pos[0] = pos[0] * zoomx;
943         pos[1] = pos[1] * zoomy - fontsize;
944
945         if (marker->flag & MARKER_DISABLED)
946                 strcpy(state, "disabled");
947         else if (marker->framenr != ED_space_clip_get_clip_frame_number(sc))
948                 strcpy(state, "estimated");
949         else if (marker->flag & MARKER_TRACKED)
950                 strcpy(state, "tracked");
951         else
952                 strcpy(state, "keyframed");
953
954         if (state[0])
955                 BLI_snprintf(str, sizeof(str), "%s: %s", track->name, state);
956         else
957                 BLI_strncpy(str, track->name, sizeof(str));
958
959         BLF_position(fontid, pos[0], pos[1], 0.0f);
960         BLF_draw(fontid, str, sizeof(str));
961         pos[1] -= fontsize;
962
963         if (track->flag & TRACK_HAS_BUNDLE) {
964                 BLI_snprintf(str, sizeof(str), "Average error: %.3f", track->error);
965                 BLF_position(fontid, pos[0], pos[1], 0.0f);
966                 BLF_draw(fontid, str, sizeof(str));
967                 pos[1] -= fontsize;
968         }
969
970         if (track->flag & TRACK_LOCKED) {
971                 BLF_position(fontid, pos[0], pos[1], 0.0f);
972                 BLF_draw(fontid, "locked", 6);
973         }
974 }
975
976 static void plane_track_colors(bool is_active, float color[3], float selected_color[3])
977 {
978         UI_GetThemeColor3fv(TH_MARKER, color);
979
980         if (is_active)
981                 UI_GetThemeColor3fv(TH_ACT_MARKER, selected_color);
982         else
983                 UI_GetThemeColor3fv(TH_SEL_MARKER, selected_color);
984 }
985
986 static void getArrowEndPoint(const int width, const int height, const float zoom,
987                              const float start_corner[2], const float end_corner[2],
988                              float end_point[2])
989 {
990         float direction[2];
991         float max_length;
992
993         sub_v2_v2v2(direction, end_corner, start_corner);
994
995         direction[0] *= width;
996         direction[1] *= height;
997         max_length = normalize_v2(direction);
998         mul_v2_fl(direction, min_ff(32.0f / zoom, max_length));
999         direction[0] /= width;
1000         direction[1] /= height;
1001
1002         add_v2_v2v2(end_point, start_corner, direction);
1003 }
1004
1005 static void homogeneous_2d_to_gl_matrix(/*const*/ float matrix[3][3],
1006                                         float gl_matrix[4][4])
1007 {
1008         gl_matrix[0][0] = matrix[0][0];
1009         gl_matrix[0][1] = matrix[0][1];
1010         gl_matrix[0][2] = 0.0f;
1011         gl_matrix[0][3] = matrix[0][2];
1012
1013         gl_matrix[1][0] = matrix[1][0];
1014         gl_matrix[1][1] = matrix[1][1];
1015         gl_matrix[1][2] = 0.0f;
1016         gl_matrix[1][3] = matrix[1][2];
1017
1018         gl_matrix[2][0] = 0.0f;
1019         gl_matrix[2][1] = 0.0f;
1020         gl_matrix[2][2] = 1.0f;
1021         gl_matrix[2][3] = 0.0f;
1022
1023         gl_matrix[3][0] = matrix[2][0];
1024         gl_matrix[3][1] = matrix[2][1];
1025         gl_matrix[3][2] = 0.0f;
1026         gl_matrix[3][3] = matrix[2][2];
1027 }
1028
1029 static void draw_plane_marker_image(Scene *scene,
1030                                     MovieTrackingPlaneTrack *plane_track,
1031                                     MovieTrackingPlaneMarker *plane_marker)
1032 {
1033         Image *image = plane_track->image;
1034         ImBuf *ibuf;
1035         void *lock;
1036
1037         if (image == NULL) {
1038                 return;
1039         }
1040
1041         ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
1042
1043         if (ibuf) {
1044                 unsigned char *display_buffer;
1045                 void *cache_handle;
1046
1047                 if (image->flag & IMA_VIEW_AS_RENDER) {
1048                         display_buffer = IMB_display_buffer_acquire(ibuf,
1049                                                                     &scene->view_settings,
1050                                                                     &scene->display_settings,
1051                                                                     &cache_handle);
1052                 }
1053                 else {
1054                         display_buffer = IMB_display_buffer_acquire(ibuf, NULL,
1055                                                                     &scene->display_settings,
1056                                                                     &cache_handle);
1057                 }
1058
1059                 if (display_buffer) {
1060                         GLuint texid, last_texid;
1061                         float frame_corners[4][2] = {{0.0f, 0.0f},
1062                                                      {1.0f, 0.0f},
1063                                                      {1.0f, 1.0f},
1064                                                      {0.0f, 1.0f}};
1065                         float perspective_matrix[3][3];
1066                         float gl_matrix[4][4];
1067                         bool transparent = false;
1068                         BKE_tracking_homography_between_two_quads(frame_corners,
1069                                                                   plane_marker->corners,
1070                                                                   perspective_matrix);
1071
1072                         homogeneous_2d_to_gl_matrix(perspective_matrix, gl_matrix);
1073
1074                         if (plane_track->image_opacity != 1.0f || ibuf->planes == 32) {
1075                                 transparent = true;
1076                                 glEnable(GL_BLEND);
1077                                 glBlendFunc(GL_SRC_ALPHA,  GL_ONE_MINUS_SRC_ALPHA);
1078                         }
1079
1080                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1081                         glColor4f(1.0, 1.0, 1.0, plane_track->image_opacity);
1082
1083                         last_texid = glaGetOneInteger(GL_TEXTURE_2D);
1084                         glEnable(GL_TEXTURE_2D);
1085                         glGenTextures(1, (GLuint *)&texid);
1086
1087                         glBindTexture(GL_TEXTURE_2D, texid);
1088
1089                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1090                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1091
1092                         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, GL_RGBA,
1093                                      GL_UNSIGNED_BYTE, display_buffer);
1094
1095                         glPushMatrix();
1096                         glMultMatrixf(gl_matrix);
1097
1098                         glBegin(GL_QUADS);
1099                         glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f);
1100                         glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f, 0.0f);
1101                         glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f, 1.0f);
1102                         glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, 1.0f);
1103                         glEnd();
1104
1105                         glPopMatrix();
1106
1107                         glBindTexture(GL_TEXTURE_2D, last_texid);
1108                         glDisable(GL_TEXTURE_2D);
1109
1110                         if (transparent) {
1111                                 glDisable(GL_BLEND);
1112                         }
1113                 }
1114
1115                 IMB_display_buffer_release(cache_handle);
1116         }
1117
1118         BKE_image_release_ibuf(image, ibuf, lock);
1119 }
1120
1121 static void draw_plane_marker_ex(SpaceClip *sc, Scene *scene, MovieTrackingPlaneTrack *plane_track,
1122                                  MovieTrackingPlaneMarker *plane_marker, bool is_active_track,
1123                                  bool draw_outline, int width, int height)
1124 {
1125         bool tiny = (sc->flag & SC_SHOW_TINY_MARKER) != 0;
1126         bool is_selected_track = plane_track->flag & SELECT;
1127         bool draw_plane_quad = plane_track->image == NULL || plane_track->image_opacity == 0.0f;
1128         float px[2];
1129
1130         if (draw_outline) {
1131                 UI_ThemeColor(TH_MARKER_OUTLINE);
1132         }
1133         else {
1134                 float color[3], selected_color[3];
1135                 plane_track_colors(is_active_track, color, selected_color);
1136                 if (is_selected_track) {
1137                         glColor3fv(selected_color);
1138                 }
1139                 else {
1140                         glColor3fv(color);
1141                 }
1142         }
1143
1144         px[0] = 1.0f / width / sc->zoom;
1145         px[1] = 1.0f / height / sc->zoom;
1146
1147         /* Draw image */
1148         if (draw_outline == false) {
1149                 draw_plane_marker_image(scene, plane_track, plane_marker);
1150         }
1151
1152         if (draw_outline) {
1153                 if (!tiny) {
1154                         glLineWidth(3.0f);
1155                 }
1156         }
1157         else if (tiny) {
1158                 glLineStipple(3, 0xaaaa);
1159                 glEnable(GL_LINE_STIPPLE);
1160         }
1161
1162         if (draw_plane_quad) {
1163                 /* Draw rectangle itself. */
1164                 glBegin(GL_LINE_LOOP);
1165                 glVertex2fv(plane_marker->corners[0]);
1166                 glVertex2fv(plane_marker->corners[1]);
1167                 glVertex2fv(plane_marker->corners[2]);
1168                 glVertex2fv(plane_marker->corners[3]);
1169                 glEnd();
1170
1171                 /* Draw axis. */
1172                 if (!draw_outline) {
1173                         float end_point[2];
1174                         glPushAttrib(GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT);
1175
1176                         getArrowEndPoint(width, height, sc->zoom, plane_marker->corners[0], plane_marker->corners[1], end_point);
1177                         glColor3f(1.0, 0.0, 0.0f);
1178                         glBegin(GL_LINES);
1179                         glVertex2fv(plane_marker->corners[0]);
1180                         glVertex2fv(end_point);
1181                         glEnd();
1182
1183                         getArrowEndPoint(width, height, sc->zoom, plane_marker->corners[0], plane_marker->corners[3], end_point);
1184                         glColor3f(0.0, 1.0, 0.0f);
1185                         glBegin(GL_LINES);
1186                         glVertex2fv(plane_marker->corners[0]);
1187                         glVertex2fv(end_point);
1188                         glEnd();
1189
1190                         glPopAttrib();
1191                 }
1192         }
1193
1194         /* Draw sliders. */
1195         if (is_selected_track) {
1196                 int i;
1197                 for (i = 0; i < 4; i++) {
1198                         draw_marker_slide_square(plane_marker->corners[i][0], plane_marker->corners[i][1],
1199                                                  3.0f * px[0], 3.0f * px[1], draw_outline, px);
1200                 }
1201         }
1202
1203         if (draw_outline) {
1204                 if (!tiny) {
1205                         glLineWidth(1.0f);
1206                 }
1207         }
1208         else if (tiny) {
1209                 glDisable(GL_LINE_STIPPLE);
1210         }
1211 }
1212
1213 static void draw_plane_marker_outline(SpaceClip *sc, Scene *scene, MovieTrackingPlaneTrack *plane_track,
1214                                       MovieTrackingPlaneMarker *plane_marker, int width, int height)
1215 {
1216         draw_plane_marker_ex(sc, scene, plane_track, plane_marker, false, true, width, height);
1217 }
1218
1219 static void draw_plane_marker(SpaceClip *sc, Scene *scene, MovieTrackingPlaneTrack *plane_track,
1220                               MovieTrackingPlaneMarker *plane_marker, bool is_active_track,
1221                               int width, int height)
1222 {
1223         draw_plane_marker_ex(sc, scene, plane_track, plane_marker, is_active_track, false, width, height);
1224 }
1225
1226 static void draw_plane_track(SpaceClip *sc, Scene *scene, MovieTrackingPlaneTrack *plane_track,
1227                              int framenr, bool is_active_track, int width, int height)
1228 {
1229         MovieTrackingPlaneMarker *plane_marker;
1230
1231         plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);
1232
1233         draw_plane_marker_outline(sc, scene, plane_track, plane_marker, width, height);
1234         draw_plane_marker(sc, scene, plane_track, plane_marker, is_active_track, width, height);
1235 }
1236
1237 /* Draw all kind of tracks. */
1238 static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, MovieClip *clip,
1239                                  int width, int height, float zoomx, float zoomy)
1240 {
1241         float x, y;
1242         MovieTracking *tracking = &clip->tracking;
1243         ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
1244         ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
1245         MovieTrackingTrack *track, *act_track;
1246         MovieTrackingPlaneTrack *plane_track, *active_plane_track;
1247         MovieTrackingMarker *marker;
1248         int framenr = ED_space_clip_get_clip_frame_number(sc);
1249         int undistort = sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT;
1250         float *marker_pos = NULL, *fp, *active_pos = NULL, cur_pos[2];
1251
1252         /* ** find window pixel coordinates of origin ** */
1253
1254         /* UI_view2d_view_to_region_no_clip return integer values, this could
1255          * lead to 1px flickering when view is locked to selection during playbeck.
1256          * to avoid this flickering, calculate base point in the same way as it happens
1257          * in UI_view2d_view_to_region_no_clip, but do it in floats here */
1258
1259         UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y);
1260
1261         glPushMatrix();
1262         glTranslatef(x, y, 0);
1263
1264         glPushMatrix();
1265         glScalef(zoomx, zoomy, 0);
1266         glMultMatrixf(sc->stabmat);
1267         glScalef(width, height, 0);
1268
1269         act_track = BKE_tracking_track_get_active(tracking);
1270
1271         /* Draw plane tracks */
1272         active_plane_track = BKE_tracking_plane_track_get_active(tracking);
1273         for (plane_track = plane_tracks_base->first;
1274              plane_track;
1275              plane_track = plane_track->next)
1276         {
1277                 if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) {
1278                         draw_plane_track(sc, scene, plane_track, framenr, plane_track == active_plane_track, width, height);
1279                 }
1280         }
1281
1282         if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
1283                 int count = 0;
1284
1285                 /* count */
1286                 track = tracksbase->first;
1287                 while (track) {
1288                         if ((track->flag & TRACK_HIDDEN) == 0) {
1289                                 marker = BKE_tracking_marker_get(track, framenr);
1290
1291                                 if (MARKER_VISIBLE(sc, track, marker))
1292                                         count++;
1293                         }
1294
1295                         track = track->next;
1296                 }
1297
1298                 /* undistort */
1299                 if (count) {
1300                         marker_pos = MEM_callocN(2 * sizeof(float) * count, "draw_tracking_tracks marker_pos");
1301
1302                         track = tracksbase->first;
1303                         fp = marker_pos;
1304                         while (track) {
1305                                 if ((track->flag & TRACK_HIDDEN) == 0) {
1306                                         marker = BKE_tracking_marker_get(track, framenr);
1307
1308                                         if (MARKER_VISIBLE(sc, track, marker)) {
1309                                                 ED_clip_point_undistorted_pos(sc, marker->pos, fp);
1310
1311                                                 if (track == act_track)
1312                                                         active_pos = fp;
1313
1314                                                 fp += 2;
1315                                         }
1316                                 }
1317
1318                                 track = track->next;
1319                         }
1320                 }
1321         }
1322
1323         if (sc->flag & SC_SHOW_TRACK_PATH) {
1324                 track = tracksbase->first;
1325                 while (track) {
1326                         if ((track->flag & TRACK_HIDDEN) == 0)
1327                                 draw_track_path(sc, clip, track);
1328
1329                         track = track->next;
1330                 }
1331         }
1332
1333         /* markers outline and non-selected areas */
1334         track = tracksbase->first;
1335         fp = marker_pos;
1336         while (track) {
1337                 if ((track->flag & TRACK_HIDDEN) == 0) {
1338                         marker = BKE_tracking_marker_get(track, framenr);
1339
1340                         if (MARKER_VISIBLE(sc, track, marker)) {
1341                                 copy_v2_v2(cur_pos, fp ? fp : marker->pos);
1342
1343                                 draw_marker_outline(sc, track, marker, cur_pos, width, height);
1344                                 draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 0);
1345                                 draw_marker_slide_zones(sc, track, marker, cur_pos, 1, 0, 0, width, height);
1346                                 draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 0, 0, width, height);
1347
1348                                 if (fp)
1349                                         fp += 2;
1350                         }
1351                 }
1352
1353                 track = track->next;
1354         }
1355
1356         /* selected areas only, so selection wouldn't be overlapped by
1357          * non-selected areas */
1358         track = tracksbase->first;
1359         fp = marker_pos;
1360         while (track) {
1361                 if ((track->flag & TRACK_HIDDEN) == 0) {
1362                         int act = track == act_track;
1363                         marker = BKE_tracking_marker_get(track, framenr);
1364
1365                         if (MARKER_VISIBLE(sc, track, marker)) {
1366                                 if (!act) {
1367                                         copy_v2_v2(cur_pos, fp ? fp : marker->pos);
1368
1369                                         draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 1);
1370                                         draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 1, 0, width, height);
1371                                 }
1372
1373                                 if (fp)
1374                                         fp += 2;
1375                         }
1376                 }
1377
1378                 track = track->next;
1379         }
1380
1381         /* active marker would be displayed on top of everything else */
1382         if (act_track) {
1383                 if ((act_track->flag & TRACK_HIDDEN) == 0) {
1384                         marker = BKE_tracking_marker_get(act_track, framenr);
1385
1386                         if (MARKER_VISIBLE(sc, act_track, marker)) {
1387                                 copy_v2_v2(cur_pos, active_pos ? active_pos : marker->pos);
1388
1389                                 draw_marker_areas(sc, act_track, marker, cur_pos, width, height, 1, 1);
1390                                 draw_marker_slide_zones(sc, act_track, marker, cur_pos, 0, 1, 1, width, height);
1391                         }
1392                 }
1393         }
1394
1395         if (sc->flag & SC_SHOW_BUNDLES) {
1396                 MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
1397                 float pos[4], vec[4], mat[4][4], aspy;
1398
1399                 glEnable(GL_POINT_SMOOTH);
1400                 glPointSize(3.0f);
1401
1402                 aspy = 1.0f / clip->tracking.camera.pixel_aspect;
1403                 BKE_tracking_get_projection_matrix(tracking, object, framenr, width, height, mat);
1404
1405                 track = tracksbase->first;
1406                 while (track) {
1407                         if ((track->flag & TRACK_HIDDEN) == 0 && track->flag & TRACK_HAS_BUNDLE) {
1408                                 marker = BKE_tracking_marker_get(track, framenr);
1409
1410                                 if (MARKER_VISIBLE(sc, track, marker)) {
1411                                         float npos[2];
1412                                         copy_v3_v3(vec, track->bundle_pos);
1413                                         vec[3] = 1;
1414
1415                                         mul_v4_m4v4(pos, mat, vec);
1416
1417                                         pos[0] = (pos[0] / (pos[3] * 2.0f) + 0.5f) * width;
1418                                         pos[1] = (pos[1] / (pos[3] * 2.0f) + 0.5f) * height * aspy;
1419
1420                                         BKE_tracking_distort_v2(tracking, pos, npos);
1421
1422                                         if (npos[0] >= 0.0f && npos[1] >= 0.0f && npos[0] <= width && npos[1] <= height * aspy) {
1423                                                 vec[0] = (marker->pos[0] + track->offset[0]) * width;
1424                                                 vec[1] = (marker->pos[1] + track->offset[1]) * height * aspy;
1425
1426                                                 sub_v2_v2(vec, npos);
1427
1428                                                 if (len_squared_v2(vec) < (3.0f * 3.0f))
1429                                                         glColor3f(0.0f, 1.0f, 0.0f);
1430                                                 else
1431                                                         glColor3f(1.0f, 0.0f, 0.0f);
1432
1433                                                 glBegin(GL_POINTS);
1434                                                 if (undistort)
1435                                                         glVertex3f(pos[0] / width, pos[1] / (height * aspy), 0);
1436                                                 else
1437                                                         glVertex3f(npos[0] / width, npos[1] / (height * aspy), 0);
1438                                                 glEnd();
1439                                         }
1440                                 }
1441                         }
1442
1443                         track = track->next;
1444                 }
1445
1446                 glPointSize(1.0f);
1447                 glDisable(GL_POINT_SMOOTH);
1448         }
1449
1450         glPopMatrix();
1451
1452         if (sc->flag & SC_SHOW_NAMES) {
1453                 /* scaling should be cleared before drawing texts, otherwise font would also be scaled */
1454                 track = tracksbase->first;
1455                 fp = marker_pos;
1456                 while (track) {
1457                         if ((track->flag & TRACK_HIDDEN) == 0) {
1458                                 marker = BKE_tracking_marker_get(track, framenr);
1459
1460                                 if (MARKER_VISIBLE(sc, track, marker)) {
1461                                         int act = track == act_track;
1462
1463                                         copy_v2_v2(cur_pos, fp ? fp : marker->pos);
1464
1465                                         draw_marker_texts(sc, track, marker, cur_pos, act, width, height, zoomx, zoomy);
1466
1467                                         if (fp)
1468                                                 fp += 2;
1469                                 }
1470                         }
1471
1472                         track = track->next;
1473                 }
1474         }
1475
1476         glPopMatrix();
1477
1478         if (marker_pos)
1479                 MEM_freeN(marker_pos);
1480 }
1481
1482 static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
1483                             int width, int height, float zoomx, float zoomy)
1484 {
1485         float x, y;
1486         const int n = 10;
1487         int i, j, a;
1488         float pos[2], tpos[2], grid[11][11][2];
1489         MovieTracking *tracking = &clip->tracking;
1490         bGPdata *gpd = NULL;
1491         float aspy = 1.0f / tracking->camera.pixel_aspect;
1492         float dx = (float)width / n, dy = (float)height / n * aspy;
1493         float offsx = 0.0f, offsy = 0.0f;
1494
1495         if (!tracking->camera.focal)
1496                 return;
1497
1498         if ((sc->flag & SC_SHOW_GRID) == 0 && (sc->flag & SC_MANUAL_CALIBRATION) == 0)
1499                 return;
1500
1501         UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y);
1502
1503         glPushMatrix();
1504         glTranslatef(x, y, 0);
1505         glScalef(zoomx, zoomy, 0);
1506         glMultMatrixf(sc->stabmat);
1507         glScalef(width, height, 0);
1508
1509         /* grid */
1510         if (sc->flag & SC_SHOW_GRID) {
1511                 float val[4][2], idx[4][2];
1512                 float min[2], max[2];
1513
1514                 for (a = 0; a < 4; a++) {
1515                         if (a < 2)
1516                                 val[a][a % 2] = FLT_MAX;
1517                         else
1518                                 val[a][a % 2] = -FLT_MAX;
1519                 }
1520
1521                 zero_v2(pos);
1522                 for (i = 0; i <= n; i++) {
1523                         for (j = 0; j <= n; j++) {
1524                                 if (i == 0 || j == 0 || i == n || j == n) {
1525                                         BKE_tracking_distort_v2(tracking, pos, tpos);
1526
1527                                         for (a = 0; a < 4; a++) {
1528                                                 int ok;
1529
1530                                                 if (a < 2)
1531                                                         ok = tpos[a % 2] < val[a][a % 2];
1532                                                 else
1533                                                         ok = tpos[a % 2] > val[a][a % 2];
1534
1535                                                 if (ok) {
1536                                                         copy_v2_v2(val[a], tpos);
1537                                                         idx[a][0] = j;
1538                                                         idx[a][1] = i;
1539                                                 }
1540                                         }
1541                                 }
1542
1543                                 pos[0] += dx;
1544                         }
1545
1546                         pos[0] = 0.0f;
1547                         pos[1] += dy;
1548                 }
1549
1550                 INIT_MINMAX2(min, max);
1551
1552                 for (a = 0; a < 4; a++) {
1553                         pos[0] = idx[a][0] * dx;
1554                         pos[1] = idx[a][1] * dy;
1555
1556                         BKE_tracking_undistort_v2(tracking, pos, tpos);
1557
1558                         minmax_v2v2_v2(min, max, tpos);
1559                 }
1560
1561                 copy_v2_v2(pos, min);
1562                 dx = (max[0] - min[0]) / n;
1563                 dy = (max[1] - min[1]) / n;
1564
1565                 for (i = 0; i <= n; i++) {
1566                         for (j = 0; j <= n; j++) {
1567                                 BKE_tracking_distort_v2(tracking, pos, grid[i][j]);
1568
1569                                 grid[i][j][0] /= width;
1570                                 grid[i][j][1] /= height * aspy;
1571
1572                                 pos[0] += dx;
1573                         }
1574
1575                         pos[0] = min[0];
1576                         pos[1] += dy;
1577                 }
1578
1579                 glColor3f(1.0f, 0.0f, 0.0f);
1580
1581                 for (i = 0; i <= n; i++) {
1582                         glBegin(GL_LINE_STRIP);
1583                         for (j = 0; j <= n; j++) {
1584                                 glVertex2fv(grid[i][j]);
1585                         }
1586                         glEnd();
1587                 }
1588
1589                 for (j = 0; j <= n; j++) {
1590                         glBegin(GL_LINE_STRIP);
1591                         for (i = 0; i <= n; i++) {
1592                                 glVertex2fv(grid[i][j]);
1593                         }
1594                         glEnd();
1595                 }
1596         }
1597
1598         if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
1599                 MovieTrackingTrack *track = BKE_tracking_track_get_active(&sc->clip->tracking);
1600
1601                 if (track) {
1602                         int framenr = ED_space_clip_get_clip_frame_number(sc);
1603                         MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
1604
1605                         offsx = marker->pos[0];
1606                         offsy = marker->pos[1];
1607
1608                         gpd = track->gpd;
1609                 }
1610
1611         }
1612         else {
1613                 gpd = clip->gpd;
1614         }
1615
1616         if (sc->flag & SC_MANUAL_CALIBRATION && gpd) {
1617                 bGPDlayer *layer = gpd->layers.first;
1618
1619                 while (layer) {
1620                         bGPDframe *frame = layer->frames.first;
1621
1622                         if (layer->flag & GP_LAYER_HIDE) {
1623                                 layer = layer->next;
1624                                 continue;
1625                         }
1626
1627                         glColor4fv(layer->color);
1628                         glLineWidth(layer->thickness);
1629                         glPointSize((float)(layer->thickness + 2));
1630
1631                         while (frame) {
1632                                 bGPDstroke *stroke = frame->strokes.first;
1633
1634                                 while (stroke) {
1635                                         if (stroke->flag & GP_STROKE_2DSPACE) {
1636                                                 if (stroke->totpoints > 1) {
1637                                                         glBegin(GL_LINE_STRIP);
1638                                                         for (i = 0; i < stroke->totpoints - 1; i++) {
1639                                                                 float npos[2], dpos[2], len;
1640                                                                 int steps;
1641
1642                                                                 pos[0] = (stroke->points[i].x + offsx) * width;
1643                                                                 pos[1] = (stroke->points[i].y + offsy) * height * aspy;
1644
1645                                                                 npos[0] = (stroke->points[i + 1].x + offsx) * width;
1646                                                                 npos[1] = (stroke->points[i + 1].y + offsy) * height * aspy;
1647
1648                                                                 len = len_v2v2(pos, npos);
1649                                                                 steps = ceil(len / 5.0f);
1650
1651                                                                 /* we want to distort only long straight lines */
1652                                                                 if (stroke->totpoints == 2) {
1653                                                                         BKE_tracking_undistort_v2(tracking, pos, pos);
1654                                                                         BKE_tracking_undistort_v2(tracking, npos, npos);
1655                                                                 }
1656
1657                                                                 sub_v2_v2v2(dpos, npos, pos);
1658                                                                 mul_v2_fl(dpos, 1.0f / steps);
1659
1660                                                                 for (j = 0; j <= steps; j++) {
1661                                                                         BKE_tracking_distort_v2(tracking, pos, tpos);
1662                                                                         glVertex2f(tpos[0] / width, tpos[1] / (height * aspy));
1663
1664                                                                         add_v2_v2(pos, dpos);
1665                                                                 }
1666                                                         }
1667                                                         glEnd();
1668                                                 }
1669                                                 else if (stroke->totpoints == 1) {
1670                                                         glBegin(GL_POINTS);
1671                                                         glVertex2f(stroke->points[0].x + offsx, stroke->points[0].y + offsy);
1672                                                         glEnd();
1673                                                 }
1674                                         }
1675
1676                                         stroke = stroke->next;
1677                                 }
1678
1679                                 frame = frame->next;
1680                         }
1681
1682                         layer = layer->next;
1683                 }
1684
1685                 glLineWidth(1.0f);
1686                 glPointSize(1.0f);
1687         }
1688
1689         glPopMatrix();
1690 }
1691
1692 void clip_draw_main(const bContext *C, SpaceClip *sc, ARegion *ar)
1693 {
1694         MovieClip *clip = ED_space_clip_get_clip(sc);
1695         Scene *scene = CTX_data_scene(C);
1696         ImBuf *ibuf = NULL;
1697         int width, height;
1698         float zoomx, zoomy;
1699
1700         ED_space_clip_get_size(sc, &width, &height);
1701         ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy);
1702
1703         /* if no clip, nothing to do */
1704         if (!clip) {
1705                 ED_region_grid_draw(ar, zoomx, zoomy);
1706                 return;
1707         }
1708
1709         if (sc->flag & SC_SHOW_STABLE) {
1710                 float smat[4][4], ismat[4][4];
1711
1712                 ibuf = ED_space_clip_get_stable_buffer(sc, sc->loc, &sc->scale, &sc->angle);
1713
1714                 if (ibuf) {
1715                         float translation[2];
1716                         float aspect = clip->tracking.camera.pixel_aspect;
1717
1718                         if (width != ibuf->x)
1719                                 mul_v2_v2fl(translation, sc->loc, (float)width / ibuf->x);
1720                         else
1721                                 copy_v2_v2(translation, sc->loc);
1722
1723                         BKE_tracking_stabilization_data_to_mat4(width, height, aspect,
1724                                                                 translation, sc->scale, sc->angle, sc->stabmat);
1725
1726                         unit_m4(smat);
1727                         smat[0][0] = 1.0f / width;
1728                         smat[1][1] = 1.0f / height;
1729                         invert_m4_m4(ismat, smat);
1730
1731                         mul_m4_series(sc->unistabmat, smat, sc->stabmat, ismat);
1732                 }
1733         }
1734         else if ((sc->flag & SC_MUTE_FOOTAGE) == 0) {
1735                 ibuf = ED_space_clip_get_buffer(sc);
1736
1737                 zero_v2(sc->loc);
1738                 sc->scale = 1.0f;
1739                 unit_m4(sc->stabmat);
1740                 unit_m4(sc->unistabmat);
1741         }
1742
1743         if (ibuf) {
1744                 draw_movieclip_buffer(C, sc, ar, ibuf, width, height, zoomx, zoomy);
1745                 IMB_freeImBuf(ibuf);
1746         }
1747         else if (sc->flag & SC_MUTE_FOOTAGE) {
1748                 draw_movieclip_muted(ar, width, height, zoomx, zoomy);
1749         }
1750         else {
1751                 ED_region_grid_draw(ar, zoomx, zoomy);
1752         }
1753
1754         if (width && height) {
1755                 draw_stabilization_border(sc, ar, width, height, zoomx, zoomy);
1756                 draw_tracking_tracks(sc, scene, ar, clip, width, height, zoomx, zoomy);
1757                 draw_distortion(sc, ar, clip, width, height, zoomx, zoomy);
1758         }
1759 }
1760
1761 void clip_draw_cache_and_notes(const bContext *C, SpaceClip *sc, ARegion *ar)
1762 {
1763         Scene *scene = CTX_data_scene(C);
1764         MovieClip *clip = ED_space_clip_get_clip(sc);
1765         if (clip) {
1766                 draw_movieclip_cache(sc, ar, clip, scene);
1767                 draw_movieclip_notes(sc, ar);
1768         }
1769 }
1770
1771 /* draw grease pencil */
1772 void clip_draw_grease_pencil(bContext *C, int onlyv2d)
1773 {
1774         SpaceClip *sc = CTX_wm_space_clip(C);
1775         MovieClip *clip = ED_space_clip_get_clip(sc);
1776
1777         if (!clip)
1778                 return;
1779
1780         if (onlyv2d) {
1781                 /* if manual calibration is used then grease pencil data is already
1782                  * drawn in draw_distortion */
1783                 if ((sc->flag & SC_MANUAL_CALIBRATION) == 0) {
1784                         glPushMatrix();
1785                         glMultMatrixf(sc->unistabmat);
1786
1787                         if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
1788                                 MovieTrackingTrack *track = BKE_tracking_track_get_active(&sc->clip->tracking);
1789
1790                                 if (track) {
1791                                         int framenr = ED_space_clip_get_clip_frame_number(sc);
1792                                         MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
1793
1794                                         glTranslatef(marker->pos[0], marker->pos[1], 0.0f);
1795                                 }
1796                         }
1797
1798                         ED_gpencil_draw_2dimage(C);
1799
1800                         glPopMatrix();
1801                 }
1802         }
1803         else {
1804                 ED_gpencil_draw_view2d(C, 0);
1805         }
1806 }