Some options used for "expert" x264 setup were removed from FFmpeg 0.11
[blender.git] / source / blender / blenkernel / intern / camera.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) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/blenkernel/intern/camera.c
29  *  \ingroup bke
30  */
31
32 #include <stdlib.h>
33
34 #include "DNA_camera_types.h"
35 #include "DNA_lamp_types.h"
36 #include "DNA_object_types.h"
37 #include "DNA_scene_types.h"
38 #include "DNA_view3d_types.h"
39
40 #include "BLI_math.h"
41 #include "BLI_utildefines.h"
42
43 #include "BKE_animsys.h"
44 #include "BKE_camera.h"
45 #include "BKE_object.h"
46 #include "BKE_global.h"
47 #include "BKE_library.h"
48 #include "BKE_main.h"
49 #include "BKE_screen.h"
50
51 /****************************** Camera Datablock *****************************/
52
53 void *BKE_camera_add(const char *name)
54 {
55         Camera *cam;
56         
57         cam =  BKE_libblock_alloc(&G.main->camera, ID_CA, name);
58
59         cam->lens = 35.0f;
60         cam->sensor_x = 32.0f;
61         cam->sensor_y = 18.0f;
62         cam->clipsta = 0.1f;
63         cam->clipend = 100.0f;
64         cam->drawsize = 0.5f;
65         cam->ortho_scale = 6.0;
66         cam->flag |= CAM_SHOWPASSEPARTOUT;
67         cam->passepartalpha = 0.5f;
68         
69         return cam;
70 }
71
72 Camera *BKE_camera_copy(Camera *cam)
73 {
74         Camera *camn;
75         
76         camn = BKE_libblock_copy(&cam->id);
77
78         id_lib_extern((ID *)camn->dof_ob);
79
80         return camn;
81 }
82
83 void BKE_camera_make_local(Camera *cam)
84 {
85         Main *bmain = G.main;
86         Object *ob;
87         int is_local = FALSE, is_lib = FALSE;
88
89         /* - only lib users: do nothing
90          * - only local users: set flag
91          * - mixed: make copy
92          */
93         
94         if (cam->id.lib == NULL) return;
95         if (cam->id.us == 1) {
96                 id_clear_lib_data(bmain, &cam->id);
97                 return;
98         }
99         
100         for (ob = bmain->object.first; ob && ELEM(0, is_lib, is_local); ob = ob->id.next) {
101                 if (ob->data == cam) {
102                         if (ob->id.lib) is_lib = TRUE;
103                         else is_local = TRUE;
104                 }
105         }
106         
107         if (is_local && is_lib == FALSE) {
108                 id_clear_lib_data(bmain, &cam->id);
109         }
110         else if (is_local && is_lib) {
111                 Camera *cam_new = BKE_camera_copy(cam);
112
113                 cam_new->id.us = 0;
114
115                 /* Remap paths of new ID using old library as base. */
116                 BKE_id_lib_local_paths(bmain, cam->id.lib, &cam_new->id);
117
118                 for (ob = bmain->object.first; ob; ob = ob->id.next) {
119                         if (ob->data == cam) {
120                                 if (ob->id.lib == NULL) {
121                                         ob->data = cam_new;
122                                         cam_new->id.us++;
123                                         cam->id.us--;
124                                 }
125                         }
126                 }
127         }
128 }
129
130 void BKE_camera_free(Camera *ca)
131 {
132         BKE_free_animdata((ID *)ca);
133 }
134
135 /******************************** Camera Usage *******************************/
136
137 void BKE_camera_object_mode(RenderData *rd, Object *cam_ob)
138 {
139         rd->mode &= ~(R_ORTHO | R_PANORAMA);
140
141         if (cam_ob && cam_ob->type == OB_CAMERA) {
142                 Camera *cam = cam_ob->data;
143                 if (cam->type == CAM_ORTHO) rd->mode |= R_ORTHO;
144                 if (cam->type == CAM_PANO) rd->mode |= R_PANORAMA;
145         }
146 }
147
148 /* get the camera's dof value, takes the dof object into account */
149 float BKE_camera_object_dof_distance(Object *ob)
150 {
151         Camera *cam = (Camera *)ob->data; 
152         if (ob->type != OB_CAMERA)
153                 return 0.0f;
154         if (cam->dof_ob) {      
155                 /* too simple, better to return the distance on the view axis only
156                  * return len_v3v3(ob->obmat[3], cam->dof_ob->obmat[3]); */
157                 float mat[4][4], imat[4][4], obmat[4][4];
158                 
159                 copy_m4_m4(obmat, ob->obmat);
160                 normalize_m4(obmat);
161                 invert_m4_m4(imat, obmat);
162                 mult_m4_m4m4(mat, imat, cam->dof_ob->obmat);
163                 return fabsf(mat[3][2]);
164         }
165         return cam->YF_dofdist;
166 }
167
168 float BKE_camera_sensor_size(int sensor_fit, float sensor_x, float sensor_y)
169 {
170         /* sensor size used to fit to. for auto, sensor_x is both x and y. */
171         if (sensor_fit == CAMERA_SENSOR_FIT_VERT)
172                 return sensor_y;
173
174         return sensor_x;
175 }
176
177 int BKE_camera_sensor_fit(int sensor_fit, float sizex, float sizey)
178 {
179         if (sensor_fit == CAMERA_SENSOR_FIT_AUTO) {
180                 if (sizex >= sizey)
181                         return CAMERA_SENSOR_FIT_HOR;
182                 else
183                         return CAMERA_SENSOR_FIT_VERT;
184         }
185
186         return sensor_fit;
187 }
188
189 /******************************** Camera Params *******************************/
190
191 void BKE_camera_params_init(CameraParams *params)
192 {
193         memset(params, 0, sizeof(CameraParams));
194
195         /* defaults */
196         params->sensor_x = DEFAULT_SENSOR_WIDTH;
197         params->sensor_y = DEFAULT_SENSOR_HEIGHT;
198         params->sensor_fit = CAMERA_SENSOR_FIT_AUTO;
199
200         params->zoom = 1.0f;
201 }
202
203 void BKE_camera_params_from_object(CameraParams *params, Object *ob)
204 {
205         if (!ob)
206                 return;
207
208         if (ob->type == OB_CAMERA) {
209                 /* camera object */
210                 Camera *cam = ob->data;
211
212                 if (cam->type == CAM_ORTHO)
213                         params->is_ortho = TRUE;
214                 params->lens = cam->lens;
215                 params->ortho_scale = cam->ortho_scale;
216
217                 params->shiftx = cam->shiftx;
218                 params->shifty = cam->shifty;
219
220                 params->sensor_x = cam->sensor_x;
221                 params->sensor_y = cam->sensor_y;
222                 params->sensor_fit = cam->sensor_fit;
223
224                 params->clipsta = cam->clipsta;
225                 params->clipend = cam->clipend;
226         }
227         else if (ob->type == OB_LAMP) {
228                 /* lamp object */
229                 Lamp *la = ob->data;
230                 float fac = cosf((float)M_PI * la->spotsize / 360.0f);
231                 float phi = acos(fac);
232
233                 params->lens = 16.0f * fac / sinf(phi);
234                 if (params->lens == 0.0f)
235                         params->lens = 35.0f;
236
237                 params->clipsta = la->clipsta;
238                 params->clipend = la->clipend;
239         }
240 }
241
242 void BKE_camera_params_from_view3d(CameraParams *params, View3D *v3d, RegionView3D *rv3d)
243 {
244         /* common */
245         params->lens = v3d->lens;
246         params->clipsta = v3d->near;
247         params->clipend = v3d->far;
248
249         if (rv3d->persp == RV3D_CAMOB) {
250                 /* camera view */
251                 BKE_camera_params_from_object(params, v3d->camera);
252
253                 params->zoom = BKE_screen_view3d_zoom_to_fac((float)rv3d->camzoom);
254
255                 params->offsetx = 2.0f * rv3d->camdx * params->zoom;
256                 params->offsety = 2.0f * rv3d->camdy * params->zoom;
257
258                 params->shiftx *= params->zoom;
259                 params->shifty *= params->zoom;
260
261                 params->zoom = 1.0f / params->zoom;
262         }
263         else if (rv3d->persp == RV3D_ORTHO) {
264                 /* orthographic view */
265                 params->clipend *= 0.5f;    // otherwise too extreme low zbuffer quality
266                 params->clipsta = -params->clipend;
267
268                 params->is_ortho = TRUE;
269                 params->ortho_scale = rv3d->dist;
270                 params->zoom = 2.0f;
271         }
272         else {
273                 /* perspective view */
274                 params->zoom = 2.0f;
275         }
276 }
277
278 void BKE_camera_params_compute_viewplane(CameraParams *params, int winx, int winy, float xasp, float yasp)
279 {
280         rctf viewplane;
281         float pixsize, viewfac, sensor_size, dx, dy;
282         int sensor_fit;
283
284         /* fields rendering */
285         params->ycor = yasp / xasp;
286         if (params->use_fields)
287                 params->ycor *= 2.0f;
288
289         if (params->is_ortho) {
290                 /* orthographic camera */
291                 /* scale == 1.0 means exact 1 to 1 mapping */
292                 pixsize = params->ortho_scale;
293         }
294         else {
295                 /* perspective camera */
296                 sensor_size = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y);
297                 pixsize = (sensor_size * params->clipsta) / params->lens;
298         }
299
300         /* determine sensor fit */
301         sensor_fit = BKE_camera_sensor_fit(params->sensor_fit, xasp * winx, yasp * winy);
302
303         if (sensor_fit == CAMERA_SENSOR_FIT_HOR)
304                 viewfac = winx;
305         else
306                 viewfac = params->ycor * winy;
307
308         pixsize /= viewfac;
309
310         /* extra zoom factor */
311         pixsize *= params->zoom;
312
313         /* compute view plane:
314          * fully centered, zbuffer fills in jittered between -.5 and +.5 */
315         viewplane.xmin = -0.5f * (float)winx;
316         viewplane.ymin = -0.5f * params->ycor * (float)winy;
317         viewplane.xmax =  0.5f * (float)winx;
318         viewplane.ymax =  0.5f * params->ycor * (float)winy;
319
320         /* lens shift and offset */
321         dx = params->shiftx * viewfac + winx * params->offsetx;
322         dy = params->shifty * viewfac + winy * params->offsety;
323
324         viewplane.xmin += dx;
325         viewplane.ymin += dy;
326         viewplane.xmax += dx;
327         viewplane.ymax += dy;
328
329         /* fields offset */
330         if (params->field_second) {
331                 if (params->field_odd) {
332                         viewplane.ymin -= 0.5f * params->ycor;
333                         viewplane.ymax -= 0.5f * params->ycor;
334                 }
335                 else {
336                         viewplane.ymin += 0.5f * params->ycor;
337                         viewplane.ymax += 0.5f * params->ycor;
338                 }
339         }
340
341         /* the window matrix is used for clipping, and not changed during OSA steps */
342         /* using an offset of +0.5 here would give clip errors on edges */
343         viewplane.xmin *= pixsize;
344         viewplane.xmax *= pixsize;
345         viewplane.ymin *= pixsize;
346         viewplane.ymax *= pixsize;
347
348         params->viewdx = pixsize;
349         params->viewdy = params->ycor * pixsize;
350         params->viewplane = viewplane;
351 }
352
353 /* viewplane is assumed to be already computed */
354 void BKE_camera_params_compute_matrix(CameraParams *params)
355 {
356         rctf viewplane = params->viewplane;
357
358         /* compute projection matrix */
359         if (params->is_ortho)
360                 orthographic_m4(params->winmat, viewplane.xmin, viewplane.xmax,
361                                 viewplane.ymin, viewplane.ymax, params->clipsta, params->clipend);
362         else
363                 perspective_m4(params->winmat, viewplane.xmin, viewplane.xmax,
364                                viewplane.ymin, viewplane.ymax, params->clipsta, params->clipend);
365 }
366
367 /***************************** Camera View Frame *****************************/
368
369 void BKE_camera_view_frame_ex(Scene *scene, Camera *camera, float drawsize, const short do_clip, const float scale[3],
370                               float r_asp[2], float r_shift[2], float *r_drawsize, float r_vec[4][3])
371 {
372         float facx, facy;
373         float depth;
374
375         /* aspect correcton */
376         if (scene) {
377                 float aspx = (float) scene->r.xsch * scene->r.xasp;
378                 float aspy = (float) scene->r.ysch * scene->r.yasp;
379                 int sensor_fit = BKE_camera_sensor_fit(camera->sensor_fit, aspx, aspy);
380
381                 if (sensor_fit == CAMERA_SENSOR_FIT_HOR) {
382                         r_asp[0] = 1.0;
383                         r_asp[1] = aspy / aspx;
384                 }
385                 else {
386                         r_asp[0] = aspx / aspy;
387                         r_asp[1] = 1.0;
388                 }
389         }
390         else {
391                 r_asp[0] = 1.0f;
392                 r_asp[1] = 1.0f;
393         }
394
395         if (camera->type == CAM_ORTHO) {
396                 facx = 0.5f * camera->ortho_scale * r_asp[0] * scale[0];
397                 facy = 0.5f * camera->ortho_scale * r_asp[1] * scale[1];
398                 r_shift[0] = camera->shiftx * camera->ortho_scale * scale[0];
399                 r_shift[1] = camera->shifty * camera->ortho_scale * scale[1];
400                 depth = do_clip ? -((camera->clipsta * scale[2]) + 0.1f) : -drawsize * camera->ortho_scale * scale[2];
401
402                 *r_drawsize = 0.5f * camera->ortho_scale;
403         }
404         else {
405                 /* that way it's always visible - clipsta+0.1 */
406                 float fac;
407                 float half_sensor = 0.5f * ((camera->sensor_fit == CAMERA_SENSOR_FIT_VERT) ? (camera->sensor_y) : (camera->sensor_x));
408
409                 *r_drawsize = drawsize / ((scale[0] + scale[1] + scale[2]) / 3.0f);
410
411                 if (do_clip) {
412                         /* fixed depth, variable size (avoids exceeding clipping range) */
413                         depth = -(camera->clipsta + 0.1f);
414                         fac = depth / (camera->lens / (-half_sensor) * scale[2]);
415                 }
416                 else {
417                         /* fixed size, variable depth (stays a reasonable size in the 3D view) */
418                         depth = *r_drawsize * camera->lens / (-half_sensor) * scale[2];
419                         fac = *r_drawsize;
420                 }
421
422                 facx = fac * r_asp[0] * scale[0];
423                 facy = fac * r_asp[1] * scale[1];
424                 r_shift[0] = camera->shiftx * fac * 2 * scale[0];
425                 r_shift[1] = camera->shifty * fac * 2 * scale[1];
426         }
427
428         r_vec[0][0] = r_shift[0] + facx; r_vec[0][1] = r_shift[1] + facy; r_vec[0][2] = depth;
429         r_vec[1][0] = r_shift[0] + facx; r_vec[1][1] = r_shift[1] - facy; r_vec[1][2] = depth;
430         r_vec[2][0] = r_shift[0] - facx; r_vec[2][1] = r_shift[1] - facy; r_vec[2][2] = depth;
431         r_vec[3][0] = r_shift[0] - facx; r_vec[3][1] = r_shift[1] + facy; r_vec[3][2] = depth;
432 }
433
434 void BKE_camera_view_frame(Scene *scene, Camera *camera, float r_vec[4][3])
435 {
436         float dummy_asp[2];
437         float dummy_shift[2];
438         float dummy_drawsize;
439         const float dummy_scale[3] = {1.0f, 1.0f, 1.0f};
440
441         BKE_camera_view_frame_ex(scene, camera, FALSE, 1.0, dummy_scale,
442                                  dummy_asp, dummy_shift, &dummy_drawsize, r_vec);
443 }
444
445
446 typedef struct CameraViewFrameData {
447         float frame_tx[4][3];
448         float normal_tx[4][3];
449         float dist_vals[4];
450         unsigned int tot;
451 } CameraViewFrameData;
452
453 static void BKE_camera_to_frame_view_cb(const float co[3], void *user_data)
454 {
455         CameraViewFrameData *data = (CameraViewFrameData *)user_data;
456         unsigned int i;
457
458         for (i = 0; i < 4; i++) {
459                 float nd = dist_to_plane_v3(co, data->frame_tx[i], data->normal_tx[i]);
460                 if (nd < data->dist_vals[i]) {
461                         data->dist_vals[i] = nd;
462                 }
463         }
464
465         data->tot++;
466 }
467
468 /* don't move the camera, just yield the fit location */
469 /* only valid for perspective cameras */
470 int BKE_camera_view_frame_fit_to_scene(Scene *scene, struct View3D *v3d, Object *camera_ob, float r_co[3])
471 {
472         float shift[2];
473         float plane_tx[4][3];
474         float rot_obmat[3][3];
475         const float zero[3] = {0, 0, 0};
476         CameraViewFrameData data_cb;
477
478         unsigned int i;
479
480         BKE_camera_view_frame(scene, camera_ob->data, data_cb.frame_tx);
481
482         copy_m3_m4(rot_obmat, camera_ob->obmat);
483         normalize_m3(rot_obmat);
484
485         for (i = 0; i < 4; i++) {
486                 /* normalize so Z is always 1.0f*/
487                 mul_v3_fl(data_cb.frame_tx[i], 1.0f / data_cb.frame_tx[i][2]);
488         }
489
490         /* get the shift back out of the frame */
491         shift[0] = (data_cb.frame_tx[0][0] +
492                     data_cb.frame_tx[1][0] +
493                     data_cb.frame_tx[2][0] +
494                     data_cb.frame_tx[3][0]) / 4.0f;
495         shift[1] = (data_cb.frame_tx[0][1] +
496                     data_cb.frame_tx[1][1] +
497                     data_cb.frame_tx[2][1] +
498                     data_cb.frame_tx[3][1]) / 4.0f;
499
500         for (i = 0; i < 4; i++) {
501                 mul_m3_v3(rot_obmat, data_cb.frame_tx[i]);
502         }
503
504         for (i = 0; i < 4; i++) {
505                 normal_tri_v3(data_cb.normal_tx[i],
506                               zero, data_cb.frame_tx[i], data_cb.frame_tx[(i + 1) % 4]);
507         }
508
509         /* initialize callback data */
510         data_cb.dist_vals[0] =
511         data_cb.dist_vals[1] =
512         data_cb.dist_vals[2] =
513         data_cb.dist_vals[3] = FLT_MAX;
514         data_cb.tot = 0;
515         /* run callback on all visible points */
516         BKE_scene_foreach_display_point(scene, v3d, BA_SELECT,
517                                         BKE_camera_to_frame_view_cb, &data_cb);
518
519         if (data_cb.tot <= 1) {
520                 return FALSE;
521         }
522         else {
523                 float plane_isect_1[3], plane_isect_1_no[3], plane_isect_1_other[3];
524                 float plane_isect_2[3], plane_isect_2_no[3], plane_isect_2_other[3];
525
526                 float plane_isect_pt_1[3], plane_isect_pt_2[3];
527
528                 /* apply the dist-from-plane's to the transformed plane points */
529                 for (i = 0; i < 4; i++) {
530                         mul_v3_v3fl(plane_tx[i], data_cb.normal_tx[i], data_cb.dist_vals[i]);
531                 }
532
533                 isect_plane_plane_v3(plane_isect_1, plane_isect_1_no,
534                                      plane_tx[0], data_cb.normal_tx[0],
535                                      plane_tx[2], data_cb.normal_tx[2]);
536                 isect_plane_plane_v3(plane_isect_2, plane_isect_2_no,
537                                      plane_tx[1], data_cb.normal_tx[1],
538                                      plane_tx[3], data_cb.normal_tx[3]);
539
540                 add_v3_v3v3(plane_isect_1_other, plane_isect_1, plane_isect_1_no);
541                 add_v3_v3v3(plane_isect_2_other, plane_isect_2, plane_isect_2_no);
542
543                 if (isect_line_line_v3(plane_isect_1, plane_isect_1_other,
544                                        plane_isect_2, plane_isect_2_other,
545                                        plane_isect_pt_1, plane_isect_pt_2) == 0)
546                 {
547                         return FALSE;
548                 }
549                 else {
550                         float cam_plane_no[3] = {0.0f, 0.0f, -1.0f};
551                         float plane_isect_delta[3];
552                         float plane_isect_delta_len;
553
554                         mul_m3_v3(rot_obmat, cam_plane_no);
555
556                         sub_v3_v3v3(plane_isect_delta, plane_isect_pt_2, plane_isect_pt_1);
557                         plane_isect_delta_len = len_v3(plane_isect_delta);
558
559                         if (dot_v3v3(plane_isect_delta, cam_plane_no) > 0.0f) {
560                                 copy_v3_v3(r_co, plane_isect_pt_1);
561
562                                 /* offset shift */
563                                 normalize_v3(plane_isect_1_no);
564                                 madd_v3_v3fl(r_co, plane_isect_1_no, shift[1] * -plane_isect_delta_len);
565                         }
566                         else {
567                                 copy_v3_v3(r_co, plane_isect_pt_2);
568
569                                 /* offset shift */
570                                 normalize_v3(plane_isect_2_no);
571                                 madd_v3_v3fl(r_co, plane_isect_2_no, shift[0] * -plane_isect_delta_len);
572                         }
573
574
575                         return TRUE;
576                 }
577         }
578 }