Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_view3d/view3d_edit.c
| Show First 20 Lines • Show All 122 Lines • ▼ Show 20 Lines | |||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Generic View Operator Custom-Data | /** \name Generic View Operator Custom-Data | ||||
| * \{ */ | * \{ */ | ||||
| typedef struct ViewOpsData { | typedef struct ViewOpsData { | ||||
| /** Context pointers (assigned by #viewops_data_alloc). */ | /** Context pointers (assigned by #viewops_data_alloc). */ | ||||
| Main *bmain; | Main *bmain; | ||||
| bContext *C; | |||||
| Scene *scene; | Scene *scene; | ||||
| ScrArea *sa; | ScrArea *sa; | ||||
| ARegion *ar; | ARegion *ar; | ||||
| View3D *v3d; | View3D *v3d; | ||||
| RegionView3D *rv3d; | RegionView3D *rv3d; | ||||
| Depsgraph *depsgraph; | Depsgraph *depsgraph; | ||||
| /** Needed for continuous zoom. */ | /** Needed for continuous zoom. */ | ||||
| Show All 14 Lines | struct { | ||||
| float ofs[3]; | float ofs[3]; | ||||
| /** Initial distance to 'ofs'. */ | /** Initial distance to 'ofs'. */ | ||||
| float zfac; | float zfac; | ||||
| /** Trackball rotation only. */ | /** Trackball rotation only. */ | ||||
| float trackvec[3]; | float trackvec[3]; | ||||
| /** Dolly only. */ | /** Dolly only. */ | ||||
| float mousevec[3]; | float mousevec[3]; | ||||
| float viewpos[3]; | |||||
| } init; | } init; | ||||
| /** Previous state (previous modal event handled). */ | /** Previous state (previous modal event handled). */ | ||||
| struct { | struct { | ||||
| int event_xy[2]; | int event_xy[2]; | ||||
| /** For operators that use time-steps (continuous zoom). */ | /** For operators that use time-steps (continuous zoom). */ | ||||
| double time; | double time; | ||||
| } prev; | } prev; | ||||
| ▲ Show 20 Lines • Show All 243 Lines • ▼ Show 20 Lines | static void viewops_data_create(bContext *C, | ||||
| ED_view3d_camera_lock_init(depsgraph, vod->v3d, vod->rv3d); | ED_view3d_camera_lock_init(depsgraph, vod->v3d, vod->rv3d); | ||||
| vod->init.dist = rv3d->dist; | vod->init.dist = rv3d->dist; | ||||
| vod->init.camzoom = rv3d->camzoom; | vod->init.camzoom = rv3d->camzoom; | ||||
| copy_qt_qt(vod->init.quat, rv3d->viewquat); | copy_qt_qt(vod->init.quat, rv3d->viewquat); | ||||
| vod->init.event_xy[0] = vod->prev.event_xy[0] = event->x; | vod->init.event_xy[0] = vod->prev.event_xy[0] = event->x; | ||||
| vod->init.event_xy[1] = vod->prev.event_xy[1] = event->y; | vod->init.event_xy[1] = vod->prev.event_xy[1] = event->y; | ||||
| vod->C = C; | |||||
| if (viewops_flag & VIEWOPS_FLAG_USE_MOUSE_INIT) { | if (viewops_flag & VIEWOPS_FLAG_USE_MOUSE_INIT) { | ||||
| vod->init.event_xy_offset[0] = 0; | vod->init.event_xy_offset[0] = 0; | ||||
| vod->init.event_xy_offset[1] = 0; | vod->init.event_xy_offset[1] = 0; | ||||
| } | } | ||||
| else { | else { | ||||
| /* Simulate the event starting in the middle of the region. */ | /* Simulate the event starting in the middle of the region. */ | ||||
| vod->init.event_xy_offset[0] = BLI_rcti_cent_x(&vod->ar->winrct) - event->x; | vod->init.event_xy_offset[0] = BLI_rcti_cent_x(&vod->ar->winrct) - event->x; | ||||
| vod->init.event_xy_offset[1] = BLI_rcti_cent_y(&vod->ar->winrct) - event->y; | vod->init.event_xy_offset[1] = BLI_rcti_cent_y(&vod->ar->winrct) - event->y; | ||||
| ▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | ED_view3d_win_to_vector(vod->ar, (const float[2]){UNPACK2(event->mval)}, vod->init.mousevec); | ||||
| vod->init.zfac = ED_view3d_calc_zfac(rv3d, tvec, NULL); | vod->init.zfac = ED_view3d_calc_zfac(rv3d, tvec, NULL); | ||||
| } | } | ||||
| vod->reverse = 1.0f; | vod->reverse = 1.0f; | ||||
| if (rv3d->persmat[2][1] < 0.0f) { | if (rv3d->persmat[2][1] < 0.0f) { | ||||
| vod->reverse = -1.0f; | vod->reverse = -1.0f; | ||||
| } | } | ||||
| copy_v3_v3(vod->init.viewpos, rv3d->viewinv[3]); | |||||
| rv3d->rflag |= RV3D_NAVIGATING; | rv3d->rflag |= RV3D_NAVIGATING; | ||||
| } | } | ||||
| static void viewops_data_free(bContext *C, wmOperator *op) | static void viewops_data_free(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| ARegion *ar; | ARegion *ar; | ||||
| #if 0 | #if 0 | ||||
| Paint *p = BKE_paint_get_active_from_context(C); | Paint *p = BKE_paint_get_active_from_context(C); | ||||
| ▲ Show 20 Lines • Show All 206 Lines • ▼ Show 20 Lines | float angle; | ||||
| }; | }; | ||||
| calctrackballvec(&vod->ar->winrct, event_xy_offset, newvec); | calctrackballvec(&vod->ar->winrct, event_xy_offset, newvec); | ||||
| } | } | ||||
| sub_v3_v3v3(dvec, newvec, vod->init.trackvec); | sub_v3_v3v3(dvec, newvec, vod->init.trackvec); | ||||
| angle = (len_v3(dvec) / (2.0f * TRACKBALLSIZE)) * (float)M_PI; | angle = (len_v3(dvec) / (2.0f * TRACKBALLSIZE)) * (float)M_PI; | ||||
| if (U.uiflag2 & USER_2D_VIEWPORT_NAVIGATION) { | |||||
| angle *= 0.7f; | |||||
| } | |||||
| /* Allow for rotation beyond the interval [-pi, pi] */ | /* Allow for rotation beyond the interval [-pi, pi] */ | ||||
| angle = angle_wrap_rad(angle); | angle = angle_wrap_rad(angle); | ||||
| /* This relation is used instead of the actual angle between vectors | /* This relation is used instead of the actual angle between vectors | ||||
| * so that the angle of rotation is linearly proportional to | * so that the angle of rotation is linearly proportional to | ||||
| * the distance that the mouse is dragged. */ | * the distance that the mouse is dragged. */ | ||||
| cross_v3_v3v3(axis, vod->init.trackvec, newvec); | cross_v3_v3v3(axis, vod->init.trackvec, newvec); | ||||
| ▲ Show 20 Lines • Show All 922 Lines • ▼ Show 20 Lines | else if ((vod->rv3d->persp == RV3D_CAMOB) && !ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) { | ||||
| vod->rv3d->camdy += (vod->prev.event_xy[1] - y) / (vod->ar->winy * zoomfac); | vod->rv3d->camdy += (vod->prev.event_xy[1] - y) / (vod->ar->winy * zoomfac); | ||||
| CLAMP(vod->rv3d->camdx, -1.0f, 1.0f); | CLAMP(vod->rv3d->camdx, -1.0f, 1.0f); | ||||
| CLAMP(vod->rv3d->camdy, -1.0f, 1.0f); | CLAMP(vod->rv3d->camdy, -1.0f, 1.0f); | ||||
| } | } | ||||
| else { | else { | ||||
| float dvec[3]; | float dvec[3]; | ||||
| float mval_f[2]; | float mval_f[2]; | ||||
| if (U.uiflag2 & USER_2D_VIEWPORT_NAVIGATION) { | |||||
| float nvec[3]; | |||||
| float center[3]; | |||||
| float ssdp[3]; | |||||
| view3d_orbit_calc_center(vod->C, center); | |||||
| ED_view3d_project(vod->ar, center, ssdp); | |||||
| ssdp[0] = ssdp[0] + x - vod->prev.event_xy[0]; | |||||
| ssdp[1] = ssdp[1] + y - vod->prev.event_xy[1]; | |||||
| ED_view3d_win_to_3d(vod->v3d, vod->ar, center, ssdp, nvec); | |||||
| sub_v3_v3v3(dvec, nvec, center); | |||||
| } | |||||
campbellbarton: I think logic could be moved into the initialization step, scaling `vod->init.zfac`.
Then this… | |||||
| else { | |||||
| mval_f[0] = x - vod->prev.event_xy[0]; | mval_f[0] = x - vod->prev.event_xy[0]; | ||||
| mval_f[1] = y - vod->prev.event_xy[1]; | mval_f[1] = y - vod->prev.event_xy[1]; | ||||
| ED_view3d_win_to_delta(vod->ar, mval_f, dvec, vod->init.zfac); | ED_view3d_win_to_delta(vod->ar, mval_f, dvec, vod->init.zfac); | ||||
| } | |||||
| add_v3_v3(vod->rv3d->ofs, dvec); | add_v3_v3(vod->rv3d->ofs, dvec); | ||||
| if (vod->rv3d->viewlock & RV3D_BOXVIEW) { | if (vod->rv3d->viewlock & RV3D_BOXVIEW) { | ||||
| view3d_boxview_sync(vod->sa, vod->ar); | view3d_boxview_sync(vod->sa, vod->ar); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 392 Lines • ▼ Show 20 Lines | static void viewzoom_apply_3d(ViewOpsData *vod, | ||||
| const bool zoom_invert, | const bool zoom_invert, | ||||
| const bool zoom_to_pos) | const bool zoom_to_pos) | ||||
| { | { | ||||
| float zfac; | float zfac; | ||||
| float dist_range[2]; | float dist_range[2]; | ||||
| ED_view3d_dist_range_get(vod->v3d, dist_range); | ED_view3d_dist_range_get(vod->v3d, dist_range); | ||||
| if (U.uiflag2 & USER_2D_VIEWPORT_NAVIGATION && vod->rv3d->is_persp) { | |||||
| float center[3], new_ofs[3], vt[3], view_dir[3]; | |||||
| float center_dist, event_dist, zf; | |||||
| view3d_orbit_calc_center(vod->C, center); | |||||
| center_dist = len_v3v3(center, vod->init.viewpos); | |||||
campbellbartonUnsubmitted Not Done Inline ActionsThis can be a large number of the center point is far outside the view (even when it's close measured by depth). I couldn't tell if this is intended, if not - both points can be projected onto the view plane before measuring. campbellbarton: This can be a large number of the center point is far outside the view (even when it's close… | |||||
| if (U.uiflag & USER_ZOOM_HORIZ) { | |||||
| event_dist = vod->init.event_xy[0] - xy[0]; | |||||
| event_dist = event_dist / vod->ar->sizex; | |||||
| } | |||||
| else { | |||||
| event_dist = vod->init.event_xy[1] - xy[1]; | |||||
| event_dist = event_dist / vod->ar->sizey; | |||||
| } | |||||
| event_dist = event_dist * 500; | |||||
| copy_v3_v3(view_dir, vod->rv3d->viewinv[2]); | |||||
| mul_v3_fl(view_dir, -1.0f); | |||||
| normalize_v3(view_dir); | |||||
| zf = 0.005f * center_dist; | |||||
| CLAMP(zf, 0, 0.05f); | |||||
| mul_v3_v3fl(vt, view_dir, event_dist * zf); | |||||
| copy_v3_v3(new_ofs, vod->init.ofs); | |||||
| add_v3_v3(new_ofs, vt); | |||||
| copy_v3_v3(vod->rv3d->ofs, new_ofs); | |||||
| } | |||||
| else { | |||||
| zfac = viewzoom_scale_value_offset(&vod->ar->winrct, | zfac = viewzoom_scale_value_offset(&vod->ar->winrct, | ||||
| viewzoom, | viewzoom, | ||||
| zoom_invert, | zoom_invert, | ||||
| false, | false, | ||||
| xy, | xy, | ||||
| vod->init.event_xy, | vod->init.event_xy, | ||||
| vod->init.event_xy_offset, | vod->init.event_xy_offset, | ||||
| vod->rv3d->dist, | vod->rv3d->dist, | ||||
| vod->init.dist, | vod->init.dist, | ||||
| &vod->prev.time); | &vod->prev.time); | ||||
| if (zfac != 1.0f) { | if (zfac != 1.0f) { | ||||
| const float zfac_min = dist_range[0] / vod->rv3d->dist; | const float zfac_min = dist_range[0] / vod->rv3d->dist; | ||||
| const float zfac_max = dist_range[1] / vod->rv3d->dist; | const float zfac_max = dist_range[1] / vod->rv3d->dist; | ||||
| CLAMP(zfac, zfac_min, zfac_max); | CLAMP(zfac, zfac_min, zfac_max); | ||||
| view_zoom_to_window_xy_3d(vod->ar, zfac, zoom_to_pos ? vod->prev.event_xy : NULL); | view_zoom_to_window_xy_3d(vod->ar, zfac, zoom_to_pos ? vod->prev.event_xy : NULL); | ||||
| } | } | ||||
| } | |||||
| /* these limits were in old code too */ | /* these limits were in old code too */ | ||||
| CLAMP(vod->rv3d->dist, dist_range[0], dist_range[1]); | CLAMP(vod->rv3d->dist, dist_range[0], dist_range[1]); | ||||
| if (vod->rv3d->viewlock & RV3D_BOXVIEW) { | if (vod->rv3d->viewlock & RV3D_BOXVIEW) { | ||||
| view3d_boxview_sync(vod->sa, vod->ar); | view3d_boxview_sync(vod->sa, vod->ar); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 3,133 Lines • Show Last 20 Lines | |||||
I think logic could be moved into the initialization step, scaling vod->init.zfac.
Then this code could be left as-is.