Camera tracking: fixed default value for pixel aspect which wasn't 1.0
[blender.git] / source / blender / editors / space_clip / clip_editor.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_editor.c
29  *  \ingroup spclip
30  */
31
32 #include <stddef.h>
33
34 #include "BKE_main.h"
35 #include "BKE_movieclip.h"
36 #include "BKE_context.h"
37 #include "BKE_tracking.h"
38 #include "DNA_object_types.h"   /* SELECT */
39
40 #include "BLI_utildefines.h"
41 #include "BLI_math.h"
42
43 #include "IMB_imbuf_types.h"
44 #include "IMB_imbuf.h"
45
46 #include "ED_screen.h"
47 #include "ED_clip.h"
48
49 #include "BIF_gl.h"
50
51 #include "WM_api.h"
52 #include "WM_types.h"
53
54 #include "UI_view2d.h"
55
56 #include "clip_intern.h"        // own include
57
58 int ED_space_clip_poll(bContext *C)
59 {
60         SpaceClip *sc= CTX_wm_space_clip(C);
61
62         if(sc && sc->clip)
63                 return 1;
64
65         return 0;
66 }
67
68 void ED_space_clip_set(bContext *C, SpaceClip *sc, MovieClip *clip)
69 {
70         sc->clip= clip;
71
72         if(sc->clip && sc->clip->id.us==0)
73                 sc->clip->id.us= 1;
74
75         if(C)
76                 WM_event_add_notifier(C, NC_MOVIECLIP|NA_SELECTED, sc->clip);
77 }
78
79 MovieClip *ED_space_clip(SpaceClip *sc)
80 {
81         return sc->clip;
82 }
83
84 ImBuf *ED_space_clip_get_buffer(SpaceClip *sc)
85 {
86         if(sc->clip) {
87                 ImBuf *ibuf;
88
89                 ibuf= BKE_movieclip_get_postprocessed_ibuf(sc->clip, &sc->user, sc->postproc_flag);
90
91                 if(ibuf && (ibuf->rect || ibuf->rect_float))
92                         return ibuf;
93
94                 if(ibuf)
95                         IMB_freeImBuf(ibuf);
96         }
97
98         return NULL;
99 }
100
101 ImBuf *ED_space_clip_get_stable_buffer(SpaceClip *sc, float loc[2], float *scale, float *angle)
102 {
103         if(sc->clip) {
104                 ImBuf *ibuf;
105
106                 ibuf= BKE_movieclip_get_stable_ibuf(sc->clip, &sc->user, loc, scale, angle, sc->postproc_flag);
107
108                 if(ibuf && (ibuf->rect || ibuf->rect_float))
109                         return ibuf;
110
111                 if(ibuf)
112                         IMB_freeImBuf(ibuf);
113         }
114
115         return NULL;
116 }
117
118 void ED_space_clip_size(SpaceClip *sc, int *width, int *height)
119 {
120         if(!sc->clip) {
121                 *width= 0;
122                 *height= 0;
123         } else
124                 BKE_movieclip_get_size(sc->clip, &sc->user, width, height);
125 }
126
127 void ED_space_clip_zoom(SpaceClip *sc, ARegion *ar, float *zoomx, float *zoomy)
128 {
129         int width, height;
130
131         ED_space_clip_size(sc, &width, &height);
132
133         *zoomx= (float)(ar->winrct.xmax - ar->winrct.xmin + 1)/(float)((ar->v2d.cur.xmax - ar->v2d.cur.xmin)*width);
134         *zoomy= (float)(ar->winrct.ymax - ar->winrct.ymin + 1)/(float)((ar->v2d.cur.ymax - ar->v2d.cur.ymin)*height);
135 }
136
137 void ED_space_clip_aspect(SpaceClip *sc, float *aspx, float *aspy)
138 {
139         MovieClip *clip= ED_space_clip(sc);
140
141         if(clip)
142                 BKE_movieclip_aspect(clip, aspx, aspy);
143         else
144                 *aspx= *aspy= 1.0f;
145 }
146
147 void ED_clip_update_frame(const Main *mainp, int cfra)
148 {
149         wmWindowManager *wm;
150         wmWindow *win;
151
152         /* image window, compo node users */
153         for(wm=mainp->wm.first; wm; wm= wm->id.next) { /* only 1 wm */
154                 for(win= wm->windows.first; win; win= win->next) {
155                         ScrArea *sa;
156                         for(sa= win->screen->areabase.first; sa; sa= sa->next) {
157                                 if(sa->spacetype==SPACE_CLIP) {
158                                         SpaceClip *sc= sa->spacedata.first;
159
160                                         sc->scopes.ok= 0;
161
162                                         BKE_movieclip_user_set_frame(&sc->user, cfra);
163                                 }
164                         }
165                 }
166         }
167 }
168
169 static int selected_boundbox(SpaceClip *sc, float min[2], float max[2])
170 {
171         MovieClip *clip= ED_space_clip(sc);
172         MovieTrackingTrack *track;
173         int width, height, ok= 0;
174         ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
175
176         INIT_MINMAX2(min, max);
177
178         ED_space_clip_size(sc, &width, &height);
179
180         track= tracksbase->first;
181         while(track) {
182                 if(TRACK_VIEW_SELECTED(sc, track)) {
183                         MovieTrackingMarker *marker= BKE_tracking_get_marker(track, sc->user.framenr);
184
185                         if(marker) {
186                                 float pos[3];
187
188                                 pos[0]= marker->pos[0]+track->offset[0];
189                                 pos[1]= marker->pos[1]+track->offset[1];
190                                 pos[2]= 0.0f;
191
192                                 /* undistortion happens for normalized coords */
193                                 if(sc->user.render_flag&MCLIP_PROXY_RENDER_UNDISTORT)
194                                         /* undistortion happens for normalized coords */
195                                         ED_clip_point_undistorted_pos(sc, pos, pos);
196
197                                 pos[0]*= width;
198                                 pos[1]*= height;
199
200                                 mul_v3_m4v3(pos, sc->stabmat, pos);
201
202                                 DO_MINMAX2(pos, min, max);
203
204                                 ok= 1;
205                         }
206                 }
207
208                 track= track->next;
209         }
210
211         return ok;
212 }
213
214 int ED_clip_view_selection(SpaceClip *sc, ARegion *ar, int fit)
215 {
216         int w, h, frame_width, frame_height;
217         float min[2], max[2];
218
219         ED_space_clip_size(sc, &frame_width, &frame_height);
220
221         if(frame_width==0 || frame_height==0) return 0;
222
223         if(!selected_boundbox(sc, min, max))
224                 return 0;
225
226         /* center view */
227         clip_view_center_to_point(sc, (max[0]+min[0])/(2*frame_width), (max[1]+min[1])/(2*frame_height));
228
229         w= max[0]-min[0];
230         h= max[1]-min[1];
231
232         /* set zoom to see all selection */
233         if(w>0 && h>0) {
234                 int width, height;
235                 float zoomx, zoomy, newzoom, aspx, aspy;
236
237                 ED_space_clip_aspect(sc, &aspx, &aspy);
238
239                 width= ar->winrct.xmax - ar->winrct.xmin + 1;
240                 height= ar->winrct.ymax - ar->winrct.ymin + 1;
241
242                 zoomx= (float)width/w/aspx;
243                 zoomy= (float)height/h/aspy;
244
245                 newzoom= 1.0f/power_of_2(1/MIN2(zoomx, zoomy));
246
247                 if(fit || sc->zoom>newzoom)
248                         sc->zoom= newzoom;
249         }
250
251         return 1;
252 }
253
254 void ED_clip_point_undistorted_pos(SpaceClip *sc, float co[2], float nco[2])
255 {
256         copy_v2_v2(nco, co);
257
258         if(sc->user.render_flag&MCLIP_PROXY_RENDER_UNDISTORT) {
259                 MovieClip *clip= ED_space_clip(sc);
260                 float aspy= 1.0f/clip->tracking.camera.pixel_aspect;
261                 int width, height;
262
263                 ED_space_clip_size(sc, &width, &height);
264
265                 nco[0]*= width;
266                 nco[1]*= height*aspy;
267
268                 BKE_tracking_invert_intrinsics(&clip->tracking, nco, nco);
269                 nco[0]/= width;
270                 nco[1]/= height*aspy;
271         }
272 }
273
274 void ED_clip_point_stable_pos(bContext *C, float x, float y, float *xr, float *yr)
275 {
276         ARegion *ar= CTX_wm_region(C);
277         SpaceClip *sc= CTX_wm_space_clip(C);
278         int sx, sy, width, height;
279         float zoomx, zoomy, pos[3]={0.0f, 0.0f, 0.0f}, imat[4][4];
280
281         ED_space_clip_zoom(sc, ar, &zoomx, &zoomy);
282         ED_space_clip_size(sc, &width, &height);
283
284         UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &sx, &sy);
285
286         pos[0]= (x-sx)/zoomx;
287         pos[1]= (y-sy)/zoomy;
288
289         invert_m4_m4(imat, sc->stabmat);
290         mul_v3_m4v3(pos, imat, pos);
291
292         *xr= pos[0]/width;
293         *yr= pos[1]/height;
294
295         if(sc->user.render_flag&MCLIP_PROXY_RENDER_UNDISTORT) {
296                 MovieClip *clip= ED_space_clip(sc);
297                 MovieTracking *tracking= &clip->tracking;
298                 float aspy= 1.0f/tracking->camera.pixel_aspect;
299                 float tmp[2]= {*xr*width, *yr*height*aspy};
300
301                 BKE_tracking_apply_intrinsics(tracking, tmp, tmp);
302
303                 *xr= tmp[0]/width;
304                 *yr= tmp[1]/(height*aspy);
305         }
306 }
307
308 void ED_clip_mouse_pos(bContext *C, wmEvent *event, float co[2])
309 {
310         ED_clip_point_stable_pos(C, event->mval[0], event->mval[1], &co[0], &co[1]);
311 }