[Bf-blender-cvs] [c9c0f893073] master: Action Constraint: Add manual time factor input control

Chris Clyne noreply at git.blender.org
Wed Sep 16 15:55:32 CEST 2020


Commit: c9c0f893073300d6898114cfc6cacd563c630750
Author: Chris Clyne
Date:   Wed Sep 16 15:52:43 2020 +0200
Branches: master
https://developer.blender.org/rBc9c0f893073300d6898114cfc6cacd563c630750

Action Constraint: Add manual time factor input control

Adds an optional slider to the action constraint so that it can be
driven without a constraint target.

This is very helpful for more complex rigging and mechanical rigs, as it
means the action constraint can be controlled with a driver/custom
property directly, currently if we want to use a driver to control it we
must add a "dummy" bone/object inbetween to act as a control.

Reviewed By: Sebastian Parborg, Sybren A. Stüvel, Demeter Dzadik, Julian Eisel

Differential Revision: http://developer.blender.org/D8022

===================================================================

M	release/scripts/startup/bl_ui/properties_constraint.py
M	source/blender/blenkernel/intern/constraint.c
M	source/blender/editors/object/object_constraint.c
M	source/blender/makesdna/DNA_constraint_types.h
M	source/blender/makesrna/intern/rna_constraint.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_constraint.py b/release/scripts/startup/bl_ui/properties_constraint.py
index da35ea680b8..14619ef916d 100644
--- a/release/scripts/startup/bl_ui/properties_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_constraint.py
@@ -508,7 +508,18 @@ class ConstraintButtonsPanel(Panel):
         layout.use_property_split = True
         layout.use_property_decorate = True
 
-        self.target_template(layout, con)
+        target_row = layout.row(align=True)
+        target_row.active = not con.use_eval_time
+        self.target_template(target_row, con)
+
+        row = layout.row(align=True, heading="Evaluation Time")
+        row.use_property_decorate = False
+        sub = row.row(align=True)
+        sub.prop(con, "use_eval_time", text="")
+        subsub = sub.row(align=True)
+        subsub.active = con.use_eval_time
+        subsub.prop(con, "eval_time", text="")
+        row.prop_decorator(con, "eval_time")
 
         layout.prop(con, "mix_mode", text="Mix")
 
@@ -1105,13 +1116,14 @@ class ConstraintButtonsSubPanel(Panel):
         layout.use_property_split = True
         layout.use_property_decorate = True
 
-        layout.prop(con, "transform_channel", text="Channel")
-        layout.prop(con, "target_space")
-
-        col = layout.column(align=True)
-        col.prop(con, "min", text="Range Min")
-        col.prop(con, "max", text="Max")
+        col = layout.column()
+        col.active = not con.use_eval_time
+        col.prop(con, "transform_channel", text="Channel")
+        col.prop(con, "target_space")
 
