diff options
author | Campbell Barton <ideasman42@gmail.com> | 2016-05-31 16:56:59 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2016-05-31 17:01:17 +0300 |
commit | a0e91ef04090790dcd683d86d3cadb9aff0062e7 (patch) | |
tree | 48941a69ffe73fdf8b292e8463581cf851cf297e /source/blender/editors/transform | |
parent | d5220d23f976d14350d5d76f7cb97d4fef8e977d (diff) |
Fix T48554: Absolute grid snap fails w/ cursor pivot
Use center of selection when using absolute grid snapping and cursor pivot.
Diffstat (limited to 'source/blender/editors/transform')
-rw-r--r-- | source/blender/editors/transform/transform.c | 2 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.h | 13 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_generics.c | 61 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_snap.c | 12 |
4 files changed, 70 insertions, 18 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 5c0c0bcd6c1..5b1a58497f0 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2863,7 +2863,7 @@ static void initBend(TransInfo *t) //copy_v3_v3(t->center, ED_view3d_cursor3d_get(t->scene, t->view)); calculateCenterCursor(t, t->center); - calculateCenterGlobal(t); + calculateCenterGlobal(t, t->center, t->center_global); t->val = 0.0f; diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 11151a9c65a..0e0d085bf6f 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -369,6 +369,11 @@ typedef struct TransCustomData { unsigned int use_free : 1; } TransCustomData; +typedef struct TransCenterData { + float local[3], global[3]; + unsigned int is_set : 1; +} TransCenterData; + typedef struct TransInfo { int mode; /* current mode */ int flag; /* generic flags for special behaviors */ @@ -396,6 +401,9 @@ typedef struct TransInfo { float center[3]; /* center of transformation (in local-space) */ float center_global[3]; /* center of transformation (in global-space) */ float center2d[2]; /* center in screen coordinates */ + /* Lazy initialize center data for when we need other center values. + * V3D_AROUND_ACTIVE + 1 (static assert checks this) */ + TransCenterData center_cache[5]; short idx_max; /* maximum index on the input vector */ float snap[3]; /* Snapping Gears */ float snap_spatial[3]; /* Spatial snapping gears(even when rotating, scaling... etc) */ @@ -742,8 +750,11 @@ void restoreTransObjects(TransInfo *t); void recalcData(TransInfo *t); void calculateCenter2D(TransInfo *t); -void calculateCenterGlobal(TransInfo *t); +void calculateCenterGlobal( + TransInfo *t, const float center_local[3], + float r_center_global[3]); +const TransCenterData *transformCenter_from_type(TransInfo *t, int around); void calculateCenter(TransInfo *t); /* API functions for getting center points */ diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index ed6477392d8..67740644afe 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1610,16 +1610,18 @@ void calculateCenter2D(TransInfo *t) } } -void calculateCenterGlobal(TransInfo *t) +void calculateCenterGlobal( + TransInfo *t, const float center_local[3], + float r_center_global[3]) { /* setting constraint center */ /* note, init functions may over-ride t->center */ if (t->flag & (T_EDIT | T_POSE)) { Object *ob = t->obedit ? t->obedit : t->poseobj; - mul_v3_m4v3(t->center_global, ob->obmat, t->center); + mul_v3_m4v3(r_center_global, ob->obmat, center_local); } else { - copy_v3_v3(t->center_global, t->center); + copy_v3_v3(r_center_global, center_local); } } @@ -1794,43 +1796,55 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3]) return ok; } - -void calculateCenter(TransInfo *t) +static void calculateCenter_FromAround(TransInfo *t, int around, float r_center[3]) { - switch (t->around) { + switch (around) { case V3D_AROUND_CENTER_BOUNDS: - calculateCenterBound(t, t->center); + calculateCenterBound(t, r_center); break; case V3D_AROUND_CENTER_MEAN: - calculateCenterMedian(t, t->center); + calculateCenterMedian(t, r_center); break; case V3D_AROUND_CURSOR: if (ELEM(t->spacetype, SPACE_IMAGE, SPACE_CLIP)) - calculateCenterCursor2D(t, t->center); + calculateCenterCursor2D(t, r_center); else if (t->spacetype == SPACE_IPO) - calculateCenterCursorGraph2D(t, t->center); + calculateCenterCursorGraph2D(t, r_center); else - calculateCenterCursor(t, t->center); + calculateCenterCursor(t, r_center); break; case V3D_AROUND_LOCAL_ORIGINS: /* Individual element center uses median center for helpline and such */ - calculateCenterMedian(t, t->center); + calculateCenterMedian(t, r_center); break; case V3D_AROUND_ACTIVE: { - if (calculateCenterActive(t, false, t->center)) { + if (calculateCenterActive(t, false, r_center)) { /* pass */ } else { /* fallback */ - calculateCenterMedian(t, t->center); + calculateCenterMedian(t, r_center); } break; } } +} + +void calculateCenter(TransInfo *t) +{ + calculateCenter_FromAround(t, t->around, t->center); + calculateCenterGlobal(t, t->center, t->center_global); + + /* avoid calculating again */ + { + TransCenterData *cd = &t->center_cache[t->around]; + copy_v3_v3(cd->local, t->center); + copy_v3_v3(cd->global, t->center_global); + cd->is_set = true; + } calculateCenter2D(t); - calculateCenterGlobal(t); /* for panning from cameraview */ if (t->flag & T_OBJECT) { @@ -1884,6 +1898,23 @@ void calculateCenter(TransInfo *t) } } +BLI_STATIC_ASSERT(ARRAY_SIZE(((TransInfo *)NULL)->center_cache) == (V3D_AROUND_ACTIVE + 1), "test size"); + +/** + * Lazy initialize transform center data, when we need to access center values from other types. + */ +const TransCenterData *transformCenter_from_type(TransInfo *t, int around) +{ + BLI_assert(around <= V3D_AROUND_ACTIVE); + TransCenterData *cd = &t->center_cache[around]; + if (cd->is_set == false) { + calculateCenter_FromAround(t, around, cd->local); + calculateCenterGlobal(t, cd->local, cd->global); + cd->is_set = true; + } + return cd; +} + void calculatePropRatio(TransInfo *t) { TransData *td = t->data; diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 38f1d37acd6..e72db4105a4 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -1520,11 +1520,21 @@ static void applyGridIncrement(TransInfo *t, float *val, int max_index, const fl /* absolute snapping on grid based on global center */ if ((t->tsnap.snap_spatial_grid) && (t->mode == TFM_TRANSLATION)) { + const float *center_global = t->center_global; + + /* use a fallback for cursor selection, + * this isn't useful as a global center for absolute grid snapping + * since its not based on the position of the selection. */ + if (t->around == V3D_AROUND_CURSOR) { + const TransCenterData *cd = transformCenter_from_type(t, V3D_AROUND_CENTER_MEAN); + center_global = cd->global; + } + for (i = 0; i <= max_index; i++) { /* do not let unconstrained axis jump to absolute grid increments */ if (!(t->con.mode & CON_APPLY) || t->con.mode & (CON_AXIS0 << i)) { const float iter_fac = fac[action] * asp[i]; - val[i] = iter_fac * roundf((val[i] + t->center_global[i]) / iter_fac) - t->center_global[i]; + val[i] = iter_fac * roundf((val[i] + center_global[i]) / iter_fac) - center_global[i]; } } } |