Revert "Constraints: remove special meaning of Local Space for parentless Objects."
authorSybren A. Stüvel <sybren@blender.org>
Mon, 9 Mar 2020 09:44:55 +0000 (10:44 +0100)
committerSybren A. Stüvel <sybren@blender.org>
Mon, 9 Mar 2020 09:44:55 +0000 (10:44 +0100)
This reverts commit 7728bfd4c45c634ba6b62e149176425ec5779945.

Although this brings back an inconsistency in the behaviour of
constraints on objects and bones, people were relying on the old
behaviour, and the new behaviour broke their files.

It is still desired to remove this inconsistency, but it will happen
more gradually.

source/blender/blenkernel/BKE_constraint.h
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/fcurve.c
source/blender/makesrna/intern/rna_object_api.c

index 73bd36844ac8295e8cc5cc15cb8c5755f04ec770..8fe3bd77a2606a6ccecec082ff112b3b5ebc7f42 100644 (file)
@@ -191,8 +191,12 @@ struct bConstraintOb *BKE_constraints_make_evalob(struct Depsgraph *depsgraph,
                                                   short datatype);
 void BKE_constraints_clear_evalob(struct bConstraintOb *cob);
 
-void BKE_constraint_mat_convertspace(
-    struct Object *ob, struct bPoseChannel *pchan, float mat[4][4], short from, short to);
+void BKE_constraint_mat_convertspace(struct Object *ob,
+                                     struct bPoseChannel *pchan,
+                                     float mat[4][4],
+                                     short from,
+                                     short to,
+                                     const bool keep_scale);
 
 void BKE_constraint_target_matrix_get(struct Depsgraph *depsgraph,
                                       struct Scene *scene,
index c1492810a11d5454639e816bf890ef7e383dd528..f751ccd66b005f558f6e35cfd21a363885d5d609 100644 (file)
@@ -255,7 +255,7 @@ void BKE_constraints_clear_evalob(bConstraintOb *cob)
  * For now, this is only implemented for Objects and PoseChannels.
  */
 void BKE_constraint_mat_convertspace(
-    Object *ob, bPoseChannel *pchan, float mat[4][4], short from, short to)
+    Object *ob, bPoseChannel *pchan, float mat[4][4], short from, short to, const bool keep_scale)
 {
   float diff_mat[4][4];
   float imat[4][4];
@@ -282,7 +282,7 @@ void BKE_constraint_mat_convertspace(
         /* use pose-space as stepping stone for other spaces... */
         if (ELEM(to, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_PARLOCAL)) {
           /* call self with slightly different values */
-          BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
+          BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
         }
         break;
       }
@@ -318,7 +318,7 @@ void BKE_constraint_mat_convertspace(
         /* use pose-space as stepping stone for other spaces */
         if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_PARLOCAL)) {
           /* call self with slightly different values */
-          BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
+          BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
         }
         break;
       }
@@ -332,7 +332,7 @@ void BKE_constraint_mat_convertspace(
         /* use pose-space as stepping stone for other spaces */
         if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL)) {
           /* call self with slightly different values */
-          BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
+          BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
         }
         break;
       }
@@ -348,6 +348,27 @@ void BKE_constraint_mat_convertspace(
         invert_m4_m4_safe(imat, diff_mat);
         mul_m4_m4m4(mat, imat, mat);
       }
+      else {
+        /* Local space in this case will have to be defined as local to the owner's
+         * transform-property-rotated axes. So subtract this rotation component.
+         */
+        /* XXX This is actually an ugly hack, local space of a parent-less object *is* the same as
+         *     global space!
+         *     Think what we want actually here is some kind of 'Final Space', i.e
+         *     . once transformations are applied - users are often confused about this too,
+         *     this is not consistent with bones
+         *     local space either... Meh :|
+         *     --mont29
+         */
+        BKE_object_to_mat4(ob, diff_mat);
+        if (!keep_scale) {
+          normalize_m4(diff_mat);
+        }
+        zero_v3(diff_mat[3]);
+
+        invert_m4_m4_safe(imat, diff_mat);
+        mul_m4_m4m4(mat, imat, mat);
+      }
     }
     else if (from == CONSTRAINT_SPACE_LOCAL && to == CONSTRAINT_SPACE_WORLD) {
       /* check that object has a parent - otherwise this won't work */
@@ -356,6 +377,19 @@ void BKE_constraint_mat_convertspace(
         mul_m4_m4m4(diff_mat, ob->parent->obmat, ob->parentinv);
         mul_m4_m4m4(mat, diff_mat, mat);
       }
+      else {
+        /* Local space in this case will have to be defined as local to the owner's
+         * transform-property-rotated axes. So add back this rotation component.
+         */
+        /* XXX See comment above for world->local case... */
+        BKE_object_to_mat4(ob, diff_mat);
+        if (!keep_scale) {
+          normalize_m4(diff_mat);
+        }
+        zero_v3(diff_mat[3]);
+
+        mul_m4_m4m4(mat, diff_mat, mat);
+      }
     }
   }
 }
