Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Clyne <lateasusual>2020-09-16 16:52:43 +0300
committerSebastian Parborg <darkdefende@gmail.com>2020-09-16 16:55:22 +0300
commitc9c0f893073300d6898114cfc6cacd563c630750 (patch)
tree2f7b102728debdddd1b9f968886e90d39ac00c1a
parent569e2e6dbac489b4143859cfeb87debf7253eab6 (diff)
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
-rw-r--r--release/scripts/startup/bl_ui/properties_constraint.py26
-rw-r--r--source/blender/blenkernel/intern/constraint.c76
-rw-r--r--source/blender/editors/object/object_constraint.c5
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h5
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c15
5 files changed, 84 insertions, 43 deletions
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);
}