- rotation and bone scaling with Durian feature 'Local Location' would fail to correctly translate the bone
because a different matrix is needed for translation and rotation.
sub_v3_v3v3(vec, vec, td->center); // Translation needed from the initial location
- mul_m3_v3(pmtx, vec); // To Global space
- mul_m3_v3(td->smtx, vec);// To Pose space
-
+ /* special exception, see TD_PBONE_LOCAL_MTX definition comments */
+ if(td->flag & TD_PBONE_LOCAL_MTX_P) {
+ /* do nothing */
+ }
+ else if (td->flag & TD_PBONE_LOCAL_MTX_C) {
+ mul_m3_v3(pmtx, vec); // To Global space
+ mul_m3_v3(td->ext->l_smtx, vec);// To Pose space (Local Location)
+ }
+ else {
+ mul_m3_v3(pmtx, vec); // To Global space
+ mul_m3_v3(td->smtx, vec);// To Pose space
+ }
+
protectedTransBits(td->protectflag, vec);
add_v3_v3v3(td->loc, td->iloc, vec);
float *size; /* Size of the data to transform (Faculative) */
float isize[3]; /* Initial size */
float obmat[4][4]; /* Object matrix */
+ float l_smtx[3][3]; /* use instead of td->smtx, It is the same but without the 'bone->bone_mat', see TD_PBONE_LOCAL_MTX_C */
} TransDataExtension;
typedef struct TransData2D {
#define TD_MIRROR_EDGE (1 << 16) /* For editmode mirror, clamp to x = 0 */
#define TD_MOVEHANDLE1 (1 << 17) /* For fcurve handles, move them along with their keyframes */
#define TD_MOVEHANDLE2 (1 << 18)
+#define TD_PBONE_LOCAL_MTX_P (1 << 19) /* exceptional case with pose bone rotating when a parent bone has 'Local Location' option enabled and rotating also transforms it. */
+#define TD_PBONE_LOCAL_MTX_C (1 << 20) /* same as above but for a child bone */
/* transsnap->status */
#define SNAP_FORCED 1
/* proper way to get parent transform + own transform + constraints transform */
copy_m3_m4(omat, ob->obmat);
- if (t->mode==TFM_TRANSLATION && (pchan->bone->flag & BONE_NO_LOCAL_LOCATION))
+ if (ELEM(t->mode, TFM_TRANSLATION, TFM_RESIZE) && (pchan->bone->flag & BONE_NO_LOCAL_LOCATION))
unit_m3(bmat);
else
copy_m3_m3(bmat, pchan->bone->bone_mat);
invert_m3_m3(td->smtx, td->mtx);
+ /* exceptional case: rotate the pose bone which also applies transformation
+ * when a parentless bone has BONE_NO_LOCAL_LOCATION [] */
+ if (!ELEM(t->mode, TFM_TRANSLATION, TFM_RESIZE) && (pchan->bone->flag & BONE_NO_LOCAL_LOCATION)) {
+ if(pchan->parent) {
+ /* same as td->smtx but without pchan->bone->bone_mat */
+ td->flag |= TD_PBONE_LOCAL_MTX_C;
+ mul_m3_m3m3(td->ext->l_smtx, pchan->bone->bone_mat, td->smtx);
+ }
+ else {
+ td->flag |= TD_PBONE_LOCAL_MTX_P;
+ }
+ }
+
/* for axismat we use bone's own transform */
copy_m3_m4(pmat, pchan->pose_mat);
mul_m3_m3m3(td->axismtx, omat, pmat);