diff options
Diffstat (limited to 'source/blender/editors')
9 files changed, 288 insertions, 261 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index bb4291555d0..5fc65522fe6 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -825,17 +825,17 @@ static void transform_event_xyz_constraint(TransInfo *t, short key_type, bool is } } else if (!edit_2d) { - if (t->orientation.index == 0 || ELEM(cmode, '\0', axis)) { + if (t->orient_curr == 0 || ELEM(cmode, '\0', axis)) { /* Successive presses on existing axis, cycle orientation modes. */ - t->orientation.index = (t->orientation.index + 1) % ARRAY_SIZE(t->orientation.types); - initTransformOrientation(t->context, t, t->orientation.types[t->orientation.index]); + t->orient_curr = (short)((t->orient_curr + 1) % (int)ARRAY_SIZE(t->orient)); + transform_orientations_current_set(t, t->orient_curr); } - if (t->orientation.index == 0) { + if (t->orient_curr == 0) { stopConstraint(t); } else { - const short orientation = t->orientation.types[t->orientation.index]; + const short orientation = t->orient[t->orient_curr].type; if (is_plane == false) { setUserConstraint(t, orientation, constraint_axis, msg2); } @@ -983,7 +983,7 @@ int transformEvent(TransInfo *t, const wmEvent *event) } else if (transform_mode_is_changeable(t->mode)) { /* Scale isn't normally very useful after extrude along normals, see T39756 */ - if ((t->con.mode & CON_APPLY) && (t->con.orientation == V3D_ORIENT_NORMAL)) { + if ((t->con.mode & CON_APPLY) && (t->orient[t->orient_curr].type == V3D_ORIENT_NORMAL)) { stopConstraint(t); } @@ -1601,8 +1601,8 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) mul_m3_v3(t->spacemtx, t->values_final); unit_m3(t->spacemtx); - BLI_assert(t->orientation.index == 0); - t->orientation.types[0] = V3D_ORIENT_GLOBAL; + BLI_assert(t->orient_curr == 0); + t->orient[0].type = V3D_ORIENT_GLOBAL; } // Save back mode in case we're in the generic operator @@ -1713,19 +1713,20 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) } if ((prop = RNA_struct_find_property(op->ptr, "orient_type"))) { - short orient_set, orient_cur; - orient_set = RNA_property_is_set(op->ptr, prop) ? RNA_property_enum_get(op->ptr, prop) : -1; - orient_cur = t->orientation.types[t->orientation.index]; + short orient_type_set, orient_type_curr; + orient_type_set = RNA_property_is_set(op->ptr, prop) ? RNA_property_enum_get(op->ptr, prop) : + -1; + orient_type_curr = t->orient[t->orient_curr].type; - if (!ELEM(orient_cur, orient_set, V3D_ORIENT_CUSTOM_MATRIX)) { - RNA_property_enum_set(op->ptr, prop, orient_cur); - orient_set = orient_cur; + if (!ELEM(orient_type_curr, orient_type_set, V3D_ORIENT_CUSTOM_MATRIX)) { + RNA_property_enum_set(op->ptr, prop, orient_type_curr); + orient_type_set = orient_type_curr; } if (((prop = RNA_struct_find_property(op->ptr, "orient_matrix_type")) && !RNA_property_is_set(op->ptr, prop))) { /* Set the first time to register on redo. */ - RNA_property_enum_set(op->ptr, prop, orient_set); + RNA_property_enum_set(op->ptr, prop, orient_type_set); RNA_float_set_array(op->ptr, "orient_matrix", &t->spacemtx[0][0]); } } @@ -1873,11 +1874,8 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve initTransInfo(C, t, op, event); /* Use the custom orientation when it is set. */ - short orientation = t->orientation.types[0] == V3D_ORIENT_CUSTOM_MATRIX ? - V3D_ORIENT_CUSTOM_MATRIX : - t->orientation.types[t->orientation.index]; - - initTransformOrientation(C, t, orientation); + short orient_index = t->orient[0].type == V3D_ORIENT_CUSTOM_MATRIX ? 0 : t->orient_curr; + transform_orientations_current_set(t, orient_index); if (t->spacetype == SPACE_VIEW3D) { t->draw_handle_apply = ED_region_draw_cb_activate( @@ -2033,7 +2031,7 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve /* Constraint init from operator */ if (t->con.mode & CON_APPLY) { - setUserConstraint(t, t->orientation.types[t->orientation.index], t->con.mode, "%s"); + setUserConstraint(t, t->orient[t->orient_curr].type, t->con.mode, "%s"); } /* Don't write into the values when non-modal because they are already set from operator redo diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 9f4b3773fd8..7720660e2e8 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -113,13 +113,8 @@ typedef struct TransSnap { } TransSnap; typedef struct TransCon { - short orientation; /** Description of the constraint for header_print. */ char text[50]; - /** Matrix of the constraint space. */ - float mtx[3][3]; - /** Inverse matrix of the constraint space. */ - float imtx[3][3]; /** Projection constraint matrix (same as #imtx with some axis == 0). */ float pmtx[3][3]; /** Initial mouse value for visual calculation @@ -531,13 +526,11 @@ typedef struct TransInfo { bool is_launch_event_tweak; struct { - short index; - short types[3]; - /* this gets used when orientation.type[x] is V3D_ORIENT_CUSTOM */ - struct TransformOrientation *custom; - /* this gets used when orientation.type[0] is V3D_ORIENT_CUSTOM_MATRIX */ - float custom_matrix[3][3]; - } orientation; + short type; + float matrix[3][3]; + } orient[3]; + short orient_curr; + /** backup from view3d, to restore on end. */ short gizmo_flag; @@ -911,8 +904,13 @@ void getViewVector(const TransInfo *t, const float coord[3], float vec[3]); void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot); /*********************** Transform Orientations ******************************/ - -void initTransformOrientation(struct bContext *C, TransInfo *t, short orientation); +short transform_orientation_matrix_get(struct bContext *C, + TransInfo *t, + const short orientation, + const float custom[3][3], + float r_spacemtx[3][3]); +const char *transform_orientations_spacename_get(TransInfo *t, const short orient_type); +void transform_orientations_current_set(struct TransInfo *t, const short orient_index); /* Those two fill in mat and return non-zero on success */ bool createSpaceNormal(float mat[3][3], const float normal[3]); diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index b05b99d9601..d13fa6de7c5 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -42,6 +42,7 @@ #include "BLI_utildefines.h" #include "BKE_context.h" +#include "BKE_scene.h" #include "ED_view3d.h" @@ -57,6 +58,27 @@ static void drawObjectConstraint(TransInfo *t); +static void projection_matrix_calc(const TransInfo *t, float r_pmtx[3][3]) +{ + unit_m3(r_pmtx); + + if (!(t->con.mode & CON_AXIS0)) { + zero_v3(r_pmtx[0]); + } + + if (!(t->con.mode & CON_AXIS1)) { + zero_v3(r_pmtx[1]); + } + + if (!(t->con.mode & CON_AXIS2)) { + zero_v3(r_pmtx[2]); + } + + float mat[3][3]; + mul_m3_m3m3(mat, r_pmtx, t->spacemtx_inv); + mul_m3_m3m3(r_pmtx, t->spacemtx, mat); +} + /* ************************** CONSTRAINTS ************************* */ static void constraintValuesFinal(TransInfo *t, float vec[3]) { @@ -123,7 +145,7 @@ void constraintNumInput(TransInfo *t, float vec[3]) static void postConstraintChecks(TransInfo *t, float vec[3]) { - mul_m3_v3(t->con.imtx, vec); + mul_m3_v3(t->spacemtx_inv, vec); snapGridIncrement(t, vec); @@ -153,7 +175,7 @@ static void postConstraintChecks(TransInfo *t, float vec[3]) /* inverse transformation at the end */ } - mul_m3_v3(t->con.mtx, vec); + mul_m3_v3(t->spacemtx, vec); } static void viewAxisCorrectCenter(const TransInfo *t, float t_con_center[3]) @@ -286,7 +308,7 @@ static bool isPlaneProjectionViewAligned(const TransInfo *t) int n = 0; for (int i = 0; i < 3; i++) { if (t->con.mode & (CON_AXIS0 << i)) { - constraint_vector[n++] = t->con.mtx[i]; + constraint_vector[n++] = t->spacemtx[i]; if (n == 2) { break; } @@ -326,6 +348,39 @@ static void planeProjection(const TransInfo *t, const float in[3], float out[3]) add_v3_v3v3(out, in, vec); } +static void applyAxisConstraintVec_impl( + TransInfo *t, float space_mat[3][3], float proj_mat[3][3], const float in[3], float out[3]) +{ + mul_m3_v3(proj_mat, out); + + // With snap, a projection is alright, no need to correct for view alignment + if (!validSnap(t)) { + const int dims = getConstraintSpaceDimension(t); + if (dims == 2) { + if (!is_zero_v3(out)) { + if (!isPlaneProjectionViewAligned(t)) { + planeProjection(t, in, out); + } + } + } + else if (dims == 1) { + float c[3]; + + if (t->con.mode & CON_AXIS0) { + copy_v3_v3(c, space_mat[0]); + } + else if (t->con.mode & CON_AXIS1) { + copy_v3_v3(c, space_mat[1]); + } + else if (t->con.mode & CON_AXIS2) { + copy_v3_v3(c, space_mat[2]); + } + axisProjection(t, c, in, out); + } + } + postConstraintChecks(t, out); +} + /* * Generic callback for constant spatial constraints applied to linear motion * @@ -339,41 +394,14 @@ static void applyAxisConstraintVec( { copy_v3_v3(out, in); if (!td && t->con.mode & CON_APPLY) { - mul_m3_v3(t->con.pmtx, out); - - // With snap, a projection is alright, no need to correct for view alignment - if (!validSnap(t)) { - const int dims = getConstraintSpaceDimension(t); - if (dims == 2) { - if (!is_zero_v3(out)) { - if (!isPlaneProjectionViewAligned(t)) { - planeProjection(t, in, out); - } - } - } - else if (dims == 1) { - float c[3]; - - if (t->con.mode & CON_AXIS0) { - copy_v3_v3(c, t->con.mtx[0]); - } - else if (t->con.mode & CON_AXIS1) { - copy_v3_v3(c, t->con.mtx[1]); - } - else if (t->con.mode & CON_AXIS2) { - copy_v3_v3(c, t->con.mtx[2]); - } - axisProjection(t, c, in, out); - } - } - postConstraintChecks(t, out); + applyAxisConstraintVec_impl(t, t->spacemtx, t->con.pmtx, in, out); } } /* * Generic callback for object based spatial constraints applied to linear motion * - * At first, the following is applied to the first data in the array + * At first, the following is applied without orientation * The IN vector in projected into the constrained space and then further * projected along the view vector. * (in perspective mode, the view vector is relative to the position on screen) @@ -387,33 +415,22 @@ static void applyObjectConstraintVec( copy_v3_v3(out, in); if (t->con.mode & CON_APPLY) { if (!td) { - mul_m3_v3(t->con.pmtx, out); - - const int dims = getConstraintSpaceDimension(t); - if (dims == 2) { - if (!is_zero_v3(out)) { - if (!isPlaneProjectionViewAligned(t)) { - planeProjection(t, in, out); - } - } + /* No specific orientation. */ + float spacemtx[3][3], pmtx[3][3] = {{0.0f}}; + unit_m3(spacemtx); + if (!(t->con.mode & CON_AXIS0)) { + pmtx[0][0] = 1.0f; } - else if (dims == 1) { - float c[3]; - - if (t->con.mode & CON_AXIS0) { - copy_v3_v3(c, t->con.mtx[0]); - } - else if (t->con.mode & CON_AXIS1) { - copy_v3_v3(c, t->con.mtx[1]); - } - else if (t->con.mode & CON_AXIS2) { - copy_v3_v3(c, t->con.mtx[2]); - } - axisProjection(t, c, in, out); + if (!(t->con.mode & CON_AXIS1)) { + pmtx[1][1] = 1.0f; + } + if (!(t->con.mode & CON_AXIS2)) { + pmtx[2][2] = 1.0f; } - postConstraintChecks(t, out); + applyAxisConstraintVec_impl(t, spacemtx, pmtx, in, out); } else { + /* Specific TransData's space, use axismtx. */ mul_m3_v3(td->axismtx, out); if (t->flag & T_EDIT) { mul_m3_v3(tc->mat3_unit, out); @@ -444,8 +461,8 @@ static void applyAxisConstraintSize(TransInfo *t, smat[2][2] = 1.0f; } - mul_m3_m3m3(tmat, smat, t->con.imtx); - mul_m3_m3m3(smat, t->con.mtx, tmat); + mul_m3_m3m3(tmat, smat, t->spacemtx_inv); + mul_m3_m3m3(smat, t->spacemtx, tmat); } } @@ -505,15 +522,15 @@ static void applyAxisConstraintRot( switch (mode) { case CON_AXIS0: case (CON_AXIS1 | CON_AXIS2): - copy_v3_v3(vec, t->con.mtx[0]); + copy_v3_v3(vec, t->spacemtx[0]); break; case CON_AXIS1: case (CON_AXIS0 | CON_AXIS2): - copy_v3_v3(vec, t->con.mtx[1]); + copy_v3_v3(vec, t->spacemtx[1]); break; case CON_AXIS2: case (CON_AXIS0 | CON_AXIS1): - copy_v3_v3(vec, t->con.mtx[2]); + copy_v3_v3(vec, t->spacemtx[2]); break; } /* don't flip axis if asked to or if num input */ @@ -586,12 +603,11 @@ static void applyObjectConstraintRot( /*--------------------- INTERNAL SETUP CALLS ------------------*/ -void setConstraint(TransInfo *t, float space[3][3], int mode, const char text[]) +void setConstraint(TransInfo *t, int mode, const char text[]) { BLI_strncpy(t->con.text + 1, text, sizeof(t->con.text) - 1); - copy_m3_m3(t->con.mtx, space); t->con.mode = mode; - getConstraintMatrix(t); + projection_matrix_calc(t, t->con.pmtx); startConstraint(t); @@ -605,41 +621,25 @@ void setConstraint(TransInfo *t, float space[3][3], int mode, const char text[]) /* applies individual td->axismtx constraints */ void setAxisMatrixConstraint(TransInfo *t, int mode, const char text[]) { - TransDataContainer *tc = t->data_container; - if (t->data_len_all == 1) { - float axismtx[3][3]; - if (t->flag & T_EDIT) { - mul_m3_m3m3(axismtx, tc->mat3_unit, tc->data->axismtx); - } - else { - copy_m3_m3(axismtx, tc->data->axismtx); - } - - setConstraint(t, axismtx, mode, text); - } - else { - BLI_strncpy(t->con.text + 1, text, sizeof(t->con.text) - 1); - unit_m3(t->con.mtx); - t->con.mode = mode; - getConstraintMatrix(t); + BLI_strncpy(t->con.text + 1, text, sizeof(t->con.text) - 1); + t->con.mode = mode; + projection_matrix_calc(t, t->con.pmtx); - startConstraint(t); + startConstraint(t); - t->con.drawExtra = drawObjectConstraint; - t->con.applyVec = applyObjectConstraintVec; - t->con.applySize = applyObjectConstraintSize; - t->con.applyRot = applyObjectConstraintRot; - t->redraw = TREDRAW_HARD; - } + t->con.drawExtra = drawObjectConstraint; + t->con.applyVec = applyObjectConstraintVec; + t->con.applySize = applyObjectConstraintSize; + t->con.applyRot = applyObjectConstraintRot; + t->redraw = TREDRAW_HARD; } void setLocalConstraint(TransInfo *t, int mode, const char text[]) { - /* edit-mode now allows local transforms too */ if (t->flag & T_EDIT) { - /* Use the active (first) edit object. */ - TransDataContainer *tc = t->data_container; - setConstraint(t, tc->mat3_unit, mode, text); + /* Although in edit-mode each object has its local space, use the + * orientation of the active object. */ + setConstraint(t, mode, text); } else { setAxisMatrixConstraint(t, mode, text); @@ -654,62 +654,43 @@ void setLocalConstraint(TransInfo *t, int mode, const char text[]) */ void setUserConstraint(TransInfo *t, short orientation, int mode, const char ftext[]) { - char text[256]; + const char *spacename = transform_orientations_spacename_get(t, orientation); switch (orientation) { case V3D_ORIENT_GLOBAL: { - float mtx[3][3]; - BLI_snprintf(text, sizeof(text), ftext, TIP_("global")); - unit_m3(mtx); - setConstraint(t, mtx, mode, text); + setConstraint(t, mode, spacename); break; } case V3D_ORIENT_LOCAL: - BLI_snprintf(text, sizeof(text), ftext, TIP_("local")); - setLocalConstraint(t, mode, text); + setLocalConstraint(t, mode, spacename); break; case V3D_ORIENT_NORMAL: - BLI_snprintf(text, sizeof(text), ftext, TIP_("normal")); if (checkUseAxisMatrix(t)) { - setAxisMatrixConstraint(t, mode, text); + setAxisMatrixConstraint(t, mode, spacename); } else { - setConstraint(t, t->spacemtx, mode, text); + setConstraint(t, mode, spacename); } break; case V3D_ORIENT_VIEW: - BLI_snprintf(text, sizeof(text), ftext, TIP_("view")); - setConstraint(t, t->spacemtx, mode, text); + setConstraint(t, mode, spacename); break; case V3D_ORIENT_CURSOR: - BLI_snprintf(text, sizeof(text), ftext, TIP_("cursor")); - setConstraint(t, t->spacemtx, mode, text); + setConstraint(t, mode, spacename); break; case V3D_ORIENT_GIMBAL: - BLI_snprintf(text, sizeof(text), ftext, TIP_("gimbal")); - setConstraint(t, t->spacemtx, mode, text); + setConstraint(t, mode, spacename); break; case V3D_ORIENT_CUSTOM_MATRIX: - BLI_snprintf(text, sizeof(text), ftext, TIP_("custom matrix")); - setConstraint(t, t->spacemtx, mode, text); + setConstraint(t, mode, spacename); break; case V3D_ORIENT_CUSTOM: default: { BLI_assert(orientation >= V3D_ORIENT_CUSTOM); - char orientation_str[128]; - BLI_snprintf(orientation_str, - sizeof(orientation_str), - "%s \"%s\"", - TIP_("custom orientation"), - t->orientation.custom->name); - BLI_snprintf(text, sizeof(text), ftext, orientation_str); - setConstraint(t, t->spacemtx, mode, text); + setConstraint(t, mode, spacename); break; } } - - t->con.orientation = orientation; - t->con.mode |= CON_USER; } @@ -740,9 +721,9 @@ void drawConstraint(TransInfo *t) convertViewVec(t, vec, (t->mval[0] - t->con.imval[0]), (t->mval[1] - t->con.imval[1])); add_v3_v3(vec, t->center_global); - drawLine(t, t->center_global, tc->mtx[0], 'X', 0); - drawLine(t, t->center_global, tc->mtx[1], 'Y', 0); - drawLine(t, t->center_global, tc->mtx[2], 'Z', 0); + drawLine(t, t->center_global, t->spacemtx[0], 'X', 0); + drawLine(t, t->center_global, t->spacemtx[1], 'Y', 0); + drawLine(t, t->center_global, t->spacemtx[2], 'Z', 0); depth_test_enabled = GPU_depth_test_enabled(); if (depth_test_enabled) { @@ -776,13 +757,13 @@ void drawConstraint(TransInfo *t) } if (tc->mode & CON_AXIS0) { - drawLine(t, t->center_global, tc->mtx[0], 'X', DRAWLIGHT); + drawLine(t, t->center_global, t->spacemtx[0], 'X', DRAWLIGHT); } if (tc->mode & CON_AXIS1) { - drawLine(t, t->center_global, tc->mtx[1], 'Y', DRAWLIGHT); + drawLine(t, t->center_global, t->spacemtx[1], 'Y', DRAWLIGHT); } if (tc->mode & CON_AXIS2) { - drawLine(t, t->center_global, tc->mtx[2], 'Z', DRAWLIGHT); + drawLine(t, t->center_global, t->spacemtx[2], 'Z', DRAWLIGHT); } } } @@ -928,28 +909,6 @@ void stopConstraint(TransInfo *t) t->num.idx_max = t->idx_max; } -void getConstraintMatrix(TransInfo *t) -{ - float mat[3][3]; - invert_m3_m3(t->con.imtx, t->con.mtx); - unit_m3(t->con.pmtx); - - if (!(t->con.mode & CON_AXIS0)) { - zero_v3(t->con.pmtx[0]); - } - - if (!(t->con.mode & CON_AXIS1)) { - zero_v3(t->con.pmtx[1]); - } - - if (!(t->con.mode & CON_AXIS2)) { - zero_v3(t->con.pmtx[2]); - } - - mul_m3_m3m3(mat, t->con.pmtx, t->con.imtx); - mul_m3_m3m3(t->con.pmtx, t->con.mtx, mat); -} - /*------------------------- MMB Select -------------------------------*/ void initSelectConstraint(TransInfo *t, bool force_global) @@ -959,11 +918,11 @@ void initSelectConstraint(TransInfo *t, bool force_global) orientation = V3D_ORIENT_GLOBAL; } else { - if (t->orientation.index == 0) { - t->orientation.index = 1; - initTransformOrientation(t->context, t, t->orientation.types[t->orientation.index]); + if (t->orient_curr == 0) { + t->orient_curr = 1; + transform_orientations_current_set(t, t->orient_curr); } - orientation = t->orientation.types[t->orientation.index]; + orientation = t->orient[t->orient_curr].type; } setUserConstraint(t, orientation, CON_APPLY | CON_SELECT, ""); @@ -1033,7 +992,7 @@ static void setNearestAxis3d(TransInfo *t) for (i = 0; i < 3; i++) { float axis[3], axis_2d[2]; - copy_v3_v3(axis, t->con.mtx[i]); + copy_v3_v3(axis, t->spacemtx[i]); mul_v3_fl(axis, zfac); /* now we can project to get window coordinate */ @@ -1102,7 +1061,7 @@ void setNearestAxis(TransInfo *t) setNearestAxis2d(t); } - getConstraintMatrix(t); + projection_matrix_calc(t, t->con.pmtx); } /*-------------- HELPER FUNCTIONS ----------------*/ diff --git a/source/blender/editors/transform/transform_constraints.h b/source/blender/editors/transform/transform_constraints.h index c98234c83da..b57a7599321 100644 --- a/source/blender/editors/transform/transform_constraints.h +++ b/source/blender/editors/transform/transform_constraints.h @@ -27,7 +27,7 @@ struct TransInfo; void constraintNumInput(TransInfo *t, float vec[3]); -void setConstraint(TransInfo *t, float space[3][3], int mode, const char text[]); +void setConstraint(TransInfo *t, int mode, const char text[]); void setAxisMatrixConstraint(TransInfo *t, int mode, const char text[]); void setLocalConstraint(TransInfo *t, int mode, const char text[]); void setUserConstraint(TransInfo *t, short orientation, int mode, const char text[]); @@ -35,7 +35,6 @@ void drawConstraint(TransInfo *t); void drawPropCircle(const struct bContext *C, TransInfo *t); void startConstraint(TransInfo *t); void stopConstraint(TransInfo *t); -void getConstraintMatrix(TransInfo *t); void initSelectConstraint(TransInfo *t, bool force_global); void selectConstraint(TransInfo *t); void postSelectConstraint(TransInfo *t); diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 2f3b50a7c1a..0614386530e 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1650,25 +1650,16 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve { TransformOrientationSlot *orient_slot = &t->scene->orientation_slots[SCE_ORIENT_DEFAULT]; - TransformOrientation *custom_orientation = NULL; short orient_type_set = -1; short orient_type_matrix_set = -1; short orient_type_scene = orient_slot->type; if (orient_type_scene == V3D_ORIENT_CUSTOM) { const int index_custom = orient_slot->index_custom; - custom_orientation = BKE_scene_transform_orientation_find(t->scene, index_custom); orient_type_scene += index_custom; } - short orient_type_default; - short orient_type_constraint[2]; - if ((t->flag & T_MODAL) && transform_mode_is_changeable(t->mode)) { - /* During modal, rotation starts with the View orientation. */ - orient_type_default = V3D_ORIENT_VIEW; - } - else { - orient_type_default = orient_type_scene; - } + short orient_types[3]; + float custom_matrix[3][3]; if (op && (prop = RNA_struct_find_property(op->ptr, "orient_axis"))) { t->orient_axis = RNA_property_enum_get(op->ptr, prop); @@ -1684,26 +1675,28 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve if (orient_type_set >= V3D_ORIENT_CUSTOM + BIF_countTransformOrientation(C)) { orient_type_set = V3D_ORIENT_GLOBAL; } - else { - custom_orientation = BKE_scene_transform_orientation_find( - t->scene, orient_type_set - V3D_ORIENT_CUSTOM); - } } /* Change the default orientation to be used when redoing. */ - orient_type_default = orient_type_set; - orient_type_constraint[0] = orient_type_set; - orient_type_constraint[1] = orient_type_scene; + orient_types[0] = orient_type_set; + orient_types[1] = orient_type_set; + orient_types[2] = orient_type_scene; } else { - orient_type_constraint[0] = orient_type_scene; - orient_type_constraint[1] = orient_type_scene != V3D_ORIENT_GLOBAL ? V3D_ORIENT_GLOBAL : - V3D_ORIENT_LOCAL; + if ((t->flag & T_MODAL) && transform_mode_is_changeable(t->mode)) { + orient_types[0] = V3D_ORIENT_VIEW; + } + else { + orient_types[0] = orient_type_scene; + } + orient_types[1] = orient_type_scene; + orient_types[2] = orient_type_scene != V3D_ORIENT_GLOBAL ? V3D_ORIENT_GLOBAL : + V3D_ORIENT_LOCAL; } if (op && ((prop = RNA_struct_find_property(op->ptr, "orient_matrix")) && RNA_property_is_set(op->ptr, prop))) { - RNA_property_float_get_array(op->ptr, prop, &t->orientation.custom_matrix[0][0]); + RNA_property_float_get_array(op->ptr, prop, &custom_matrix[0][0]); if ((prop = RNA_struct_find_property(op->ptr, "orient_matrix_type")) && RNA_property_is_set(op->ptr, prop)) { @@ -1718,18 +1711,30 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve if (orient_type_matrix_set == orient_type_set) { /* Constraints are forced to use the custom matrix when redoing. */ - orient_type_default = V3D_ORIENT_CUSTOM_MATRIX; + orient_types[0] = V3D_ORIENT_CUSTOM_MATRIX; } } - t->orientation.types[0] = orient_type_default; - t->orientation.types[1] = orient_type_constraint[0]; - t->orientation.types[2] = orient_type_constraint[1]; - t->orientation.custom = custom_orientation; - if (t->con.mode & CON_APPLY) { - t->orientation.index = 1; + t->orient_curr = 1; + } + + /* For efficiency, avoid calculating the same orientation twice. */ + for (int i = 1; i < 3; i++) { + t->orient[i].type = transform_orientation_matrix_get( + C, t, orient_types[i], custom_matrix, t->orient[i].matrix); + } + + if (orient_types[0] != orient_types[1]) { + t->orient[0].type = transform_orientation_matrix_get( + C, t, orient_types[0], custom_matrix, t->orient[0].matrix); + } + else { + memcpy(&t->orient[0], &t->orient[1], sizeof(t->orient[0])); } + + const char *spacename = transform_orientations_spacename_get(t, orient_types[0]); + BLI_strncpy(t->spacename, spacename, sizeof(t->spacename)); } if (op && ((prop = RNA_struct_find_property(op->ptr, "release_confirm")) && diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c index f143d4c2993..ddeba206e4a 100644 --- a/source/blender/editors/transform/transform_gizmo_3d.c +++ b/source/blender/editors/transform/transform_gizmo_3d.c @@ -1390,16 +1390,16 @@ void drawDial3d(const TransInfo *t) if (tc->mode & CON_APPLY) { if (tc->mode & CON_AXIS0) { axis_idx = MAN_AXIS_ROT_X; - negate_v3_v3(mat_basis[2], tc->mtx[0]); + negate_v3_v3(mat_basis[2], t->spacemtx[0]); } else if (tc->mode & CON_AXIS1) { axis_idx = MAN_AXIS_ROT_Y; - negate_v3_v3(mat_basis[2], tc->mtx[1]); + negate_v3_v3(mat_basis[2], t->spacemtx[1]); } else { BLI_assert((tc->mode & CON_AXIS2) != 0); axis_idx = MAN_AXIS_ROT_Z; - negate_v3_v3(mat_basis[2], tc->mtx[2]); + negate_v3_v3(mat_basis[2], t->spacemtx[2]); } } else { diff --git a/source/blender/editors/transform/transform_mode_shear.c b/source/blender/editors/transform/transform_mode_shear.c index dc0479f4e60..3eeb8a1e758 100644 --- a/source/blender/editors/transform/transform_mode_shear.c +++ b/source/blender/editors/transform/transform_mode_shear.c @@ -56,7 +56,7 @@ static void initShear_mouseInputMode(TransInfo *t) copy_v3_v3(dir, t->spacemtx[t->orient_axis_ortho]); /* Needed for axis aligned view gizmo. */ - if (t->orientation.types[t->orientation.index] == V3D_ORIENT_VIEW) { + if (t->orient[t->orient_curr].type == V3D_ORIENT_VIEW) { if (t->orient_axis_ortho == 0) { if (t->center2d[1] > t->mouse.imval[1]) { dir_flip = !dir_flip; diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index ff15bbfb5d6..4cddb9d3b4a 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -438,79 +438,147 @@ static int armature_bone_transflags_update_recursive(bArmature *arm, return total; } -void initTransformOrientation(bContext *C, TransInfo *t, short orientation) +/* Sets the matrix of the specified space orientation. + * If the matrix cannot be obtained, an orientation different from the one + * informed is returned */ +short transform_orientation_matrix_get(bContext *C, + TransInfo *t, + const short orientation, + const float custom[3][3], + float r_spacemtx[3][3]) { Object *ob = CTX_data_active_object(C); Object *obedit = CTX_data_active_object(C); switch (orientation) { case V3D_ORIENT_GLOBAL: - unit_m3(t->spacemtx); - BLI_strncpy(t->spacename, TIP_("global"), sizeof(t->spacename)); - break; + unit_m3(r_spacemtx); + return V3D_ORIENT_GLOBAL; case V3D_ORIENT_GIMBAL: - unit_m3(t->spacemtx); - if (ob && gimbal_axis(ob, t->spacemtx)) { - BLI_strncpy(t->spacename, TIP_("gimbal"), sizeof(t->spacename)); - break; + unit_m3(r_spacemtx); + if (ob && gimbal_axis(ob, r_spacemtx)) { + return V3D_ORIENT_GIMBAL; } ATTR_FALLTHROUGH; /* no gimbal fallthrough to normal */ + case V3D_ORIENT_NORMAL: if (obedit || (ob && ob->mode & OB_MODE_POSE)) { - BLI_strncpy(t->spacename, TIP_("normal"), sizeof(t->spacename)); - ED_getTransformOrientationMatrix(C, t->spacemtx, t->around); - break; + ED_getTransformOrientationMatrix(C, r_spacemtx, t->around); + return V3D_ORIENT_NORMAL; } ATTR_FALLTHROUGH; /* we define 'normal' as 'local' in Object mode */ - case V3D_ORIENT_LOCAL: - BLI_strncpy(t->spacename, TIP_("local"), sizeof(t->spacename)); + case V3D_ORIENT_LOCAL: if (ob) { - copy_m3_m4(t->spacemtx, ob->obmat); - normalize_m3(t->spacemtx); + copy_m3_m4(r_spacemtx, ob->obmat); + normalize_m3(r_spacemtx); + return V3D_ORIENT_LOCAL; } - else { - unit_m3(t->spacemtx); - } - - break; + unit_m3(r_spacemtx); + return V3D_ORIENT_GLOBAL; case V3D_ORIENT_VIEW: { float mat[3][3]; if ((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW)) { - BLI_strncpy(t->spacename, TIP_("view"), sizeof(t->spacename)); - copy_m3_m4(mat, t->viewinv); + RegionView3D *rv3d = t->region->regiondata; + copy_m3_m4(mat, rv3d->viewinv); normalize_m3(mat); } else { unit_m3(mat); } - copy_m3_m3(t->spacemtx, mat); - break; - } - case V3D_ORIENT_CURSOR: { - BLI_strncpy(t->spacename, TIP_("cursor"), sizeof(t->spacename)); - BKE_scene_cursor_rot_to_mat3(&t->scene->cursor, t->spacemtx); - break; + copy_m3_m3(r_spacemtx, mat); + return V3D_ORIENT_VIEW; } + case V3D_ORIENT_CURSOR: + BKE_scene_cursor_rot_to_mat3(&t->scene->cursor, r_spacemtx); + return V3D_ORIENT_CURSOR; + case V3D_ORIENT_CUSTOM_MATRIX: - BLI_strncpy(t->spacename, TIP_("custom"), sizeof(t->spacename)); - copy_m3_m3(t->spacemtx, t->orientation.custom_matrix); - break; + copy_m3_m3(r_spacemtx, custom); + return V3D_ORIENT_CUSTOM_MATRIX; + case V3D_ORIENT_CUSTOM: default: BLI_assert(orientation >= V3D_ORIENT_CUSTOM); - BLI_strncpy(t->spacename, t->orientation.custom->name, sizeof(t->spacename)); - if (applyTransformOrientation(t->orientation.custom, t->spacemtx, t->spacename)) { + TransformOrientation *ts = BKE_scene_transform_orientation_find( + t->scene, orientation - V3D_ORIENT_CUSTOM); + if (applyTransformOrientation(ts, r_spacemtx, t->spacename)) { /* pass */ } else { - unit_m3(t->spacemtx); + unit_m3(r_spacemtx); } break; } + return orientation; +} + +const char *transform_orientations_spacename_get(TransInfo *t, const short orient_type) +{ + switch (orient_type) { + case V3D_ORIENT_GLOBAL: + return TIP_("global"); + case V3D_ORIENT_GIMBAL: + return TIP_("gimbal"); + case V3D_ORIENT_NORMAL: + return TIP_("normal"); + case V3D_ORIENT_LOCAL: + return TIP_("local"); + case V3D_ORIENT_VIEW: + return TIP_("view"); + case V3D_ORIENT_CURSOR: + return TIP_("cursor"); + case V3D_ORIENT_CUSTOM_MATRIX: + return TIP_("custom"); + case V3D_ORIENT_CUSTOM: + default: + BLI_assert(orient_type >= V3D_ORIENT_CUSTOM); + TransformOrientation *ts = BKE_scene_transform_orientation_find( + t->scene, orient_type - V3D_ORIENT_CUSTOM); + return ts->name; + } +} + +void transform_orientations_current_set(TransInfo *t, const short orient_index) +{ + const short orientation = t->orient[orient_index].type; + const char *spacename; + switch (orientation) { + case V3D_ORIENT_GLOBAL: + spacename = TIP_("global"); + break; + case V3D_ORIENT_GIMBAL: + spacename = TIP_("gimbal"); + break; + case V3D_ORIENT_NORMAL: + spacename = TIP_("normal"); + break; + case V3D_ORIENT_LOCAL: + spacename = TIP_("local"); + break; + case V3D_ORIENT_VIEW: + spacename = TIP_("view"); + break; + case V3D_ORIENT_CURSOR: + spacename = TIP_("cursor"); + break; + case V3D_ORIENT_CUSTOM_MATRIX: + spacename = TIP_("custom"); + break; + case V3D_ORIENT_CUSTOM: + default: + BLI_assert(orientation >= V3D_ORIENT_CUSTOM); + TransformOrientation *ts = BKE_scene_transform_orientation_find( + t->scene, orientation - V3D_ORIENT_CUSTOM); + spacename = ts->name; + break; + } + + BLI_strncpy(t->spacename, spacename, sizeof(t->spacename)); + copy_m3_m3(t->spacemtx, t->orient[orient_index].matrix); invert_m3_m3(t->spacemtx_inv, t->spacemtx); } diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 154af6c8ae2..d3df68b21da 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -1749,8 +1749,8 @@ static void applyGridIncrement( float local_axis[3]; float pos_on_axis[3]; - copy_v3_v3(local_axis, t->con.mtx[i]); - copy_v3_v3(pos_on_axis, t->con.mtx[i]); + copy_v3_v3(local_axis, t->spacemtx[i]); + copy_v3_v3(pos_on_axis, t->spacemtx[i]); /* amount of movement on axis from initial pos */ mul_v3_fl(pos_on_axis, val[i]); |