From 7bf2f72be4b31a0f7f28619fb023ecd7ade230d1 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Wed, 7 Feb 2007 23:28:33 +0000 Subject: [PATCH] === Transform === [ #5833 ] 2.43 RC2: Incorrect Bone rotation when 3D cursor set as Pivot There's really ugly stuff going on with pose mode rotation in transform which I'll have to fix later, in the mean time, this commit fixes the problem (which happens when you rotate bones in post mode around an arbitrary point) and includes some juicy comments to further document the actual architectural problem. --- config/linux2-config.py | 2 +- source/blender/src/transform.c | 53 ++++++++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/config/linux2-config.py b/config/linux2-config.py index 6e9106f9ea3..5e7dcfa7297 100644 --- a/config/linux2-config.py +++ b/config/linux2-config.py @@ -163,4 +163,4 @@ BF_INSTALLDIR='../install/linux2' #Link against pthread -PLATFORM_LINKFLAGS = ['-pthread'] +PLATFORM_LINKFLAGS = ['-pthread'] \ No newline at end of file diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c index 7e80e948ea8..6868dad881f 100755 --- a/source/blender/src/transform.c +++ b/source/blender/src/transform.c @@ -1732,6 +1732,54 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) { QuatMul(td->ext->quat, quat, td->ext->iquat); } } + /** + * HACK WARNING + * + * This is some VERY ugly special case to deal with pose mode. + * + * The problem is that mtx and smtx include each bone orientation. + * + * That is needed to rotate each bone properly, HOWEVER, to calculate + * the translation component, we only need the actual armature object's + * matrix (and inverse). That is not all though. Once the proper translation + * has been computed, it has to be converted back into the bone's space. + */ + else if (t->flag & T_POSE) { + float pmtx[3][3], imtx[3][3]; + + // Extract and invert armature object matrix + Mat3CpyMat4(pmtx, t->poseobj->obmat); + Mat3Inv(imtx, pmtx); + + VecSubf(vec, td->center, t->center); + + Mat3MulVecfl(pmtx, vec); // To Global space + Mat3MulVecfl(mat, vec); // Applying rotation + Mat3MulVecfl(imtx, vec); // To Local space + + VecAddf(vec, vec, t->center); + /* vec now is the location where the object has to be */ + + VecSubf(vec, vec, td->center); // Translation needed from the initial location + + Mat3MulVecfl(pmtx, vec); // To Global space + Mat3MulVecfl(td->smtx, vec);// To Pose space + + protectedTransBits(td->protectflag, vec); + + VecAddf(td->loc, td->iloc, vec); + + /* rotation */ + if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't rotate objects itself + Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0); + + Mat3ToQuat(fmat, quat); // Actual transform + + QuatMul(td->ext->quat, quat, td->ext->iquat); + /* this function works on end result */ + protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat); + } + } else { /* translation */ @@ -1832,7 +1880,7 @@ static void applyRotation(TransInfo *t, float angle, float axis[3]) } VecRotToMat3(axis, angle, mat); - + for(i = 0 ; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) @@ -1869,7 +1917,6 @@ static void applyRotation(TransInfo *t, float angle, float axis[3]) int Rotation(TransInfo *t, short mval[2]) { - TransData *td = t->data; char str[64]; float final; @@ -1947,7 +1994,7 @@ int Rotation(TransInfo *t, short mval[2]) sprintf(str, "Rot: %.2f%s %s", 180.0*final/M_PI, t->con.text, t->proptext); } - VecRotToMat3(axis, final * td->factor, mat); + VecRotToMat3(axis, final, mat); t->val = final; // used in manipulator Mat3CpyMat3(t->mat, mat); // used in manipulator