Cleanup: remove redundant doxygen \file argument
[blender.git] / source / blender / blenkernel / intern / camera.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19
20 /** \file \ingroup bke
21  */
22
23 #include <stdlib.h>
24 #include <stddef.h>
25
26 #include "DNA_camera_types.h"
27 #include "DNA_lamp_types.h"
28 #include "DNA_object_types.h"
29 #include "DNA_scene_types.h"
30 #include "DNA_view3d_types.h"
31 #include "DNA_ID.h"
32
33 #include "BLI_math.h"
34 #include "BLI_listbase.h"
35 #include "BLI_rect.h"
36 #include "BLI_string.h"
37 #include "BLI_utildefines.h"
38
39 #include "BKE_animsys.h"
40 #include "BKE_camera.h"
41 #include "BKE_object.h"
42 #include "BKE_layer.h"
43 #include "BKE_library.h"
44 #include "BKE_main.h"
45 #include "BKE_scene.h"
46 #include "BKE_screen.h"
47
48 #include "DEG_depsgraph_query.h"
49
50 #include "MEM_guardedalloc.h"
51
52 /****************************** Camera Datablock *****************************/
53
54 void BKE_camera_init(Camera *cam)
55 {
56         BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(cam, id));
57
58         cam->lens = 50.0f;
59         cam->sensor_x = DEFAULT_SENSOR_WIDTH;
60         cam->sensor_y = DEFAULT_SENSOR_HEIGHT;
61         cam->clipsta = 0.1f;
62         cam->clipend = 1000.0f;
63         cam->drawsize = 1.0f;
64         cam->ortho_scale = 6.0;
65         cam->flag |= CAM_SHOWPASSEPARTOUT;
66         cam->passepartalpha = 0.5f;
67
68         cam->gpu_dof.fstop = 128.0f;
69         cam->gpu_dof.ratio = 1.0f;
70
71         /* stereoscopy 3d */
72         cam->stereo.interocular_distance = 0.065f;
73         cam->stereo.convergence_distance = 30.f * 0.065f;
74         cam->stereo.pole_merge_angle_from = DEG2RADF(60.0f);
75         cam->stereo.pole_merge_angle_to = DEG2RADF(75.0f);
76 }
77
78 void *BKE_camera_add(Main *bmain, const char *name)
79 {
80         Camera *cam;
81
82         cam =  BKE_libblock_alloc(bmain, ID_CA, name, 0);
83
84         BKE_camera_init(cam);
85
86         return cam;
87 }
88
89 /**
90  * Only copy internal data of Camera ID from source to already allocated/initialized destination.
91  * You probably never want to use that directly, use BKE_id_copy or BKE_id_copy_ex for typical needs.
92  *
93  * WARNING! This function will not handle ID user count!
94  *
95  * \param flag: Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
96  */
97 void BKE_camera_copy_data(Main *UNUSED(bmain), Camera *cam_dst, const Camera *cam_src, const int UNUSED(flag))
98 {
99         BLI_duplicatelist(&cam_dst->bg_images, &cam_src->bg_images);
100 }
101
102 Camera *BKE_camera_copy(Main *bmain, const Camera *cam)
103 {
104         Camera *cam_copy;
105         BKE_id_copy(bmain, &cam->id, (ID **)&cam_copy);
106         return cam_copy;
107 }
108
109 void BKE_camera_make_local(Main *bmain, Camera *cam, const bool lib_local)
110 {
111         BKE_id_make_local_generic(bmain, &cam->id, true, lib_local);
112 }
113
114 /** Free (or release) any data used by this camera (does not free the camera itself). */
115 void BKE_camera_free(Camera *ca)
116 {
117         BLI_freelistN(&ca->bg_images);
118
119         BKE_animdata_free((ID *)ca, false);
120 }
121
122 /******************************** Camera Usage *******************************/
123
124 /* get the camera's dof value, takes the dof object into account */
125 float BKE_camera_object_dof_distance(Object *ob)
126 {
127         Camera *cam = (Camera *)ob->data;
128         if (ob->type != OB_CAMERA)
129                 return 0.0f;
130         if (cam->dof_ob) {
131                 float view_dir[3], dof_dir[3];
132                 normalize_v3_v3(view_dir, ob->obmat[2]);
133                 sub_v3_v3v3(dof_dir, ob->obmat[3], cam->dof_ob->obmat[3]);
134                 return fabsf(dot_v3v3(view_dir, dof_dir));
135         }
136         return cam->YF_dofdist;
137 }
138
139 float BKE_camera_sensor_size(int sensor_fit, float sensor_x, float sensor_y)
140 {
141         /* sensor size used to fit to. for auto, sensor_x is both x and y. */
142         if (sensor_fit == CAMERA_SENSOR_FIT_VERT)
143                 return sensor_y;
144
145         return sensor_x;
146 }
147
148 int BKE_camera_sensor_fit(int sensor_fit, float sizex, float sizey)
149 {
150         if (sensor_fit == CAMERA_SENSOR_FIT_AUTO) {
151                 if (sizex >= sizey)
152                         return CAMERA_SENSOR_FIT_HOR;
153                 else
154                         return CAMERA_SENSOR_FIT_VERT;
155         }
156
157         return sensor_fit;
158 }
159
160 /******************************** Camera Params *******************************/
161
162 void BKE_camera_params_init(CameraParams *params)
163 {
164         memset(params, 0, sizeof(CameraParams));
165
166         /* defaults */
167         params->sensor_x = DEFAULT_SENSOR_WIDTH;
168         params->sensor_y = DEFAULT_SENSOR_HEIGHT;
169         params->sensor_fit = CAMERA_SENSOR_FIT_AUTO;
170
171         params->zoom = 1.0f;
172
173         /* fallback for non camera objects */
174         params->clipsta = 0.1f;
175         params->clipend = 100.0f;
176 }
177
178 void BKE_camera_params_from_object(CameraParams *params, const Object *ob)
179 {
180         if (!ob)
181                 return;
182
183         if (ob->type == OB_CAMERA) {
184                 /* camera object */
185                 Camera *cam = ob->data;
186
187                 if (cam->type == CAM_ORTHO)
188                         params->is_ortho = true;
189                 params->lens = cam->lens;
190                 params->ortho_scale = cam->ortho_scale;
191
192                 params->shiftx = cam->shiftx;
193                 params->shifty = cam->shifty;
194
195                 params->sensor_x = cam->sensor_x;
196                 params->sensor_y = cam->sensor_y;
197                 params->sensor_fit = cam->sensor_fit;
198
199                 params->clipsta = cam->clipsta;
200                 params->clipend = cam->clipend;
201         }
202         else if (ob->type == OB_LAMP) {
203                 /* lamp object */
204                 Lamp *la = ob->data;
205                 params->lens = 16.0f / tanf(la->spotsize * 0.5f);
206                 if (params->lens == 0.0f)
207                         params->lens = 35.0f;
208
209                 params->clipsta = la->clipsta;
210                 params->clipend = la->clipend;
211         }
212         else {
213                 params->lens = 35.0f;
214         }
215 }
216
217 void BKE_camera_params_from_view3d(CameraParams *params, Depsgraph *depsgraph, const View3D *v3d, const RegionView3D *rv3d)
218 {
219         /* common */
220         params->lens = v3d->lens;
221         params->clipsta = v3d->near;
222         params->clipend = v3d->far;
223
224         if (rv3d->persp == RV3D_CAMOB) {
225                 /* camera view */
226                 const Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
227                 BKE_camera_params_from_object(params, ob_camera_eval);
228
229                 params->zoom = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom);
230
231                 params->offsetx = 2.0f * rv3d->camdx * params->zoom;
232                 params->offsety = 2.0f * rv3d->camdy * params->zoom;
233
234                 params->shiftx *= params->zoom;
235                 params->shifty *= params->zoom;
236
237                 params->zoom = CAMERA_PARAM_ZOOM_INIT_CAMOB / params->zoom;
238         }
239         else if (rv3d->persp == RV3D_ORTHO) {
240                 /* orthographic view */
241                 float sensor_size = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y);
242                 params->clipend *= 0.5f;    // otherwise too extreme low zbuffer quality
243                 params->clipsta = -params->clipend;
244
245                 params->is_ortho = true;
246                 /* make sure any changes to this match ED_view3d_radius_to_dist_ortho() */
247                 params->ortho_scale = rv3d->dist * sensor_size / v3d->lens;
248                 params->zoom = CAMERA_PARAM_ZOOM_INIT_PERSP;
249         }
250         else {
251                 /* perspective view */
252                 params->zoom = CAMERA_PARAM_ZOOM_INIT_PERSP;
253         }
254 }
255
256 void BKE_camera_params_compute_viewplane(CameraParams *params, int winx, int winy, float xasp, float yasp)
257 {
258         rctf viewplane;
259         float pixsize, viewfac, sensor_size, dx, dy;
260         int sensor_fit;
261
262         params->ycor = yasp / xasp;
263
264         if (params->is_ortho) {
265                 /* orthographic camera */
266                 /* scale == 1.0 means exact 1 to 1 mapping */
267                 pixsize = params->ortho_scale;
268         }
269         else {
270                 /* perspective camera */
271                 sensor_size = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y);
272                 pixsize = (sensor_size * params->clipsta) / params->lens;
273         }
274
275         /* determine sensor fit */
276         sensor_fit = BKE_camera_sensor_fit(params->sensor_fit, xasp * winx, yasp * winy);
277
278         if (sensor_fit == CAMERA_SENSOR_FIT_HOR)
279                 viewfac = winx;
280         else
281                 viewfac = params->ycor * winy;
282
283         pixsize /= viewfac;
284
285         /* extra zoom factor */
286         pixsize *= params->zoom;
287
288         /* compute view plane:
289          * fully centered, zbuffer fills in jittered between -.5 and +.5 */
290         viewplane.xmin = -0.5f * (float)winx;
291         viewplane.ymin = -0.5f * params->ycor * (float)winy;
292         viewplane.xmax =  0.5f * (float)winx;
293         viewplane.ymax =  0.5f * params->ycor * (float)winy;
294
295         /* lens shift and offset */
296         dx = params->shiftx * viewfac + winx * params->offsetx;
297         dy = params->shifty * viewfac + winy * params->offsety;
298
299         viewplane.xmin += dx;
300         viewplane.ymin += dy;
301         viewplane.xmax += dx;
302         viewplane.ymax += dy;
303
304         /* the window matrix is used for clipping, and not changed during OSA steps */
305         /* using an offset of +0.5 here would give clip errors on edges */
306         viewplane.xmin *= pixsize;
307         viewplane.xmax *= pixsize;
308         viewplane.ymin *= pixsize;
309         viewplane.ymax *= pixsize;
310
311         /* Used for rendering (offset by near-clip with perspective views), passed to RE_SetPixelSize.
312          * For viewport drawing 'RegionView3D.pixsize'. */
313         params->viewdx = pixsize;
314         params->viewdy = params->ycor * pixsize;
315         params->viewplane = viewplane;
316 }
317
318 /* viewplane is assumed to be already computed */
319 void BKE_camera_params_compute_matrix(CameraParams *params)
320 {
321         rctf viewplane = params->viewplane;
322
323         /* compute projection matrix */
324         if (params->is_ortho)
325                 orthographic_m4(params->winmat, viewplane.xmin, viewplane.xmax,
326                                 viewplane.ymin, viewplane.ymax, params->clipsta, params->clipend);
327         else
328                 perspective_m4(params->winmat, viewplane.xmin, viewplane.xmax,
329                                viewplane.ymin, viewplane.ymax, params->clipsta, params->clipend);
330 }
331
332 /***************************** Camera View Frame *****************************/
333
334 void BKE_camera_view_frame_ex(
335         const Scene *scene, const Camera *camera,
336         const float drawsize, const bool do_clip, const float scale[3],
337         float r_asp[2], float r_shift[2], float *r_drawsize, float r_vec[4][3])
338 {
339         float facx, facy;
340         float depth;
341
342         /* aspect correcton */
343         if (scene) {
344                 float aspx = (float) scene->r.xsch * scene->r.xasp;
345                 float aspy = (float) scene->r.ysch * scene->r.yasp;
346                 int sensor_fit = BKE_camera_sensor_fit(camera->sensor_fit, aspx, aspy);
347
348                 if (sensor_fit == CAMERA_SENSOR_FIT_HOR) {
349                         r_asp[0] = 1.0;
350                         r_asp[1] = aspy / aspx;
351                 }
352                 else {
353                         r_asp[0] = aspx / aspy;
354                         r_asp[1] = 1.0;
355                 }
356         }
357         else {
358                 r_asp[0] = 1.0f;
359                 r_asp[1] = 1.0f;
360         }
361
362         if (camera->type == CAM_ORTHO) {
363                 facx = 0.5f * camera->ortho_scale * r_asp[0] * scale[0];
364                 facy = 0.5f * camera->ortho_scale * r_asp[1] * scale[1];
365                 r_shift[0] = camera->shiftx * camera->ortho_scale * scale[0];
366                 r_shift[1] = camera->shifty * camera->ortho_scale * scale[1];
367                 depth = do_clip ? -((camera->clipsta * scale[2]) + 0.1f) : -drawsize * scale[2];
368
369                 *r_drawsize = 0.5f * camera->ortho_scale;
370         }
371         else {
372                 /* that way it's always visible - clipsta+0.1 */
373                 float fac, scale_x, scale_y;
374                 float half_sensor = 0.5f * ((camera->sensor_fit == CAMERA_SENSOR_FIT_VERT) ?
375                                             (camera->sensor_y) : (camera->sensor_x));
376
377
378                 if (do_clip) {
379                         /* fixed depth, variable size (avoids exceeding clipping range) */
380                         /* r_drawsize shouldn't be used in this case, set to dummy value */
381                         *r_drawsize = 1.0f;
382                         depth = -(camera->clipsta + 0.1f) * scale[2];
383                         fac = depth / (camera->lens / (-half_sensor));
384                         scale_x = scale[0] / scale[2];
385                         scale_y = scale[1] / scale[2];
386                 }
387                 else {
388                         /* fixed size, variable depth (stays a reasonable size in the 3D view) */
389                         *r_drawsize = (drawsize / 2.0f) / ((scale[0] + scale[1] + scale[2]) / 3.0f);
390                         depth = *r_drawsize * camera->lens / (-half_sensor) * scale[2];
391                         fac = *r_drawsize;
392                         scale_x = scale[0];
393                         scale_y = scale[1];
394                 }
395
396                 facx = fac * r_asp[0] * scale_x;
397                 facy = fac * r_asp[1] * scale_y;
398                 r_shift[0] = camera->shiftx * fac * 2.0f * scale_x;
399                 r_shift[1] = camera->shifty * fac * 2.0f * scale_y;
400         }
401
402         r_vec[0][0] = r_shift[0] + facx; r_vec[0][1] = r_shift[1] + facy; r_vec[0][2] = depth;
403         r_vec[1][0] = r_shift[0] + facx; r_vec[1][1] = r_shift[1] - facy; r_vec[1][2] = depth;
404         r_vec[2][0] = r_shift[0] - facx; r_vec[2][1] = r_shift[1] - facy; r_vec[2][2] = depth;
405         r_vec[3][0] = r_shift[0] - facx; r_vec[3][1] = r_shift[1] + facy; r_vec[3][2] = depth;
406 }
407
408 void BKE_camera_view_frame(const Scene *scene, const Camera *camera, float r_vec[4][3])
409 {
410         float dummy_asp[2];
411         float dummy_shift[2];
412         float dummy_drawsize;
413         const float dummy_scale[3] = {1.0f, 1.0f, 1.0f};
414
415         BKE_camera_view_frame_ex(scene, camera, 0.0, true, dummy_scale,
416                                  dummy_asp, dummy_shift, &dummy_drawsize, r_vec);
417 }
418
419 #define CAMERA_VIEWFRAME_NUM_PLANES 4
420
421 typedef struct CameraViewFrameData {
422         float plane_tx[CAMERA_VIEWFRAME_NUM_PLANES][4];  /* 4 planes */
423         float normal_tx[CAMERA_VIEWFRAME_NUM_PLANES][3];
424         float dist_vals_sq[CAMERA_VIEWFRAME_NUM_PLANES];  /* distance squared (signed) */
425         unsigned int tot;
426
427         /* Ortho camera only. */
428         bool is_ortho;
429         float camera_no[3];
430         float dist_to_cam;
431
432         /* Not used by callbacks... */
433         float camera_rotmat[3][3];
434 } CameraViewFrameData;
435
436 static void camera_to_frame_view_cb(const float co[3], void *user_data)
437 {
438         CameraViewFrameData *data = (CameraViewFrameData *)user_data;
439         unsigned int i;
440
441         for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) {
442                 const float nd = dist_signed_squared_to_plane_v3(co, data->plane_tx[i]);
443                 CLAMP_MAX(data->dist_vals_sq[i], nd);
444         }
445
446         if (data->is_ortho) {
447                 const float d = dot_v3v3(data->camera_no, co);
448                 CLAMP_MAX(data->dist_to_cam, d);
449         }
450
451         data->tot++;
452 }
453
454 static void camera_frame_fit_data_init(
455         const Scene *scene, const Object *ob,
456         CameraParams *params, CameraViewFrameData *data)
457 {
458         float camera_rotmat_transposed_inversed[4][4];
459         unsigned int i;
460
461         /* setup parameters */
462         BKE_camera_params_init(params);
463         BKE_camera_params_from_object(params, ob);
464
465         /* compute matrix, viewplane, .. */
466         if (scene) {
467                 BKE_camera_params_compute_viewplane(params, scene->r.xsch, scene->r.ysch, scene->r.xasp, scene->r.yasp);
468         }
469         else {
470                 BKE_camera_params_compute_viewplane(params, 1, 1, 1.0f, 1.0f);
471         }
472         BKE_camera_params_compute_matrix(params);
473
474         /* initialize callback data */
475         copy_m3_m4(data->camera_rotmat, (float (*)[4])ob->obmat);
476         normalize_m3(data->camera_rotmat);
477         /* To transform a plane which is in its homogeneous representation (4d vector),
478          * we need the inverse of the transpose of the transform matrix... */
479         copy_m4_m3(camera_rotmat_transposed_inversed, data->camera_rotmat);
480         transpose_m4(camera_rotmat_transposed_inversed);
481         invert_m4(camera_rotmat_transposed_inversed);
482
483         /* Extract frustum planes from projection matrix. */
484         planes_from_projmat(params->winmat,
485                             /*   left              right                 top              bottom        near  far */
486                             data->plane_tx[2], data->plane_tx[0], data->plane_tx[3], data->plane_tx[1], NULL, NULL);
487
488         /* Rotate planes and get normals from them */
489         for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) {
490                 mul_m4_v4(camera_rotmat_transposed_inversed, data->plane_tx[i]);
491                 normalize_v3_v3(data->normal_tx[i], data->plane_tx[i]);
492         }
493
494         copy_v4_fl(data->dist_vals_sq, FLT_MAX);
495         data->tot = 0;
496         data->is_ortho = params->is_ortho;
497         if (params->is_ortho) {
498                 /* we want (0, 0, -1) transformed by camera_rotmat, this is a quicker shortcut. */
499                 negate_v3_v3(data->camera_no, data->camera_rotmat[2]);
500                 data->dist_to_cam = FLT_MAX;
501         }
502 }
503
504 static bool camera_frame_fit_calc_from_data(
505         CameraParams *params, CameraViewFrameData *data, float r_co[3], float *r_scale)
506 {
507         float plane_tx[CAMERA_VIEWFRAME_NUM_PLANES][4];
508         unsigned int i;
509
510         if (data->tot <= 1) {
511                 return false;
512         }
513
514         if (params->is_ortho) {
515                 const float *cam_axis_x = data->camera_rotmat[0];
516                 const float *cam_axis_y = data->camera_rotmat[1];
517                 const float *cam_axis_z = data->camera_rotmat[2];
518                 float dists[CAMERA_VIEWFRAME_NUM_PLANES];
519                 float scale_diff;
520
521                 /* apply the dist-from-plane's to the transformed plane points */
522                 for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) {
523                         dists[i] = sqrtf_signed(data->dist_vals_sq[i]);
524                 }
525
526                 if ((dists[0] + dists[2]) > (dists[1] + dists[3])) {
527                         scale_diff = (dists[1] + dists[3]) *
528                                      (BLI_rctf_size_x(&params->viewplane) / BLI_rctf_size_y(&params->viewplane));
529                 }
530                 else {
531                         scale_diff = (dists[0] + dists[2]) *
532                                      (BLI_rctf_size_y(&params->viewplane) / BLI_rctf_size_x(&params->viewplane));
533                 }
534                 *r_scale = params->ortho_scale - scale_diff;
535
536                 zero_v3(r_co);
537                 madd_v3_v3fl(r_co, cam_axis_x, (dists[2] - dists[0]) * 0.5f + params->shiftx * scale_diff);
538                 madd_v3_v3fl(r_co, cam_axis_y, (dists[1] - dists[3]) * 0.5f + params->shifty * scale_diff);
539                 madd_v3_v3fl(r_co, cam_axis_z, -(data->dist_to_cam - 1.0f - params->clipsta));
540
541                 return true;
542         }
543         else {
544                 float plane_isect_1[3], plane_isect_1_no[3], plane_isect_1_other[3];
545                 float plane_isect_2[3], plane_isect_2_no[3], plane_isect_2_other[3];
546
547                 float plane_isect_pt_1[3], plane_isect_pt_2[3];
548
549                 /* apply the dist-from-plane's to the transformed plane points */
550                 for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) {
551                         float co[3];
552                         mul_v3_v3fl(co, data->normal_tx[i], sqrtf_signed(data->dist_vals_sq[i]));
553                         plane_from_point_normal_v3(plane_tx[i], co, data->normal_tx[i]);
554                 }
555
556                 if ((!isect_plane_plane_v3(plane_tx[0], plane_tx[2], plane_isect_1, plane_isect_1_no)) ||
557                     (!isect_plane_plane_v3(plane_tx[1], plane_tx[3], plane_isect_2, plane_isect_2_no)))
558                 {
559                         return false;
560                 }
561
562                 add_v3_v3v3(plane_isect_1_other, plane_isect_1, plane_isect_1_no);
563                 add_v3_v3v3(plane_isect_2_other, plane_isect_2, plane_isect_2_no);
564
565                 if (isect_line_line_v3(plane_isect_1, plane_isect_1_other,
566                                        plane_isect_2, plane_isect_2_other,
567                                        plane_isect_pt_1, plane_isect_pt_2) != 0)
568                 {
569                         float cam_plane_no[3];
570                         float plane_isect_delta[3];
571                         float plane_isect_delta_len;
572
573                         float shift_fac = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y) /
574                                           params->lens;
575
576                         /* we want (0, 0, -1) transformed by camera_rotmat, this is a quicker shortcut. */
577                         negate_v3_v3(cam_plane_no, data->camera_rotmat[2]);
578
579                         sub_v3_v3v3(plane_isect_delta, plane_isect_pt_2, plane_isect_pt_1);
580                         plane_isect_delta_len = len_v3(plane_isect_delta);
581
582                         if (dot_v3v3(plane_isect_delta, cam_plane_no) > 0.0f) {
583                                 copy_v3_v3(r_co, plane_isect_pt_1);
584
585                                 /* offset shift */
586                                 normalize_v3(plane_isect_1_no);
587                                 madd_v3_v3fl(r_co, plane_isect_1_no, params->shifty * plane_isect_delta_len * shift_fac);
588                         }
589                         else {
590                                 copy_v3_v3(r_co, plane_isect_pt_2);
591
592                                 /* offset shift */
593                                 normalize_v3(plane_isect_2_no);
594                                 madd_v3_v3fl(r_co, plane_isect_2_no, params->shiftx * plane_isect_delta_len * shift_fac);
595                         }
596
597                         return true;
598                 }
599         }
600
601         return false;
602 }
603
604 /* don't move the camera, just yield the fit location */
605 /* r_scale only valid/useful for ortho cameras */
606 bool BKE_camera_view_frame_fit_to_scene(
607         Depsgraph *depsgraph, Scene *scene, Object *camera_ob, float r_co[3], float *r_scale)
608 {
609         CameraParams params;
610         CameraViewFrameData data_cb;
611
612         /* just in case */
613         *r_scale = 1.0f;
614
615         camera_frame_fit_data_init(scene, camera_ob, &params, &data_cb);
616
617         /* run callback on all visible points */
618         BKE_scene_foreach_display_point(depsgraph, camera_to_frame_view_cb, &data_cb);
619
620         return camera_frame_fit_calc_from_data(&params, &data_cb, r_co, r_scale);
621 }
622
623 bool BKE_camera_view_frame_fit_to_coords(
624         const Depsgraph *depsgraph, const float (*cos)[3], int num_cos, Object *camera_ob,
625         float r_co[3], float *r_scale)
626 {
627         Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
628         Object *camera_ob_eval = DEG_get_evaluated_object(depsgraph, camera_ob);
629         CameraParams params;
630         CameraViewFrameData data_cb;
631
632         /* just in case */
633         *r_scale = 1.0f;
634
635         camera_frame_fit_data_init(scene_eval, camera_ob_eval, &params, &data_cb);
636
637         /* run callback on all given coordinates */
638         while (num_cos--) {
639                 camera_to_frame_view_cb(cos[num_cos], &data_cb);
640         }
641
642         return camera_frame_fit_calc_from_data(&params, &data_cb, r_co, r_scale);
643 }
644
645 /******************* multiview matrix functions ***********************/
646
647 static void camera_model_matrix(const Object *camera, float r_modelmat[4][4])
648 {
649         copy_m4_m4(r_modelmat, camera->obmat);
650 }
651
652 static void camera_stereo3d_model_matrix(const Object *camera, const bool is_left, float r_modelmat[4][4])
653 {
654         Camera *data = (Camera *)camera->data;
655         float interocular_distance, convergence_distance;
656         short convergence_mode, pivot;
657         float sizemat[4][4];
658
659         float fac = 1.0f;
660         float fac_signed;
661
662         interocular_distance = data->stereo.interocular_distance;
663         convergence_distance = data->stereo.convergence_distance;
664         convergence_mode = data->stereo.convergence_mode;
665         pivot = data->stereo.pivot;
666
667         if (((pivot == CAM_S3D_PIVOT_LEFT) && is_left) ||
668             ((pivot == CAM_S3D_PIVOT_RIGHT) && !is_left))
669         {
670                 camera_model_matrix(camera, r_modelmat);
671                 return;
672         }
673         else {
674                 float size[3];
675                 mat4_to_size(size, camera->obmat);
676                 size_to_mat4(sizemat, size);
677         }
678
679         if (pivot == CAM_S3D_PIVOT_CENTER)
680                 fac = 0.5f;
681
682         fac_signed = is_left ? fac : -fac;
683
684         /* rotation */
685         if (convergence_mode == CAM_S3D_TOE) {
686                 float angle;
687                 float angle_sin, angle_cos;
688                 float toeinmat[4][4];
689                 float rotmat[4][4];
690
691                 unit_m4(rotmat);
692
693                 if (pivot == CAM_S3D_PIVOT_CENTER) {
694                         fac = -fac;
695                         fac_signed = -fac_signed;
696                 }
697
698                 angle = atanf((interocular_distance * 0.5f) / convergence_distance) / fac;
699
700                 angle_cos = cosf(angle * fac_signed);
701                 angle_sin = sinf(angle * fac_signed);
702
703                 rotmat[0][0] =  angle_cos;
704                 rotmat[2][0] = -angle_sin;
705                 rotmat[0][2] =  angle_sin;
706                 rotmat[2][2] =  angle_cos;
707
708                 if (pivot == CAM_S3D_PIVOT_CENTER) {
709                         /* set the rotation */
710                         copy_m4_m4(toeinmat, rotmat);
711                         /* set the translation */
712                         toeinmat[3][0] = interocular_distance * fac_signed;
713
714                         /* transform */
715                         normalize_m4_m4(r_modelmat, camera->obmat);
716                         mul_m4_m4m4(r_modelmat, r_modelmat, toeinmat);
717
718                         /* scale back to the original size */
719                         mul_m4_m4m4(r_modelmat, r_modelmat, sizemat);
720                 }
721                 else { /* CAM_S3D_PIVOT_LEFT, CAM_S3D_PIVOT_RIGHT */
722                         /* rotate perpendicular to the interocular line */
723                         normalize_m4_m4(r_modelmat, camera->obmat);
724                         mul_m4_m4m4(r_modelmat, r_modelmat, rotmat);
725
726                         /* translate along the interocular line */
727                         unit_m4(toeinmat);
728                         toeinmat[3][0] = -interocular_distance * fac_signed;
729                         mul_m4_m4m4(r_modelmat, r_modelmat, toeinmat);
730
731                         /* rotate to toe-in angle */
732                         mul_m4_m4m4(r_modelmat, r_modelmat, rotmat);
733
734                         /* scale back to the original size */
735                         mul_m4_m4m4(r_modelmat, r_modelmat, sizemat);
736                 }
737         }
738         else {
739                 normalize_m4_m4(r_modelmat, camera->obmat);
740
741                 /* translate - no rotation in CAM_S3D_OFFAXIS, CAM_S3D_PARALLEL */
742                 translate_m4(r_modelmat, -interocular_distance * fac_signed, 0.0f, 0.0f);
743
744                 /* scale back to the original size */
745                 mul_m4_m4m4(r_modelmat, r_modelmat, sizemat);
746         }
747 }
748
749 /* the view matrix is used by the viewport drawing, it is basically the inverted model matrix */
750 void BKE_camera_multiview_view_matrix(RenderData *rd, const Object *camera, const bool is_left, float r_viewmat[4][4])
751 {
752         BKE_camera_multiview_model_matrix(rd, camera, is_left ? STEREO_LEFT_NAME : STEREO_RIGHT_NAME, r_viewmat);
753         invert_m4(r_viewmat);
754 }
755
756 /* left is the default */
757 static bool camera_is_left(const char *viewname)
758 {
759         if (viewname && viewname[0] != '\0') {
760                 return !STREQ(viewname, STEREO_RIGHT_NAME);
761         }
762         return true;
763 }
764
765 void BKE_camera_multiview_model_matrix(RenderData *rd, const Object *camera, const char *viewname, float r_modelmat[4][4])
766 {
767         BKE_camera_multiview_model_matrix_scaled(rd, camera, viewname, r_modelmat);
768         normalize_m4(r_modelmat);
769 }
770
771 void BKE_camera_multiview_model_matrix_scaled(RenderData *rd, const Object *camera, const char *viewname, float r_modelmat[4][4])
772 {
773         const bool is_multiview = (rd && rd->scemode & R_MULTIVIEW) != 0;
774
775         if (!is_multiview) {
776                 camera_model_matrix(camera, r_modelmat);
777         }
778         else if (rd->views_format == SCE_VIEWS_FORMAT_MULTIVIEW) {
779                 camera_model_matrix(camera, r_modelmat);
780         }
781         else { /* SCE_VIEWS_SETUP_BASIC */
782                 const bool is_left = camera_is_left(viewname);
783                 camera_stereo3d_model_matrix(camera, is_left, r_modelmat);
784         }
785 }
786
787 void BKE_camera_multiview_window_matrix(RenderData *rd, const Object *camera, const char *viewname, float r_winmat[4][4])
788 {
789         CameraParams params;
790
791         /* Setup parameters */
792         BKE_camera_params_init(&params);
793         BKE_camera_params_from_object(&params, camera);
794         BKE_camera_multiview_params(rd, &params, camera, viewname);
795
796         /* Compute matrix, viewplane, .. */
797         BKE_camera_params_compute_viewplane(&params, rd->xsch, rd->ysch, rd->xasp, rd->yasp);
798         BKE_camera_params_compute_matrix(&params);
799
800         copy_m4_m4(r_winmat, params.winmat);
801 }
802
803 bool BKE_camera_multiview_spherical_stereo(RenderData *rd, const Object *camera)
804 {
805         Camera *cam;
806         const bool is_multiview = (rd && rd->scemode & R_MULTIVIEW) != 0;
807
808         if (!is_multiview)
809                 return false;
810
811         if (camera->type != OB_CAMERA)
812                 return false;
813         else
814                 cam = camera->data;
815
816         if ((rd->views_format == SCE_VIEWS_FORMAT_STEREO_3D) &&
817             ELEM(cam->type, CAM_PANO, CAM_PERSP) &&
818             ((cam->stereo.flag & CAM_S3D_SPHERICAL) != 0))
819         {
820                 return true;
821         }
822
823         return false;
824 }
825
826 static Object *camera_multiview_advanced(Scene *scene, Object *camera, const char *suffix)
827 {
828         SceneRenderView *srv;
829         char name[MAX_NAME];
830         const char *camera_name = camera->id.name + 2;
831         const int len_name = strlen(camera_name);
832         int len_suffix_max = -1;
833
834         name[0] = '\0';
835
836         /* we need to take the better match, thus the len_suffix_max test */
837         for (srv = scene->r.views.first; srv; srv = srv->next) {
838                 const int len_suffix = strlen(srv->suffix);
839
840                 if ((len_suffix < len_suffix_max) || (len_name < len_suffix))
841                         continue;
842
843                 if (STREQ(camera_name + (len_name - len_suffix), srv->suffix)) {
844                         BLI_snprintf(name, sizeof(name), "%.*s%s", (len_name - len_suffix), camera_name, suffix);
845                         len_suffix_max = len_suffix;
846                 }
847         }
848
849         if (name[0] != '\0') {
850                 Object *ob = BKE_scene_object_find_by_name(scene, name);
851                 if (ob != NULL) {
852                         return ob;
853                 }
854         }
855
856         return camera;
857 }
858
859 /* returns the camera to be used for render */
860 Object *BKE_camera_multiview_render(Scene *scene, Object *camera, const char *viewname)
861 {
862         const bool is_multiview = (camera != NULL) &&  (scene->r.scemode & R_MULTIVIEW) != 0;
863
864         if (!is_multiview) {
865                 return camera;
866         }
867         else if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
868                 return camera;
869         }
870         else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
871                 const char *suffix = BKE_scene_multiview_view_suffix_get(&scene->r, viewname);
872                 return camera_multiview_advanced(scene, camera, suffix);
873         }
874 }
875
876 static float camera_stereo3d_shift_x(const Object *camera, const char *viewname)
877 {
878         Camera *data = camera->data;
879         float shift = data->shiftx;
880         float interocular_distance, convergence_distance;
881         short convergence_mode, pivot;
882         bool is_left = true;
883
884         float fac = 1.0f;
885         float fac_signed;
886
887         if (viewname && viewname[0]) {
888                 is_left = STREQ(viewname, STEREO_LEFT_NAME);
889         }
890
891         interocular_distance = data->stereo.interocular_distance;
892         convergence_distance = data->stereo.convergence_distance;
893         convergence_mode = data->stereo.convergence_mode;
894         pivot = data->stereo.pivot;
895
896         if (convergence_mode != CAM_S3D_OFFAXIS)
897                 return shift;
898
899         if (((pivot == CAM_S3D_PIVOT_LEFT) && is_left) ||
900             ((pivot == CAM_S3D_PIVOT_RIGHT) && !is_left))
901         {
902                 return shift;
903         }
904
905         if (pivot == CAM_S3D_PIVOT_CENTER)
906                 fac = 0.5f;
907
908         fac_signed = is_left ? fac : -fac;
909         shift += ((interocular_distance / data->sensor_x) * (data->lens / convergence_distance)) * fac_signed;
910
911         return shift;
912 }
913
914 float BKE_camera_multiview_shift_x(RenderData *rd, const Object *camera, const char *viewname)
915 {
916         const bool is_multiview = (rd && rd->scemode & R_MULTIVIEW) != 0;
917         Camera *data = camera->data;
918
919         BLI_assert(camera->type == OB_CAMERA);
920
921         if (!is_multiview) {
922                 return data->shiftx;
923         }
924         else if (rd->views_format == SCE_VIEWS_FORMAT_MULTIVIEW) {
925                 return data->shiftx;
926         }
927         else { /* SCE_VIEWS_SETUP_BASIC */
928                 return camera_stereo3d_shift_x(camera, viewname);
929         }
930 }
931
932 void BKE_camera_multiview_params(RenderData *rd, CameraParams *params, const Object *camera, const char *viewname)
933 {
934         if (camera->type == OB_CAMERA) {
935                 params->shiftx = BKE_camera_multiview_shift_x(rd, camera, viewname);
936         }
937 }
938
939 void BKE_camera_to_gpu_dof(struct Object *camera, struct GPUFXSettings *r_fx_settings)
940 {
941         if (camera->type == OB_CAMERA) {
942                 Camera *cam = camera->data;
943                 r_fx_settings->dof = &cam->gpu_dof;
944                 r_fx_settings->dof->focal_length = cam->lens;
945                 r_fx_settings->dof->sensor = BKE_camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
946                 r_fx_settings->dof->focus_distance = BKE_camera_object_dof_distance(camera);
947         }
948 }
949
950 CameraBGImage *BKE_camera_background_image_new(Camera *cam)
951 {
952         CameraBGImage *bgpic = MEM_callocN(sizeof(CameraBGImage), "Background Image");
953
954         bgpic->scale = 1.0f;
955         bgpic->alpha = 0.5f;
956         bgpic->iuser.ok = 1;
957         bgpic->iuser.flag |= IMA_ANIM_ALWAYS;
958         bgpic->flag |= CAM_BGIMG_FLAG_EXPANDED;
959
960         BLI_addtail(&cam->bg_images, bgpic);
961
962         return bgpic;
963 }
964
965 void BKE_camera_background_image_remove(Camera *cam, CameraBGImage *bgpic)
966 {
967         BLI_remlink(&cam->bg_images, bgpic);
968
969         MEM_freeN(bgpic);
970 }
971
972 void BKE_camera_background_image_clear(Camera *cam)
973 {
974         CameraBGImage *bgpic = cam->bg_images.first;
975
976         while (bgpic) {
977                 CameraBGImage *next_bgpic = bgpic->next;
978
979                 BKE_camera_background_image_remove(cam, bgpic);
980
981                 bgpic = next_bgpic;
982         }
983 }