+        sub = col.column(align=True)
+        sub.prop(con, "min", text="Range Min")
+        sub.prop(con, "max", text="Max")
 
     def draw_action_action(self, context):
         layout = self.layout
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index fc1b4d82c20..9411f937f08 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -2634,7 +2634,7 @@ static void actcon_get_tarmat(struct Depsgraph *depsgraph,
 {
   bActionConstraint *data = con->data;
 
-  if (VALID_CONS_TARGET(ct)) {
+  if (VALID_CONS_TARGET(ct) || data->flag & ACTCON_USE_EVAL_TIME) {
     float tempmat[4][4], vec[3];
     float s, t;
     short axis;
@@ -2642,42 +2642,48 @@ static void actcon_get_tarmat(struct Depsgraph *depsgraph,
     /* initialize return matrix */
     unit_m4(ct->matrix);
 
-    /* get the transform matrix of the target */
-    constraint_target_to_mat4(ct->tar,
-                              ct->subtarget,
-                              tempmat,
-                              CONSTRAINT_SPACE_WORLD,
-                              ct->space,
-                              con->flag,
-                              con->headtail);
+    /* Skip targets if we're using local float property to set action time */
+    if (data->flag & ACTCON_USE_EVAL_TIME) {
+      s = data->eval_time;
+    } else {
+      /* get the transform matrix of the target */
+      constraint_target_to_mat4(ct->tar,
+                                ct->subtarget,
+                                tempmat,
+                                CONSTRAINT_SPACE_WORLD,
+                                ct->space,
+                                con->flag,
+                                con->headtail);
+
+      /* determine where in transform range target is */
+      /* data->type is mapped as follows for backwards compatibility:
+       * 00,01,02 - rotation (it used to be like this)
+       * 10,11,12 - scaling
+       * 20,21,22 - location
+       */
+      if (data->type < 10) {
+        /* extract rotation (is in whatever space target should be in) */
+        mat4_to_eul(vec, tempmat);
+        mul_v3_fl(vec, RAD2DEGF(1.0f)); /* rad -> deg */
+        axis = data->type;
+      }
+      else if (data->type < 20) {
+        /* extract scaling (is in whatever space target should be in) */
+        mat4_to_size(vec, tempmat);
+        axis = data->type - 10;
+      }
+      else {
+        /* extract location */
+        copy_v3_v3(vec, tempmat[3]);
+        axis = data->type - 20;
+      }
 
-    /* determine where in transform range target is */
-    /* data->type is mapped as follows for backwards compatibility:
-     * 00,01,02 - rotation (it used to be like this)
-     * 10,11,12 - scaling
-     * 20,21,22 - location
-     */
-    if (data->type < 10) {
-      /* extract rotation (is in whatever space target should be in) */
-      mat4_to_eul(vec, tempmat);
-      mul_v3_fl(vec, RAD2DEGF(1.0f)); /* rad -> deg */
-      axis = data->type;
-    }
-    else if (data->type < 20) {
-      /* extract scaling (is in whatever space target should be in) */
-      mat4_to_size(vec, tempmat);
-      axis = data->type - 10;
-    }
-    else {
-      /* extract location */
-      copy_v3_v3(vec, tempmat[3]);
-      axis = data->type - 20;
-    }
+      BLI_assert((unsigned int)axis < 3);
 
-    BLI_assert((unsigned int)axis < 3);
+      /* Target defines the animation */
+      s = (vec[axis] - data->min) / (data->max - data->min);
+    }
 
-    /* Target defines the animation */
-    s = (vec[axis] - data->min) / (data->max - data->min);
     CLAMP(s, 0, 1);
     t = (s * (data->end - data->start)) + data->start;
     const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
@@ -2734,7 +2740,7 @@ static void actcon_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targ
   bActionConstraint *data = con->data;
   bConstraintTarget *ct = targets->first;
 
-  if (VALID_CONS_TARGET(ct)) {
+  if (VALID_CONS_TARGET(ct) || data->flag & ACTCON_USE_EVAL_TIME) {
     switch (data->mix_mode) {
       case ACTCON_MIX_BEFORE:
         mul_m4_m4m4_aligned_scale(cob->matrix, ct->matrix, cob->matrix);
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index b062ae0c698..af04c4a3263 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -387,6 +387,11 @@ static void test_constraint(
       data->act = NULL;
       con->flag |= CONSTRAINT_DISABLE;
     }
+
+    /* Skip target checking if we're not using it */
+    if (data->flag & ACTCON_USE_EVAL_TIME) {
+      check_targets = false;
+    }
   }
   else if (con->type == CONSTRAINT_TYPE_FOLLOWPATH) {
     bFollowPathConstraint *data = con->data;
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index cddc78d7640..92ee3f062a6 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -337,7 +337,8 @@ typedef struct bActionConstraint {
   float max;
   int flag;
   char mix_mode;
-  char _pad[7];
+  char _pad[3];
+  float eval_time; /* Only used when flag ACTCON_USE_EVAL_TIME is set. */
   struct bAction *act;
   /** MAX_ID_NAME-2. */
   char subtarget[64];
@@ -860,6 +861,8 @@ typedef enum eSameVolume_Mode {
 typedef enum eActionConstraint_Flags {
   /* Bones use "object" part of target action, instead of "same bone name" part */
   ACTCON_BONE_USE_OBJECT_ACTION = (1 << 0),
+  /* Ignore the transform of 'tar' and use 'eval_time' instead: */
+  ACTCON_USE_EVAL_TIME = (1 << 1),
 } eActionConstraint_Flags;
 
 /* bActionConstraint.mix_mode */
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index d9dd35c4280..653056e4dc1 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -1790,6 +1790,21 @@ static void rna_def_constraint_action(BlenderRNA *brna)
   RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
   RNA_def_property_float_funcs(prop, NULL, NULL, "rna_ActionConstraint_minmax_range");
 
+  prop = RNA_def_property(srna, "eval_time", PROP_FLOAT, PROP_FACTOR);
+  RNA_def_property_float_sdna(prop, NULL, "eval_time");
+  RNA_def_property_range(prop, 0.f, 1.f);
+  RNA_def_property_ui_text(
+      prop, "Evaluation Time", "Interpolates between Action Start and End frames");
+  RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+  prop = RNA_def_property(srna, "use_eval_time", PROP_BOOLEAN, PROP_NONE);
+  RNA_def_property_boolean_sdna(prop, NULL, "flag", ACTCON_USE_EVAL_TIME);
+  RNA_def_property_ui_text(prop,
+                           "Use Evaluation Time",
+                           "Interpolate between Action Start and End frames, with the Evaluation "
+                           "Time slider instead of the Target object/bone");
+  RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
   RNA_define_lib_overridable(false);
 }



More information about the Bf-blender-cvs mailing list