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