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_gpencil_types.h"
35 #include "DNA_movieclip_types.h"
36 #include "DNA_scene_types.h"
37 #include "DNA_object_types.h"   /* SELECT */
38
39 #include "MEM_guardedalloc.h"
40
41 #include "BKE_context.h"
42 #include "BKE_movieclip.h"
43 #include "BKE_tracking.h"
44
45 #include "IMB_imbuf_types.h"
46 #include "IMB_imbuf.h"
47
48 #include "BLI_utildefines.h"
49 #include "BLI_math.h"
50 #include "BLI_string.h"
51 #include "BLI_rect.h"
52 #include "BLI_math_base.h"
53
54 #include "ED_screen.h"
55 #include "ED_clip.h"
56 #include "ED_gpencil.h"
57
58 #include "BIF_gl.h"
59 #include "BIF_glutil.h"
60
61 #include "WM_api.h"
62 #include "WM_types.h"
63
64 #include "UI_resources.h"
65 #include "UI_view2d.h"
66
67 #include "RNA_access.h"
68
69 #include "BLF_api.h"
70
71 #include "clip_intern.h"        // own include
72
73 /*********************** main area drawing *************************/
74
75 static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Scene *scene)
76 {
77         float x;
78         int *points, totseg, i, a;
79         float sfra= SFRA, efra= EFRA, framelen= ar->winx/(efra-sfra+1), fontsize, fontwidth;
80         uiStyle *style= U.uistyles.first;
81         int fontid= style->widget.uifont_id;
82         char str[32];
83
84         glEnable(GL_BLEND);
85
86         /* cache background */
87         glColor4ub(128, 128, 255, 64);
88         glRecti(0, 0, ar->winx, 8);
89
90         /* cached segments -- could be usefu lto debug caching strategies */
91         BKE_movieclip_get_cache_segments(clip, &sc->user, &totseg, &points);
92         if(totseg) {
93                 glColor4ub(128, 128, 255, 128);
94
95                 for(a= 0; a<totseg; a++) {
96                         float x1, x2;
97
98                         x1= (points[a*2]-sfra)/(efra-sfra+1)*ar->winx;
99                         x2= (points[a*2+1]-sfra+1)/(efra-sfra+1)*ar->winx;
100
101                         glRecti(x1, 0, x2, 8);
102                 }
103         }
104
105         /* track */
106         if(clip->tracking.act_track) {
107                 MovieTrackingTrack *track= clip->tracking.act_track;
108
109                 for(i= sfra, a= 0; i <= efra; i++) {
110                         int framenr;
111                         MovieTrackingMarker *marker;
112
113                         while(a<track->markersnr) {
114                                 if(track->markers[a].framenr>=i)
115                                         break;
116
117                                 if(a<track->markersnr-1 && track->markers[a+1].framenr>i)
118                                         break;
119
120                                 a++;
121                         }
122
123                         if(a<track->markersnr) marker= &track->markers[a];
124                         else marker= &track->markers[track->markersnr-1];
125
126                         if((marker->flag&MARKER_DISABLED)==0) {
127                                 framenr= marker->framenr;
128
129                                 if(framenr!=i) glColor4ub(128, 128, 0, 96);
130                                 else if((marker->flag&MARKER_TRACKED)==0) glColor4ub(255, 255, 0, 196);
131                                 else glColor4ub(255, 255, 0, 96);
132
133                                 glRecti((i-sfra)*framelen, 0, (i-sfra+1)*framelen, 4);
134                         }
135                 }
136         }
137
138         /* failed frames */
139         if(clip->tracking.reconstruction.flag&TRACKING_RECONSTRUCTED) {
140                 int n= clip->tracking.reconstruction.camnr;
141                 MovieReconstructedCamera *cameras= clip->tracking.reconstruction.cameras;
142
143                 glColor4ub(255, 0, 0, 96);
144
145                 for(i= sfra, a= 0; i <= efra; i++) {
146                         int ok= 0;
147
148                         while(a<n) {
149                                 if(cameras[a].framenr==i) {
150                                         ok= 1;
151                                         break;
152                                 }
153                                 else if(cameras[a].framenr>i) {
154                                         break;
155                                 }
156
157                                 a++;
158                         }
159
160                         if(!ok)
161                                 glRecti((i-sfra)*framelen, 0, (i-sfra+1)*framelen, 8);
162                 }
163         }
164
165         glDisable(GL_BLEND);
166
167         /* current frame */
168         x= (sc->user.framenr-sfra)/(efra-sfra+1)*ar->winx;
169
170         UI_ThemeColor(TH_CFRAME);
171         glRecti(x, 0, x+framelen, 8);
172
173         /* frame number */
174         BLF_size(fontid, 11.f, U.dpi);
175         BLI_snprintf(str, sizeof(str), "%d", sc->user.framenr);
176         fontsize= BLF_height(fontid, str);
177         fontwidth= BLF_width(fontid, str);
178
179         if(x+fontwidth+6.f<=ar->winx) {
180                 glRecti(x, 8.f, x+fontwidth+6.f, 12.f+fontsize);
181
182                 glColor3f(0.f, 0.f, 0.f);
183                 BLF_position(fontid, x+2.f, 10.f, 0.f);
184                 BLF_draw(fontid, str, strlen(str));
185         } else {
186                 glRecti(x+framelen, 8.f, x+framelen-fontwidth-6.f, 12.f+fontsize);
187
188                 glColor3f(0.f, 0.f, 0.f);
189                 BLF_position(fontid, x-2.f-fontwidth+framelen, 10.f, 0.f);
190                 BLF_draw(fontid, str, strlen(str));
191         }
192 }
193
194 static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf,
195                         int width, int height, float zoomx, float zoomy)
196 {
197         int x, y;
198         MovieClip *clip= ED_space_clip(sc);
199
200         /* set zoom */
201         glPixelZoom(zoomx*width/ibuf->x, zoomy*height/ibuf->y);
202
203         /* find window pixel coordinates of origin */
204         UI_view2d_to_region_no_clip(&ar->v2d, 0.f, 0.f, &x, &y);
205
206         if(sc->flag&SC_MUTE_FOOTAGE) {
207                 glColor3f(0.0f, 0.0f, 0.0f);
208                 glRectf(x, y, x+zoomx*width, y+zoomy*height);
209         } else {
210                 if(ibuf->rect_float && !ibuf->rect) {
211                         IMB_rect_from_float(ibuf);
212                 }
213
214                 if(ibuf->rect)
215                         glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
216         }
217
218         /* draw boundary border for frame if stabilization is enabled */
219         if(sc->flag&SC_SHOW_STABLE && clip->tracking.stabilization.flag&TRACKING_2D_STABILIZATION) {
220                 glColor3f(0.f, 0.f, 0.f);
221                 glLineStipple(3, 0xaaaa);
222                 glEnable(GL_LINE_STIPPLE);
223                 glEnable(GL_COLOR_LOGIC_OP);
224                 glLogicOp(GL_NOR);
225
226                 glPushMatrix();
227                 glTranslatef(x, y, 0);
228
229                 glScalef(zoomx, zoomy, 0);
230                 glMultMatrixf(sc->stabmat);
231
232                 glBegin(GL_LINE_LOOP);
233                         glVertex2f(0.f, 0.f);
234                         glVertex2f(ibuf->x, 0.f);
235                         glVertex2f(ibuf->x, ibuf->y);
236                         glVertex2f(0.f, ibuf->y);
237                 glEnd();
238
239                 glPopMatrix();
240
241                 glDisable(GL_COLOR_LOGIC_OP);
242                 glDisable(GL_LINE_STIPPLE);
243         }
244
245
246         /* reset zoom */
247         glPixelZoom(1.f, 1.f);
248 }
249
250 static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackingTrack *track)
251 {
252         int count= sc->path_length;
253         int i, a, b, curindex= -1;
254         float path[102][2];
255         int tiny= sc->flag&SC_SHOW_TINY_MARKER, framenr;
256         MovieTrackingMarker *marker;
257
258         if(count==0)
259                 return;
260
261         marker= BKE_tracking_get_marker(track, sc->user.framenr);
262         if(marker->framenr!=sc->user.framenr || marker->flag&MARKER_DISABLED)
263                 return;
264
265         framenr= marker->framenr;
266
267         a= count;
268         i= framenr-1;
269         while(i>=framenr-count) {
270                 marker= BKE_tracking_get_marker(track, i);
271
272                 if(!marker || marker->flag&MARKER_DISABLED)
273                         break;
274
275                 if(marker->framenr==i) {
276                         add_v2_v2v2(path[--a], marker->pos, track->offset);
277
278                         if(marker->framenr==sc->user.framenr)
279                                 curindex= a;
280                 } else
281                         break;
282
283                 i--;
284         }
285
286         b= count;
287         i= framenr;
288         while(i<=framenr+count) {
289                 marker= BKE_tracking_get_marker(track, i);
290
291                 if(!marker || marker->flag&MARKER_DISABLED)
292                         break;
293
294                 if(marker->framenr==i) {
295                         if(marker->framenr==sc->user.framenr)
296                                 curindex= b;
297
298                         add_v2_v2v2(path[b++], marker->pos, track->offset);
299                 } else
300                         break;
301
302                 i++;
303         }
304
305         if(!tiny) {
306                 UI_ThemeColor(TH_MARKER_OUTLINE);
307
308                 if(TRACK_VIEW_SELECTED(sc, track)) {
309                         glPointSize(5.0f);
310                         glBegin(GL_POINTS);
311                                 for(i= a; i<b; i++) {
312                                         if(i!=curindex)
313                                                 glVertex2f(path[i][0], path[i][1]);
314                                 }
315                         glEnd();
316                 }
317
318                 glLineWidth(3.0f);
319                 glBegin(GL_LINE_STRIP);
320                         for(i= a; i<b; i++)
321                                 glVertex2f(path[i][0], path[i][1]);
322                 glEnd();
323                 glLineWidth(1.0f);
324         }
325
326         UI_ThemeColor(TH_PATH_BEFORE);
327
328         if(TRACK_VIEW_SELECTED(sc, track)) {
329                 glPointSize(3.0f);
330                 glBegin(GL_POINTS);
331                         for(i= a; i<b; i++) {
332                                 if(i==count+1)
333                                         UI_ThemeColor(TH_PATH_AFTER);
334
335                                 if(i!=curindex)
336                                         glVertex2f(path[i][0], path[i][1]);
337                         }
338                 glEnd();
339         }
340
341         UI_ThemeColor(TH_PATH_BEFORE);
342
343         glBegin(GL_LINE_STRIP);
344                 for(i= a; i<b; i++) {
345                         if(i==count+1)
346                                 UI_ThemeColor(TH_PATH_AFTER);
347
348                         glVertex2f(path[i][0], path[i][1]);
349                 }
350         glEnd();
351         glPointSize(1.0f);
352 }
353
354 static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, int width, int height)
355 {
356         int tiny= sc->flag&SC_SHOW_TINY_MARKER;
357         int show_search= 0;
358         float px[2];
359
360         UI_ThemeColor(TH_MARKER_OUTLINE);
361
362         px[0]= 1.0f/width/sc->zoom;
363         px[1]= 1.0f/height/sc->zoom;
364
365         if((marker->flag&MARKER_DISABLED)==0) {
366                 float pos[2];
367                 rctf r;
368
369                 BLI_init_rctf(&r, track->pat_min[0], track->pat_max[0], track->pat_min[1], track->pat_max[1]);
370                 add_v2_v2v2(pos, marker->pos, track->offset);
371
372                 if(BLI_in_rctf(&r, pos[0]-marker->pos[0], pos[1]-marker->pos[1])) {
373                         if(tiny) glPointSize(3.0f);
374                         else glPointSize(4.0f);
375                         glBegin(GL_POINTS);
376                                 glVertex2f(pos[0], pos[1]);
377                         glEnd();
378                         glPointSize(1.0f);
379                 } else {
380                         if(!tiny) glLineWidth(3.0f);
381                         glBegin(GL_LINES);
382                                 glVertex2f(pos[0] + px[0]*2, pos[1]);
383                                 glVertex2f(pos[0] + px[0]*8, pos[1]);
384
385                                 glVertex2f(pos[0] - px[0]*2, pos[1]);
386                                 glVertex2f(pos[0] - px[0]*8, pos[1]);
387
388                                 glVertex2f(pos[0], pos[1] - px[1]*2);
389                                 glVertex2f(pos[0], pos[1] - px[1]*8);
390
391                                 glVertex2f(pos[0], pos[1] + px[1]*2);
392                                 glVertex2f(pos[0], pos[1] + px[1]*8);
393                         glEnd();
394                         if(!tiny) glLineWidth(1.0f);
395                 }
396         }
397
398         /* pattern and search outline */
399         glPushMatrix();
400         glTranslatef(marker->pos[0], marker->pos[1], 0);
401
402         if(!tiny) glLineWidth(3.0f);
403
404         if(sc->flag&SC_SHOW_MARKER_PATTERN) {
405                 glBegin(GL_LINE_LOOP);
406                         glVertex2f(track->pat_min[0], track->pat_min[1]);
407                         glVertex2f(track->pat_max[0], track->pat_min[1]);
408                         glVertex2f(track->pat_max[0], track->pat_max[1]);
409                         glVertex2f(track->pat_min[0], track->pat_max[1]);
410                 glEnd();
411         }
412
413         show_search= TRACK_VIEW_SELECTED(sc, track) && ((marker->flag&MARKER_DISABLED)==0 || (sc->flag&SC_SHOW_MARKER_PATTERN)==0);
414         if(sc->flag&SC_SHOW_MARKER_SEARCH && show_search) {
415                 glBegin(GL_LINE_LOOP);
416                         glVertex2f(track->search_min[0], track->search_min[1]);
417                         glVertex2f(track->search_max[0], track->search_min[1]);
418                         glVertex2f(track->search_max[0], track->search_max[1]);
419                         glVertex2f(track->search_min[0], track->search_max[1]);
420                 glEnd();
421         }
422         glPopMatrix();
423
424         if(!tiny) glLineWidth(1.0f);
425 }
426
427 static void track_colors(MovieTrackingTrack *track, int act, float col[3], float scol[3])
428 {
429         if(track->flag&TRACK_CUSTOMCOLOR) {
430                 if(act) UI_GetThemeColor3fv(TH_ACT_MARKER, scol);
431                 else copy_v3_v3(scol, track->color);
432
433                 mul_v3_v3fl(col, track->color, 0.5f);
434         } else {
435                 UI_GetThemeColor3fv(TH_MARKER, col);
436
437                 if(act) UI_GetThemeColor3fv(TH_ACT_MARKER, scol);
438                 else UI_GetThemeColor3fv(TH_SEL_MARKER, scol);
439         }
440 }
441
442 static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, int width, int height, int act, int sel)
443 {
444         int tiny= sc->flag&SC_SHOW_TINY_MARKER;
445         int show_search= 0;
446         float col[3], scol[3], px[2];
447
448         track_colors(track, act, col, scol);
449
450         px[0]= 1.0f/width/sc->zoom;
451         px[1]= 1.0f/height/sc->zoom;
452
453         /* marker position and offset position */
454         if((track->flag&SELECT)==sel && (marker->flag&MARKER_DISABLED)==0) {
455                 float pos[2];
456                 rctf r;
457
458                 if(track->flag&TRACK_LOCKED) {
459                         if(act) UI_ThemeColor(TH_ACT_MARKER);
460                         else if(track->flag&SELECT) UI_ThemeColorShade(TH_LOCK_MARKER, 64);
461                         else UI_ThemeColor(TH_LOCK_MARKER);
462                 } else {
463                         if(track->flag&SELECT) glColor3fv(scol);
464                         else glColor3fv(col);
465                 }
466
467                 add_v2_v2v2(pos, marker->pos, track->offset);
468
469                 BLI_init_rctf(&r, track->pat_min[0], track->pat_max[0], track->pat_min[1], track->pat_max[1]);
470                 add_v2_v2v2(pos, marker->pos, track->offset);
471
472                 if(BLI_in_rctf(&r, pos[0]-marker->pos[0], pos[1]-marker->pos[1])) {
473                         if(!tiny) glPointSize(2.0f);
474                         glBegin(GL_POINTS);
475                                 glVertex2f(pos[0], pos[1]);
476                         glEnd();
477                         if(!tiny) glPointSize(1.0f);
478                 } else {
479                         glBegin(GL_LINES);
480                                 glVertex2f(pos[0] + px[0]*3, pos[1]);
481                                 glVertex2f(pos[0] + px[0]*7, pos[1]);
482
483                                 glVertex2f(pos[0] - px[0]*3, pos[1]);
484                                 glVertex2f(pos[0] - px[0]*7, pos[1]);
485
486                                 glVertex2f(pos[0], pos[1] - px[1]*3);
487                                 glVertex2f(pos[0], pos[1] - px[1]*7);
488
489                                 glVertex2f(pos[0], pos[1] + px[1]*3);
490                                 glVertex2f(pos[0], pos[1] + px[1]*7);
491                         glEnd();
492
493                         glColor3f(0.f, 0.f, 0.f);
494                         glLineStipple(3, 0xaaaa);
495                         glEnable(GL_LINE_STIPPLE);
496                         glEnable(GL_COLOR_LOGIC_OP);
497                         glLogicOp(GL_NOR);
498
499                         glBegin(GL_LINES);
500                                 glVertex2fv(pos);
501                                 glVertex2fv(marker->pos);
502                         glEnd();
503
504                         glDisable(GL_COLOR_LOGIC_OP);
505                         glDisable(GL_LINE_STIPPLE);
506                 }
507         }
508
509         /* pattern */
510         glPushMatrix();
511         glTranslatef(marker->pos[0], marker->pos[1], 0);
512
513         if(tiny) {
514                 glLineStipple(3, 0xaaaa);
515                 glEnable(GL_LINE_STIPPLE);
516         }
517
518         if((track->pat_flag&SELECT)==sel && (sc->flag&SC_SHOW_MARKER_PATTERN)) {
519                 if(track->flag&TRACK_LOCKED) {
520                         if(act) UI_ThemeColor(TH_ACT_MARKER);
521                         else if(track->pat_flag&SELECT) UI_ThemeColorShade(TH_LOCK_MARKER, 64);
522                         else UI_ThemeColor(TH_LOCK_MARKER);
523                 }
524                 else if(marker->flag&MARKER_DISABLED) {
525                         if(act) UI_ThemeColor(TH_ACT_MARKER);
526                         else if(track->pat_flag&SELECT) UI_ThemeColorShade(TH_DIS_MARKER, 128);
527                         else UI_ThemeColor(TH_DIS_MARKER);
528                 } else {
529                         if(track->pat_flag&SELECT) glColor3fv(scol);
530                         else glColor3fv(col);
531                 }
532
533                 glBegin(GL_LINE_LOOP);
534                         glVertex2f(track->pat_min[0], track->pat_min[1]);
535                         glVertex2f(track->pat_max[0], track->pat_min[1]);
536                         glVertex2f(track->pat_max[0], track->pat_max[1]);
537                         glVertex2f(track->pat_min[0], track->pat_max[1]);
538                 glEnd();
539         }
540
541         /* search */
542         show_search= TRACK_VIEW_SELECTED(sc, track) && ((marker->flag&MARKER_DISABLED)==0 || (sc->flag&SC_SHOW_MARKER_PATTERN)==0);
543         if((track->search_flag&SELECT)==sel && (sc->flag&SC_SHOW_MARKER_SEARCH) && show_search) {
544                 if(track->flag&TRACK_LOCKED) {
545                         if(act) UI_ThemeColor(TH_ACT_MARKER);
546                         else if(track->search_flag&SELECT) UI_ThemeColorShade(TH_LOCK_MARKER, 64);
547                         else UI_ThemeColor(TH_LOCK_MARKER);
548                 }
549                 else if(marker->flag&MARKER_DISABLED) {
550                         if(act) UI_ThemeColor(TH_ACT_MARKER);
551                         else if(track->search_flag&SELECT) UI_ThemeColorShade(TH_DIS_MARKER, 128);
552                         else UI_ThemeColor(TH_DIS_MARKER);
553                 } else {
554                         if(track->search_flag&SELECT) glColor3fv(scol);
555                         else glColor3fv(col);
556                 }
557
558                 glBegin(GL_LINE_LOOP);
559                         glVertex2f(track->search_min[0], track->search_min[1]);
560                         glVertex2f(track->search_max[0], track->search_min[1]);
561                         glVertex2f(track->search_max[0], track->search_max[1]);
562                         glVertex2f(track->search_min[0], track->search_max[1]);
563                 glEnd();
564         }
565
566         if(tiny)
567                 glDisable(GL_LINE_STIPPLE);
568
569         glPopMatrix();
570 }
571
572 static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, int outline, int sel, int act, int width, int height)
573 {
574         float x, y, dx, dy, patdx, patdy, searchdx, searchdy, tdx, tdy;
575         int tiny= sc->flag&SC_SHOW_TINY_MARKER;
576         float col[3], scol[3], px[2];
577
578         if((tiny && outline) || (marker->flag&MARKER_DISABLED))
579                 return;
580
581         if(!TRACK_VIEW_SELECTED(sc, track) || track->flag&TRACK_LOCKED)
582                 return;
583
584         track_colors(track, act, col, scol);
585
586         if(outline) {
587                 glLineWidth(3.0f);
588                 UI_ThemeColor(TH_MARKER_OUTLINE);
589         }
590
591         glPushMatrix();
592         glTranslatef(marker->pos[0], marker->pos[1], 0);
593
594         dx= 6.0f/width/sc->zoom;
595         dy= 6.0f/height/sc->zoom;
596
597         patdx= MIN2(dx*2.f/3.f, (track->pat_max[0]-track->pat_min[0])/6.f);
598         patdy= MIN2(dy*2.f/3.f, (track->pat_max[1]-track->pat_min[1])/6.f);
599
600         searchdx= MIN2(dx, (track->search_max[0]-track->search_min[0])/6.f);
601         searchdy= MIN2(dy, (track->search_max[1]-track->search_min[1])/6.f);
602
603         px[0]= 1.0f/sc->zoom/width/sc->scale;
604         px[1]= 1.0f/sc->zoom/height/sc->scale;
605
606         if((sc->flag&SC_SHOW_MARKER_SEARCH) && ((track->search_flag&SELECT)==sel || outline)) {
607                 if(!outline) {
608                         if(track->search_flag&SELECT) glColor3fv(scol);
609                         else glColor3fv(col);
610                 }
611
612                 /* search offset square */
613                 x= track->search_min[0];
614                 y= track->search_max[1];
615
616                 tdx= searchdx;
617                 tdy= searchdy;
618
619                 if(outline) {
620                         tdx+= px[0];
621                         tdy+= px[1];
622                 }
623
624                 glBegin(GL_QUADS);
625                         glVertex3f(x-tdx, y+tdy, 0);
626                         glVertex3f(x+tdx, y+tdy, 0);
627                         glVertex3f(x+tdx, y-tdy, 0);
628                         glVertex3f(x-tdx, y-tdy, 0);
629                 glEnd();
630
631                 /* search resizing triangle */
632                 x= track->search_max[0];
633                 y= track->search_min[1];
634
635                 tdx= searchdx*2.f;
636                 tdy= searchdy*2.f;
637
638                 if(outline) {
639                         tdx+= px[0];
640                         tdy+= px[1];
641                 }
642
643                 glBegin(GL_TRIANGLES);
644                         glVertex3f(x, y, 0);
645                         glVertex3f(x-tdx, y, 0);
646                         glVertex3f(x, y+tdy, 0);
647                 glEnd();
648         }
649
650         if((sc->flag&SC_SHOW_MARKER_PATTERN) && ((track->pat_flag&SELECT)==sel || outline)) {
651                 if(!outline) {
652                         if(track->pat_flag&SELECT) glColor3fv(scol);
653                         else glColor3fv(col);
654                 }
655
656                 /* pattern offset square */
657                 x= track->pat_min[0];
658                 y= track->pat_max[1];
659
660                 tdx= patdx;
661                 tdy= patdy;
662
663                 if(outline) {
664                         tdx+= px[0];
665                         tdy+= px[1];
666                 }
667
668                 glBegin(GL_QUADS);
669                         glVertex3f(x-tdx, y+tdy, 0);
670                         glVertex3f(x+tdx, y+tdy, 0);
671                         glVertex3f(x+tdx, y-tdy, 0);
672                         glVertex3f(x-tdx, y-tdy, 0);
673                 glEnd();
674
675                 /* pattern resizing triangle */
676                 x= track->pat_max[0];
677                 y= track->pat_min[1];
678
679                 tdx= patdx*2.f;
680                 tdy= patdy*2.f;
681
682                 if(outline) {
683                         tdx+= px[0];
684                         tdy+= px[1];
685                 }
686
687                 glBegin(GL_TRIANGLES);
688                         glVertex3f(x, y, 0);
689                         glVertex3f(x-tdx, y, 0);
690                         glVertex3f(x, y+tdy, 0);
691                 glEnd();
692         }
693
694         glPopMatrix();
695
696         if(outline)
697                 glLineWidth(1.0f);
698 }
699
700 static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, int act,
701                         int width, int height, float zoomx, float zoomy)
702 {
703         char str[128]= {0}, state[64]= {0};
704         float dx= 0.f, dy= 0.f, fontsize, pos[3];
705         uiStyle *style= U.uistyles.first;
706         int fontid= style->widget.uifont_id;
707
708         if(!TRACK_VIEW_SELECTED(sc, track))
709                 return;
710
711         BLF_size(fontid, 11.f, U.dpi);
712         fontsize= BLF_height_max(fontid);
713
714         if(marker->flag&MARKER_DISABLED) {
715                 if(act) UI_ThemeColor(TH_ACT_MARKER);
716                 else UI_ThemeColorShade(TH_DIS_MARKER, 128);
717         } else {
718                 if(act) UI_ThemeColor(TH_ACT_MARKER);
719                 else UI_ThemeColor(TH_SEL_MARKER);
720         }
721
722         if(sc->flag&SC_SHOW_MARKER_SEARCH) {
723                 dx= track->search_min[0];
724                 dy= track->search_min[1];
725         } else if(sc->flag&SC_SHOW_MARKER_PATTERN) {
726                 dx= track->pat_min[0];
727                 dy= track->pat_min[1];
728         }
729
730         pos[0]= (marker->pos[0]+dx)*width;
731         pos[1]= (marker->pos[1]+dy)*height;
732         pos[2]= 0.f;
733
734         mul_m4_v3(sc->stabmat, pos);
735
736         pos[0]= pos[0]*zoomx;
737         pos[1]= pos[1]*zoomy - fontsize;
738
739         if(marker->flag&MARKER_DISABLED) strcpy(state, "disabled");
740         else if(marker->framenr!=sc->user.framenr) strcpy(state, "estimated");
741         else if(marker->flag&MARKER_TRACKED) strcpy(state, "tracked");
742         else strcpy(state, "keyframed");
743
744         if(state[0])
745                 BLI_snprintf(str, sizeof(str), "%s: %s", track->name, state);
746         else
747                 BLI_snprintf(str, sizeof(str), "%s", track->name);
748
749         BLF_position(fontid, pos[0], pos[1], 0.f);
750         BLF_draw(fontid, str, strlen(str));
751         pos[1]-= fontsize;
752
753         if(track->flag&TRACK_HAS_BUNDLE) {
754                 BLI_snprintf(str, sizeof(str), "Average error: %.3f", track->error);
755                 BLF_position(fontid, pos[0], pos[1], 0.f);
756                 BLF_draw(fontid, str, strlen(str));
757                 pos[1]-= fontsize;
758         }
759
760         if(track->flag&TRACK_LOCKED) {
761                 BLF_position(fontid, pos[0], pos[1], 0.f);
762                 BLF_draw(fontid, "locked", 6);
763         }
764 }
765
766 static void view2d_to_region_float(View2D *v2d, float x, float y, float *regionx, float *regiony)
767 {
768         /* express given coordinates as proportional values */
769         x= -v2d->cur.xmin / (v2d->cur.xmax-v2d->cur.xmin);
770         y= -v2d->cur.ymin / (v2d->cur.ymax-v2d->cur.ymin);
771
772         /* convert proportional distances to screen coordinates */
773         *regionx= v2d->mask.xmin + x*(v2d->mask.xmax-v2d->mask.xmin);
774         *regiony= v2d->mask.ymin + y*(v2d->mask.ymax-v2d->mask.ymin);
775 }
776
777 static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
778                         int width, int height, float zoomx, float zoomy)
779 {
780         float x, y;
781         MovieTracking* tracking= &clip->tracking;
782         MovieTrackingMarker *marker;
783         MovieTrackingTrack *track, *act_track;
784         int framenr= sc->user.framenr;
785
786         /* ** find window pixel coordinates of origin ** */
787
788         /* UI_view2d_to_region_no_clip return integer values, this could
789            lead to 1px flickering when view is locked to selection during playbeck.
790            to avoid this flickering, calclate base point in the same way as it happens
791            in UI_view2d_to_region_no_clip, but do it in floats here */
792
793         view2d_to_region_float(&ar->v2d, 0.0f, 0.0f, &x, &y);
794
795         glPushMatrix();
796         glTranslatef(x, y, 0);
797
798         glPushMatrix();
799         glScalef(zoomx, zoomy, 0);
800         glMultMatrixf(sc->stabmat);
801         glScalef(width, height, 0);
802
803         act_track= clip->tracking.act_track;
804
805         if(sc->flag&SC_SHOW_TRACK_PATH) {
806                 track= tracking->tracks.first;
807                 while(track) {
808                         if((track->flag&TRACK_HIDDEN)==0)
809                                 draw_track_path(sc, clip, track);
810
811                         track= track->next;
812                 }
813         }
814
815         /* markers outline and non-selected areas */
816         track= tracking->tracks.first;
817         while(track) {
818                 if((track->flag&TRACK_HIDDEN)==0) {
819                         marker= BKE_tracking_get_marker(track, framenr);
820
821                         if(MARKER_VISIBLE(sc, marker)) {
822                                 draw_marker_outline(sc, track, marker, width, height);
823                                 draw_marker_areas(sc, track, marker, width, height, 0, 0);
824                                 draw_marker_slide_zones(sc, track, marker, 1, 0, 0, width, height);
825                                 draw_marker_slide_zones(sc, track, marker, 0, 0, 0, width, height);
826                         }
827                 }
828
829                 track= track->next;
830         }
831
832         /* selected areas only, so selection wouldn't be overlapped by
833            non-selected areas */
834         track= tracking->tracks.first;
835         while(track) {
836                 if((track->flag&TRACK_HIDDEN)==0) {
837                         int act= track==act_track;
838
839                         if(!act) {
840                                 marker= BKE_tracking_get_marker(track, framenr);
841
842                                 if(MARKER_VISIBLE(sc, marker)) {
843                                         draw_marker_areas(sc, track, marker, width, height, 0, 1);
844                                         draw_marker_slide_zones(sc, track, marker, 0, 1, 0, width, height);
845                                 }
846                         }
847                 }
848
849                 track= track->next;
850         }
851
852         /* active marker would be displayed on top of everything else */
853         if(act_track) {
854                 if((act_track->flag&TRACK_HIDDEN)==0) {
855                         marker= BKE_tracking_get_marker(act_track, framenr);
856
857                         if(MARKER_VISIBLE(sc, marker)) {
858                                 draw_marker_areas(sc, act_track, marker, width, height, 1, 1);
859                                 draw_marker_slide_zones(sc, act_track, marker, 0, 1, 1, width, height);
860                         }
861                 }
862         }
863
864         if(sc->flag&SC_SHOW_BUNDLES) {
865                 float pos[4], vec[4], mat[4][4], aspy;
866
867                 glEnable(GL_POINT_SMOOTH);
868                 glPointSize(3.0f);
869
870                 aspy= 1.f/clip->tracking.camera.pixel_aspect;
871                 BKE_tracking_projection_matrix(tracking, framenr, width, height, mat);
872
873                 track= tracking->tracks.first;
874                 while(track) {
875                         if((track->flag&TRACK_HIDDEN)==0 && track->flag&TRACK_HAS_BUNDLE) {
876                                 marker= BKE_tracking_get_marker(track, framenr);
877
878                                 if(MARKER_VISIBLE(sc, marker)) {
879                                         copy_v4_v4(vec, track->bundle_pos);
880                                         vec[3]=1;
881
882                                         mul_v4_m4v4(pos, mat, vec);
883
884                                         pos[0]= (pos[0]/(pos[3]*2.0f)+0.5f)*width;
885                                         pos[1]= (pos[1]/(pos[3]*2.0f)+0.5f)*height*aspy;
886
887                                         if(pos[0]>=0.f && pos[1]>=0.f && pos[0]<=width && pos[1]<=height*aspy) {
888                                                 BKE_tracking_apply_intrinsics(tracking, pos, pos);
889
890                                                 vec[0]= (marker->pos[0]+track->offset[0])*width;
891                                                 vec[1]= (marker->pos[1]+track->offset[1])*height*aspy;
892
893                                                 sub_v2_v2(vec, pos);
894
895                                                 if(len_v2(vec)<3) glColor3f(0.0f, 1.0f, 0.0f);
896                                                 else glColor3f(1.0f, 0.0f, 0.0f);
897
898                                                 glBegin(GL_POINTS);
899                                                         glVertex3f(pos[0]/width, pos[1]/(height*aspy), 0);
900                                                 glEnd();
901                                         }
902                                 }
903                         }
904
905                         track= track->next;
906                 }
907
908                 glPointSize(1.0f);
909                 glDisable(GL_POINT_SMOOTH);
910         }
911
912         glPopMatrix();
913
914         if(sc->flag&SC_SHOW_NAMES) {
915                 /* scaling should be cleared before drawing texts, otherwise font would also be scaled */
916                 track= tracking->tracks.first;
917                 while(track) {
918                         if((track->flag&TRACK_HIDDEN)==0) {
919                                 marker= BKE_tracking_get_marker(track, framenr);
920
921                                 if(MARKER_VISIBLE(sc, marker)) {
922                                         int act= track==act_track;
923
924                                         draw_marker_texts(sc, track, marker, act, width, height, zoomx, zoomy);
925                                 }
926                         }
927
928                         track= track->next;
929                 }
930         }
931
932         glPopMatrix();
933 }
934
935 static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, int width, int height, float zoomx, float zoomy)
936 {
937         float x, y;
938         const int n= 10;
939         int i, j, a;
940         float pos[2], tpos[2], grid[11][11][2];
941         MovieTracking *tracking= &clip->tracking;
942         float aspy= 1.f/tracking->camera.pixel_aspect;
943         float dx= (float)width/n, dy= (float)height/n*aspy;
944
945         if(sc->mode!=SC_MODE_DISTORTION)
946                 return;
947
948         if(!tracking->camera.focal)
949                 return;
950
951         if((sc->flag&SC_SHOW_GRID)==0 && (sc->flag&SC_MANUAL_CALIBRATION)==0)
952                 return;
953
954         view2d_to_region_float(&ar->v2d, 0.0f, 0.0f, &x, &y);
955
956         glPushMatrix();
957         glTranslatef(x, y, 0);
958         glScalef(zoomx, zoomy, 0);
959         glMultMatrixf(sc->stabmat);
960         glScalef(width, height, 0);
961
962         /* grid */
963         if(sc->flag&SC_SHOW_GRID) {
964                 float val[4][2], idx[4][2];
965                 float min[2], max[2];
966
967                 for(a=0; a<4; a++) {
968                         if(a<2) val[a][a%2]= FLT_MAX;
969                         else val[a][a%2]= -FLT_MAX;
970                 }
971
972                 zero_v2(pos);
973                 for(i= 0; i<=n; i++) {
974                         for(j= 0; j<=n; j++) {
975                                 if(i==0 || j==0 || i==n || j==n) {
976                                         BKE_tracking_apply_intrinsics(tracking, pos, tpos);
977
978                                         for(a=0; a<4; a++) {
979                                                 int ok;
980
981                                                 if(a<2) ok= tpos[a%2] < val[a][a%2];
982                                                 else ok= tpos[a%2] > val[a][a%2];
983
984                                                 if(ok) {
985                                                         copy_v2_v2(val[a], tpos);
986                                                         idx[a][0]= j;
987                                                         idx[a][1]= i;
988                                                 }
989                                         }
990                                 }
991
992                                 pos[0]+= dx;
993                         }
994
995                         pos[0]= 0.f;
996                         pos[1]+= dy;
997                 }
998
999                 INIT_MINMAX2(min, max);
1000
1001                 for(a= 0; a<4; a++) {
1002                         pos[0]= idx[a][0]*dx;
1003                         pos[1]= idx[a][1]*dy;
1004
1005                         BKE_tracking_invert_intrinsics(tracking, pos, tpos);
1006
1007                         DO_MINMAX2(tpos, min, max);
1008                 }
1009
1010                 copy_v2_v2(pos, min);
1011                 dx= (max[0]-min[0])/n;
1012                 dy= (max[1]-min[1])/n;
1013
1014                 for(i= 0; i<=n; i++) {
1015                         for(j= 0; j<=n; j++) {
1016                                 BKE_tracking_apply_intrinsics(tracking, pos, grid[i][j]);
1017
1018                                 grid[i][j][0]/= width;
1019                                 grid[i][j][1]/= height*aspy;
1020
1021                                 pos[0]+= dx;
1022                         }
1023
1024                         pos[0]= min[0];
1025                         pos[1]+= dy;
1026                 }
1027
1028                 glColor3f(1.f, 0.f, 0.f);
1029
1030                 for(i= 0; i<=n; i++) {
1031                         glBegin(GL_LINE_STRIP);
1032                                 for(j= 0; j<=n; j++) {
1033                                         glVertex2fv(grid[i][j]);
1034                                 }
1035                         glEnd();
1036                 }
1037
1038                 for(j= 0; j<=n; j++) {
1039                         glBegin(GL_LINE_STRIP);
1040                                 for(i= 0; i<=n; i++) {
1041                                         glVertex2fv(grid[i][j]);
1042                                 }
1043                         glEnd();
1044                 }
1045         }
1046
1047         if(sc->flag&SC_MANUAL_CALIBRATION && clip->gpd) {
1048                 bGPDlayer *layer= clip->gpd->layers.first;
1049
1050                 while(layer) {
1051                         bGPDframe *frame= layer->frames.first;
1052
1053                         glColor4fv(layer->color);
1054                         glLineWidth(layer->thickness);
1055                         glPointSize((float)(layer->thickness + 2));
1056
1057                         while(frame) {
1058                                 bGPDstroke *stroke= frame->strokes.first;
1059
1060                                 while(stroke) {
1061                                         if(stroke->flag&GP_STROKE_2DSPACE) {
1062                                                 if(stroke->totpoints>1) {
1063                                                         glBegin(GL_LINE_STRIP);
1064                                                                 for(i= 0; i<stroke->totpoints-1; i++) {
1065                                                                         float npos[2], dpos[2], len;
1066                                                                         int steps;
1067
1068                                                                         pos[0]= stroke->points[i].x*width;
1069                                                                         pos[1]= stroke->points[i].y*height*aspy;
1070
1071                                                                         npos[0]= stroke->points[i+1].x*width;
1072                                                                         npos[1]= stroke->points[i+1].y*height*aspy;
1073
1074                                                                         len= len_v2v2(pos, npos);
1075                                                                         steps= ceil(len/5.f);
1076
1077                                                                         /* we want to distort only long straight lines */
1078                                                                         if(stroke->totpoints==2) {
1079                                                                                 BKE_tracking_invert_intrinsics(tracking, pos, pos);
1080                                                                                 BKE_tracking_invert_intrinsics(tracking, npos, npos);
1081                                                                         }
1082
1083                                                                         sub_v2_v2v2(dpos, npos, pos);
1084                                                                         mul_v2_fl(dpos, 1.f/steps);
1085
1086                                                                         for(j= 0; j<=steps; j++) {
1087                                                                                 BKE_tracking_apply_intrinsics(tracking, pos, tpos);
1088                                                                                 glVertex2f(tpos[0]/width, tpos[1]/(height*aspy));
1089
1090                                                                                 add_v2_v2(pos, dpos);
1091                                                                         }
1092                                                                 }
1093                                                         glEnd();
1094                                                 }
1095                                                 else if(stroke->totpoints==1) {
1096                                                         glBegin(GL_POINTS);
1097                                                                 glVertex2f(stroke->points[0].x, stroke->points[0].y);
1098                                                         glEnd();
1099                                                 }
1100                                         }
1101
1102                                         stroke= stroke->next;
1103                                 }
1104
1105                                 frame= frame->next;
1106                         }
1107
1108                         layer= layer->next;
1109                 }
1110
1111                 glLineWidth(1.f);
1112                 glPointSize(1.f);
1113         }
1114
1115         glPopMatrix();
1116 }
1117
1118 void draw_clip_main(SpaceClip *sc, ARegion *ar, Scene *scene)
1119 {
1120         MovieClip *clip= ED_space_clip(sc);
1121         ImBuf *ibuf;
1122         int width, height;
1123         float zoomx, zoomy;
1124
1125         /* if no clip, nothing to do */
1126         if(!clip)
1127                 return;
1128
1129         ED_space_clip_size(sc, &width, &height);
1130         ED_space_clip_zoom(sc, ar, &zoomx, &zoomy);
1131
1132         if(sc->flag&SC_SHOW_STABLE) {
1133                 float smat[4][4], ismat[4][4];
1134
1135                 ibuf= ED_space_clip_acquire_stable_buffer(sc, sc->loc, &sc->scale, &sc->angle);
1136                 BKE_tracking_stabdata_to_mat4(width, height, sc->loc, sc->scale, sc->angle, sc->stabmat);
1137
1138                 unit_m4(smat);
1139                 smat[0][0]= 1.f/width;
1140                 smat[1][1]= 1.f/height;
1141                 invert_m4_m4(ismat, smat);
1142
1143                 mul_serie_m4(sc->unistabmat, smat, sc->stabmat, ismat, NULL, NULL, NULL, NULL, NULL);
1144         } else {
1145                 ibuf= ED_space_clip_acquire_buffer(sc);
1146
1147                 zero_v2(sc->loc);
1148                 sc->scale= 1.f;
1149                 unit_m4(sc->stabmat);
1150                 unit_m4(sc->unistabmat);
1151         }
1152
1153         if(ibuf) {
1154                 draw_movieclip_buffer(sc, ar, ibuf, width, height, zoomx, zoomy);
1155                 IMB_freeImBuf(ibuf);
1156
1157                 draw_tracking_tracks(sc, ar, clip, width, height, zoomx, zoomy);
1158                 draw_distortion(sc, ar, clip, width, height, zoomx, zoomy);
1159         }
1160
1161         draw_movieclip_cache(sc, ar, clip, scene);
1162 }
1163
1164 /* draw grease pencil */
1165 void draw_clip_grease_pencil(bContext *C, int onlyv2d)
1166 {
1167         SpaceClip *sc= CTX_wm_space_clip(C);
1168         MovieClip *clip= ED_space_clip(sc);
1169         ImBuf *ibuf;
1170
1171         if((sc->flag&SC_SHOW_GPENCIL)==0 || !clip)
1172                 return;
1173
1174         if(onlyv2d) {
1175                 /* if manual calibration is used then grase pencil data is already
1176                     drawed in draw_distortion */
1177                 if((sc->flag&SC_MANUAL_CALIBRATION)==0 || sc->mode!=SC_MODE_DISTORTION) {
1178                         ibuf= ED_space_clip_acquire_buffer(sc);
1179
1180                         if(ibuf) {
1181                                 glPushMatrix();
1182                                 glMultMatrixf(sc->unistabmat);
1183                                 draw_gpencil_2dimage(C, ibuf);
1184
1185                                 IMB_freeImBuf(ibuf);
1186                                 glPopMatrix();
1187                         }
1188                 }
1189         } else {
1190                 draw_gpencil_view2d(C, 0);
1191         }
1192 }