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:
authorMartin Poirier <theeth@yahoo.com>2008-11-11 00:23:54 +0300
committerMartin Poirier <theeth@yahoo.com>2008-11-11 00:23:54 +0300
commit3c698645400cfd4204e32656b8fa994a853c722d (patch)
treedb121da1ed23a79a5f81931427dce291b18f0f79 /source/blender/src
parent61a83d2fbadbaff39f72743d4a0a3c037cfcce8f (diff)
Chain rotations for objects and pose bones (for teamto)
This commit adds an exception for rotations (standard rotation and tracball) to still work on children of transformed objects and bones in an expected fashion. That is, you can select a chain of finger bones and rotate to flex them all at once. Notes: [1] This could be expended to other transformations if needed. [2] Center of transformation is determined using the same principle as hinge bones (transformed children aren't taken into account)
Diffstat (limited to 'source/blender/src')
-rw-r--r--source/blender/src/transform.c76
-rw-r--r--source/blender/src/transform_conversions.c48
2 files changed, 82 insertions, 42 deletions
diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c
index b9b8a4a21a9..7a13943d0e0 100644
--- a/source/blender/src/transform.c
+++ b/source/blender/src/transform.c
@@ -2486,25 +2486,28 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
Mat3CpyMat4(pmtx, t->poseobj->obmat);
Mat3Inv(imtx, pmtx);
- VecSubf(vec, td->center, center);
-
- Mat3MulVecfl(pmtx, vec); // To Global space
- Mat3MulVecfl(mat, vec); // Applying rotation
- Mat3MulVecfl(imtx, vec); // To Local space
-
- VecAddf(vec, vec, 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);
-
- constraintTransLim(t, td);
+ if ((td->flag & TD_NO_LOC) == 0)
+ {
+ VecSubf(vec, td->center, center);
+
+ Mat3MulVecfl(pmtx, vec); // To Global space
+ Mat3MulVecfl(mat, vec); // Applying rotation
+ Mat3MulVecfl(imtx, vec); // To Local space
+
+ VecAddf(vec, vec, 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);
+
+ constraintTransLim(t, td);
+ }
/* rotation */
if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't rotate objects itself
@@ -2520,23 +2523,28 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
}
}
else {
- /* translation */
- VecSubf(vec, td->center, center);
- Mat3MulVecfl(mat, vec);
- VecAddf(vec, vec, center);
- /* vec now is the location where the object has to be */
- VecSubf(vec, vec, td->center);
- Mat3MulVecfl(td->smtx, vec);
-
- protectedTransBits(td->protectflag, vec);
- if(td->tdi) {
- TransDataIpokey *tdi= td->tdi;
- add_tdi_poin(tdi->locx, tdi->oldloc, vec[0]);
- add_tdi_poin(tdi->locy, tdi->oldloc+1, vec[1]);
- add_tdi_poin(tdi->locz, tdi->oldloc+2, vec[2]);
+ if ((td->flag & TD_NO_LOC) == 0)
+ {
+ /* translation */
+ VecSubf(vec, td->center, center);
+ Mat3MulVecfl(mat, vec);
+ VecAddf(vec, vec, center);
+ /* vec now is the location where the object has to be */
+ VecSubf(vec, vec, td->center);
+ Mat3MulVecfl(td->smtx, vec);
+
+ protectedTransBits(td->protectflag, vec);
+
+ if(td->tdi) {
+ TransDataIpokey *tdi= td->tdi;
+ add_tdi_poin(tdi->locx, tdi->oldloc, vec[0]);
+ add_tdi_poin(tdi->locy, tdi->oldloc+1, vec[1]);
+ add_tdi_poin(tdi->locz, tdi->oldloc+2, vec[2]);
+ }
+ else VecAddf(td->loc, td->iloc, vec);
}
- else VecAddf(td->loc, td->iloc, vec);
+
constraintTransLim(t, td);
diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c
index 3465983d110..496d5120bb9 100644
--- a/source/blender/src/transform_conversions.c
+++ b/source/blender/src/transform_conversions.c
@@ -540,8 +540,17 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
td->ob = ob;
td->flag= TD_SELECTED|TD_USEQUAT;
- if(bone->flag & BONE_HINGE_CHILD_TRANSFORM)
+ if (bone->flag & BONE_HINGE_CHILD_TRANSFORM)
+ {
+ td->flag |= TD_NOCENTER;
+ }
+
+ if (bone->flag & BONE_TRANSFORM_CHILD)
+ {
td->flag |= TD_NOCENTER;
+ td->flag |= TD_NO_LOC;
+ }
+
td->protectflag= pchan->protectflag;
td->loc = pchan->loc;
@@ -628,17 +637,25 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
td->con= pchan->constraints.first;
}
-static void bone_children_clear_transflag(ListBase *lb)
+static void bone_children_clear_transflag(TransInfo *t, ListBase *lb)
{
Bone *bone= lb->first;
for(;bone;bone= bone->next) {
if((bone->flag & BONE_HINGE) && (bone->flag & BONE_CONNECTED))
+ {
bone->flag |= BONE_HINGE_CHILD_TRANSFORM;
+ }
+ else if (bone->flag & BONE_TRANSFORM && (t->mode == TFM_ROTATION || t->mode == TFM_TRACKBALL))
+ {
+ bone->flag |= BONE_TRANSFORM_CHILD;
+ }
else
+ {
bone->flag &= ~BONE_TRANSFORM;
+ }
- bone_children_clear_transflag(&bone->childbase);
+ bone_children_clear_transflag(t, &bone->childbase);
}
}
@@ -661,6 +678,7 @@ static void set_pose_transflags(TransInfo *t, Object *ob)
bone->flag &= ~BONE_TRANSFORM;
bone->flag &= ~BONE_HINGE_CHILD_TRANSFORM;
+ bone->flag &= ~BONE_TRANSFORM_CHILD;
}
}
@@ -670,7 +688,7 @@ static void set_pose_transflags(TransInfo *t, Object *ob)
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
bone= pchan->bone;
if(bone->flag & BONE_TRANSFORM)
- bone_children_clear_transflag(&bone->childbase);
+ bone_children_clear_transflag(t, &bone->childbase);
}
}
/* now count, and check if we have autoIK or have to switch from translate to rotate */
@@ -3497,9 +3515,17 @@ static void set_trans_object_base_flags(TransInfo *t)
parsel= parsel->parent;
}
- if(parsel) {
- base->flag &= ~SELECT;
- base->flag |= BA_WAS_SEL;
+ if(parsel)
+ {
+ if (t->mode == TFM_ROTATION || t->mode == TFM_TRACKBALL)
+ {
+ base->flag |= BA_TRANSFORM_CHILD;
+ }
+ else
+ {
+ base->flag &= ~SELECT;
+ base->flag |= BA_WAS_SEL;
+ }
}
/* used for flush, depgraph will change recalcs if needed :) */
ob->recalc |= OB_RECALC_OB;
@@ -3526,7 +3552,7 @@ static void clear_trans_object_base_flags(void)
base= FIRSTBASE;
while(base) {
if(base->flag & BA_WAS_SEL) base->flag |= SELECT;
- base->flag &= ~(BA_WAS_SEL|BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA|BA_DO_IPO);
+ base->flag &= ~(BA_WAS_SEL|BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA|BA_DO_IPO|BA_TRANSFORM_CHILD);
base = base->next;
}
@@ -4097,6 +4123,12 @@ static void createTransObject(TransInfo *t)
td->protectflag= ob->protectflag;
td->ext = tx;
+ if (base->flag & BA_TRANSFORM_CHILD)
+ {
+ td->flag |= TD_NOCENTER;
+ td->flag |= TD_NO_LOC;
+ }
+
/* select linked objects, but skip them later */
if (ob->id.lib != 0) {
td->flag |= TD_SKIP;