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