diff options
author | Joshua Leung <aligorith@gmail.com> | 2010-10-17 14:46:06 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2010-10-17 14:46:06 +0400 |
commit | 6f1783470e249c60b8a96956f2f0ed564efaf107 (patch) | |
tree | 06f43446b3f56186a23e8d5d717eb6a96623dbca /source/blender/editors | |
parent | d6d1f3cb68f59566fbfa0f23ccaaa4b84a073247 (diff) |
Partial fix for #22409: Locked axis + auto IK = bad
The "root" bone in an Auto-IK chain was never added properly if it didn't have a parent that it was connected to. This meant that if it had axis-locking (using transform locks), these would not get converted to temporary IK-locks. This also affects 2.49
The second part of the bug report though, is something more ingrained in the IK-solver internals (numeric error, which means that even locked axes aren't exactly untouched).
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 22b83ee4c89..5de08d7832c 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -446,16 +446,21 @@ static short apply_targetless_ik(Object *ob) /* apply and decompose, doesn't work for constraints or non-uniform scale well */ { float rmat3[3][3], qrmat[3][3], imat[3][3], smat[3][3]; - + copy_m3_m4(rmat3, rmat); /* rotation */ - if (parchan->rotmode > 0) - mat3_to_eulO( parchan->eul, parchan->rotmode,rmat3); + /* [#22409] is partially caused by this, as slight numeric error introduced during + * the solving process leads to locked-axis values changing. However, we cannot modify + * the values here, or else there are huge discreptancies between IK-solver (interactive) + * and applied poses. + */ + if (parchan->rotmode > 0) + mat3_to_eulO(parchan->eul, parchan->rotmode,rmat3); else if (parchan->rotmode == ROT_MODE_AXISANGLE) - mat3_to_axis_angle( parchan->rotAxis, &pchan->rotAngle,rmat3); + mat3_to_axis_angle(parchan->rotAxis, &parchan->rotAngle,rmat3); else - mat3_to_quat( parchan->quat,rmat3); + mat3_to_quat(parchan->quat,rmat3); /* for size, remove rotation */ /* causes problems with some constraints (so apply only if needed) */ @@ -840,9 +845,9 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan) data->flag |= CONSTRAINT_IK_TEMP|CONSTRAINT_IK_AUTO; VECCOPY(data->grabtarget, pchan->pose_tail); data->rootbone= 1; - - /* we include only a connected chain */ - while ((pchan) && (pchan->bone->flag & BONE_CONNECTED)) { + + /* we only include bones that are part of a continual connected chain */ + while (pchan) { /* here, we set ik-settings for bone from pchan->protectflag */ if (pchan->protectflag & OB_LOCK_ROTX) pchan->ikflag |= BONE_IK_NO_XDOF_TEMP; if (pchan->protectflag & OB_LOCK_ROTY) pchan->ikflag |= BONE_IK_NO_YDOF_TEMP; @@ -850,7 +855,12 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan) /* now we count this pchan as being included */ data->rootbone++; - pchan= pchan->parent; + + /* continue to parent, but only if we're connected to it */ + if (pchan->bone->flag & BONE_CONNECTED) + pchan = pchan->parent; + else + pchan = NULL; } /* make a copy of maximum chain-length */ |