Camera tracking integration
[blender.git] / source / blender / editors / space_clip / clip_draw.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2011 Blender Foundation.
21  * All rights reserved.
22  *
23  *
24  * Contributor(s): Blender Foundation,
25  *                 Sergey Sharybin
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 /** \file blender/editors/space_clip/clip_draw.c
31  *  \ingroup spclip
32  */
33
34 #include "DNA_movieclip_types.h"
35 #include "DNA_scene_types.h"
36 #include "DNA_object_types.h"   /* SELECT */
37
38 #include "MEM_guardedalloc.h"
39
40 #include "BKE_context.h"
41 #include "BKE_movieclip.h"
42 #include "BKE_tracking.h"
43
44 #include "IMB_imbuf_types.h"
45 #include "IMB_imbuf.h"
46
47 #include "BLI_utildefines.h"
48 #include "BLI_math.h"
49 #include "BLI_string.h"
50 #include "BLI_rect.h"
51
52 #include "ED_screen.h"
53 #include "ED_clip.h"
54
55 #include "BIF_gl.h"
56 #include "BIF_glutil.h"
57
58 #include "WM_api.h"
59 #include "WM_types.h"
60
61 #include "UI_interface.h"
62 #include "UI_resources.h"
63 #include "UI_view2d.h"
64
65 #include "RNA_access.h"
66
67 #include "clip_intern.h"        // own include
68
69 /*********************** main area drawing *************************/
70
71 static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Scene *scene)
72 {
73         float x;
74         int *points, totseg, sel_type, i, a;
75         float sfra= SFRA, efra= EFRA;
76         void *sel;
77         float framelen= ar->winx/(efra-sfra+1);
78
79         BKE_movieclip_last_selection(clip, &sel_type, &sel);
80
81         glEnable(GL_BLEND);
82
83         /* cache background */
84         glColor4ub(128, 128, 255, 64);
85         glRecti(0, 0, ar->winx, 8);
86
87         /* cached segments -- could be usefu lto debug caching strategies */
88         BKE_movieclip_get_cache_segments(clip, &totseg, &points);
89         if(totseg) {
90                 glColor4ub(128, 128, 255, 128);
91
92                 for(a= 0; a<totseg; a++) {
93                         float x1, x2;
94
95                         x1= (points[a*2]-sfra)/(efra-sfra+1)*ar->winx;
96                         x2= (points[a*2+1]-sfra+1)/(efra-sfra+1)*ar->winx;
97
98                         glRecti(x1, 0, x2, 8);
99                 }
100         }
101
102         /* track */
103         if(sel_type==MCLIP_SEL_TRACK) {
104                 MovieTrackingTrack *track= (MovieTrackingTrack *)sel;
105
106                 for(i= sfra, a= 0; i <= efra; i++) {
107                         int framenr;
108                         MovieTrackingMarker *marker;
109
110                         while(a<track->markersnr) {
111                                 if(track->markers[a].framenr>=i)
112                                         break;
113
114                                 if(a<track->markersnr-1 && track->markers[a+1].framenr>i)
115                                         break;
116
117                                 a++;
118                         }
119
120                         if(a<track->markersnr) marker= &track->markers[a];
121                         else marker= &track->markers[track->markersnr-1];
122
123                         if((marker->flag&MARKER_DISABLED)==0) {
124                                 framenr= marker->framenr;
125
126                                 if(framenr!=i) glColor4ub(128, 128, 0, 96);
127                                 else glColor4ub(255, 255, 0, 96);
128
129                                 glRecti((i-sfra)*framelen, 0, (i-sfra+1)*framelen, 4);
130                         }
131                 }
132         }
133
134         /* failed frames */
135         if(clip->tracking.reconstruction.flag&TRACKING_RECONSTRUCTED) {
136                 int n= clip->tracking.reconstruction.camnr;
137                 MovieReconstructedCamera *cameras= clip->tracking.reconstruction.cameras;
138
139                 glColor4ub(255, 0, 0, 96);
140
141                 for(i= sfra, a= 0; i <= efra; i++) {
142                         int ok= 0;
143
144                         while(a<n) {
145                                 if(cameras[a].framenr==i) {
146                                         ok= 1;
147                                         break;
148                                 }
149                                 else if(cameras[a].framenr>i) {
150                                         break;
151                                 }
152
153                                 a++;
154                         }
155
156                         if(!ok)
157                                 glRecti((i-sfra)*framelen, 0, (i-sfra+1)*framelen, 8);
158                 }
159         }
160
161         glDisable(GL_BLEND);
162
163         /* current frame */
164         x= (sc->user.framenr-sfra)/(efra-sfra+1)*ar->winx;
165
166         UI_ThemeColor(TH_CFRAME);
167         glRecti(x, 0, x+framelen, 8);
168 }
169
170 static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf, float zoomx, float zoomy)
171 {
172         int x, y;
173
174         /* set zoom */
175         glPixelZoom(zoomx, zoomy);
176
177         /* find window pixel coordinates of origin */
178         UI_view2d_to_region_no_clip(&ar->v2d, 0.f, 0.f, &x, &y);
179
180         if(sc->flag&SC_MUTE_FOOTAGE) {
181                 glColor3f(0.0f, 0.0f, 0.0f);
182                 glRectf(x, y, x+ibuf->x*sc->zoom, y+ibuf->y*sc->zoom);
183         } else {
184                 if(ibuf->rect_float && !ibuf->rect) {
185                         IMB_rect_from_float(ibuf);
186                 }
187
188                 if(ibuf->rect) {
189                         MovieClip *clip= ED_space_clip(sc);
190
191                         glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
192
193                         /* draw boundary border for frame if stabilization is enabled */
194                         if(sc->flag&SC_SHOW_STABLE && clip->tracking.stabilization.flag&TRACKING_2D_STABILIZATION) {
195                                 glColor3f(0.f, 0.f, 0.f);
196                                 glLineStipple(3, 0xaaaa);
197                                 glEnable(GL_LINE_STIPPLE);
198                                 glEnable(GL_COLOR_LOGIC_OP);
199                                 glLogicOp(GL_NOR);
200
201                                 glPushMatrix();
202                                 glTranslatef(x, y, 0);
203
204                                 glScalef(zoomx, zoomy, 0);
205                                 glMultMatrixf(sc->stabmat);
206
207                                 glBegin(GL_LINE_LOOP);
208                                         glVertex2f(0.f, 0.f);
209                                         glVertex2f(ibuf->x, 0.f);
210                                         glVertex2f(ibuf->x, ibuf->y);
211                                         glVertex2f(0.f, ibuf->y);
212                                 glEnd();
213
214                                 glPopMatrix();
215
216                                 glDisable(GL_COLOR_LOGIC_OP);
217                                 glDisable(GL_LINE_STIPPLE);
218                         }
219                 }
220         }
221
222         /* reset zoom */
223         glPixelZoom(1.f, 1.f);
224 }
225
226 static void draw_track_path(SpaceClip *sc, MovieClip *clip, MovieTrackingTrack *track)
227 {
228         int count= sc->path_length;
229         int i, a, b, sel_type, curindex= -1;
230         float path[102][2];
231         int tiny= sc->flag&SC_SHOW_TINY_MARKER, framenr;
232         MovieTrackingMarker *marker;
233         void *sel;
234
235         if(count==0)
236                 return;
237
238         BKE_movieclip_last_selection(clip, &sel_type, &sel);
239
240         marker= BKE_tracking_get_marker(track, sc->user.framenr);
241         if(marker->framenr!=sc->user.framenr || marker->flag&MARKER_DISABLED)
242                 return;
243
244         framenr= marker->framenr;
245
246         a= count;
247         i= framenr-1;
248         while(i>=framenr-count) {
249                 marker= BKE_tracking_get_marker(track, i);
250
251                 if(!marker || marker->flag&MARKER_DISABLED)
252                         break;
253
254                 if(marker->framenr==i) {
255                         add_v2_v2v2(path[--a], marker->pos, track->offset);
256
257                         if(marker->framenr==sc->user.framenr)
258                                 curindex= a;
259                 } else
260                         break;
261
262                 i--;
263         }
264
265         b= count;
266         i= framenr;
267         while(i<=framenr+count) {
268                 marker= BKE_tracking_get_marker(track, i);
269
270                 if(!marker || marker->flag&MARKER_DISABLED)
271                         break;
272
273                 if(marker->framenr==i) {
274                         if(marker->framenr==sc->user.framenr)
275                                 curindex= b;
276
277                         add_v2_v2v2(path[b++], marker->pos, track->offset);
278                 } else
279                         break;
280
281                 i++;
282         }
283
284         if(!tiny) {
285                 UI_ThemeColor(TH_MARKER_OUTLINE);
286
287                 if(TRACK_SELECTED(track)) {
288                         glPointSize(5.0f);
289                         glBegin(GL_POINTS);
290                                 for(i= a; i<b; i++) {
291                                         if(i!=curindex)
292                                                 glVertex2f(path[i][0], path[i][1]);
293                                 }
294                         glEnd();
295                 }
296
297                 glLineWidth(3.0f);
298                 glBegin(GL_LINE_STRIP);
299                         for(i= a; i<b; i++)
300                                 glVertex2f(path[i][0], path[i][1]);
301                 glEnd();
302                 glLineWidth(1.0f);
303         }
304
305         UI_ThemeColor(TH_PATH_BEFORE);
306
307         if(TRACK_SELECTED(track)) {
308                 glPointSize(3.0f);
309                 glBegin(GL_POINTS);
310                         for(i= a; i<b; i++) {
311                                 if(i==count+1)
312                                         UI_ThemeColor(TH_PATH_AFTER);
313
314                                 if(i!=curindex)
315                                         glVertex2f(path[i][0], path[i][1]);
316                         }
317                 glEnd();
318         }
319
320         UI_ThemeColor(TH_PATH_BEFORE);
321
322         glBegin(GL_LINE_STRIP);
323                 for(i= a; i<b; i++) {
324                         if(i==count+1)
325                                 UI_ThemeColor(TH_PATH_AFTER);
326
327                         glVertex2f(path[i][0], path[i][1]);
328                 }
329         glEnd();
330         glPointSize(1.0f);
331 }
332
333 static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, int width, int height)
334 {
335         int tiny= sc->flag&SC_SHOW_TINY_MARKER;
336         int show_pat= 0;
337         float px[2];
338
339         UI_ThemeColor(TH_MARKER_OUTLINE);
340
341         px[0]= 1.0f/width/sc->zoom;
342         px[1]= 1.0f/height/sc->zoom;
343
344         if((marker->flag&MARKER_DISABLED)==0) {
345                 float pos[2];
346                 rctf r;
347
348                 BLI_init_rctf(&r, track->pat_min[0], track->pat_max[0], track->pat_min[1], track->pat_max[1]);
349                 add_v2_v2v2(pos, marker->pos, track->offset);
350
351                 if(BLI_in_rctf(&r, pos[0]-marker->pos[0], pos[1]-marker->pos[1])) {
352                         if(tiny) glPointSize(3.0f);
353                         else glPointSize(4.0f);
354                         glBegin(GL_POINTS);
355                                 glVertex2f(pos[0], pos[1]);
356                         glEnd();
357                         glPointSize(1.0f);
358                 } else {
359                         if(!tiny) glLineWidth(3.0f);
360                         glBegin(GL_LINES);
361                                 glVertex2f(pos[0] + px[0]*2, pos[1]);
362                                 glVertex2f(pos[0] + px[0]*8, pos[1]);
363
364                                 glVertex2f(pos[0] - px[0]*2, pos[1]);
365                                 glVertex2f(pos[0] - px[0]*8, pos[1]);
366
367                                 glVertex2f(pos[0], pos[1] - px[1]*2);
368                                 glVertex2f(pos[0], pos[1] - px[1]*8);
369
370                                 glVertex2f(pos[0], pos[1] + px[1]*2);
371                                 glVertex2f(pos[0], pos[1] + px[1]*8);
372                         glEnd();
373                         if(!tiny) glLineWidth(1.0f);
374                 }
375         }
376
377         /* pattern and search outline */
378         glPushMatrix();
379         glTranslatef(marker->pos[0], marker->pos[1], 0);
380
381         if(!tiny) glLineWidth(3.0f);
382
383         show_pat= ((marker->flag&MARKER_DISABLED)==0 || (sc->flag&SC_SHOW_MARKER_SEARCH)==0);
384         if(sc->flag&SC_SHOW_MARKER_PATTERN && show_pat) {
385                 glBegin(GL_LINE_LOOP);
386                         glVertex2f(track->pat_min[0], track->pat_min[1]);
387                         glVertex2f(track->pat_max[0], track->pat_min[1]);
388                         glVertex2f(track->pat_max[0], track->pat_max[1]);
389                         glVertex2f(track->pat_min[0], track->pat_max[1]);
390                 glEnd();
391         }
392
393         if(sc->flag&SC_SHOW_MARKER_SEARCH) {
394                 glBegin(GL_LINE_LOOP);
395                         glVertex2f(track->search_min[0], track->search_min[1]);
396                         glVertex2f(track->search_max[0], track->search_min[1]);
397                         glVertex2f(track->search_max[0], track->search_max[1]);
398                         glVertex2f(track->search_min[0], track->search_max[1]);
399                 glEnd();
400         }
401         glPopMatrix();
402
403         if(!tiny) glLineWidth(1.0f);
404 }
405
406 static void track_colors(MovieTrackingTrack *track, int act, float col[3], float scol[3])
407 {
408         if(track->flag&TRACK_CUSTOMCOLOR) {
409                 if(act) UI_GetThemeColor3fv(TH_ACT_MARKER, scol);
410                 else copy_v3_v3(scol, track->color);
411
412                 mul_v3_v3fl(col, track->color, 0.5f);
413         } else {
414                 UI_GetThemeColor3fv(TH_MARKER, col);
415
416                 if(act) UI_GetThemeColor3fv(TH_ACT_MARKER, scol);
417                 else UI_GetThemeColor3fv(TH_SEL_MARKER, scol);
418         }
419 }
420
421 static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, int width, int height, int act, int sel)
422 {
423         int tiny= sc->flag&SC_SHOW_TINY_MARKER;
424         int show_pat= 0;
425         float col[3], scol[3], px[2];
426
427         track_colors(track, act, col, scol);
428
429         px[0]= 1.0f/width/sc->zoom;
430         px[1]= 1.0f/height/sc->zoom;
431
432         /* marker position and offset position */
433         if((track->flag&SELECT)==sel && (marker->flag&MARKER_DISABLED)==0) {
434                 float pos[2];
435                 rctf r;
436
437                 if(track->flag&TRACK_LOCKED) {
438                         if(act) UI_ThemeColor(TH_ACT_MARKER);
439                         else if(track->flag&SELECT) UI_ThemeColorShade(TH_LOCK_MARKER, 64);
440                         else UI_ThemeColor(TH_LOCK_MARKER);
441                 } else {
442                         if(track->flag&SELECT) glColor3fv(scol);
443                         else glColor3fv(col);
444                 }
445
446                 add_v2_v2v2(pos, marker->pos, track->offset);
447
448                 BLI_init_rctf(&r, track->pat_min[0], track->pat_max[0], track->pat_min[1], track->pat_max[1]);
449                 add_v2_v2v2(pos, marker->pos, track->offset);
450
451                 if(BLI_in_rctf(&r, pos[0]-marker->pos[0], pos[1]-marker->pos[1])) {
452                         if(!tiny) glPointSize(2.0f);
453                         glBegin(GL_POINTS);
454                                 glVertex2f(pos[0], pos[1]);
455                         glEnd();
456                         if(!tiny) glPointSize(1.0f);
457                 } else {
458                         glBegin(GL_LINES);
459                                 glVertex2f(pos[0] + px[0]*3, pos[1]);
460                                 glVertex2f(pos[0] + px[0]*7, pos[1]);
461
462                                 glVertex2f(pos[0] - px[0]*3, pos[1]);
463                                 glVertex2f(pos[0] - px[0]*7, pos[1]);
464
465                                 glVertex2f(pos[0], pos[1] - px[1]*3);
466                                 glVertex2f(pos[0], pos[1] - px[1]*7);
467
468                                 glVertex2f(pos[0], pos[1] + px[1]*3);
469                                 glVertex2f(pos[0], pos[1] + px[1]*7);
470                         glEnd();
471
472                         glColor3f(0.f, 0.f, 0.f);
473                         glLineStipple(3, 0xaaaa);
474                         glEnable(GL_LINE_STIPPLE);
475                         glEnable(GL_COLOR_LOGIC_OP);
476                         glLogicOp(GL_NOR);
477
478                         glBegin(GL_LINES);
479                                 glVertex2fv(pos);
480                                 glVertex2fv(marker->pos);
481                         glEnd();
482
483                         glDisable(GL_COLOR_LOGIC_OP);
484                         glDisable(GL_LINE_STIPPLE);
485                 }
486         }
487
488         /* pattern */
489         glPushMatrix();
490         glTranslatef(marker->pos[0], marker->pos[1], 0);
491
492         if(tiny) {
493                 glLineStipple(3, 0xaaaa);
494                 glEnable(GL_LINE_STIPPLE);
495         }
496
497         show_pat= ((marker->flag&MARKER_DISABLED)==0 || (sc->flag&SC_SHOW_MARKER_SEARCH)==0);
498         if((track->pat_flag&SELECT)==sel && show_pat) {
499                 if(track->flag&TRACK_LOCKED) {
500                         if(act) UI_ThemeColor(TH_ACT_MARKER);
501                         else if(track->pat_flag&SELECT) UI_ThemeColorShade(TH_LOCK_MARKER, 64);
502                         else UI_ThemeColor(TH_LOCK_MARKER);
503                 }
504                 else if(marker->flag&MARKER_DISABLED) {
505                         if(act) UI_ThemeColor(TH_ACT_MARKER);
506                         else if(track->pat_flag&SELECT) UI_ThemeColorShade(TH_DIS_MARKER, 128);
507                         else UI_ThemeColor(TH_DIS_MARKER);
508                 } else {
509                         if(track->pat_flag&SELECT) glColor3fv(scol);
510                         else glColor3fv(col);
511                 }
512
513                 if(sc->flag&SC_SHOW_MARKER_PATTERN) {
514                         glBegin(GL_LINE_LOOP);
515                                 glVertex2f(track->pat_min[0], track->pat_min[1]);
516                                 glVertex2f(track->pat_max[0], track->pat_min[1]);
517                                 glVertex2f(track->pat_max[0], track->pat_max[1]);
518                                 glVertex2f(track->pat_min[0], track->pat_max[1]);
519                         glEnd();
520                 }
521         }
522
523         /* search */
524         if((track->search_flag&SELECT)==sel) {
525                 if(track->flag&TRACK_LOCKED) {
526                         if(act) UI_ThemeColor(TH_ACT_MARKER);
527                         else if(track->search_flag&SELECT) UI_ThemeColorShade(TH_LOCK_MARKER, 64);
528                         else UI_ThemeColor(TH_LOCK_MARKER);
529                 }
530                 else if(marker->flag&MARKER_DISABLED) {
531                         if(act) UI_ThemeColor(TH_ACT_MARKER);
532                         else if(track->search_flag&SELECT) UI_ThemeColorShade(TH_DIS_MARKER, 128);
533                         else UI_ThemeColor(TH_DIS_MARKER);
534                 } else {
535                         if(track->search_flag&SELECT) glColor3fv(scol);
536                         else glColor3fv(col);
537                 }
538
539                 if(sc->flag&SC_SHOW_MARKER_SEARCH) {
540                         glBegin(GL_LINE_LOOP);
541                                 glVertex2f(track->search_min[0], track->search_min[1]);
542                                 glVertex2f(track->search_max[0], track->search_min[1]);
543                                 glVertex2f(track->search_max[0], track->search_max[1]);
544                                 glVertex2f(track->search_min[0], track->search_max[1]);
545                         glEnd();
546                 }
547         }
548
549         if(tiny)
550                 glDisable(GL_LINE_STIPPLE);
551
552         glPopMatrix();
553 }
554
555 static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, int outline, int sel, int act, int width, int height)
556 {
557         float x, y, dx, dy, patdx, patdy, searchdx, searchdy, tdx, tdy;
558         int tiny= sc->flag&SC_SHOW_TINY_MARKER;
559         float col[3], scol[3], px[2];
560
561         if((tiny && outline) || (marker->flag&MARKER_DISABLED))
562                 return;
563
564         if(!TRACK_SELECTED(track) || track->flag&TRACK_LOCKED)
565                 return;
566
567         track_colors(track, act, col, scol);
568
569         if(outline) {
570                 glLineWidth(3.0f);
571                 UI_ThemeColor(TH_MARKER_OUTLINE);
572         }
573
574         glPushMatrix();
575         glTranslatef(marker->pos[0], marker->pos[1], 0);
576
577         dx= 6.0f/width/sc->zoom;
578         dy= 6.0f/height/sc->zoom;
579
580         patdx= MIN2(dx*2.f/3.f, (track->pat_max[0]-track->pat_min[0])/6.f);
581         patdy= MIN2(dy*2.f/3.f, (track->pat_max[1]-track->pat_min[1])/6.f);
582
583         searchdx= MIN2(dx, (track->search_max[0]-track->search_min[0])/6.f);
584         searchdy= MIN2(dy, (track->search_max[1]-track->search_min[1])/6.f);
585
586         px[0]= 1.0f/sc->zoom/width/sc->scale;
587         px[1]= 1.0f/sc->zoom/height/sc->scale;
588
589         if((sc->flag&SC_SHOW_MARKER_SEARCH) && ((track->search_flag&SELECT)==sel || outline)) {
590                 if(!outline) {
591                         if(track->search_flag&SELECT) glColor3fv(scol);
592                         else glColor3fv(col);
593                 }
594
595                 /* search offset square */
596                 x= track->search_min[0];
597                 y= track->search_max[1];
598
599                 tdx= searchdx;
600                 tdy= searchdy;
601
602                 if(outline) {
603                         tdx+= px[0];
604                         tdy+= px[1];
605                 }
606
607                 glBegin(GL_QUADS);
608                         glVertex3f(x-tdx, y+tdy, 0);
609                         glVertex3f(x+tdx, y+tdy, 0);
610                         glVertex3f(x+tdx, y-tdy, 0);
611                         glVertex3f(x-tdx, y-tdy, 0);
612                 glEnd();
613
614                 /* search resizing triangle */
615                 x= track->search_max[0];
616                 y= track->search_min[1];
617
618                 tdx= searchdx*2.f;
619                 tdy= searchdy*2.f;
620
621                 if(outline) {
622                         tdx+= px[0];
623                         tdy+= px[1];
624                 }
625
626                 glBegin(GL_TRIANGLES);
627                         glVertex3f(x, y, 0);
628                         glVertex3f(x-tdx, y, 0);
629                         glVertex3f(x, y+tdy, 0);
630                 glEnd();
631         }
632
633         if((sc->flag&SC_SHOW_MARKER_PATTERN) && ((track->pat_flag&SELECT)==sel || outline)) {
634                 if(!outline) {
635                         if(track->pat_flag&SELECT) glColor3fv(scol);
636                         else glColor3fv(col);
637                 }
638
639                 /* pattern offset square */
640                 x= track->pat_min[0];
641                 y= track->pat_max[1];
642
643                 tdx= patdx;
644                 tdy= patdy;
645
646                 if(outline) {
647                         tdx+= px[0];
648                         tdy+= px[1];
649                 }
650
651                 glBegin(GL_QUADS);
652                         glVertex3f(x-tdx, y+tdy, 0);
653                         glVertex3f(x+tdx, y+tdy, 0);
654                         glVertex3f(x+tdx, y-tdy, 0);
655                         glVertex3f(x-tdx, y-tdy, 0);
656                 glEnd();
657
658                 /* pattern resizing triangle */
659                 x= track->pat_max[0];
660                 y= track->pat_min[1];
661
662                 tdx= patdx*2.f;
663                 tdy= patdy*2.f;
664
665                 if(outline) {
666                         tdx+= px[0];
667                         tdy+= px[1];
668                 }
669
670                 glBegin(GL_TRIANGLES);
671                         glVertex3f(x, y, 0);
672                         glVertex3f(x-tdx, y, 0);
673                         glVertex3f(x, y+tdy, 0);
674                 glEnd();
675         }
676
677         glPopMatrix();
678
679         if(outline)
680                 glLineWidth(1.0f);
681 }
682
683 static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, int act,
684                         int width, int height, float zoomx, float zoomy)
685 {
686         char str[128]= {0}, state[64]= {0};
687         float x, y, dx= 0.f, dy= 0.f;
688
689         if(!TRACK_SELECTED(track))
690                 return;
691
692         if(marker->flag&MARKER_DISABLED) {
693                 if(act) UI_ThemeColor(TH_ACT_MARKER);
694                 else UI_ThemeColorShade(TH_DIS_MARKER, 128);
695         } else {
696                 if(act) UI_ThemeColor(TH_ACT_MARKER);
697                 else UI_ThemeColor(TH_SEL_MARKER);
698         }
699
700         if(sc->flag&SC_SHOW_MARKER_SEARCH) {
701                 dx= track->search_min[0];
702                 dy= track->search_min[1];
703         } else if(sc->flag&SC_SHOW_MARKER_PATTERN) {
704                 dx= track->pat_min[0];
705                 dy= track->pat_min[1];
706         }
707
708         x= (marker->pos[0]+dx)*width*sc->scale*zoomx+sc->loc[0]*zoomx;
709         y= (marker->pos[1]+dy)*height*sc->scale*zoomy-14.f*UI_DPI_FAC+sc->loc[1]*zoomy;
710
711         if(marker->flag&MARKER_DISABLED) strcpy(state, "disabled");
712         else if(marker->framenr!=sc->user.framenr) strcpy(state, "estimated");
713         else if(marker->flag&MARKER_TRACKED) strcpy(state, "tracked");
714         else strcpy(state, "keyframed");
715
716         if(state[0])
717                 BLI_snprintf(str, sizeof(str), "%s: %s", track->name, state);
718         else
719                 BLI_snprintf(str, sizeof(str), "%s", track->name);
720
721         UI_DrawString(x, y, str);
722
723         if(track->flag&TRACK_LOCKED) {
724                 UI_DrawString(x, y-12.f*UI_DPI_FAC, "locked");
725         }
726 }
727
728 static void view2d_to_region_float(View2D *v2d, float x, float y, float *regionx, float *regiony)
729 {
730         /* express given coordinates as proportional values */
731         x= -v2d->cur.xmin / (v2d->cur.xmax-v2d->cur.xmin);
732         y= -v2d->cur.ymin / (v2d->cur.ymax-v2d->cur.ymin);
733
734         /* convert proportional distances to screen coordinates */
735         *regionx= v2d->mask.xmin + x*(v2d->mask.xmax-v2d->mask.xmin);
736         *regiony= v2d->mask.ymin + y*(v2d->mask.ymax-v2d->mask.ymin);
737 }
738
739 static void draw_distorion_grid(MovieTracking *tracking, int width, int height)
740 {
741         const int n= 9;
742         int x, y;
743         float pos[2], grid[10][10][2];
744         float dx= (float)width/n, dy= (float)height/n;
745
746         if(!tracking->camera.focal)
747                 return;
748
749         zero_v2(pos);
750
751         for(y= 0; y<=n; y++) {
752                 for(x= 0; x<=n; x++) {
753                         BKE_tracking_invert_intrinsics(tracking, pos, grid[y][x]);
754
755                         grid[y][x][0]/= width;
756                         grid[y][x][1]/= height;
757
758                         pos[0]+= dx;
759                 }
760
761                 pos[0]= 0.f;
762                 pos[1]+= dy;
763         }
764
765         glColor3f(1.f, 0.f, 0.f);
766
767         for(y= 0; y<=n; y++) {
768                 glBegin(GL_LINE_STRIP);
769                         for(x= 0; x<=n; x++) {
770                                 glVertex2fv(grid[y][x]);
771                         }
772                 glEnd();
773         }
774
775         for(x= 0; x<=n; x++) {
776                 glBegin(GL_LINE_STRIP);
777                         for(y= 0; y<=n; y++) {
778                                 glVertex2fv(grid[y][x]);
779                         }
780                 glEnd();
781         }
782 }
783
784 static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
785                         int width, int height, float zoomx, float zoomy)
786 {
787         float x, y;
788         MovieTracking* tracking= &clip->tracking;
789         MovieTrackingMarker *marker;
790         MovieTrackingTrack *track;
791         int sel_type, framenr= sc->user.framenr;
792         void *sel;
793
794         /* ** find window pixel coordinates of origin ** */
795
796         /* UI_view2d_to_region_no_clip return integer values, this could
797            lead to 1px flickering when view is locked to selection during playbeck.
798            to avoid this flickering, calclate base point in the same way as it happens
799            in UI_view2d_to_region_no_clip, but do it in floats here */
800
801         view2d_to_region_float(&ar->v2d, 0.0f, 0.0f, &x, &y);
802
803         glPushMatrix();
804         glTranslatef(x, y, 0);
805
806         glPushMatrix();
807         glScalef(zoomx, zoomy, 0);
808         glMultMatrixf(sc->stabmat);
809         glScalef(width, height, 0);
810
811         BKE_movieclip_last_selection(clip, &sel_type, &sel);
812
813         if(sc->flag&SC_SHOW_TRACK_PATH) {
814                 track= tracking->tracks.first;
815                 while(track) {
816                         if((track->flag&TRACK_HIDDEN)==0)
817                                 draw_track_path(sc, clip, track);
818
819                         track= track->next;
820                 }
821         }
822
823         /* markers outline and non-selected areas */
824         track= tracking->tracks.first;
825         while(track) {
826                 if((track->flag&TRACK_HIDDEN)==0) {
827                         marker= BKE_tracking_get_marker(track, framenr);
828
829                         if(MARKER_VISIBLE(sc, marker)) {
830                                 draw_marker_outline(sc, track, marker, width, height);
831                                 draw_marker_areas(sc, track, marker, width, height, 0, 0);
832                                 draw_marker_slide_zones(sc, track, marker, 1, 0, 0, width, height);
833                                 draw_marker_slide_zones(sc, track, marker, 0, 0, 0, width, height);
834                         }
835                 }
836
837                 track= track->next;
838         }
839
840         /* selected areas only, so selection wouldn't be overlapped by
841            non-selected areas */
842         track= tracking->tracks.first;
843         while(track) {
844                 if((track->flag&TRACK_HIDDEN)==0) {
845                         int act= sel_type==MCLIP_SEL_TRACK && sel==track;
846
847                         if(!act) {
848                                 marker= BKE_tracking_get_marker(track, framenr);
849
850                                 if(MARKER_VISIBLE(sc, marker)) {
851                                         draw_marker_areas(sc, track, marker, width, height, 0, 1);
852                                         draw_marker_slide_zones(sc, track, marker, 0, 1, 0, width, height);
853                                 }
854                         }
855                 }
856
857                 track= track->next;
858         }
859
860         /* active marker would be displayed on top of everything else */
861         if(sel_type==MCLIP_SEL_TRACK) {
862                 if((((MovieTrackingTrack *)sel)->flag&TRACK_HIDDEN)==0) {
863                         marker= BKE_tracking_get_marker(sel, framenr);
864
865                         if(MARKER_VISIBLE(sc, marker)) {
866                                 draw_marker_areas(sc, sel, marker, width, height, 1, 1);
867                                 draw_marker_slide_zones(sc, sel, marker, 0, 1, 1, width, height);
868                         }
869                 }
870         }
871
872         if(sc->flag&SC_SHOW_BUNDLES) {
873                 float pos[4], vec[4], mat[4][4], aspx, aspy;
874
875                 glEnable(GL_POINT_SMOOTH);
876                 glPointSize(3.0f);
877
878                 BKE_movieclip_aspect(clip, &aspx, &aspy);
879                 BKE_tracking_projection_matrix(tracking, framenr, width*aspx, height*aspy, mat);
880
881                 track= tracking->tracks.first;
882                 while(track) {
883                         if((track->flag&TRACK_HIDDEN)==0 && track->flag&TRACK_HAS_BUNDLE) {
884                                 marker= BKE_tracking_get_marker(track, framenr);
885
886                                 if(MARKER_VISIBLE(sc, marker)) {
887                                         copy_v4_v4(vec, track->bundle_pos);
888                                         vec[3]=1;
889
890                                         mul_v4_m4v4(pos, mat, vec);
891
892                                         pos[0]= (pos[0]/(pos[3]*2.0f)+0.5f)*width;
893                                         pos[1]= (pos[1]/(pos[3]*2.0f)+0.5f)*height;
894
895                                         BKE_tracking_apply_intrinsics(tracking, pos, pos);
896
897                                         vec[0]= (marker->pos[0]+track->offset[0])*width;
898                                         vec[1]= (marker->pos[1]+track->offset[1])*height;
899                                         sub_v2_v2(vec, pos);
900
901                                         if(len_v2(vec)<3) glColor3f(0.0f, 1.0f, 0.0f);
902                                         else glColor3f(1.0f, 0.0f, 0.0f);
903
904                                         glBegin(GL_POINTS);
905                                                 glVertex3f(pos[0]/width, pos[1]/height, 0);
906                                         glEnd();
907                                 }
908                         }
909
910                         track= track->next;
911                 }
912
913                 glPointSize(1.0f);
914                 glDisable(GL_POINT_SMOOTH);
915         }
916
917         if(sc->flag&SC_SHOW_GRID)
918                 draw_distorion_grid(tracking, width, height);
919
920         glPopMatrix();
921
922         if(sc->flag&SC_SHOW_NAMES) {
923                 /* scaling should be cleared before drawing texts, otherwise font would also be scaled */
924                 track= tracking->tracks.first;
925                 while(track) {
926                         if((track->flag&TRACK_HIDDEN)==0) {
927                                 marker= BKE_tracking_get_marker(track, framenr);
928
929                                 if(MARKER_VISIBLE(sc, marker)) {
930                                         int act= sel_type==MCLIP_SEL_TRACK && sel==track;
931
932                                         draw_marker_texts(sc, track, marker, act, width, height, zoomx, zoomy);
933                                 }
934                         }
935
936                         track= track->next;
937                 }
938         }
939
940         glPopMatrix();
941 }
942
943 static void draw_tracking(SpaceClip *sc, ARegion *ar, MovieClip *clip,
944                         int width, int height, float zoomx, float zoomy)
945 {
946         draw_tracking_tracks(sc, ar, clip, width, height, zoomx, zoomy);
947 }
948
949 void draw_clip_main(SpaceClip *sc, ARegion *ar, Scene *scene)
950 {
951         MovieClip *clip= ED_space_clip(sc);
952         ImBuf *ibuf;
953         float zoomx, zoomy;
954
955         /* if no clip, nothing to do */
956         if(!clip)
957                 return;
958
959         ED_space_clip_zoom(sc, ar, &zoomx, &zoomy);
960
961         if(sc->flag&SC_SHOW_STABLE) {
962                 ibuf= ED_space_clip_acquire_stable_buffer(sc, sc->loc, &sc->scale);
963                 BKE_tracking_stabdata_to_mat4(sc->loc, sc->scale, sc->stabmat);
964         } else {
965                 ibuf= ED_space_clip_acquire_buffer(sc);
966
967                 zero_v2(sc->loc);
968                 sc->scale= 1.f;
969                 unit_m4(sc->stabmat);
970         }
971
972         if(ibuf) {
973                 draw_movieclip_buffer(sc, ar, ibuf, zoomx, zoomy);
974                 IMB_freeImBuf(ibuf);
975
976                 draw_tracking(sc, ar, clip, ibuf->x, ibuf->y, zoomx, zoomy);
977         }
978
979         draw_movieclip_cache(sc, ar, clip, scene);
980 }