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