df14491c9c910f193fed8c7839206c192a91a09c
[blender.git] / source / blender / editors / space_clip / clip_graph_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_graph_draw.c
29  *  \ingroup spclip
30  */
31
32 #include "DNA_movieclip_types.h"
33 #include "DNA_scene_types.h"
34 #include "DNA_object_types.h"   /* SELECT */
35
36 #include "MEM_guardedalloc.h"
37
38 #include "BKE_context.h"
39 #include "BKE_movieclip.h"
40 #include "BKE_tracking.h"
41
42 #include "BLI_utildefines.h"
43 #include "BLI_math.h"
44 #include "BLI_string.h"
45
46 #include "ED_screen.h"
47 #include "ED_clip.h"
48
49 #include "BIF_gl.h"
50 #include "BIF_glutil.h"
51
52 #include "WM_types.h"
53
54 #include "UI_interface.h"
55 #include "UI_resources.h"
56 #include "UI_view2d.h"
57
58 #include "BLF_api.h"
59
60 #include "clip_intern.h"        // own include
61
62 static void draw_curve_knot(float x, float y, float xscale, float yscale, float hsize)
63 {
64         static GLuint displist=0;
65
66         /* initialize round circle shape */
67         if (displist == 0) {
68                 GLUquadricObj *qobj;
69
70                 displist = glGenLists(1);
71                 glNewList(displist, GL_COMPILE);
72
73                 qobj = gluNewQuadric();
74                 gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
75                 gluDisk(qobj, 0,  0.7, 8, 1);
76                 gluDeleteQuadric(qobj);
77
78                 glEndList();
79         }
80
81         glPushMatrix();
82
83         glTranslatef(x, y, 0.0f);
84         glScalef(1.0f/xscale*hsize, 1.0f/yscale*hsize, 1.0f);
85         glCallList(displist);
86
87         glPopMatrix();
88 }
89
90 static void draw_graph_cfra(SpaceClip *sc, ARegion *ar, Scene *scene)
91 {
92         View2D *v2d = &ar->v2d;
93         float xscale, yscale;
94         float vec[2];
95
96         /* Draw a light green line to indicate current frame */
97         vec[0] = (float)(sc->user.framenr * scene->r.framelen);
98
99         UI_ThemeColor(TH_CFRAME);
100         glLineWidth(2.0);
101
102         glBegin(GL_LINE_STRIP);
103                 vec[1] = v2d->cur.ymin;
104                 glVertex2fv(vec);
105
106                 vec[1] = v2d->cur.ymax;
107                 glVertex2fv(vec);
108         glEnd();
109
110         glLineWidth(1.0);
111
112         UI_view2d_view_orthoSpecial(ar, v2d, 1);
113
114         /* because the frame number text is subject to the same scaling as the contents of the view */
115         UI_view2d_getscale(v2d, &xscale, &yscale);
116         glScalef(1.0f/xscale, 1.0f, 1.0f);
117
118         clip_draw_curfra_label(sc, (float)sc->user.framenr * xscale, 18);
119
120         /* restore view transform */
121         glScalef(xscale, 1.0, 1.0);
122 }
123
124 static void draw_graph_sfra_efra(Scene *scene, View2D *v2d)
125 {
126         UI_view2d_view_ortho(v2d);
127
128         /* currently clip editor supposes that editing clip length is equal to scene frame range */
129         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
130         glEnable(GL_BLEND);
131                 glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
132
133                 glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)SFRA, v2d->cur.ymax);
134                 glRectf((float)EFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
135         glDisable(GL_BLEND);
136
137         UI_ThemeColorShade(TH_BACK, -60);
138
139         /* thin lines where the actual frames are */
140         fdrawline((float)SFRA, v2d->cur.ymin, (float)SFRA, v2d->cur.ymax);
141         fdrawline((float)EFRA, v2d->cur.ymin, (float)EFRA, v2d->cur.ymax);
142 }
143
144 static void tracking_segment_point_cb(void *UNUSED(userdata), MovieTrackingTrack *UNUSED(track),
145                         MovieTrackingMarker *marker, int UNUSED(coord), float val)
146 {
147         glVertex2f(marker->framenr, val);
148 }
149
150 void tracking_segment_start_cb(void *userdata, MovieTrackingTrack *track, int coord)
151 {
152         static float colors[2][3] = {{1.0f, 0.0f, 0.0f},
153                                      {0.0f, 1.0f, 0.0f}};
154         float col[4];
155
156         copy_v3_v3(col, colors[coord]);
157
158         if (track==userdata) {
159                 col[3] = 1.0f;
160                 glLineWidth(2.0f);
161         }
162         else {
163                 col[3] = 0.5f;
164                 glLineWidth(1.0f);
165         }
166
167         glColor4fv(col);
168
169         glBegin(GL_LINE_STRIP);
170 }
171
172 void tracking_segment_end_cb(void *UNUSED(userdata))
173 {
174         glEnd();
175
176         glLineWidth(1.0f);
177 }
178
179 static void tracking_segment_knot_cb(void *userdata, MovieTrackingTrack *track,
180                         MovieTrackingMarker *marker, int coord, float val)
181 {
182         struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } *data = userdata;
183         int sel= 0, sel_flag;
184
185         if (track != data->act_track)
186                 return;
187
188         sel_flag = coord == 0 ? MARKER_GRAPH_SEL_X : MARKER_GRAPH_SEL_Y;
189         sel = (marker->flag & sel_flag) ? 1 : 0;
190
191         if (sel == data->sel) {
192                 if (sel)
193                         UI_ThemeColor(TH_HANDLE_VERTEX_SELECT);
194                 else
195                         UI_ThemeColor(TH_HANDLE_VERTEX);
196
197                 draw_curve_knot(marker->framenr, val, data->xscale, data->yscale, data->hsize);
198         }
199 }
200
201 static void draw_tracks_curves(View2D *v2d, SpaceClip *sc)
202 {
203         MovieClip *clip = ED_space_clip(sc);
204         MovieTracking *tracking = &clip->tracking;
205         MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking);
206         int width, height;
207         struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } userdata;
208
209         BKE_movieclip_get_size(clip, &sc->user, &width, &height);
210
211         if (!width || !height)
212                 return;
213
214         /* non-selected knot handles */
215         userdata.hsize = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE);
216         userdata.sel = FALSE;
217         userdata.act_track = act_track;
218         UI_view2d_getscale(v2d, &userdata.xscale, &userdata.yscale);
219         clip_graph_tracking_values_iterate(sc, &userdata, tracking_segment_knot_cb, NULL, NULL);
220
221         /* draw graph lines */
222         glEnable(GL_BLEND);
223         clip_graph_tracking_values_iterate(sc, act_track, tracking_segment_point_cb, tracking_segment_start_cb, tracking_segment_end_cb);
224         glDisable(GL_BLEND);
225
226         /* selected knot handles on top of curves */
227         userdata.sel= TRUE;
228         clip_graph_tracking_values_iterate(sc, &userdata, tracking_segment_knot_cb, NULL, NULL);
229 }
230
231 static void draw_frame_curves(SpaceClip *sc)
232 {
233         MovieClip *clip = ED_space_clip(sc);
234         MovieTracking *tracking = &clip->tracking;
235         MovieTrackingReconstruction *reconstruction = BKE_tracking_get_reconstruction(tracking);
236         int i, lines = 0, prevfra = 0;
237
238         glColor3f(0.0f, 0.0f, 1.0f);
239
240         for (i = 0; i<reconstruction->camnr; i++) {
241                 MovieReconstructedCamera *camera = &reconstruction->cameras[i];
242
243                 if (lines && camera->framenr!=prevfra+1) {
244                         glEnd();
245                         lines = 0;
246                 }
247
248                 if (!lines) {
249                         glBegin(GL_LINE_STRIP);
250                         lines = 1;
251                 }
252
253                 glVertex2f(camera->framenr, camera->error);
254
255                 prevfra = camera->framenr;
256         }
257
258         if (lines)
259                 glEnd();
260 }
261
262 void clip_draw_graph(SpaceClip *sc, ARegion *ar, Scene *scene)
263 {
264         MovieClip *clip = ED_space_clip(sc);
265         View2D *v2d = &ar->v2d;
266         View2DGrid *grid;
267         short unitx = V2D_UNIT_FRAMESCALE, unity = V2D_UNIT_VALUES;
268
269         /* grid */
270         grid = UI_view2d_grid_calc(scene, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP, ar->winx, ar->winy);
271         UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL);
272         UI_view2d_grid_free(grid);
273
274         if (clip) {
275                 if (sc->flag & SC_SHOW_GRAPH_TRACKS)
276                         draw_tracks_curves(v2d, sc);
277
278                 if (sc->flag & SC_SHOW_GRAPH_FRAMES)
279                         draw_frame_curves(sc);
280         }
281
282         /* frame range */
283         draw_graph_sfra_efra(scene, v2d);
284
285         /* current frame */
286         draw_graph_cfra(sc, ar, scene);
287 }