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