Merge branch 'master' into blender2.8
[blender.git] / source / blender / blenkernel / intern / camera.c
index 3e6e88c5f444a891cd1728954de602aa9528de7e..7457fc8b7ad0916ae97568973b1abf9ec08d2c17 100644 (file)
@@ -40,6 +40,7 @@
 #include "DNA_ID.h"
 
 #include "BLI_math.h"
+#include "BLI_listbase.h"
 #include "BLI_rect.h"
 #include "BLI_string.h"
 #include "BLI_utildefines.h"
@@ -47,6 +48,7 @@
 #include "BKE_animsys.h"
 #include "BKE_camera.h"
 #include "BKE_object.h"
+#include "BKE_layer.h"
 #include "BKE_library.h"
 #include "BKE_library_query.h"
 #include "BKE_library_remap.h"
@@ -54,7 +56,9 @@
 #include "BKE_scene.h"
 #include "BKE_screen.h"
 
-#include "GPU_compositing.h"
+#include "DEG_depsgraph_query.h"
+
+#include "MEM_guardedalloc.h"
 
 /****************************** Camera Datablock *****************************/
 
@@ -62,17 +66,18 @@ void BKE_camera_init(Camera *cam)
 {
        BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(cam, id));
 
-       cam->lens = 35.0f;
+       cam->lens = 50.0f;
        cam->sensor_x = DEFAULT_SENSOR_WIDTH;
        cam->sensor_y = DEFAULT_SENSOR_HEIGHT;
        cam->clipsta = 0.1f;
-       cam->clipend = 100.0f;
+       cam->clipend = 1000.0f;
        cam->drawsize = 0.5f;
        cam->ortho_scale = 6.0;
        cam->flag |= CAM_SHOWPASSEPARTOUT;
        cam->passepartalpha = 0.5f;
 
-       GPU_fx_compositor_init_dof_settings(&cam->gpu_dof);
+       cam->gpu_dof.fstop = 128.0f;
+       cam->gpu_dof.ratio = 1.0f;
 
        /* stereoscopy 3d */
        cam->stereo.interocular_distance = 0.065f;
@@ -100,9 +105,9 @@ void *BKE_camera_add(Main *bmain, const char *name)
  *
  * \param flag  Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
  */
-void BKE_camera_copy_data(Main *UNUSED(bmain), Camera *UNUSED(cam_dst), const Camera *UNUSED(cam_src), const int UNUSED(flag))
+void BKE_camera_copy_data(Main *UNUSED(bmain), Camera *cam_dst, const Camera *cam_src, const int UNUSED(flag))
 {
-       /* Nothing to do! */
+       BLI_duplicatelist(&cam_dst->bg_images, &cam_src->bg_images);
 }
 
 Camera *BKE_camera_copy(Main *bmain, const Camera *cam)
@@ -120,22 +125,13 @@ void BKE_camera_make_local(Main *bmain, Camera *cam, const bool lib_local)
 /** Free (or release) any data used by this camera (does not free the camera itself). */
 void BKE_camera_free(Camera *ca)
 {
+       BLI_freelistN(&ca->bg_images);
+
        BKE_animdata_free((ID *)ca, false);
 }
 
 /******************************** Camera Usage *******************************/
 
-void BKE_camera_object_mode(RenderData *rd, Object *cam_ob)
-{
-       rd->mode &= ~(R_ORTHO | R_PANORAMA);
-
-       if (cam_ob && cam_ob->type == OB_CAMERA) {
-               Camera *cam = cam_ob->data;
-               if (cam->type == CAM_ORTHO) rd->mode |= R_ORTHO;
-               if (cam->type == CAM_PANO) rd->mode |= R_PANORAMA;
-       }
-}
-
 /* get the camera's dof value, takes the dof object into account */
 float BKE_camera_object_dof_distance(Object *ob)
 {
@@ -143,15 +139,10 @@ float BKE_camera_object_dof_distance(Object *ob)
        if (ob->type != OB_CAMERA)
                return 0.0f;
        if (cam->dof_ob) {
-#if 0
-               /* too simple, better to return the distance on the view axis only */
-               return len_v3v3(ob->obmat[3], cam->dof_ob->obmat[3]);
-#else
                float view_dir[3], dof_dir[3];
                normalize_v3_v3(view_dir, ob->obmat[2]);
                sub_v3_v3v3(dof_dir, ob->obmat[3], cam->dof_ob->obmat[3]);
                return fabsf(dot_v3v3(view_dir, dof_dir));
-#endif
        }
        return cam->YF_dofdist;
 }
@@ -237,7 +228,7 @@ void BKE_camera_params_from_object(CameraParams *params, const Object *ob)
        }
 }
 
