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:
authorSebastian Parborg <darkdefende@gmail.com>2020-04-10 14:58:56 +0300
committerSebastian Parborg <darkdefende@gmail.com>2020-04-10 15:01:02 +0300
commit9a7f5f1bb42292eeb70b4832e7883846df0cb76a (patch)
tree039d9017f2815b4689ecd051ee39a7323d79bbc2 /source/blender/editors/transform/transform_convert_armature.c
parent9c5b0542069bfec5ba8bfa65fa031014d3750cbe (diff)
Fix T67232: Multiples targetless IKs in a chain gives weird behaviour (known as FakeIK for FK posing)
The issue was that the deps graph relation builder assumed that all bones that had a IK constraint on them would be evaluated. However for targetless IK bones, only the active bone would receive updates and the others would be skipped (as those would be treated as if the IK constraint was disabled). I didn't see an easy way to solve this from the depsgraph side of things. Instead I came up with a solution that I feel is quite strait forward and reflects what is actually supposed to happen under the hood. Now all targetless IK constraints are treated as disabled and will not be added to any relations in the depsgraph. Instead, a temporary IK constraint will be created when the bone in question is transformed. This is basically activating "Auto IK" for the bone while transforming. Reviewed By: Sergey, Brecht Differential Revision: http://developer.blender.org/D7378
Diffstat (limited to 'source/blender/editors/transform/transform_convert_armature.c')
-rw-r--r--source/blender/editors/transform/transform_convert_armature.c66
1 files changed, 46 insertions, 20 deletions
diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c
index e52bd15b0d5..481198ea88c 100644
--- a/source/blender/editors/transform/transform_convert_armature.c
+++ b/source/blender/editors/transform/transform_convert_armature.c
@@ -58,6 +58,34 @@ typedef struct BoneInitData {
float zwidth;
} BoneInitData;
+static void add_temporary_ik_constraint(bPoseChannel *pchan, bKinematicConstraint *targetless_con)
+{
+ bConstraint *con = BKE_constraint_add_for_pose(
+ NULL, pchan, "TempConstraint", CONSTRAINT_TYPE_KINEMATIC);
+
+ /* for draw, but also for detecting while pose solving */
+ pchan->constflag |= (PCHAN_HAS_IK | PCHAN_HAS_TARGET);
+
+ bKinematicConstraint *temp_con_data = con->data;
+
+ if (targetless_con) {
+ /* if exists, use values from last targetless (but disabled) IK-constraint as base */
+ *temp_con_data = *targetless_con;
+ }
+ else {
+ temp_con_data->flag = CONSTRAINT_IK_TIP;
+ }
+
+ temp_con_data->flag |= CONSTRAINT_IK_TEMP | CONSTRAINT_IK_AUTO | CONSTRAINT_IK_POS;
+}
+
+static void update_deg_with_temporary_ik(Main *bmain, Object *ob)
+{
+ BIK_clear_data(ob->pose);
+ /* TODO(sergey): Consider doing partial update only. */
+ DEG_relations_tag_update(bmain);
+}
+
static void add_pose_transdata(
TransInfo *t, bPoseChannel *pchan, Object *ob, TransDataContainer *tc, TransData *td)
{
@@ -200,8 +228,16 @@ static void add_pose_transdata(
}
td->loc = data->grabtarget;
copy_v3_v3(td->iloc, td->loc);
+
data->flag |= CONSTRAINT_IK_AUTO;
+ /* Add a temporary auto IK constraint here, as we will only temporarly active this targetless
+ * bone during transform. (Targetless IK constraints are treated as if they are disabled
+ * unless they are transformed) */
+ add_temporary_ik_constraint(pchan, data);
+ Main *bmain = CTX_data_main(t->context);
+ update_deg_with_temporary_ik(bmain, ob);
+
/* only object matrix correction */
copy_m3_m3(td->mtx, omat);
pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
@@ -221,7 +257,8 @@ bKinematicConstraint *has_targetless_ik(bPoseChannel *pchan)
bConstraint *con = pchan->constraints.first;
for (; con; con = con->next) {
- if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce != 0.0f)) {
+ if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->flag & CONSTRAINT_OFF) == 0 &&
+ (con->enforce != 0.0f)) {
bKinematicConstraint *data = con->data;
if (data->tar == NULL) {
@@ -278,8 +315,6 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan)
}
}
}
-
- return 0;
}
}
@@ -289,20 +324,7 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan)
}
}
- con = BKE_constraint_add_for_pose(NULL, pchan, "TempConstraint", CONSTRAINT_TYPE_KINEMATIC);
-
- /* for draw, but also for detecting while pose solving */
- pchan->constflag |= (PCHAN_HAS_IK | PCHAN_HAS_TARGET);
-
- data = con->data;
- if (targetless) {
- /* if exists, use values from last targetless (but disabled) IK-constraint as base */
- *data = *targetless;
- }
- else {
- data->flag = CONSTRAINT_IK_TIP;
- }
- data->flag |= CONSTRAINT_IK_TEMP | CONSTRAINT_IK_AUTO | CONSTRAINT_IK_POS;
+ add_temporary_ik_constraint(pchan, targetless);
copy_v3_v3(data->grabtarget, pchan->pose_tail);
/* watch-it! has to be 0 here, since we're still on the
@@ -415,9 +437,7 @@ static short pose_grab_with_ik(Main *bmain, Object *ob)
/* iTaSC needs clear for new IK constraints */
if (tot_ik) {
- BIK_clear_data(ob->pose);
- /* TODO(sergey): Consider doing partial update only. */
- DEG_relations_tag_update(bmain);
+ update_deg_with_temporary_ik(bmain, ob);
}
return (tot_ik) ? 1 : 0;
@@ -585,6 +605,12 @@ void pose_transform_mirror_update(TransInfo *t, TransDataContainer *tc, Object *
/* TODO(germano): Realitve Mirror support */
}
data->flag |= CONSTRAINT_IK_AUTO;
+ /* Add a temporary auto IK constraint here, as we will only temporarly active this targetless
+ * bone during transform. (Targetless IK constraints are treated as if they are disabled
+ * unless they are transformed) */
+ add_temporary_ik_constraint(pchan, data);
+ Main *bmain = CTX_data_main(t->context);
+ update_deg_with_temporary_ik(bmain, ob);
}
if (pid) {