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