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