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
This commit is contained in:
Chris Clyne
2020-09-16 15:52:43 +02:00
committed by Sebastian Parborg
parent 569e2e6dba
commit c9c0f89307
5 changed files with 84 additions and 43 deletions

View File

@@ -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);
/* Target defines the animation */
s = (vec[axis] - data->min) / (data->max - data->min);
}
BLI_assert((unsigned int)axis < 3);
/* 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);