@@ -541,7 +575,7 @@ static void constraint_target_to_mat4(Object *ob,
   /* Case OBJECT */
   if (substring[0] == '\0') {
     copy_m4_m4(mat, ob->obmat);
-    BKE_constraint_mat_convertspace(ob, NULL, mat, from, to);
+    BKE_constraint_mat_convertspace(ob, NULL, mat, from, to, false);
   }
   /*  Case VERTEXGROUP */
   /* Current method just takes the average location of all the points in the
@@ -554,11 +588,11 @@ static void constraint_target_to_mat4(Object *ob,
    */
   else if (ob->type == OB_MESH) {
     contarget_get_mesh_mat(ob, substring, mat);
-    BKE_constraint_mat_convertspace(ob, NULL, mat, from, to);
+    BKE_constraint_mat_convertspace(ob, NULL, mat, from, to, false);
   }
   else if (ob->type == OB_LATTICE) {
     contarget_get_lattice_mat(ob, substring, mat);
-    BKE_constraint_mat_convertspace(ob, NULL, mat, from, to);
+    BKE_constraint_mat_convertspace(ob, NULL, mat, from, to, false);
   }
   /* Case BONE */
   else {
@@ -622,7 +656,7 @@ static void constraint_target_to_mat4(Object *ob,
     }
 
     /* convert matrix space as required */
-    BKE_constraint_mat_convertspace(ob, pchan, mat, from, to);
+    BKE_constraint_mat_convertspace(ob, pchan, mat, from, to, false);
   }
 }
 
@@ -4051,9 +4085,12 @@ static void shrinkwrap_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
           }
 
           /* Transform normal into requested space */
+          /* Note that in this specific case, we need to keep scaling in non-parented 'local2world'
+           * object case, because SpaceTransform also takes it into account when handling normals.
+           * See T42447. */
           unit_m4(mat);
           BKE_constraint_mat_convertspace(
-              cob->ob, cob->pchan, mat, CONSTRAINT_SPACE_LOCAL, scon->projAxisSpace);
+              cob->ob, cob->pchan, mat, CONSTRAINT_SPACE_LOCAL, scon->projAxisSpace, true);
           invert_m4(mat);
           mul_mat3_m4_v3(mat, no);
 
@@ -5798,7 +5835,7 @@ void BKE_constraints_solve(struct Depsgraph *depsgraph,
 
     /* move owner matrix into right space */
     BKE_constraint_mat_convertspace(
-        cob->ob, cob->pchan, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace);
+        cob->ob, cob->pchan, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace, false);
 
     /* prepare targets for constraint solving */
     BKE_constraint_targets_for_solving_get(depsgraph, con, cob, &targets, ctime);
@@ -5817,7 +5854,7 @@ void BKE_constraints_solve(struct Depsgraph *depsgraph,
     /* move owner back into worldspace for next constraint/other business */
     if ((con->flag & CONSTRAINT_SPACEONCE) == 0) {
       BKE_constraint_mat_convertspace(
-          cob->ob, cob->pchan, cob->matrix, con->ownspace, CONSTRAINT_SPACE_WORLD);
+          cob->ob, cob->pchan, cob->matrix, con->ownspace, CONSTRAINT_SPACE_WORLD, false);
     }
 
     /* Interpolate the enforcement, to blend result of constraint into final owner transform
index ee6daa632fc3a1aeb511e199284c8ab0a49d82b0..ebc048ce286bc559d10bb967e6ee9c4621c18783 100644 (file)
@@ -1595,7 +1595,7 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
           /* extract transform just like how the constraints do it! */
           copy_m4_m4(mat, pchan->pose_mat);
           BKE_constraint_mat_convertspace(
-              ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
+              ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false);
 
           /* ... and from that, we get our transform */
           copy_v3_v3(tmp_loc, mat[3]);
@@ -1621,7 +1621,7 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
           /* extract transform just like how the constraints do it! */
           copy_m4_m4(mat, ob->obmat);
           BKE_constraint_mat_convertspace(
-              ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL);
+              ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false);
 
           /* ... and from that, we get our transform */
           copy_v3_v3(tmp_loc, mat[3]);
@@ -1698,7 +1698,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
         /* just like how the constraints do it! */
         copy_m4_m4(mat, pchan->pose_mat);
         BKE_constraint_mat_convertspace(
-            ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
+            ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false);
       }
       else {
         /* specially calculate local matrix, since chan_mat is not valid
@@ -1726,7 +1726,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
         /* just like how the constraints do it! */
         copy_m4_m4(mat, ob->obmat);
         BKE_constraint_mat_convertspace(
-            ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL);
+            ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false);
       }
       else {
         /* transforms to matrix */
index cbeb8f1799144708a9e759da2447da13f8fa2dea..2afebf7e3f603aaa10c83a2e0a9828468e3d875f 100644 (file)
@@ -323,7 +323,7 @@ static void rna_Object_mat_convert_space(Object *ob,
     }
   }
 
-  BKE_constraint_mat_convertspace(ob, pchan, (float(*)[4])mat_ret, from, to);
+  BKE_constraint_mat_convertspace(ob, pchan, (float(*)[4])mat_ret, from, to, false);
 }
 
 static void rna_Object_calc_matrix_camera(Object *ob,