From 0ebcc711fc2767f2d260d8e124af1074da9c8a59 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Mon, 4 Apr 2022 16:16:36 -0300 Subject: Fix T95678: Thumbnails are not working with big / large Objects The internal camera used to render the thumbnails also has to consider `clip_start` and `clip_end`. Reviewed By: Severin Maniphest Tasks: T95678 Differential Revision: https://developer.blender.org/D14138 --- source/blender/blenkernel/BKE_camera.h | 4 +- source/blender/blenkernel/intern/camera.c | 106 ++++++++++++--------- source/blender/editors/include/ED_view3d.h | 5 + source/blender/editors/render/render_preview.cc | 3 +- source/blender/editors/space_view3d/view3d_utils.c | 45 ++++++++- 5 files changed, 111 insertions(+), 52 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h index 9d254bba8e7..57dc1e288dc 100644 --- a/source/blender/blenkernel/BKE_camera.h +++ b/source/blender/blenkernel/BKE_camera.h @@ -114,7 +114,9 @@ bool BKE_camera_view_frame_fit_to_scene(struct Depsgraph *depsgraph, const struct Scene *scene, struct Object *camera_ob, float r_co[3], - float *r_scale); + float *r_scale, + float *r_clip_start, + float *r_clip_end); bool BKE_camera_view_frame_fit_to_coords(const struct Depsgraph *depsgraph, const float (*cos)[3], int num_cos, diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index b840fb1e665..3897df9f05f 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -552,12 +552,11 @@ void BKE_camera_view_frame(const Scene *scene, const Camera *camera, float r_vec typedef struct CameraViewFrameData { float plane_tx[CAMERA_VIEWFRAME_NUM_PLANES][4]; /* 4 planes normalized */ float dist_vals[CAMERA_VIEWFRAME_NUM_PLANES]; /* distance (signed) */ + float camera_no[3]; + float z_range[2]; unsigned int tot; - /* Ortho camera only. */ - bool is_ortho; - float camera_no[3]; - float dist_to_cam; + bool do_zrange; /* Not used by callbacks... */ float camera_rotmat[3][3]; @@ -572,9 +571,10 @@ static void camera_to_frame_view_cb(const float co[3], void *user_data) CLAMP_MAX(data->dist_vals[i], nd); } - if (data->is_ortho) { + if (data->do_zrange) { const float d = dot_v3v3(data->camera_no, co); - CLAMP_MAX(data->dist_to_cam, d); + CLAMP_MAX(data->z_range[0], d); + CLAMP_MIN(data->z_range[1], d); } data->tot++; @@ -582,6 +582,7 @@ static void camera_to_frame_view_cb(const float co[3], void *user_data) static void camera_frame_fit_data_init(const Scene *scene, const Object *ob, + const bool do_clip_dists, CameraParams *params, CameraViewFrameData *data) { @@ -626,22 +627,27 @@ static void camera_frame_fit_data_init(const Scene *scene, mul_m4_v4(camera_rotmat_transposed_inversed, data->plane_tx[i]); /* Normalize. */ data->plane_tx[i][3] /= normalize_v3(data->plane_tx[i]); + + data->dist_vals[i] = FLT_MAX; } - copy_v4_fl(data->dist_vals, FLT_MAX); data->tot = 0; - data->is_ortho = params->is_ortho; - if (params->is_ortho) { - /* we want (0, 0, -1) transformed by camera_rotmat, this is a quicker shortcut. */ + data->do_zrange = params->is_ortho || do_clip_dists; + + if (data->do_zrange) { + /* We want (0, 0, -1) transformed by camera_rotmat, this is a quicker shortcut. */ negate_v3_v3(data->camera_no, data->camera_rotmat[2]); - data->dist_to_cam = FLT_MAX; + data->z_range[0] = FLT_MAX; + data->z_range[1] = -FLT_MAX; } } static bool camera_frame_fit_calc_from_data(CameraParams *params, CameraViewFrameData *data, float r_co[3], - float *r_scale) + float *r_scale, + float *r_clip_start, + float *r_clip_end) { float plane_tx[CAMERA_VIEWFRAME_NUM_PLANES][4]; @@ -669,37 +675,38 @@ static bool camera_frame_fit_calc_from_data(CameraParams *params, zero_v3(r_co); madd_v3_v3fl(r_co, cam_axis_x, (dists[2] - dists[0]) * 0.5f + params->shiftx * scale_diff); madd_v3_v3fl(r_co, cam_axis_y, (dists[1] - dists[3]) * 0.5f + params->shifty * scale_diff); - madd_v3_v3fl(r_co, cam_axis_z, -(data->dist_to_cam - 1.0f - params->clip_start)); - - return true; + madd_v3_v3fl(r_co, cam_axis_z, -(data->z_range[0] - 1.0f - params->clip_start)); } + else { + float plane_isect_1[3], plane_isect_1_no[3], plane_isect_1_other[3]; + float plane_isect_2[3], plane_isect_2_no[3], plane_isect_2_other[3]; - float plane_isect_1[3], plane_isect_1_no[3], plane_isect_1_other[3]; - float plane_isect_2[3], plane_isect_2_no[3], plane_isect_2_other[3]; + float plane_isect_pt_1[3], plane_isect_pt_2[3]; - float plane_isect_pt_1[3], plane_isect_pt_2[3]; + /* apply the dist-from-plane's to the transformed plane points */ + for (int i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) { + float co[3]; + mul_v3_v3fl(co, data->plane_tx[i], data->dist_vals[i]); + plane_from_point_normal_v3(plane_tx[i], co, data->plane_tx[i]); + } - /* apply the dist-from-plane's to the transformed plane points */ - for (int i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) { - float co[3]; - mul_v3_v3fl(co, data->plane_tx[i], data->dist_vals[i]); - plane_from_point_normal_v3(plane_tx[i], co, data->plane_tx[i]); - } + if ((!isect_plane_plane_v3(plane_tx[0], plane_tx[2], plane_isect_1, plane_isect_1_no)) || + (!isect_plane_plane_v3(plane_tx[1], plane_tx[3], plane_isect_2, plane_isect_2_no))) { + return false; + } - if ((!isect_plane_plane_v3(plane_tx[0], plane_tx[2], plane_isect_1, plane_isect_1_no)) || - (!isect_plane_plane_v3(plane_tx[1], plane_tx[3], plane_isect_2, plane_isect_2_no))) { - return false; - } + add_v3_v3v3(plane_isect_1_other, plane_isect_1, plane_isect_1_no); + add_v3_v3v3(plane_isect_2_other, plane_isect_2, plane_isect_2_no); - add_v3_v3v3(plane_isect_1_other, plane_isect_1, plane_isect_1_no); - add_v3_v3v3(plane_isect_2_other, plane_isect_2, plane_isect_2_no); + if (!isect_line_line_v3(plane_isect_1, + plane_isect_1_other, + plane_isect_2, + plane_isect_2_other, + plane_isect_pt_1, + plane_isect_pt_2) != 0) { + return false; + } - if (isect_line_line_v3(plane_isect_1, - plane_isect_1_other, - plane_isect_2, - plane_isect_2_other, - plane_isect_pt_1, - plane_isect_pt_2) != 0) { float cam_plane_no[3]; float plane_isect_delta[3]; float plane_isect_delta_len; @@ -728,15 +735,23 @@ static bool camera_frame_fit_calc_from_data(CameraParams *params, normalize_v3(plane_isect_2_no); madd_v3_v3fl(r_co, plane_isect_2_no, params->shiftx * plane_isect_delta_len * shift_fac); } - - return true; } - return false; + if (r_clip_start && r_clip_end) { + const float z_offs = dot_v3v3(r_co, data->camera_no); + *r_clip_start = data->z_range[0] - z_offs; + *r_clip_end = data->z_range[1] - z_offs; + } + return true; } -bool BKE_camera_view_frame_fit_to_scene( - Depsgraph *depsgraph, const Scene *scene, Object *camera_ob, float r_co[3], float *r_scale) +bool BKE_camera_view_frame_fit_to_scene(Depsgraph *depsgraph, + const Scene *scene, + Object *camera_ob, + float r_co[3], + float *r_scale, + float *r_clip_start, + float *r_clip_end) { CameraParams params; CameraViewFrameData data_cb; @@ -744,12 +759,13 @@ bool BKE_camera_view_frame_fit_to_scene( /* just in case */ *r_scale = 1.0f; - camera_frame_fit_data_init(scene, camera_ob, ¶ms, &data_cb); + camera_frame_fit_data_init(scene, camera_ob, r_clip_start && r_clip_end, ¶ms, &data_cb); /* run callback on all visible points */ BKE_scene_foreach_display_point(depsgraph, camera_to_frame_view_cb, &data_cb); - return camera_frame_fit_calc_from_data(¶ms, &data_cb, r_co, r_scale); + return camera_frame_fit_calc_from_data( + ¶ms, &data_cb, r_co, r_scale, r_clip_start, r_clip_end); } bool BKE_camera_view_frame_fit_to_coords(const Depsgraph *depsgraph, @@ -767,14 +783,14 @@ bool BKE_camera_view_frame_fit_to_coords(const Depsgraph *depsgraph, /* just in case */ *r_scale = 1.0f; - camera_frame_fit_data_init(scene_eval, camera_ob_eval, ¶ms, &data_cb); + camera_frame_fit_data_init(scene_eval, camera_ob_eval, false, ¶ms, &data_cb); /* run callback on all given coordinates */ while (num_cos--) { camera_to_frame_view_cb(cos[num_cos], &data_cb); } - return camera_frame_fit_calc_from_data(¶ms, &data_cb, r_co, r_scale); + return camera_frame_fit_calc_from_data(¶ms, &data_cb, r_co, r_scale, NULL, NULL); } /** \} */ diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index c3571bb3788..3f9f26560b2 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -163,6 +163,11 @@ bool ED_view3d_camera_to_view_selected(struct Main *bmain, const struct Scene *scene, struct Object *camera_ob); +bool ED_view3d_camera_to_view_selected_with_set_clipping(struct Main *bmain, + struct Depsgraph *depsgraph, + const struct Scene *scene, + struct Object *camera_ob); + /** * Use to store the last view, before entering camera view. */ diff --git a/source/blender/editors/render/render_preview.cc b/source/blender/editors/render/render_preview.cc index 7404b3bf010..78e786a2130 100644 --- a/source/blender/editors/render/render_preview.cc +++ b/source/blender/editors/render/render_preview.cc @@ -830,7 +830,8 @@ static Scene *object_preview_scene_create(const struct ObjectPreviewData *previe DEG_graph_build_from_view_layer(depsgraph); DEG_evaluate_on_refresh(depsgraph); - ED_view3d_camera_to_view_selected(preview_data->pr_main, depsgraph, scene, camera_object); + ED_view3d_camera_to_view_selected_with_set_clipping( + preview_data->pr_main, depsgraph, scene, camera_object); BKE_scene_graph_update_tagged(depsgraph, preview_data->pr_main); diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c index 744fc61ddcf..e6895c0f4a3 100644 --- a/source/blender/editors/space_view3d/view3d_utils.c +++ b/source/blender/editors/space_view3d/view3d_utils.c @@ -1440,16 +1440,19 @@ void ED_view3d_to_object(const Depsgraph *depsgraph, BKE_object_apply_mat4_ex(ob, mat, ob_eval->parent, ob_eval->parentinv, true); } -bool ED_view3d_camera_to_view_selected(struct Main *bmain, - Depsgraph *depsgraph, - const Scene *scene, - Object *camera_ob) +static bool view3d_camera_to_view_selected_impl(struct Main *bmain, + Depsgraph *depsgraph, + const Scene *scene, + Object *camera_ob, + float *r_clip_start, + float *r_clip_end) { Object *camera_ob_eval = DEG_get_evaluated_object(depsgraph, camera_ob); float co[3]; /* the new location to apply */ float scale; /* only for ortho cameras */ - if (BKE_camera_view_frame_fit_to_scene(depsgraph, scene, camera_ob_eval, co, &scale)) { + if (BKE_camera_view_frame_fit_to_scene( + depsgraph, scene, camera_ob_eval, co, &scale, r_clip_start, r_clip_end)) { ObjectTfmProtectedChannels obtfm; float obmat_new[4][4]; @@ -1475,6 +1478,38 @@ bool ED_view3d_camera_to_view_selected(struct Main *bmain, return false; } +bool ED_view3d_camera_to_view_selected(struct Main *bmain, + Depsgraph *depsgraph, + const Scene *scene, + Object *camera_ob) +{ + return view3d_camera_to_view_selected_impl(bmain, depsgraph, scene, camera_ob, NULL, NULL); +} + +bool ED_view3d_camera_to_view_selected_with_set_clipping(struct Main *bmain, + Depsgraph *depsgraph, + const Scene *scene, + Object *camera_ob) +{ + float clip_start; + float clip_end; + if (view3d_camera_to_view_selected_impl( + bmain, depsgraph, scene, camera_ob, &clip_start, &clip_end)) { + + ((Camera *)camera_ob->data)->clip_start = clip_start; + ((Camera *)camera_ob->data)->clip_end = clip_end; + + /* TODO: Support update via #ID_RECALC_PARAMETERS. */ + Object *camera_ob_eval = DEG_get_evaluated_object(depsgraph, camera_ob); + ((Camera *)camera_ob_eval->data)->clip_start = clip_start; + ((Camera *)camera_ob_eval->data)->clip_end = clip_end; + + return true; + } + + return false; +} + /** \} */ /* -------------------------------------------------------------------- */ -- cgit v1.2.3