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