Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_view3d/view3d_utils.c
| Show First 20 Lines • Show All 218 Lines • ▼ Show 20 Lines | void view3d_region_operator_needs_opengl(wmWindow *UNUSED(win), ARegion *region) | ||||
| } | } | ||||
| } | } | ||||
| /** | /** | ||||
| * Use instead of: `GPU_polygon_offset(rv3d->dist, ...)` see bug T37727. | * Use instead of: `GPU_polygon_offset(rv3d->dist, ...)` see bug T37727. | ||||
| */ | */ | ||||
| void ED_view3d_polygon_offset(const RegionView3D *rv3d, const float dist) | void ED_view3d_polygon_offset(const RegionView3D *rv3d, const float dist) | ||||
| { | { | ||||
| float viewdist; | |||||
| if (rv3d->rflag & RV3D_ZOFFSET_DISABLED) { | if (rv3d->rflag & RV3D_ZOFFSET_DISABLED) { | ||||
| return; | return; | ||||
| } | } | ||||
| viewdist = rv3d->dist; | float viewdist = rv3d->dist; | ||||
| /* special exception for ortho camera (viewdist isnt used for perspective cameras) */ | /* special exception for ortho camera (viewdist isnt used for perspective cameras) */ | ||||
| if (dist != 0.0f) { | if (dist != 0.0f) { | ||||
| if (rv3d->persp == RV3D_CAMOB) { | if (rv3d->persp == RV3D_CAMOB) { | ||||
| if (rv3d->is_persp == false) { | if (rv3d->is_persp == false) { | ||||
| viewdist = 1.0f / max_ff(fabsf(rv3d->winmat[0][0]), fabsf(rv3d->winmat[1][1])); | viewdist = 1.0f / max_ff(fabsf(rv3d->winmat[0][0]), fabsf(rv3d->winmat[1][1])); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| GPU_polygon_offset(viewdist, dist); | GPU_polygon_offset(viewdist, dist); | ||||
| } | } | ||||
| bool ED_view3d_context_activate(bContext *C) | bool ED_view3d_context_activate(bContext *C) | ||||
| { | { | ||||
| bScreen *screen = CTX_wm_screen(C); | bScreen *screen = CTX_wm_screen(C); | ||||
| ScrArea *area = CTX_wm_area(C); | ScrArea *area = CTX_wm_area(C); | ||||
| ARegion *region; | |||||
| /* area can be NULL when called from python */ | /* area can be NULL when called from python */ | ||||
| if (area == NULL || area->spacetype != SPACE_VIEW3D) { | if (area == NULL || area->spacetype != SPACE_VIEW3D) { | ||||
| area = BKE_screen_find_big_area(screen, SPACE_VIEW3D, 0); | area = BKE_screen_find_big_area(screen, SPACE_VIEW3D, 0); | ||||
| } | } | ||||
| if (area == NULL) { | if (area == NULL) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| region = BKE_area_find_region_active_win(area); | ARegion *region = BKE_area_find_region_active_win(area); | ||||
| if (region == NULL) { | if (region == NULL) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| /* bad context switch .. */ | /* bad context switch .. */ | ||||
| CTX_wm_area_set(C, area); | CTX_wm_area_set(C, area); | ||||
| CTX_wm_region_set(C, region); | CTX_wm_region_set(C, region); | ||||
| return true; | return true; | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name View Clipping Utilities | /** \name View Clipping Utilities | ||||
| * | * | ||||
| * \{ */ | * \{ */ | ||||
| void ED_view3d_clipping_calc_from_boundbox(float clip[4][4], | void ED_view3d_clipping_calc_from_boundbox(float clip[4][4], | ||||
| const BoundBox *bb, | const BoundBox *bb, | ||||
| const bool is_flip) | const bool is_flip) | ||||
| { | { | ||||
| int val; | for (int val = 0; val < 4; val++) { | ||||
| for (val = 0; val < 4; val++) { | |||||
| normal_tri_v3(clip[val], bb->vec[val], bb->vec[val == 3 ? 0 : val + 1], bb->vec[val + 4]); | normal_tri_v3(clip[val], bb->vec[val], bb->vec[val == 3 ? 0 : val + 1], bb->vec[val + 4]); | ||||
| if (UNLIKELY(is_flip)) { | if (UNLIKELY(is_flip)) { | ||||
| negate_v3(clip[val]); | negate_v3(clip[val]); | ||||
| } | } | ||||
| clip[val][3] = -dot_v3v3(clip[val], bb->vec[val]); | clip[val][3] = -dot_v3v3(clip[val], bb->vec[val]); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 451 Lines • ▼ Show 20 Lines | |||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Box View Support | /** \name Box View Support | ||||
| * | * | ||||
| * Use with quad-split so each view is clipped by the bounds of each view axis. | * Use with quad-split so each view is clipped by the bounds of each view axis. | ||||
| * \{ */ | * \{ */ | ||||
| static void view3d_boxview_clip(ScrArea *area) | static void view3d_boxview_clip(ScrArea *area) | ||||
| { | { | ||||
| ARegion *region; | |||||
| BoundBox *bb = MEM_callocN(sizeof(BoundBox), "clipbb"); | BoundBox *bb = MEM_callocN(sizeof(BoundBox), "clipbb"); | ||||
| float clip[6][4]; | float clip[6][4]; | ||||
| float x1 = 0.0f, y1 = 0.0f, z1 = 0.0f, ofs[3] = {0.0f, 0.0f, 0.0f}; | float x1 = 0.0f, y1 = 0.0f, z1 = 0.0f, ofs[3] = {0.0f, 0.0f, 0.0f}; | ||||
| int val; | |||||
| /* create bounding box */ | /* create bounding box */ | ||||
| for (region = area->regionbase.first; region; region = region->next) { | LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { | ||||
| if (region->regiontype == RGN_TYPE_WINDOW) { | if (region->regiontype == RGN_TYPE_WINDOW) { | ||||
| RegionView3D *rv3d = region->regiondata; | RegionView3D *rv3d = region->regiondata; | ||||
| if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXCLIP) { | if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXCLIP) { | ||||
| if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) { | if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) { | ||||
| if (region->winx > region->winy) { | if (region->winx > region->winy) { | ||||
| x1 = rv3d->dist; | x1 = rv3d->dist; | ||||
| } | } | ||||
| Show All 18 Lines | if (region->regiontype == RGN_TYPE_WINDOW) { | ||||
| else { | else { | ||||
| z1 = rv3d->dist; | z1 = rv3d->dist; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| for (val = 0; val < 8; val++) { | for (int val = 0; val < 8; val++) { | ||||
| if (ELEM(val, 0, 3, 4, 7)) { | if (ELEM(val, 0, 3, 4, 7)) { | ||||
| bb->vec[val][0] = -x1 - ofs[0]; | bb->vec[val][0] = -x1 - ofs[0]; | ||||
| } | } | ||||
| else { | else { | ||||
| bb->vec[val][0] = x1 - ofs[0]; | bb->vec[val][0] = x1 - ofs[0]; | ||||
| } | } | ||||
| if (ELEM(val, 0, 1, 4, 5)) { | if (ELEM(val, 0, 1, 4, 5)) { | ||||
| Show All 15 Lines | static void view3d_boxview_clip(ScrArea *area) | ||||
| normal_tri_v3(clip[0], bb->vec[0], bb->vec[1], bb->vec[4]); | normal_tri_v3(clip[0], bb->vec[0], bb->vec[1], bb->vec[4]); | ||||
| normal_tri_v3(clip[1], bb->vec[1], bb->vec[2], bb->vec[5]); | normal_tri_v3(clip[1], bb->vec[1], bb->vec[2], bb->vec[5]); | ||||
| normal_tri_v3(clip[2], bb->vec[2], bb->vec[3], bb->vec[6]); | normal_tri_v3(clip[2], bb->vec[2], bb->vec[3], bb->vec[6]); | ||||
| normal_tri_v3(clip[3], bb->vec[3], bb->vec[0], bb->vec[7]); | normal_tri_v3(clip[3], bb->vec[3], bb->vec[0], bb->vec[7]); | ||||
| normal_tri_v3(clip[4], bb->vec[4], bb->vec[5], bb->vec[6]); | normal_tri_v3(clip[4], bb->vec[4], bb->vec[5], bb->vec[6]); | ||||
| normal_tri_v3(clip[5], bb->vec[0], bb->vec[2], bb->vec[1]); | normal_tri_v3(clip[5], bb->vec[0], bb->vec[2], bb->vec[1]); | ||||
| /* then plane equations */ | /* then plane equations */ | ||||
| for (val = 0; val < 6; val++) { | for (int val = 0; val < 6; val++) { | ||||
| clip[val][3] = -dot_v3v3(clip[val], bb->vec[val % 5]); | clip[val][3] = -dot_v3v3(clip[val], bb->vec[val % 5]); | ||||
| } | } | ||||
| /* create bounding box */ | /* create bounding box */ | ||||
| for (region = area->regionbase.first; region; region = region->next) { | LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { | ||||
| if (region->regiontype == RGN_TYPE_WINDOW) { | if (region->regiontype == RGN_TYPE_WINDOW) { | ||||
| RegionView3D *rv3d = region->regiondata; | RegionView3D *rv3d = region->regiondata; | ||||
| if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXCLIP) { | if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXCLIP) { | ||||
| rv3d->rflag |= RV3D_CLIPPING; | rv3d->rflag |= RV3D_CLIPPING; | ||||
| memcpy(rv3d->clip, clip, sizeof(clip)); | memcpy(rv3d->clip, clip, sizeof(clip)); | ||||
| if (rv3d->clipbb) { | if (rv3d->clipbb) { | ||||
| MEM_freeN(rv3d->clipbb); | MEM_freeN(rv3d->clipbb); | ||||
| ▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | void view3d_boxview_copy(ScrArea *area, ARegion *region) | ||||
| } | } | ||||
| } | } | ||||
| /* 'clip' is used to know if our clip setting has changed */ | /* 'clip' is used to know if our clip setting has changed */ | ||||
| void ED_view3d_quadview_update(ScrArea *area, ARegion *region, bool do_clip) | void ED_view3d_quadview_update(ScrArea *area, ARegion *region, bool do_clip) | ||||
| { | { | ||||
| ARegion *region_sync = NULL; | ARegion *region_sync = NULL; | ||||
| RegionView3D *rv3d = region->regiondata; | RegionView3D *rv3d = region->regiondata; | ||||
| short viewlock; | |||||
| /* this function copies flags from the first of the 3 other quadview | /* this function copies flags from the first of the 3 other quadview | ||||
| * regions to the 2 other, so it assumes this is the region whose | * regions to the 2 other, so it assumes this is the region whose | ||||
| * properties are always being edited, weak */ | * properties are always being edited, weak */ | ||||
| viewlock = rv3d->viewlock; | short viewlock = rv3d->viewlock; | ||||
| if ((viewlock & RV3D_LOCK_ROTATION) == 0) { | if ((viewlock & RV3D_LOCK_ROTATION) == 0) { | ||||
| do_clip = (viewlock & RV3D_BOXCLIP) != 0; | do_clip = (viewlock & RV3D_BOXCLIP) != 0; | ||||
| viewlock = 0; | viewlock = 0; | ||||
| } | } | ||||
| else if ((viewlock & RV3D_BOXVIEW) == 0 && (viewlock & RV3D_BOXCLIP) != 0) { | else if ((viewlock & RV3D_BOXVIEW) == 0 && (viewlock & RV3D_BOXCLIP) != 0) { | ||||
| do_clip = true; | do_clip = true; | ||||
| viewlock &= ~RV3D_BOXCLIP; | viewlock &= ~RV3D_BOXCLIP; | ||||
| ▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name View Auto-Depth Utilities | /** \name View Auto-Depth Utilities | ||||
| * \{ */ | * \{ */ | ||||
| static float view_autodist_depth_margin(ARegion *region, const int mval[2], int margin) | static float view_autodist_depth_margin(ARegion *region, const int mval[2], int margin) | ||||
| { | { | ||||
| ViewDepths depth_temp = {0}; | |||||
| rcti rect; | rcti rect; | ||||
| float depth_close; | |||||
| if (margin == 0) { | if (margin == 0) { | ||||
| /* Get Z Depths, needed for perspective, nice for ortho */ | /* Get Z Depths, needed for perspective, nice for ortho */ | ||||
| rect.xmin = mval[0]; | rect.xmin = mval[0]; | ||||
| rect.ymin = mval[1]; | rect.ymin = mval[1]; | ||||
| rect.xmax = mval[0] + 1; | rect.xmax = mval[0] + 1; | ||||
| rect.ymax = mval[1] + 1; | rect.ymax = mval[1] + 1; | ||||
| } | } | ||||
| else { | else { | ||||
| BLI_rcti_init_pt_radius(&rect, mval, margin); | BLI_rcti_init_pt_radius(&rect, mval, margin); | ||||
| } | } | ||||
| ViewDepths depth_temp = {0}; | |||||
| view3d_update_depths_rect(region, &depth_temp, &rect); | view3d_update_depths_rect(region, &depth_temp, &rect); | ||||
| depth_close = view3d_depth_near(&depth_temp); | float depth_close = view3d_depth_near(&depth_temp); | ||||
| MEM_SAFE_FREE(depth_temp.depths); | MEM_SAFE_FREE(depth_temp.depths); | ||||
| return depth_close; | return depth_close; | ||||
| } | } | ||||
| /** | /** | ||||
| * Get the world-space 3d location from a screen-space 2d point. | * Get the world-space 3d location from a screen-space 2d point. | ||||
| * | * | ||||
| * \param mval: Input screen-space pixel location. | * \param mval: Input screen-space pixel location. | ||||
| * \param mouse_worldloc: Output world-space location. | * \param mouse_worldloc: Output world-space location. | ||||
| * \param fallback_depth_pt: Use this points depth when no depth can be found. | * \param fallback_depth_pt: Use this points depth when no depth can be found. | ||||
| */ | */ | ||||
| bool ED_view3d_autodist(Depsgraph *depsgraph, | bool ED_view3d_autodist(Depsgraph *depsgraph, | ||||
| ARegion *region, | ARegion *region, | ||||
| View3D *v3d, | View3D *v3d, | ||||
| const int mval[2], | const int mval[2], | ||||
| float mouse_worldloc[3], | float mouse_worldloc[3], | ||||
| const bool alphaoverride, | const bool alphaoverride, | ||||
| const float fallback_depth_pt[3]) | const float fallback_depth_pt[3]) | ||||
| { | { | ||||
| float depth_close; | float depth_close; | ||||
| int margin_arr[] = {0, 2, 4}; | int margin_arr[] = {0, 2, 4}; | ||||
| int i; | |||||
| bool depth_ok = false; | bool depth_ok = false; | ||||
| /* Get Z Depths, needed for perspective, nice for ortho */ | /* Get Z Depths, needed for perspective, nice for ortho */ | ||||
| ED_view3d_draw_depth(depsgraph, region, v3d, alphaoverride); | ED_view3d_draw_depth(depsgraph, region, v3d, alphaoverride); | ||||
| /* Attempt with low margin's first */ | /* Attempt with low margin's first */ | ||||
| i = 0; | int i = 0; | ||||
| do { | do { | ||||
| depth_close = view_autodist_depth_margin(region, mval, margin_arr[i++] * U.pixelsize); | depth_close = view_autodist_depth_margin(region, mval, margin_arr[i++] * U.pixelsize); | ||||
| depth_ok = (depth_close != FLT_MAX); | depth_ok = (depth_close != FLT_MAX); | ||||
| } while ((depth_ok == false) && (i < ARRAY_SIZE(margin_arr))); | } while ((depth_ok == false) && (i < ARRAY_SIZE(margin_arr))); | ||||
| if (depth_ok) { | if (depth_ok) { | ||||
| float centx = (float)mval[0] + 0.5f; | float centx = (float)mval[0] + 0.5f; | ||||
| float centy = (float)mval[1] + 0.5f; | float centy = (float)mval[1] + 0.5f; | ||||
| Show All 27 Lines | |||||
| /* no 4x4 sampling, run #ED_view3d_autodist_init first */ | /* no 4x4 sampling, run #ED_view3d_autodist_init first */ | ||||
| bool ED_view3d_autodist_simple(ARegion *region, | bool ED_view3d_autodist_simple(ARegion *region, | ||||
| const int mval[2], | const int mval[2], | ||||
| float mouse_worldloc[3], | float mouse_worldloc[3], | ||||
| int margin, | int margin, | ||||
| const float *force_depth) | const float *force_depth) | ||||
| { | { | ||||
| float depth; | |||||
| /* Get Z Depths, needed for perspective, nice for ortho */ | /* Get Z Depths, needed for perspective, nice for ortho */ | ||||
| float depth; | |||||
| if (force_depth) { | if (force_depth) { | ||||
| depth = *force_depth; | depth = *force_depth; | ||||
| } | } | ||||
| else { | else { | ||||
| depth = view_autodist_depth_margin(region, mval, margin); | depth = view_autodist_depth_margin(region, mval, margin); | ||||
| } | } | ||||
| if (depth == FLT_MAX) { | if (depth == FLT_MAX) { | ||||
| ▲ Show 20 Lines • Show All 114 Lines • ▼ Show 20 Lines | float ED_view3d_radius_to_dist(const View3D *v3d, | ||||
| BLI_assert(ELEM(persp, RV3D_ORTHO, RV3D_PERSP, RV3D_CAMOB)); | BLI_assert(ELEM(persp, RV3D_ORTHO, RV3D_PERSP, RV3D_CAMOB)); | ||||
| BLI_assert((persp != RV3D_CAMOB) || v3d->camera); | BLI_assert((persp != RV3D_CAMOB) || v3d->camera); | ||||
| if (persp == RV3D_ORTHO) { | if (persp == RV3D_ORTHO) { | ||||
| dist = ED_view3d_radius_to_dist_ortho(v3d->lens, radius); | dist = ED_view3d_radius_to_dist_ortho(v3d->lens, radius); | ||||
| } | } | ||||
| else { | else { | ||||
| float lens, sensor_size, zoom; | float lens, sensor_size, zoom; | ||||
| float angle; | |||||
| if (persp == RV3D_CAMOB) { | if (persp == RV3D_CAMOB) { | ||||
| CameraParams params; | CameraParams params; | ||||
| BKE_camera_params_init(¶ms); | BKE_camera_params_init(¶ms); | ||||
| params.clip_start = v3d->clip_start; | params.clip_start = v3d->clip_start; | ||||
| params.clip_end = v3d->clip_end; | params.clip_end = v3d->clip_end; | ||||
| Object *camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera); | Object *camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera); | ||||
| BKE_camera_params_from_object(¶ms, camera_eval); | BKE_camera_params_from_object(¶ms, camera_eval); | ||||
| lens = params.lens; | lens = params.lens; | ||||
| sensor_size = BKE_camera_sensor_size(params.sensor_fit, params.sensor_x, params.sensor_y); | sensor_size = BKE_camera_sensor_size(params.sensor_fit, params.sensor_x, params.sensor_y); | ||||
| /* ignore 'rv3d->camzoom' because we want to fit to the cameras frame */ | /* ignore 'rv3d->camzoom' because we want to fit to the cameras frame */ | ||||
| zoom = CAMERA_PARAM_ZOOM_INIT_CAMOB; | zoom = CAMERA_PARAM_ZOOM_INIT_CAMOB; | ||||
| } | } | ||||
| else { | else { | ||||
| lens = v3d->lens; | lens = v3d->lens; | ||||
| sensor_size = DEFAULT_SENSOR_WIDTH; | sensor_size = DEFAULT_SENSOR_WIDTH; | ||||
| zoom = CAMERA_PARAM_ZOOM_INIT_PERSP; | zoom = CAMERA_PARAM_ZOOM_INIT_PERSP; | ||||
| } | } | ||||
| angle = focallength_to_fov(lens, sensor_size); | float angle = focallength_to_fov(lens, sensor_size); | ||||
| /* zoom influences lens, correct this by scaling the angle as a distance | /* zoom influences lens, correct this by scaling the angle as a distance | ||||
| * (by the zoom-level) */ | * (by the zoom-level) */ | ||||
| angle = atanf(tanf(angle / 2.0f) * zoom) * 2.0f; | angle = atanf(tanf(angle / 2.0f) * zoom) * 2.0f; | ||||
| dist = ED_view3d_radius_to_dist_persp(angle, radius); | dist = ED_view3d_radius_to_dist_persp(angle, radius); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | |||||
| * \returns A newly calculated distance or the fallback. | * \returns A newly calculated distance or the fallback. | ||||
| */ | */ | ||||
| float ED_view3d_offset_distance(const float mat[4][4], | float ED_view3d_offset_distance(const float mat[4][4], | ||||
| const float ofs[3], | const float ofs[3], | ||||
| const float fallback_dist) | const float fallback_dist) | ||||
| { | { | ||||
| float pos[4] = {0.0f, 0.0f, 0.0f, 1.0f}; | float pos[4] = {0.0f, 0.0f, 0.0f, 1.0f}; | ||||
| float dir[4] = {0.0f, 0.0f, 1.0f, 0.0f}; | float dir[4] = {0.0f, 0.0f, 1.0f, 0.0f}; | ||||
| float dist; | |||||
| mul_m4_v4(mat, pos); | mul_m4_v4(mat, pos); | ||||
| add_v3_v3(pos, ofs); | add_v3_v3(pos, ofs); | ||||
| mul_m4_v4(mat, dir); | mul_m4_v4(mat, dir); | ||||
| normalize_v3(dir); | normalize_v3(dir); | ||||
| dist = dot_v3v3(pos, dir); | float dist = dot_v3v3(pos, dir); | ||||
| if ((dist < FLT_EPSILON) && (fallback_dist != 0.0f)) { | if ((dist < FLT_EPSILON) && (fallback_dist != 0.0f)) { | ||||
| dist = fallback_dist; | dist = fallback_dist; | ||||
| } | } | ||||
| return dist; | return dist; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 414 Lines • Show Last 20 Lines | |||||