Transform: use bool when local matrix is needed
authorCampbell Barton <ideasman42@gmail.com>
Fri, 4 May 2018 12:41:51 +0000 (14:41 +0200)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 4 May 2018 13:18:27 +0000 (15:18 +0200)
Existing code checked pose/edit mode to check for transforming in an
objects local space.

This added many similar checks all over the code,
which leads to confusion.
Multi-edit caused a regression in UV transform since where UV's
had the object matrix applied by accident.

Now there is a boolean to use a local matrix,
this allows for any mode to have a 4x4 matrix
applied w/o adding mode specific checks everywhere.

source/blender/editors/transform/transform.c
source/blender/editors/transform/transform.h
source/blender/editors/transform/transform_constraints.c
source/blender/editors/transform/transform_generics.c
source/blender/editors/transform/transform_snap.c

index cc7dd08b8a9654715cb0957619b1b4c8535b4208..69f48292b71f0e57bf15f7063190e36818e470f9 100644 (file)
@@ -3055,11 +3055,11 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2]))
                float warp_end_radius_local[3];
                float pivot_local[3];
 
-               if (t->flag & T_EDIT) {
-                       sub_v3_v3v3(warp_sta_local, data->warp_sta, tc->obedit->obmat[3]);
-                       sub_v3_v3v3(warp_end_local, data->warp_end, tc->obedit->obmat[3]);
-                       sub_v3_v3v3(warp_end_radius_local, warp_end_radius_global, tc->obedit->obmat[3]);
-                       sub_v3_v3v3(pivot_local, pivot_global, tc->obedit->obmat[3]);
+               if (tc->use_local_mat) {
+                       sub_v3_v3v3(warp_sta_local, data->warp_sta, tc->mat[3]);
+                       sub_v3_v3v3(warp_end_local, data->warp_end, tc->mat[3]);
+                       sub_v3_v3v3(warp_end_radius_local, warp_end_radius_global, tc->mat[3]);
+                       sub_v3_v3v3(pivot_local, pivot_global, tc->mat[3]);
                }
                else {
                        copy_v3_v3(warp_sta_local, data->warp_sta);
@@ -3855,18 +3855,14 @@ static void ElementRotation_ex(TransInfo *t, TransDataContainer *tc, TransData *
         * has been computed, it has to be converted back into the bone's space.
         */
        else if (t->flag & T_POSE) {
-               float pmtx[3][3], imtx[3][3];
-               
                // Extract and invert armature object matrix
-               copy_m3_m4(pmtx, tc->poseobj->obmat);
-               invert_m3_m3(imtx, pmtx);
-               
+
                if ((td->flag & TD_NO_LOC) == 0) {
                        sub_v3_v3v3(vec, td->center, center);
                        
-                       mul_m3_v3(pmtx, vec);   // To Global space
+                       mul_m3_v3(tc->mat3, vec);   // To Global space
                        mul_m3_v3(mat, vec);        // Applying rotation
-                       mul_m3_v3(imtx, vec);   // To Local space
+                       mul_m3_v3(tc->imat3, vec);  // To Local space
                        
                        add_v3_v3(vec, center);
                        /* vec now is the location where the object has to be */
@@ -3878,11 +3874,11 @@ static void ElementRotation_ex(TransInfo *t, TransDataContainer *tc, TransData *
                                /* do nothing */
                        }
                        else if (td->flag & TD_PBONE_LOCAL_MTX_C) {
-                               mul_m3_v3(pmtx, vec);   // To Global space
+                               mul_m3_v3(tc->mat3, vec);        // To Global space
                                mul_m3_v3(td->ext->l_smtx, vec); // To Pose space (Local Location)
                        }
                        else {
-                               mul_m3_v3(pmtx, vec);   // To Global space
+                               mul_m3_v3(tc->mat3, vec); // To Global space
                                mul_m3_v3(td->smtx, vec); // To Pose space
                        }
 
@@ -4441,9 +4437,8 @@ static void applyTranslationValue(TransInfo *t, const float vec[3])
                if (apply_snap_align_rotation) {
                        copy_v3_v3(pivot, t->tsnap.snapTarget);
                        /* The pivot has to be in local-space (see T49494) */
-                       if (t->flag & (T_EDIT | T_POSE)) {
-                               Object *ob = tc->obedit ? tc->obedit : tc->poseobj;
-                               mul_m4_v3(ob->imat, pivot);
+                       if (tc->use_local_mat) {
+                               mul_m4_v3(tc->imat, pivot);
                        }
                }
 
index 19e023b467d3a36b793f2464b2fb0ecf93936b90..358be8f9e2982f1491165a39d3390bf29a0909ab 100644 (file)
@@ -423,8 +423,20 @@ typedef struct TransDataContainer {
        TransData2D *data_2d;
 
        struct Object *obedit;
-       /** Normalized editmode matrix ('T_EDIT' only). */
-       float          obedit_mat[3][3];
+
+       /**
+        * Use when #T_LOCAL_MATRIX is set.
+        * Typically: 'obedit->obmat' or 'poseobj->obmat', but may be used elsewhere too.
+        */
+       bool use_local_mat;
+       float  mat[4][4];
+       float imat[4][4];
+       /** 3x3 copies of matrices above. */
+       float  mat3[3][3];
+       float imat3[3][3];
+
+       /** Normalized 'mat3' */
+       float  mat3_unit[3][3];
 
        /** if 't->flag & T_POSE', this denotes pose object */
        struct Object *poseobj;
@@ -545,7 +557,10 @@ typedef struct TransInfo {
 #define T_CAMERA               (1 << 4)
                 // trans on points, having no rotation/scale
 #define T_POINTS               (1 << 6)
-/* empty slot - (1 << 7) */
+/**
+ * Apply matrix #TransDataContainer.matrix, this avoids having to have duplicate check all over
+ * that happen to apply to spesiifc modes (edit & pose for eg). */
+#define T_LOCAL_MATRIX (1 << 7)
 
        /* restrictions flags */
 #define T_ALL_RESTRICTIONS     ((1 << 8)|(1 << 9)|(1 << 10))
index bc9d0f19389f87bc45d76ba29bfa14890c19dcfd..bd03c0cedbabb7e63f404bbde75e66e1d61ef80a 100644 (file)
@@ -430,7 +430,7 @@ static void applyObjectConstraintVec(
 
                        mul_m3_v3(td->axismtx, out);
                        if (t->flag & T_EDIT) {
-                               mul_m3_v3(tc->obedit_mat, out);
+                               mul_m3_v3(tc->mat3_unit, out);
                        }
                }
        }
@@ -486,7 +486,7 @@ static void applyObjectConstraintSize(
 
                mul_m3_m3m3(tmat, smat, imat);
                if (t->flag & T_EDIT) {
-                       mul_m3_m3m3(smat, tc->obedit_mat, smat);
+                       mul_m3_m3m3(smat, tc->mat3_unit, smat);
                }
                mul_m3_m3m3(smat, td->axismtx, tmat);
        }
@@ -562,7 +562,7 @@ static void applyObjectConstraintRot(
                }
 
                if (t->flag & T_EDIT) {
-                       mul_m3_m3m3(tmp_axismtx, tc->obedit_mat, td->axismtx);
+                       mul_m3_m3m3(tmp_axismtx, tc->mat3_unit, td->axismtx);
                        axismtx = tmp_axismtx;
                }
                else {
@@ -616,7 +616,7 @@ void setAxisMatrixConstraint(TransInfo *t, int mode, const char text[])
        if (t->data_len_all == 1) {
                float axismtx[3][3];
                if (t->flag & T_EDIT) {
-                       mul_m3_m3m3(axismtx, tc->obedit_mat, tc->data->axismtx);
+                       mul_m3_m3m3(axismtx, tc->mat3_unit, tc->data->axismtx);
                }
                else {
                        copy_m3_m3(axismtx, tc->data->axismtx);
@@ -646,7 +646,7 @@ void setLocalConstraint(TransInfo *t, int mode, const char text[])
        if (t->flag & T_EDIT) {
                /* Use the active (first) edit object. */
                TransDataContainer *tc = t->data_container;
-               setConstraint(t, tc->obedit_mat, mode, text);
+               setConstraint(t, tc->mat3_unit, mode, text);
        }
        else {
                setAxisMatrixConstraint(t, mode, text);
@@ -872,13 +872,13 @@ static void drawObjectConstraint(TransInfo *t)
                                axismtx = td->axismtx;
                        }
                        else if (t->flag & T_EDIT) {
-                               mul_v3_m4v3(co, tc->obedit->obmat, td->center);
+                               mul_v3_m4v3(co, tc->mat, td->center);
 
-                               mul_m3_m3m3(tmp_axismtx, tc->obedit_mat, td->axismtx);
+                               mul_m3_m3m3(tmp_axismtx, tc->mat3_unit, td->axismtx);
                                axismtx = tmp_axismtx;
                        }
                        else if (t->flag & T_POSE) {
-                               mul_v3_m4v3(co, tc->poseobj->obmat, td->center);
+                               mul_v3_m4v3(co, tc->mat, td->center);
                                axismtx = td->axismtx;
                        }
                        else {
index 831867988cbbfae6c695d3e0b1eb96867dbc87c4..195c2ef3986e6bf7196f39bef2c7da9d9aeabc65 100644 (file)
@@ -1105,8 +1105,6 @@ void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis
                
                gpuPushMatrix();
 
-               // if (t->obedit) gpuLoadMatrix(t->obedit->obmat); // sets opengl viewing
-
                copy_v3_v3(v3, dir);
                mul_v3_fl(v3, v3d->far);
                
@@ -1187,12 +1185,25 @@ void initTransDataContainers_FromObjectData(TransInfo *t)
                        TransDataContainer *tc = &t->data_container[i];
                        if (object_mode & OB_MODE_EDIT) {
                                tc->obedit = objects[i];
-                               copy_m3_m4(tc->obedit_mat, tc->obedit->obmat);
-                               normalize_m3(tc->obedit_mat);
+                               /* Check needed for UV's */
+                               if ((t->flag & T_2D_EDIT) == 0) {
+                                       tc->use_local_mat = true;
+                               }
                        }
                        else if (object_mode & OB_MODE_POSE) {
                                tc->poseobj = objects[i];
+                               tc->use_local_mat = true;
                        }
+
+                       if (tc->use_local_mat) {
+                               BLI_assert((t->flag & T_2D_EDIT) == 0);
+                               copy_m4_m4(tc->mat, objects[i]->obmat);
+                               copy_m3_m4(tc->mat3, tc->mat);
+                               invert_m4_m4(tc->imat, tc->mat);
+                               invert_m3_m3(tc->imat3, tc->mat3);
+                               normalize_m3_m3(tc->mat3_unit, tc->mat3);
+                       }
+                       /* Otherwise leave as zero. */
                }
                MEM_freeN(objects);
        }
@@ -1766,16 +1777,11 @@ void calculateCenterLocal(
 {
        /* setting constraint center */
        /* note, init functions may over-ride t->center */
-       if (t->flag & (T_EDIT | T_POSE)) {
-               FOREACH_TRANS_DATA_CONTAINER (t, tc) {
-                       float obinv[4][4];
-                       Object *ob = tc->obedit ? tc->obedit : tc->poseobj;
-                       invert_m4_m4(obinv, ob->obmat);
-                       mul_v3_m4v3(tc->center_local, obinv, center_global);
+       FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+               if (tc->use_local_mat) {
+                       mul_v3_m4v3(tc->center_local, tc->imat, center_global);
                }
-       }
-       else {
-               FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+               else {
                        copy_v3_v3(tc->center_local, center_global);
                }
        }
@@ -1865,14 +1871,13 @@ void calculateCenterMedian(TransInfo *t, float r_center[3])
        int total = 0;
 
        FOREACH_TRANS_DATA_CONTAINER (t, tc) {
-               Object *ob_xform = tc->obedit ? tc->obedit : tc->poseobj;
                int i;
                for (i = 0; i < tc->data_len; i++) {
                        if (tc->data[i].flag & TD_SELECTED) {
                                if (!(tc->data[i].flag & TD_NOCENTER)) {
-                                       if (ob_xform) {
+                                       if (tc->use_local_mat) {
                                                float v[3];
-                                               mul_v3_m4v3(v, ob_xform->obmat, tc->data[i].center);
+                                               mul_v3_m4v3(v, tc->mat, tc->data[i].center);
                                                add_v3_v3(partial, v);
                                        }
                                        else {
@@ -1896,14 +1901,13 @@ void calculateCenterBound(TransInfo *t, float r_center[3])
        int i;
        bool is_first = true;
        FOREACH_TRANS_DATA_CONTAINER (t, tc) {
-               Object *ob_xform = tc->obedit ? tc->obedit : tc->poseobj;
                for (i = 0; i < tc->data_len; i++) {
                        if (is_first == false) {
                                if (tc->data[i].flag & TD_SELECTED) {
                                        if (!(tc->data[i].flag & TD_NOCENTER)) {
-                                               if (ob_xform) {
+                                               if (tc->use_local_mat) {
                                                        float v[3];
-                                                       mul_v3_m4v3(v, ob_xform->obmat, tc->data[i].center);
+                                                       mul_v3_m4v3(v, tc->mat, tc->data[i].center);
                                                        minmax_v3v3_v3(min, max, v);
                                                }
                                                else {
index 7e996fd4086967f8b8b414340fd6e43651ef52eb..f0cb291925adc29ff1cafaafd3617dd6ef81d5ce 100644 (file)
@@ -277,13 +277,6 @@ void applyProject(TransInfo *t)
 
                FOREACH_TRANS_DATA_CONTAINER(t, tc) {
                        TransData *td = tc->data;
-
-                       float imat[4][4];
-                       if (t->flag & (T_EDIT | T_POSE)) {
-                               Object *ob = tc->obedit ? tc->obedit : tc->poseobj;
-                               invert_m4_m4(imat, ob->obmat);
-                       }
-
                        for (i = 0; i < tc->data_len; i++, td++) {
                                float iloc[3], loc[3], no[3];
                                float mval_fl[2];
@@ -299,9 +292,8 @@ void applyProject(TransInfo *t)
                                        continue;
 
                                copy_v3_v3(iloc, td->loc);
-                               if (t->flag & (T_EDIT | T_POSE)) {
-                                       Object *ob = tc->obedit ? tc->obedit : tc->poseobj;
-                                       mul_m4_v3(ob->obmat, iloc);
+                               if (tc->use_local_mat) {
+                                       mul_m4_v3(tc->mat, iloc);
                                }
                                else if (t->flag & T_OBJECT) {
                                        BKE_object_eval_transform_all(t->depsgraph, t->scene, td->ob);
@@ -314,8 +306,8 @@ void applyProject(TransInfo *t)
                                                loc, no))
                                        {
 #if 0
-                                               if (t->flag & (T_EDIT | T_POSE)) {
-                                                       mul_m4_v3(imat, loc);
+                                               if (tc->use_local_mat) {
+                                                       mul_m4_v3(tc->imat, loc);
                                                }
 #endif
 
@@ -352,8 +344,6 @@ void applyGridAbsolute(TransInfo *t)
 {
        float grid_size = 0.0f;
        GearsType grid_action;
-       float (*obmat)[4] = NULL;
-       bool use_obmat = false;
        int i;
        
        if (!(activeSnap(t) && (ELEM(t->tsnap.mode, SCE_SNAP_MODE_INCREMENT, SCE_SNAP_MODE_GRID))))
@@ -375,12 +365,6 @@ void applyGridAbsolute(TransInfo *t)
        FOREACH_TRANS_DATA_CONTAINER(t, tc) {
                TransData *td;
 
-               if (t->flag & (T_EDIT | T_POSE)) {
-                       Object *ob = tc->obedit ? tc->obedit : tc->poseobj;
-                       obmat = ob->obmat;
-                       use_obmat = true;
-               }
-
                for (i = 0, td = tc->data; i < tc->data_len; i++, td++) {
                        float iloc[3], loc[3], tvec[3];
 
@@ -394,8 +378,8 @@ void applyGridAbsolute(TransInfo *t)
                                continue;
 
                        copy_v3_v3(iloc, td->loc);
-                       if (use_obmat) {
-                               mul_m4_v3(obmat, iloc);
+                       if (tc->use_local_mat) {
+                               mul_m4_v3(tc->mat, iloc);
                        }
                        else if (t->flag & T_OBJECT) {
                                BKE_object_eval_transform_all(t->depsgraph, t->scene, td->ob);
@@ -1093,17 +1077,13 @@ static void TargetSnapMedian(TransInfo *t)
                t->tsnap.snapTarget[2] = 0;
 
                FOREACH_TRANS_DATA_CONTAINER (t, tc) {
-                       Object *ob_xform = NULL;
-                       if (t->flag & (T_EDIT | T_POSE)) {
-                               ob_xform = tc->obedit ? tc->obedit : tc->poseobj;
-                       }
                        TransData *td = tc->data;
                        int i;
                        for (i = 0; i < tc->data_len && td->flag & TD_SELECTED; i++, td++) {
                                /* TODO(campbell): perform the global transformation once per TransDataContainer */
-                               if (ob_xform) {
+                               if (tc->use_local_mat) {
                                        float v[3];
-                                       mul_v3_m4v3(v, ob_xform->obmat, td->center);
+                                       mul_v3_m4v3(v, tc->mat, td->center);
                                        add_v3_v3(t->tsnap.snapTarget, v);
                                }
                                else {
@@ -1187,9 +1167,8 @@ static void TargetSnapClosest(TransInfo *t)
 
                                        copy_v3_v3(loc, td->center);
 
-                                       if (t->flag & (T_EDIT | T_POSE)) {
-                                               Object *ob = tc->obedit ? tc->obedit : tc->poseobj;
-                                               mul_m4_v3(ob->obmat, loc);
+                                       if (tc->use_local_mat) {
+                                               mul_m4_v3(tc->mat, loc);
                                        }
 
                                        dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint);