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:
Diffstat (limited to 'source/blender/editors/transform/transform_manipulator.c')
-rw-r--r--source/blender/editors/transform/transform_manipulator.c105
1 files changed, 77 insertions, 28 deletions
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index a3f45acc02e..6b016bf4303 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -148,10 +148,8 @@ static void stats_pose(Scene *scene, RegionView3D *rv3d, bPoseChannel *pchan)
Bone *bone = pchan->bone;
if (bone) {
- if (bone->flag & BONE_TRANSFORM) {
- calc_tw_center(scene, pchan->pose_head);
- protectflag_to_drawflags(pchan->protectflag, &rv3d->twdrawflag);
- }
+ calc_tw_center(scene, pchan->pose_head);
+ protectflag_to_drawflags(pchan->protectflag, &rv3d->twdrawflag);
}
}
@@ -199,7 +197,7 @@ static int test_rotmode_euler(short rotmode)
return (ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT)) ? 0 : 1;
}
-int gimbal_axis(Object *ob, float gmat[][3])
+int gimbal_axis(Object *ob, float gmat[3][3])
{
if (ob) {
if (ob->mode & OB_MODE_POSE) {
@@ -361,18 +359,35 @@ int calc_manipulator_stats(const bContext *C)
else if (obedit->type == OB_ARMATURE) {
bArmature *arm = obedit->data;
EditBone *ebo;
- for (ebo = arm->edbo->first; ebo; ebo = ebo->next) {
- if (EBONE_VISIBLE(arm, ebo)) {
- if (ebo->flag & BONE_TIPSEL) {
- calc_tw_center(scene, ebo->tail);
- totsel++;
- }
- if (ebo->flag & BONE_ROOTSEL) {
- calc_tw_center(scene, ebo->head);
- totsel++;
- }
- if (ebo->flag & BONE_SELECTED) {
- stats_editbone(rv3d, ebo);
+
+ if ((v3d->around == V3D_ACTIVE) && (ebo = arm->act_edbone)) {
+ /* doesn't check selection or visibility intentionally */
+ if (ebo->flag & BONE_TIPSEL) {
+ calc_tw_center(scene, ebo->tail);
+ totsel++;
+ }
+ if ((ebo->flag & BONE_ROOTSEL) ||
+ ((ebo->flag & BONE_TIPSEL) == FALSE)) /* ensure we get at least one point */
+ {
+ calc_tw_center(scene, ebo->head);
+ totsel++;
+ }
+ stats_editbone(rv3d, ebo);
+ }
+ else {
+ for (ebo = arm->edbo->first; ebo; ebo = ebo->next) {
+ if (EBONE_VISIBLE(arm, ebo)) {
+ if (ebo->flag & BONE_TIPSEL) {
+ calc_tw_center(scene, ebo->tail);
+ totsel++;
+ }
+ if (ebo->flag & BONE_ROOTSEL) {
+ calc_tw_center(scene, ebo->head);
+ totsel++;
+ }
+ if (ebo->flag & BONE_SELECTED) {
+ stats_editbone(rv3d, ebo);
+ }
}
}
}
@@ -480,17 +495,35 @@ int calc_manipulator_stats(const bContext *C)
else if (ob && (ob->mode & OB_MODE_POSE)) {
bPoseChannel *pchan;
int mode = TFM_ROTATION; // mislead counting bones... bah. We don't know the manipulator mode, could be mixed
+ int ok = FALSE;
if ((ob->lay & v3d->lay) == 0) return 0;
- totsel = count_set_pose_transflags(&mode, 0, ob);
-
- if (totsel) {
- /* use channels to get stats */
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ if ((v3d->around == V3D_ACTIVE) && (pchan = BKE_pose_channel_active(ob))) {
+ /* doesn't check selection or visibility intentionally */
+ Bone *bone = pchan->bone;
+ if (bone) {
stats_pose(scene, rv3d, pchan);
+ totsel = 1;
+ ok = TRUE;
+ }
+ }
+ else {
+ totsel = count_set_pose_transflags(&mode, 0, ob);
+
+ if (totsel) {
+ /* use channels to get stats */
+ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ Bone *bone = pchan->bone;
+ if (bone && (bone->flag & BONE_TRANSFORM)) {
+ stats_pose(scene, rv3d, pchan);
+ }
+ }
+ ok = TRUE;
}
+ }
+ if (ok) {
mul_v3_fl(scene->twcent, 1.0f / (float)totsel); // centroid!
mul_m4_v3(ob->obmat, scene->twcent);
mul_m4_v3(ob->obmat, scene->twmin);
@@ -552,8 +585,9 @@ int calc_manipulator_stats(const bContext *C)
switch (v3d->twmode) {
case V3D_MANIP_GLOBAL:
+ {
break; /* nothing to do */
-
+ }
case V3D_MANIP_GIMBAL:
{
float mat[3][3];
@@ -562,28 +596,43 @@ int calc_manipulator_stats(const bContext *C)
break;
}
/* if not gimbal, fall through to normal */
+ /* pass through */
}
case V3D_MANIP_NORMAL:
+ {
if (obedit || ob->mode & OB_MODE_POSE) {
float mat[3][3];
ED_getTransformOrientationMatrix(C, mat, (v3d->around == V3D_ACTIVE));
copy_m4_m3(rv3d->twmat, mat);
break;
}
- /* no break we define 'normal' as 'local' in Object mode */
+ /* no break we define 'normal' as 'local' in Object mode */
+ /* pass through */
+ }
case V3D_MANIP_LOCAL:
+ {
+ if (ob->mode & OB_MODE_POSE) {
+ /* each bone moves on its own local axis, but to avoid confusion,
+ * use the active pones axis for display [#33575], this works as expected on a single bone
+ * and users who select many bones will understand whats going on and what local means
+ * when they start transforming */
+ float mat[3][3];
+ ED_getTransformOrientationMatrix(C, mat, (v3d->around == V3D_ACTIVE));
+ copy_m4_m3(rv3d->twmat, mat);
+ break;
+ }
copy_m4_m4(rv3d->twmat, ob->obmat);
normalize_m4(rv3d->twmat);
break;
-
+ }
case V3D_MANIP_VIEW:
{
float mat[3][3];
copy_m3_m4(mat, rv3d->viewinv);
normalize_m3(mat);
copy_m4_m3(rv3d->twmat, mat);
+ break;
}
- break;
default: /* V3D_MANIP_CUSTOM */
{
float mat[3][3];
@@ -638,7 +687,7 @@ static void test_manipulator_axis(const bContext *C)
/* ******************** DRAWING STUFFIES *********** */
-static float screen_aligned(RegionView3D *rv3d, float mat[][4])
+static float screen_aligned(RegionView3D *rv3d, float mat[4][4])
{
glTranslatef(mat[3][0], mat[3][1], mat[3][2]);
@@ -826,7 +875,7 @@ static void draw_manipulator_axes(View3D *v3d, RegionView3D *rv3d, int colcode,
}
}
-static void preOrthoFront(int ortho, float twmat[][4], int axis)
+static void preOrthoFront(int ortho, float twmat[4][4], int axis)
{
if (ortho == 0) {
float omat[4][4];