Patch #34204: [Render Animation] Fails with "Error: Specified sample_fmt is not suppo...
[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(Main *bmain, const char *name)
54 {
55         Camera *cam;
56         
57         cam =  BKE_libblock_alloc(&bmain->camera, ID_CA, name);
58
59         cam->lens = 35.0f;
60         cam->sensor_x = DEFAULT_SENSOR_WIDTH;
61         cam->sensor_y = DEFAULT_SENSOR_HEIGHT;
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         else {
241                 params->lens = 35.0f;
242         }
243 }
244
245 void BKE_camera_params_from_view3d(CameraParams *params, View3D *v3d, RegionView3D *rv3d)
246 {
247         /* common */
248         params->lens = v3d->lens;
249         params->clipsta = v3d->near;
250         params->clipend = v3d->far;
251
252         if (rv3d->persp == RV3D_CAMOB) {
253                 /* camera view */
254                 BKE_camera_params_from_object(params, v3d->camera);
255
256                 params->zoom = BKE_screen_view3d_zoom_to_fac((float)rv3d->camzoom);
257
258                 params->offsetx = 2.0f * rv3d->camdx * params->zoom;
259                 params->offsety = 2.0f * rv3d->camdy * params->zoom;
260
261                 params->shiftx *= params->zoom;
262                 params->shifty *= params->zoom;
263
264                 params->zoom = 1.0f / params->zoom;
265         }
266         else if (rv3d->persp == RV3D_ORTHO) {
267                 /* orthographic view */
268                 int sensor_size = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y);
269                 params->clipend *= 0.5f;    // otherwise too extreme low zbuffer quality
270                 params->clipsta = -params->clipend;
271
272                 params->is_ortho = TRUE;
273                 /* make sure any changes to this match ED_view3d_radius_to_ortho_dist() */
274                 params->ortho_scale = rv3d->dist * sensor_size / v3d->lens;
275                 params->zoom = 2.0f;
276         }
277         else {
278                 /* perspective view */
279                 params->zoom = 2.0f;
280         }
281 }
282
283 void BKE_camera_params_compute_viewplane(CameraParams *params, int winx, int winy, float xasp, float yasp)
284 {
285         rctf viewplane;
286         float pixsize, viewfac, sensor_size, dx, dy;
287         int sensor_fit;
288
289         /* fields rendering */
290         params->ycor = yasp / xasp;
291         if (params->use_fields)
292                 params->ycor *= 2.0f;
293
294         if (params->is_ortho) {
295                 /* orthographic camera */
296                 /* scale == 1.0 means exact 1 to 1 mapping */
297                 pixsize = params->ortho_scale;
298         }
299         else {
300                 /* perspective camera */
301                 sensor_size = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y);
302                 pixsize = (sensor_size * params->clipsta) / params->lens;
303         }
304
305         /* determine sensor fit */
306         sensor_fit = BKE_camera_sensor_fit(params->sensor_fit, xasp * winx, yasp * winy);
307
308         if (sensor_fit == CAMERA_SENSOR_FIT_HOR)
309                 viewfac = winx;
310         else
311                 viewfac = params->ycor * winy;
312
313         pixsize /= viewfac;
314
315         /* extra zoom factor */
316         pixsize *= params->zoom;
317
318         /* compute view plane:
319          * fully centered, zbuffer fills in jittered between -.5 and +.5 */
320         viewplane.xmin = -0.5f * (float)winx;
321         viewplane.ymin = -0.5f * params->ycor * (float)winy;
322         viewplane.xmax =  0.5f * (float)winx;
323         viewplane.ymax =  0.5f * params->ycor * (float)winy;
324
325         /* lens shift and offset */
326         dx = params->shiftx * viewfac + winx * params->offsetx;
327         dy = params->shifty * viewfac + winy * params->offsety;
328
329         viewplane.xmin += dx;
330         viewplane.ymin += dy;
331         viewplane.xmax += dx;
332         viewplane.ymax += dy;
333
334         /* fields offset */
335         if (params->field_second) {
336                 if (params->field_odd) {
337                         viewplane.ymin -= 0.5f * params->ycor;
338                         viewplane.ymax -= 0.5f * params->ycor;
339                 }
340                 else {
341                         viewplane.ymin += 0.5f * params->ycor;
342                         viewplane.ymax += 0.5f * params->ycor;
343                 }
344         }
345
346         /* the window matrix is used for clipping, and not changed during OSA steps */
347         /* using an offset of +0.5 here would give clip errors on edges */
348         viewplane.xmin *= pixsize;
349         viewplane.xmax *= pixsize;
350         viewplane.ymin *= pixsize;
351         viewplane.ymax *= pixsize;
352
353         params->viewdx = pixsize;
354         params->viewdy = params->ycor * pixsize;
355         params->viewplane = viewplane;
356 }
357
358 /* viewplane is assumed to be already computed */
359 void BKE_camera_params_compute_matrix(CameraParams *params)
360 {
361         rctf viewplane = params->viewplane;
362
363         /* compute projection matrix */
364         if (params->is_ortho)
365                 orthographic_m4(params->winmat, viewplane.xmin, viewplane.xmax,
366                                 viewplane.ymin, viewplane.ymax, params->clipsta, params->clipend);
367         else
368                 perspective_m4(params->winmat, viewplane.xmin, viewplane.xmax,
369                                viewplane.ymin, viewplane.ymax, params->clipsta, params->clipend);
370 }
371
372 /***************************** Camera View Frame *****************************/
373
374 void BKE_camera_view_frame_ex(Scene *scene, Camera *camera, float drawsize, const short do_clip, const float scale[3],
375                               float r_asp[2], float r_shift[2], float *r_drawsize, float r_vec[4][3])
376 {
377         float facx, facy;
378         float depth;
379
380         /* aspect correcton */
381         if (scene) {
382                 float aspx = (float) scene->r.xsch * scene->r.xasp;
383                 float aspy = (float) scene->r.ysch * scene->r.yasp;
384                 int sensor_fit = BKE_camera_sensor_fit(camera->sensor_fit, aspx, aspy);
385
386                 if (sensor_fit == CAMERA_SENSOR_FIT_HOR) {
387                         r_asp[0] = 1.0;
388                         r_asp[1] = aspy / aspx;
389                 }
390                 else {
391                         r_asp[0] = aspx / aspy;
392                         r_asp[1] = 1.0;
393                 }
394         }
395         else {
396                 r_asp[0] = 1.0f;
397                 r_asp[1] = 1.0f;
398         }
399
400         if (camera->type == CAM_ORTHO) {
401                 facx = 0.5f * camera->ortho_scale * r_asp[0] * scale[0];
402                 facy = 0.5f * camera->ortho_scale * r_asp[1] * scale[1];
403                 r_shift[0] = camera->shiftx * camera->ortho_scale * scale[0];
404                 r_shift[1] = camera->shifty * camera->ortho_scale * scale[1];
405                 depth = do_clip ? -((camera->clipsta * scale[2]) + 0.1f) : -drawsize * camera->ortho_scale * scale[2];
406
407                 *r_drawsize = 0.5f * camera->ortho_scale;
408         }
409         else {
410                 /* that way it's always visible - clipsta+0.1 */
411                 float fac;
412                 float half_sensor = 0.5f * ((camera->sensor_fit == CAMERA_SENSOR_FIT_VERT) ? (camera->sensor_y) : (camera->sensor_x));
413
414                 *r_drawsize = drawsize / ((scale[0] + scale[1] + scale[2]) / 3.0f);
415
416                 if (do_clip) {
417                         /* fixed depth, variable size (avoids exceeding clipping range) */
418                         depth = -(camera->clipsta + 0.1f);
419                         fac = depth / (camera->lens / (-half_sensor) * scale[2]);
420                 }
421                 else {
422                         /* fixed size, variable depth (stays a reasonable size in the 3D view) */
423                         depth = *r_drawsize * camera->lens / (-half_sensor) * scale[2];
424                         fac = *r_drawsize;
425                 }
426
427                 facx = fac * r_asp[0] * scale[0];
428                 facy = fac * r_asp[1] * scale[1];
429                 r_shift[0] = camera->shiftx * fac * 2 * scale[0];
430                 r_shift[1] = camera->shifty * fac * 2 * scale[1];
431         }
432
433         r_vec[0][0] = r_shift[0] + facx; r_vec[0][1] = r_shift[1] + facy; r_vec[0][2] = depth;
434         r_vec[1][0] = r_shift[0] + facx; r_vec[1][1] = r_shift[1] - facy; r_vec[1][2] = depth;
435         r_vec[2][0] = r_shift[0] - facx; r_vec[2][1] = r_shift[1] - facy; r_vec[2][2] = depth;
436         r_vec[3][0] = r_shift[0] - facx; r_vec[3][1] = r_shift[1] + facy; r_vec[3][2] = depth;
437 }
438
439 void BKE_camera_view_frame(Scene *scene, Camera *camera, float r_vec[4][3])
440 {
441         float dummy_asp[2];
442         float dummy_shift[2];
443         float dummy_drawsize;
444         const float dummy_scale[3] = {1.0f, 1.0f, 1.0f};
445
446         BKE_camera_view_frame_ex(scene, camera, FALSE, 1.0, dummy_scale,
447                                  dummy_asp, dummy_shift, &dummy_drawsize, r_vec);
448 }
449
450
451 typedef struct CameraViewFrameData {
452         float frame_tx[4][3];
453         float normal_tx[4][3];
454         float dist_vals[4];
455         unsigned int tot;
456 } CameraViewFrameData;
457
458 static void BKE_camera_to_frame_view_cb(const float co[3], void *user_data)
459 {
460         CameraViewFrameData *data = (CameraViewFrameData *)user_data;
461         unsigned int i;
462
463         for (i = 0; i < 4; i++) {
464                 float nd = dist_to_plane_v3(co, data->frame_tx[i], data->normal_tx[i]);
465                 if (nd < data->dist_vals[i]) {
466                         data->dist_vals[i] = nd;
467                 }
468         }
469
470         data->tot++;
471 }
472
473 /* don't move the camera, just yield the fit location */
474 /* only valid for perspective cameras */
475 int BKE_camera_view_frame_fit_to_scene(Scene *scene, struct View3D *v3d, Object *camera_ob, float r_co[3])
476 {
477         float shift[2];
478         float plane_tx[4][3];
479         float rot_obmat[3][3];
480         const float zero[3] = {0, 0, 0};
481         CameraViewFrameData data_cb;
482
483         unsigned int i;
484
485         BKE_camera_view_frame(scene, camera_ob->data, data_cb.frame_tx);
486
487         copy_m3_m4(rot_obmat, camera_ob->obmat);
488         normalize_m3(rot_obmat);
489
490         for (i = 0; i < 4; i++) {
491                 /* normalize so Z is always 1.0f*/
492                 mul_v3_fl(data_cb.frame_tx[i], 1.0f / data_cb.frame_tx[i][2]);
493         }
494
495         /* get the shift back out of the frame */
496         shift[0] = (data_cb.frame_tx[0][0] +
497                     data_cb.frame_tx[1][0] +
498                     data_cb.frame_tx[2][0] +
499                     data_cb.frame_tx[3][0]) / 4.0f;
500         shift[1] = (data_cb.frame_tx[0][1] +
501                     data_cb.frame_tx[1][1] +
502                     data_cb.frame_tx[2][1] +
503                     data_cb.frame_tx[3][1]) / 4.0f;
504
505         for (i = 0; i < 4; i++) {
506                 mul_m3_v3(rot_obmat, data_cb.frame_tx[i]);
507         }
508
509         for (i = 0; i < 4; i++) {
510                 normal_tri_v3(data_cb.normal_tx[i],
511                               zero, data_cb.frame_tx[i], data_cb.frame_tx[(i + 1) % 4]);
512         }
513
514         /* initialize callback data */
515         data_cb.dist_vals[0] =
516         data_cb.dist_vals[1] =
517         data_cb.dist_vals[2] =
518         data_cb.dist_vals[3] = FLT_MAX;
519         data_cb.tot = 0;
520         /* run callback on all visible points */
521         BKE_scene_foreach_display_point(scene, v3d, BA_SELECT,
522                                         BKE_camera_to_frame_view_cb, &data_cb);
523
524         if (data_cb.tot <= 1) {
525                 return FALSE;
526         }
527         else {
528                 float plane_isect_1[3], plane_isect_1_no[3], plane_isect_1_other[3];
529                 float plane_isect_2[3], plane_isect_2_no[3], plane_isect_2_other[3];
530
531                 float plane_isect_pt_1[3], plane_isect_pt_2[3];
532
533                 /* apply the dist-from-plane's to the transformed plane points */
534                 for (i = 0; i < 4; i++) {
535                         mul_v3_v3fl(plane_tx[i], data_cb.normal_tx[i], data_cb.dist_vals[i]);
536                 }
537
538                 isect_plane_plane_v3(plane_isect_1, plane_isect_1_no,
539                                      plane_tx[0], data_cb.normal_tx[0],
540                                      plane_tx[2], data_cb.normal_tx[2]);
541                 isect_plane_plane_v3(plane_isect_2, plane_isect_2_no,
542                                      plane_tx[1], data_cb.normal_tx[1],
543                                      plane_tx[3], data_cb.normal_tx[3]);
544
545                 add_v3_v3v3(plane_isect_1_other, plane_isect_1, plane_isect_1_no);
546                 add_v3_v3v3(plane_isect_2_other, plane_isect_2, plane_isect_2_no);
547
548                 if (isect_line_line_v3(plane_isect_1, plane_isect_1_other,
549                                        plane_isect_2, plane_isect_2_other,
550                                        plane_isect_pt_1, plane_isect_pt_2) == 0)
551                 {
552                         return FALSE;
553                 }
554                 else {
555                         float cam_plane_no[3] = {0.0f, 0.0f, -1.0f};
556                         float plane_isect_delta[3];
557                         float plane_isect_delta_len;
558
559                         mul_m3_v3(rot_obmat, cam_plane_no);
560
561                         sub_v3_v3v3(plane_isect_delta, plane_isect_pt_2, plane_isect_pt_1);
562                         plane_isect_delta_len = len_v3(plane_isect_delta);
563
564                         if (dot_v3v3(plane_isect_delta, cam_plane_no) > 0.0f) {
565                                 copy_v3_v3(r_co, plane_isect_pt_1);
566
567                                 /* offset shift */
568                                 normalize_v3(plane_isect_1_no);
569                                 madd_v3_v3fl(r_co, plane_isect_1_no, shift[1] * -plane_isect_delta_len);
570                         }
571                         else {
572                                 copy_v3_v3(r_co, plane_isect_pt_2);
573
574                                 /* offset shift */
575                                 normalize_v3(plane_isect_2_no);
576                                 madd_v3_v3fl(r_co, plane_isect_2_no, shift[0] * -plane_isect_delta_len);
577                         }
578
579
580                         return TRUE;
581                 }
582         }
583 }