-void BKE_camera_params_from_view3d(CameraParams *params, const View3D *v3d, const RegionView3D *rv3d)
+void BKE_camera_params_from_view3d(CameraParams *params, Depsgraph *depsgraph, const View3D *v3d, const RegionView3D *rv3d)
 {
        /* common */
        params->lens = v3d->lens;
@@ -246,7 +237,8 @@ void BKE_camera_params_from_view3d(CameraParams *params, const View3D *v3d, cons
 
        if (rv3d->persp == RV3D_CAMOB) {
                /* camera view */
-               BKE_camera_params_from_object(params, v3d->camera);
+               const Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
+               BKE_camera_params_from_object(params, ob_camera_eval);
 
                params->zoom = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom);
 
@@ -281,10 +273,7 @@ void BKE_camera_params_compute_viewplane(CameraParams *params, int winx, int win
        float pixsize, viewfac, sensor_size, dx, dy;
        int sensor_fit;
 
-       /* fields rendering */
        params->ycor = yasp / xasp;
-       if (params->use_fields)
-               params->ycor *= 2.0f;
 
        if (params->is_ortho) {
                /* orthographic camera */
@@ -326,18 +315,6 @@ void BKE_camera_params_compute_viewplane(CameraParams *params, int winx, int win
        viewplane.xmax += dx;
        viewplane.ymax += dy;
 
-       /* fields offset */
-       if (params->field_second) {
-               if (params->field_odd) {
-                       viewplane.ymin -= 0.5f * params->ycor;
-                       viewplane.ymax -= 0.5f * params->ycor;
-               }
-               else {
-                       viewplane.ymin += 0.5f * params->ycor;
-                       viewplane.ymax += 0.5f * params->ycor;
-               }
-       }
-
        /* the window matrix is used for clipping, and not changed during OSA steps */
        /* using an offset of +0.5 here would give clip errors on edges */
        viewplane.xmin *= pixsize;
@@ -641,7 +618,7 @@ static bool camera_frame_fit_calc_from_data(
 /* don't move the camera, just yield the fit location */
 /* r_scale only valid/useful for ortho cameras */
 bool BKE_camera_view_frame_fit_to_scene(
-        Main *bmain, Scene *scene, struct View3D *v3d, Object *camera_ob, float r_co[3], float *r_scale)
+        Depsgraph *depsgraph, Scene *scene, Object *camera_ob, float r_co[3], float *r_scale)
 {
        CameraParams params;
        CameraViewFrameData data_cb;
@@ -652,22 +629,24 @@ bool BKE_camera_view_frame_fit_to_scene(
        camera_frame_fit_data_init(scene, camera_ob, &params, &data_cb);
 
        /* run callback on all visible points */
-       BKE_scene_foreach_display_point(bmain, scene, v3d, BA_SELECT, camera_to_frame_view_cb, &data_cb);
+       BKE_scene_foreach_display_point(depsgraph, camera_to_frame_view_cb, &data_cb);
 
        return camera_frame_fit_calc_from_data(&params, &data_cb, r_co, r_scale);
 }
 
 bool BKE_camera_view_frame_fit_to_coords(
-        const Scene *scene, const float (*cos)[3], int num_cos, const Object *camera_ob,
+        const Depsgraph *depsgraph, const float (*cos)[3], int num_cos, Object *camera_ob,
         float r_co[3], float *r_scale)
 {
+       Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
+       Object *camera_ob_eval = DEG_get_evaluated_object(depsgraph, camera_ob);
        CameraParams params;
        CameraViewFrameData data_cb;
 
        /* just in case */
        *r_scale = 1.0f;
 
-       camera_frame_fit_data_init(scene, camera_ob, &params, &data_cb);
+       camera_frame_fit_data_init(scene_eval, camera_ob_eval, &params, &data_cb);
 
        /* run callback on all given coordinates */
        while (num_cos--) {
@@ -679,12 +658,12 @@ bool BKE_camera_view_frame_fit_to_coords(
 
 /******************* multiview matrix functions ***********************/
 
-static void camera_model_matrix(Object *camera, float r_modelmat[4][4])
+static void camera_model_matrix(const Object *camera, float r_modelmat[4][4])
 {
        copy_m4_m4(r_modelmat, camera->obmat);
 }
 
-static void camera_stereo3d_model_matrix(Object *camera, const bool is_left, float r_modelmat[4][4])
+static void camera_stereo3d_model_matrix(const Object *camera, const bool is_left, float r_modelmat[4][4])
 {
        Camera *data = (Camera *)camera->data;
        float interocular_distance, convergence_distance;
@@ -782,7 +761,7 @@ static void camera_stereo3d_model_matrix(Object *camera, const bool is_left, flo
 }
 
 /* the view matrix is used by the viewport drawing, it is basically the inverted model matrix */
-void BKE_camera_multiview_view_matrix(RenderData *rd, Object *camera, const bool is_left, float r_viewmat[4][4])
+void BKE_camera_multiview_view_matrix(RenderData *rd, const Object *camera, const bool is_left, float r_viewmat[4][4])
 {
        BKE_camera_multiview_model_matrix(rd, camera, is_left ? STEREO_LEFT_NAME : STEREO_RIGHT_NAME, r_viewmat);
        invert_m4(r_viewmat);
@@ -797,7 +776,7 @@ static bool camera_is_left(const char *viewname)
        return true;
 }
 
-void BKE_camera_multiview_model_matrix(RenderData *rd, Object *camera, const char *viewname, float r_modelmat[4][4])
+void BKE_camera_multiview_model_matrix(RenderData *rd, const Object *camera, const char *viewname, float r_modelmat[4][4])
 {
        const bool is_multiview = (rd && rd->scemode & R_MULTIVIEW) != 0;
 
@@ -814,7 +793,7 @@ void BKE_camera_multiview_model_matrix(RenderData *rd, Object *camera, const cha
        normalize_m4(r_modelmat);
 }
 
-bool BKE_camera_multiview_spherical_stereo(RenderData *rd, Object *camera)
+bool BKE_camera_multiview_spherical_stereo(RenderData *rd, const Object *camera)
 {
        Camera *cam;
        const bool is_multiview = (rd && rd->scemode & R_MULTIVIEW) != 0;
@@ -861,9 +840,9 @@ static Object *camera_multiview_advanced(Scene *scene, Object *camera, const cha
        }
 
        if (name[0] != '\0') {
-               Base *base = BKE_scene_base_find_by_name(scene, name);
-               if (base) {
-                       return base->object;
+               Object *ob = BKE_scene_object_find_by_name(scene, name);
+               if (ob != NULL) {
+                       return ob;
                }
        }
 
@@ -887,7 +866,7 @@ Object *BKE_camera_multiview_render(Scene *scene, Object *camera, const char *vi
        }
 }
 
-static float camera_stereo3d_shift_x(Object *camera, const char *viewname)
+static float camera_stereo3d_shift_x(const Object *camera, const char *viewname)
 {
        Camera *data = camera->data;
        float shift = data->shiftx;
@@ -925,7 +904,7 @@ static float camera_stereo3d_shift_x(Object *camera, const char *viewname)
        return shift;
 }
 
-float BKE_camera_multiview_shift_x(RenderData *rd, Object *camera, const char *viewname)
+float BKE_camera_multiview_shift_x(RenderData *rd, const Object *camera, const char *viewname)
 {
        const bool is_multiview = (rd && rd->scemode & R_MULTIVIEW) != 0;
        Camera *data = camera->data;
@@ -943,7 +922,7 @@ float BKE_camera_multiview_shift_x(RenderData *rd, Object *camera, const char *v
        }
 }
 
-void BKE_camera_multiview_params(RenderData *rd, CameraParams *params, Object *camera, const char *viewname)
+void BKE_camera_multiview_params(RenderData *rd, CameraParams *params, const Object *camera, const char *viewname)
 {
        if (camera->type == OB_CAMERA) {
                params->shiftx = BKE_camera_multiview_shift_x(rd, camera, viewname);
@@ -960,3 +939,38 @@ void BKE_camera_to_gpu_dof(struct Object *camera, struct GPUFXSettings *r_fx_set
                r_fx_settings->dof->focus_distance = BKE_camera_object_dof_distance(camera);
        }
 }
+
+CameraBGImage *BKE_camera_background_image_new(Camera *cam)
+{
+       CameraBGImage *bgpic = MEM_callocN(sizeof(CameraBGImage), "Background Image");
+
+       bgpic->scale = 1.0f;
+       bgpic->alpha = 0.5f;
+       bgpic->iuser.ok = 1;
+       bgpic->iuser.flag |= IMA_ANIM_ALWAYS;
+       bgpic->flag |= CAM_BGIMG_FLAG_EXPANDED;
+
+       BLI_addtail(&cam->bg_images, bgpic);
+
+       return bgpic;
+}
+
+void BKE_camera_background_image_remove(Camera *cam, CameraBGImage *bgpic)
+{
+       BLI_remlink(&cam->bg_images, bgpic);
+
+       MEM_freeN(bgpic);
+}
+
+void BKE_camera_background_image_clear(Camera *cam)
+{
+       CameraBGImage *bgpic = cam->bg_images.first;
+
+       while (bgpic) {
+               CameraBGImage *next_bgpic = bgpic->next;
+
+               BKE_camera_background_image_remove(cam, bgpic);
+
+               bgpic = next_bgpic;
+       }
+}