diff options
Diffstat (limited to 'source')
7 files changed, 262 insertions, 84 deletions
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index b84ce83500f..0429e37a077 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -355,10 +355,12 @@ typedef struct MouseInput { /** Initial mouse position. */ int imval[2]; - bool precision; - float precision_factor; + float imval_unproj[3]; float center[2]; float factor; + float precision_factor; + bool precision; + /** Additional data, if needed by the particular function. */ void *data; @@ -758,6 +760,7 @@ void applyMouseInput(struct TransInfo *t, struct MouseInput *mi, const int mval[2], float output[3]); +void transform_input_update(TransInfo *t, const float fac); void setCustomPoints(TransInfo *t, MouseInput *mi, const int start[2], const int end[2]); void setCustomPointsFromDirection(TransInfo *t, MouseInput *mi, const float dir[2]); @@ -806,6 +809,7 @@ void calculateCenter2D(TransInfo *t); void calculateCenterLocal(TransInfo *t, const float center_global[3]); void calculateCenter(TransInfo *t); +void tranformViewUpdate(TransInfo *t); /* API functions for getting center points */ void calculateCenterBound(TransInfo *t, float r_center[3]); diff --git a/source/blender/editors/transform/transform_convert_node.c b/source/blender/editors/transform/transform_convert_node.c index e18f75b71ae..0712fd8f719 100644 --- a/source/blender/editors/transform/transform_convert_node.c +++ b/source/blender/editors/transform/transform_convert_node.c @@ -153,6 +153,7 @@ static void createTransNodeData(bContext *UNUSED(C), TransInfo *t) static void flushTransNodes(TransInfo *t) { const float dpi_fac = UI_DPI_FAC; + float offset[2] = {0.0f, 0.0f}; View2DEdgePanData *customdata = (View2DEdgePanData *)t->custom.type.data; @@ -166,14 +167,16 @@ static void flushTransNodes(TransInfo *t) t->region->winrct.xmin + t->mval[0], t->region->winrct.ymin + t->mval[1], }; + const rctf rect = t->region->v2d.cur; UI_view2d_edge_pan_apply(t->context, customdata, xy); + if (!BLI_rctf_compare(&rect, &t->region->v2d.cur, FLT_EPSILON)) { + /* Additional offset due to change in view2D rect. */ + BLI_rctf_transform_pt_v(&t->region->v2d.cur, &rect, offset, offset); + tranformViewUpdate(t); + } } } - /* Initial and current view2D rects for additional transform due to view panning and zooming */ - const rctf *rect_src = &customdata->initial_rect; - const rctf *rect_dst = &t->region->v2d.cur; - FOREACH_TRANS_DATA_CONTAINER (t, tc) { applyGridAbsolute(t); @@ -184,10 +187,7 @@ static void flushTransNodes(TransInfo *t) bNode *node = td->extra; float loc[2]; - copy_v2_v2(loc, td2d->loc); - - /* additional offset due to change in view2D rect */ - BLI_rctf_transform_pt_v(rect_dst, rect_src, loc, loc); + add_v2_v2v2(loc, td2d->loc, offset); #ifdef USE_NODE_CENTER loc[0] -= 0.5f * BLI_rctf_size_x(&node->totr); diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 56a7d045dfd..5bdd64dacb9 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1132,6 +1132,33 @@ static void calculateCenter_FromAround(TransInfo *t, int around, float r_center[ } } +static void calculateZfac(TransInfo *t) +{ + /* ED_view3d_calc_zfac() defines a factor for perspective depth correction, + * used in ED_view3d_win_to_delta() */ + + /* zfac is only used convertViewVec only in cases operator was invoked in RGN_TYPE_WINDOW + * and never used in other cases. + * + * We need special case here as well, since ED_view3d_calc_zfac will crash when called + * for a region different from RGN_TYPE_WINDOW. + */ + if ((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW)) { + t->zfac = ED_view3d_calc_zfac(t->region->regiondata, t->center_global); + } + else if (t->spacetype == SPACE_IMAGE) { + SpaceImage *sima = t->area->spacedata.first; + t->zfac = 1.0f / sima->zoom; + } + else { + View2D *v2d = &t->region->v2d; + /* Get zoom fac the same way as in + * `ui_view2d_curRect_validate_resize` - better keep in sync! */ + const float zoomx = (float)(BLI_rcti_size_x(&v2d->mask) + 1) / BLI_rctf_size_x(&v2d->cur); + t->zfac = 1.0f / zoomx; + } +} + void calculateCenter(TransInfo *t) { if ((t->flag & T_OVERRIDE_CENTER) == 0) { @@ -1166,22 +1193,46 @@ void calculateCenter(TransInfo *t) } } - if (t->spacetype == SPACE_VIEW3D) { - /* #ED_view3d_calc_zfac() defines a factor for perspective depth correction, - * used in #ED_view3d_win_to_delta(). */ + calculateZfac(t); +} + +/* Called every time the view changes due to navigation. + * Adjusts the mouse position relative to the object. */ +void tranformViewUpdate(TransInfo *t) +{ + float zoom_prev = t->zfac; + float zoom_new; + if ((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW)) { + if (!t->persp) { + zoom_prev *= len_v3(t->persinv[0]); + } + + setTransformViewMatrices(t); + calculateZfac(t); - /* NOTE: `t->zfac` is only used #convertViewVec only in cases operator was invoked in - * #RGN_TYPE_WINDOW and never used in other cases. - * - * We need special case here as well, since #ED_view3d_calc_zfac will crash when called - * for a region different from #RGN_TYPE_WINDOW. */ - if (t->region->regiontype == RGN_TYPE_WINDOW) { - t->zfac = ED_view3d_calc_zfac(t->region->regiondata, t->center_global); + zoom_new = t->zfac; + if (!t->persp) { + zoom_new *= len_v3(t->persinv[0]); } - else { - t->zfac = 0.0f; + + for (int i = 0; i < ARRAY_SIZE(t->orient); i++) { + if (t->orient[i].type == V3D_ORIENT_VIEW) { + copy_m3_m4(t->orient[i].matrix, t->viewinv); + normalize_m3(t->orient[i].matrix); + if (t->orient_curr == i) { + copy_m3_m3(t->spacemtx, t->orient[i].matrix); + invert_m3_m3_safe_ortho(t->spacemtx_inv, t->spacemtx); + } + } } } + else { + calculateZfac(t); + zoom_new = t->zfac; + } + + calculateCenter2D(t); + transform_input_update(t, zoom_prev / zoom_new); } void calculatePropRatio(TransInfo *t) diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c index 3b320ff51d5..b541b199328 100644 --- a/source/blender/editors/transform/transform_input.c +++ b/source/blender/editors/transform/transform_input.c @@ -8,6 +8,7 @@ #include <stdlib.h> #include "DNA_screen_types.h" +#include "DNA_space_types.h" #include "BKE_context.h" @@ -18,6 +19,7 @@ #include "WM_types.h" #include "transform.h" +#include "transform_mode.h" #include "MEM_guardedalloc.h" @@ -251,11 +253,8 @@ void setCustomPointsFromDirection(TransInfo *t, MouseInput *mi, const float dir[ /** \name Setup & Handle Mouse Input * \{ */ -void initMouseInput(TransInfo *UNUSED(t), - MouseInput *mi, - const float center[2], - const int mval[2], - const bool precision) +void initMouseInput( + TransInfo *t, MouseInput *mi, const float center[2], const int mval[2], const bool precision) { mi->factor = 0; mi->precision = precision; @@ -266,6 +265,12 @@ void initMouseInput(TransInfo *UNUSED(t), mi->imval[0] = mval[0]; mi->imval[1] = mval[1]; + if ((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW)) { + float delta[3] = {mval[0] - center[0], mval[1] - center[1]}; + ED_view3d_win_to_delta(t->region, delta, t->zfac, delta); + add_v3_v3v3(mi->imval_unproj, t->center_global, delta); + } + mi->post = NULL; } @@ -441,4 +446,52 @@ void applyMouseInput(TransInfo *t, MouseInput *mi, const int mval[2], float outp } } +void transform_input_update(TransInfo *t, const float fac) +{ + MouseInput *mi = &t->mouse; + t->mouse.factor *= fac; + if ((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW)) { + projectIntView(t, mi->imval_unproj, mi->imval); + } + else { + int offset[2], center_2d_int[2] = {mi->center[0], mi->center[1]}; + sub_v2_v2v2_int(offset, mi->imval, center_2d_int); + offset[0] *= fac; + offset[1] *= fac; + + center_2d_int[0] = t->center2d[0]; + center_2d_int[1] = t->center2d[1]; + add_v2_v2v2_int(mi->imval, center_2d_int, offset); + } + + float center_old[2]; + copy_v2_v2(center_old, mi->center); + copy_v2_v2(mi->center, t->center2d); + + if (mi->use_virtual_mval) { + /* Update accumulator. */ + double mval_delta[2]; + sub_v2_v2v2_db(mval_delta, mi->virtual_mval.accum, mi->virtual_mval.prev); + mval_delta[0] *= fac; + mval_delta[1] *= fac; + copy_v2_v2_db(mi->virtual_mval.accum, mi->virtual_mval.prev); + add_v2_v2_db(mi->virtual_mval.accum, mval_delta); + } + + if (ELEM(mi->apply, InputAngle, InputAngleSpring)) { + float offset_center[2]; + sub_v2_v2v2(offset_center, mi->center, center_old); + struct InputAngle_Data *data = mi->data; + data->mval_prev[0] += offset_center[0]; + data->mval_prev[1] += offset_center[1]; + } + + if (t->mode == TFM_EDGE_SLIDE) { + transform_mode_edge_slide_reproject_input(t); + } + else if (t->mode == TFM_VERT_SLIDE) { + transform_mode_vert_slide_reproject_input(t); + } +} + /** \} */ diff --git a/source/blender/editors/transform/transform_mode.h b/source/blender/editors/transform/transform_mode.h index eac6734ed88..063de87ebb2 100644 --- a/source/blender/editors/transform/transform_mode.h +++ b/source/blender/editors/transform/transform_mode.h @@ -117,6 +117,7 @@ void drawEdgeSlide(TransInfo *t); void initEdgeSlide_ex( TransInfo *t, bool use_double_side, bool use_even, bool flipped, bool use_clamp); void initEdgeSlide(TransInfo *t); +void transform_mode_edge_slide_reproject_input(TransInfo *t); /* transform_mode_gpopacity.c */ @@ -191,3 +192,4 @@ void initTranslation(TransInfo *t); void drawVertSlide(TransInfo *t); void initVertSlide_ex(TransInfo *t, bool use_even, bool flipped, bool use_clamp); void initVertSlide(TransInfo *t); +void transform_mode_vert_slide_reproject_input(TransInfo *t); diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c index b48ba0640ad..85285e38bdd 100644 --- a/source/blender/editors/transform/transform_mode_edge_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_slide.c @@ -292,6 +292,73 @@ static BMLoop *get_next_loop( return NULL; } +static void edge_slide_projmat_get(TransInfo *t, TransDataContainer *tc, float r_projectMat[4][4]) +{ + RegionView3D *rv3d = NULL; + + if (t->spacetype == SPACE_VIEW3D) { + /* Background mode support. */ + rv3d = t->region ? t->region->regiondata : NULL; + } + + if (!rv3d) { + /* Ok, let's try to survive this. */ + unit_m4(r_projectMat); + } + else { + ED_view3d_ob_project_mat_get(rv3d, tc->obedit, r_projectMat); + } +} + +static void edge_slide_pair_project(TransDataEdgeSlideVert *sv, + ARegion *region, + float projectMat[4][4], + float r_sco_a[3], + float r_sco_b[3]) +{ + BMVert *v = sv->v; + + if (sv->v_side[1]) { + ED_view3d_project_float_v3_m4(region, sv->v_side[1]->co, r_sco_b, projectMat); + } + else { + add_v3_v3v3(r_sco_b, v->co, sv->dir_side[1]); + ED_view3d_project_float_v3_m4(region, r_sco_b, r_sco_b, projectMat); + } + + if (sv->v_side[0]) { + ED_view3d_project_float_v3_m4(region, sv->v_side[0]->co, r_sco_a, projectMat); + } + else { + add_v3_v3v3(r_sco_a, v->co, sv->dir_side[0]); + ED_view3d_project_float_v3_m4(region, r_sco_a, r_sco_a, projectMat); + } +} + +static void edge_slide_data_init_mval(MouseInput *mi, EdgeSlideData *sld, float *mval_dir) +{ + /* Possible all of the edge loops are pointing directly at the view. */ + if (UNLIKELY(len_squared_v2(mval_dir) < 0.1f)) { + mval_dir[0] = 0.0f; + mval_dir[1] = 100.0f; + } + + float mval_start[2], mval_end[2]; + + /* Zero out Start. */ + zero_v2(mval_start); + + /* dir holds a vector along edge loop */ + copy_v2_v2(mval_end, mval_dir); + mul_v2_fl(mval_end, 0.5f); + + sld->mval_start[0] = mi->imval[0] + mval_start[0]; + sld->mval_start[1] = mi->imval[1] + mval_start[1]; + + sld->mval_end[0] = mi->imval[0] + mval_end[0]; + sld->mval_end[1] = mi->imval[1] + mval_end[1]; +} + /** * Calculate screenspace `mval_start` / `mval_end`, optionally slide direction. */ @@ -308,29 +375,20 @@ static void calcEdgeSlide_mval_range(TransInfo *t, BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); ARegion *region = t->region; View3D *v3d = NULL; - RegionView3D *rv3d = NULL; float projectMat[4][4]; BMBVHTree *bmbvh; /* only for use_calc_direction */ float(*loop_dir)[3] = NULL, *loop_maxdist = NULL; - float mval_start[2], mval_end[2]; float mval_dir[3], dist_best_sq; if (t->spacetype == SPACE_VIEW3D) { /* background mode support */ v3d = t->area ? t->area->spacedata.first : NULL; - rv3d = t->region ? t->region->regiondata : NULL; } - if (!rv3d) { - /* ok, let's try to survive this */ - unit_m4(projectMat); - } - else { - ED_view3d_ob_project_mat_get(rv3d, tc->obedit, projectMat); - } + edge_slide_projmat_get(t, tc, projectMat); if (use_occlude_geometry) { bmbvh = BKE_bmbvh_new_from_editmesh(em, BMBVH_RESPECT_HIDDEN, NULL, false); @@ -379,21 +437,7 @@ static void calcEdgeSlide_mval_range(TransInfo *t, continue; } - if (sv->v_side[1]) { - ED_view3d_project_float_v3_m4(region, sv->v_side[1]->co, sco_b, projectMat); - } - else { - add_v3_v3v3(sco_b, v->co, sv->dir_side[1]); - ED_view3d_project_float_v3_m4(region, sco_b, sco_b, projectMat); - } - - if (sv->v_side[0]) { - ED_view3d_project_float_v3_m4(region, sv->v_side[0]->co, sco_a, projectMat); - } - else { - add_v3_v3v3(sco_a, v->co, sv->dir_side[0]); - ED_view3d_project_float_v3_m4(region, sco_a, sco_a, projectMat); - } + edge_slide_pair_project(sv, region, projectMat, sco_a, sco_b); /* global direction */ dist_sq = dist_squared_to_line_segment_v2(mval, sco_b, sco_a); @@ -433,24 +477,7 @@ static void calcEdgeSlide_mval_range(TransInfo *t, MEM_freeN(loop_maxdist); } - /* possible all of the edge loops are pointing directly at the view */ - if (UNLIKELY(len_squared_v2(mval_dir) < 0.1f)) { - mval_dir[0] = 0.0f; - mval_dir[1] = 100.0f; - } - - /* zero out start */ - zero_v2(mval_start); - - /* dir holds a vector along edge loop */ - copy_v2_v2(mval_end, mval_dir); - mul_v2_fl(mval_end, 0.5f); - - sld->mval_start[0] = t->mval[0] + mval_start[0]; - sld->mval_start[1] = t->mval[1] + mval_start[1]; - - sld->mval_end[0] = t->mval[0] + mval_end[0]; - sld->mval_end[1] = t->mval[1] + mval_end[1]; + edge_slide_data_init_mval(&t->mouse, sld, mval_dir); if (bmbvh) { BKE_bmbvh_free(bmbvh); @@ -466,7 +493,6 @@ static void calcEdgeSlide_even(TransInfo *t, if (sld->totsv > 0) { ARegion *region = t->region; - RegionView3D *rv3d = NULL; float projectMat[4][4]; int i = 0; @@ -475,18 +501,7 @@ static void calcEdgeSlide_even(TransInfo *t, float dist_sq = 0; float dist_min_sq = FLT_MAX; - if (t->spacetype == SPACE_VIEW3D) { - /* background mode support */ - rv3d = t->region ? t->region->regiondata : NULL; - } - - if (!rv3d) { - /* ok, let's try to survive this */ - unit_m4(projectMat); - } - else { - ED_view3d_ob_project_mat_get(rv3d, tc->obedit, projectMat); - } + edge_slide_projmat_get(t, tc, projectMat); for (i = 0; i < sld->totsv; i++, sv++) { /* Set length */ @@ -1553,3 +1568,32 @@ void initEdgeSlide(TransInfo *t) } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Mouse Input Utilities + * \{ */ + +void transform_mode_edge_slide_reproject_input(TransInfo *t) +{ + ARegion *region = t->region; + + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + EdgeSlideData *sld = tc->custom.mode.data; + if (sld) { + float projectMat[4][4]; + edge_slide_projmat_get(t, tc, projectMat); + + TransDataEdgeSlideVert *curr_sv = &sld->sv[sld->curr_sv_index]; + + float mval_dir[3], sco_a[3], sco_b[3]; + edge_slide_pair_project(curr_sv, region, projectMat, sco_a, sco_b); + sub_v3_v3v3(mval_dir, sco_b, sco_a); + edge_slide_data_init_mval(&t->mouse, sld, mval_dir); + } + } + + EdgeSlideData *sld = edgeSlideFirstGet(t); + setCustomPoints(t, &t->mouse, sld->mval_end, sld->mval_start); +} + +/** \} */ diff --git a/source/blender/editors/transform/transform_mode_vert_slide.c b/source/blender/editors/transform/transform_mode_vert_slide.c index 674ffcf17a8..d7c4d862b23 100644 --- a/source/blender/editors/transform/transform_mode_vert_slide.c +++ b/source/blender/editors/transform/transform_mode_vert_slide.c @@ -68,7 +68,7 @@ typedef struct VertSlideParams { bool flipped; } VertSlideParams; -static void calcVertSlideCustomPoints(struct TransInfo *t) +static void vert_slide_update_input(TransInfo *t) { VertSlideParams *slp = t->custom.mode.data; VertSlideData *sld = TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data; @@ -94,6 +94,11 @@ static void calcVertSlideCustomPoints(struct TransInfo *t) else { setCustomPoints(t, &t->mouse, mval_end, mval_start); } +} + +static void calcVertSlideCustomPoints(struct TransInfo *t) +{ + vert_slide_update_input(t); /* setCustomPoints isn't normally changing as the mouse moves, * in this case apply mouse input immediately so we don't refresh @@ -673,3 +678,22 @@ void initVertSlide(TransInfo *t) } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Mouse Input Utilities + * \{ */ + +void transform_mode_vert_slide_reproject_input(TransInfo *t) +{ + if (t->spacetype == SPACE_VIEW3D) { + RegionView3D *rv3d = t->region->regiondata; + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + VertSlideData *sld = tc->custom.mode.data; + ED_view3d_ob_project_mat_get(rv3d, tc->obedit, sld->proj_mat); + } + } + + vert_slide_update_input(t); +} + +/** \} */ |