Fix T38843: Bone parallel to world z axis flicking when scale in edit mode.
This commit hopefully fixes all glitches we had when bone was Z-aligned. Note that when you init a transform with a Z-aligned bone and change it to be non-Z-aligned, you will still get some brutal roll change, there is not much things we can do here afaik...
This commit is contained in:
@@ -257,7 +257,8 @@ typedef struct TransData {
|
|||||||
float *loc; /* Location of the data to transform */
|
float *loc; /* Location of the data to transform */
|
||||||
float iloc[3]; /* Initial location */
|
float iloc[3]; /* Initial location */
|
||||||
float *val; /* Value pointer for special transforms */
|
float *val; /* Value pointer for special transforms */
|
||||||
float ival; /* Old value*/
|
float ival; /* Old value */
|
||||||
|
float ival2; /* Another old value (for bone roll we need two different "old values" :/ ). */
|
||||||
float center[3]; /* Individual data center */
|
float center[3]; /* Individual data center */
|
||||||
float mtx[3][3]; /* Transformation matrix from data space to global space */
|
float mtx[3][3]; /* Transformation matrix from data space to global space */
|
||||||
float smtx[3][3]; /* Transformation matrix from global space to data space */
|
float smtx[3][3]; /* Transformation matrix from global space to data space */
|
||||||
|
|||||||
@@ -1061,6 +1061,27 @@ static void createTransPose(TransInfo *t, Object *ob)
|
|||||||
|
|
||||||
/* ********************* armature ************** */
|
/* ********************* armature ************** */
|
||||||
|
|
||||||
|
static void createTransArmatureVerts_init_roll_fix(TransData *td, EditBone *ebo)
|
||||||
|
{
|
||||||
|
/* To fix roll, see comments in transform_generic.c::recalcData_objects() */
|
||||||
|
const float z_axis[3] = {0.0f, 0.0f, 1.0f};
|
||||||
|
float vec[3];
|
||||||
|
|
||||||
|
sub_v3_v3v3(vec, ebo->tail, ebo->head);
|
||||||
|
normalize_v3(vec);
|
||||||
|
|
||||||
|
td->extra = ebo;
|
||||||
|
|
||||||
|
if (fabsf(dot_v3v3(vec, z_axis)) > 0.999999f) {
|
||||||
|
/* If nearly aligned with Z axis, do not alter roll. See T38843. */
|
||||||
|
td->ival = ebo->roll;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
td->ival = ebo->roll - ED_rollBoneToVector(ebo, z_axis, false);
|
||||||
|
}
|
||||||
|
td->ival2 = ebo->roll;
|
||||||
|
}
|
||||||
|
|
||||||
static void createTransArmatureVerts(TransInfo *t)
|
static void createTransArmatureVerts(TransInfo *t)
|
||||||
{
|
{
|
||||||
EditBone *ebo;
|
EditBone *ebo;
|
||||||
@@ -1182,7 +1203,6 @@ static void createTransArmatureVerts(TransInfo *t)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const float z_axis[3] = {0.0f, 0.0f, 1.0f};
|
|
||||||
if (ebo->flag & BONE_TIPSEL) {
|
if (ebo->flag & BONE_TIPSEL) {
|
||||||
copy_v3_v3(td->iloc, ebo->tail);
|
copy_v3_v3(td->iloc, ebo->tail);
|
||||||
copy_v3_v3(td->center, (t->around == V3D_LOCAL) ? ebo->head : td->iloc);
|
copy_v3_v3(td->center, (t->around == V3D_LOCAL) ? ebo->head : td->iloc);
|
||||||
@@ -1197,9 +1217,7 @@ static void createTransArmatureVerts(TransInfo *t)
|
|||||||
ED_armature_ebone_to_mat3(ebo, td->axismtx);
|
ED_armature_ebone_to_mat3(ebo, td->axismtx);
|
||||||
|
|
||||||
if ((ebo->flag & BONE_ROOTSEL) == 0) {
|
if ((ebo->flag & BONE_ROOTSEL) == 0) {
|
||||||
/* To fix roll, see comments in transform_generic.c::recalcData_objects() */
|
createTransArmatureVerts_init_roll_fix(td, ebo);
|
||||||
td->extra = ebo;
|
|
||||||
td->ival = ebo->roll - ED_rollBoneToVector(ebo, z_axis, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
td->ext = NULL;
|
td->ext = NULL;
|
||||||
@@ -1221,9 +1239,7 @@ static void createTransArmatureVerts(TransInfo *t)
|
|||||||
|
|
||||||
ED_armature_ebone_to_mat3(ebo, td->axismtx);
|
ED_armature_ebone_to_mat3(ebo, td->axismtx);
|
||||||
|
|
||||||
/* To fix roll, see comments in transform_generic.c::recalcData_objects() */
|
createTransArmatureVerts_init_roll_fix(td, ebo);
|
||||||
td->extra = ebo;
|
|
||||||
td->ival = ebo->roll - ED_rollBoneToVector(ebo, z_axis, false);
|
|
||||||
|
|
||||||
td->ext = NULL;
|
td->ext = NULL;
|
||||||
td->val = NULL;
|
td->val = NULL;
|
||||||
|
|||||||
@@ -810,16 +810,27 @@ static void recalcData_objects(TransInfo *t)
|
|||||||
* armature's Z axis), and do the reverse to get final roll.
|
* armature's Z axis), and do the reverse to get final roll.
|
||||||
* This method at least gives predictable, consistent results (the bone basically keeps "facing"
|
* This method at least gives predictable, consistent results (the bone basically keeps "facing"
|
||||||
* the armature's Z axis).
|
* the armature's Z axis).
|
||||||
|
* Note we need some special handling when bone is Z-aligned... sigh.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < t->total; i++, td++) {
|
for (i = 0; i < t->total; i++, td++) {
|
||||||
if (td->extra) {
|
if (td->extra) {
|
||||||
const float z_axis[3] = {0.0f, 0.0f, 1.0f};
|
const float z_axis[3] = {0.0f, 0.0f, 1.0f};
|
||||||
|
float vec[3];
|
||||||
|
|
||||||
ebo = td->extra;
|
ebo = td->extra;
|
||||||
|
sub_v3_v3v3(vec, ebo->tail, ebo->head);
|
||||||
|
normalize_v3(vec);
|
||||||
|
|
||||||
|
if (fabsf(dot_v3v3(vec, z_axis)) > 0.999999f) {
|
||||||
|
/* If our bone is Z-aligned, do not alter roll. See T38843. */
|
||||||
|
ebo->roll = td->ival2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
ebo->roll = td->ival + ED_rollBoneToVector(ebo, z_axis, false);
|
ebo->roll = td->ival + ED_rollBoneToVector(ebo, z_axis, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (arm->flag & ARM_MIRROR_EDIT)
|
if (arm->flag & ARM_MIRROR_EDIT)
|
||||||
transform_armature_mirror_update(t->obedit);
|
transform_armature_mirror_update(t->obedit);
|
||||||
|
|||||||
Reference in New Issue
Block a user