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-14 01:35:40 +0300
committerMartin Poirier <theeth@yahoo.com>2008-11-14 01:35:40 +0300
commitdc4ef17eea1a0dba1e9b9e99970005a394b1d37d (patch)
treef754f74d3c629e3cd77656a19d5850c4c55d99b3
parente76f7e793064f72557a8148b8c8cbf748cdaf152 (diff)
==Armature==
Fix the roll mess in transform. Since roll is based on an automatically calculated up axis, transforming bones would mess up bone orientation. This code automatically adjusts the roll value to keep bone orientation as consistant as possible. That works all around in transform for all transformations. Doesn't work with x-axis mirror though as that doesn't use transform elements (fixing it would be nice for later) Most interesting is that it works with the mirror tool (obviously), so you don't have to fix all the rolls after mirroring one side of an armature. It could be made an option if someone presents a good enough point for that, but I can't see why you'd want the previous mess instead. NB: this also ports a utility fonction from etch-a-ton to set bone roll from an up axis.
-rw-r--r--source/blender/include/BIF_editarmature.h2
-rw-r--r--source/blender/include/transform.h2
-rw-r--r--source/blender/src/editarmature.c25
-rw-r--r--source/blender/src/transform_conversions.c17
-rw-r--r--source/blender/src/transform_generics.c26
5 files changed, 68 insertions, 4 deletions
diff --git a/source/blender/include/BIF_editarmature.h b/source/blender/include/BIF_editarmature.h
index 02d73680818..ce275563a87 100644
--- a/source/blender/include/BIF_editarmature.h
+++ b/source/blender/include/BIF_editarmature.h
@@ -68,6 +68,8 @@ typedef struct EditBone
} EditBone;
+float rollBoneToVector(EditBone *bone, float new_up_axis[3]);
+
void make_boneList(struct ListBase *list, struct ListBase *bones, EditBone *parent);
void editbones_to_armature (struct ListBase *list, struct Object *ob);
diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h
index bd91bf8100a..fa7b8fc0a19 100644
--- a/source/blender/include/transform.h
+++ b/source/blender/include/transform.h
@@ -160,7 +160,7 @@ typedef struct TransData {
TransDataExtension *ext; /* for objects, poses. 1 single malloc per TransInfo! */
TransDataIpokey *tdi; /* for objects, ipo keys. per transdata a malloc */
TransDataCurveHandleFlags *hdata; /* for curves, stores handle flags for modification/cancel */
- void *tdmir; /* mirrored element pointer, in editmode mesh to EditVert */
+ void *extra; /* extra data (mirrored element pointer, in editmode mesh to EditVert) (editbone for roll fixing) (...) */
short flag; /* Various flags */
short protectflag; /* If set, copy of Object or PoseChannel protection */
/*#ifdef WITH_VERSE*/
diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c
index 5ddf522e4a8..ee5d56eaf43 100644
--- a/source/blender/src/editarmature.c
+++ b/source/blender/src/editarmature.c
@@ -1817,6 +1817,31 @@ void deselectall_armature(int toggle, int doundo)
}
}
+/* adjust bone roll to align Z axis with vector
+ * vec is in local space and is normalized
+ */
+float rollBoneToVector(EditBone *bone, float new_up_axis[3])
+{
+ float mat[3][3], nor[3], up_axis[3], vec[3];
+ float roll;
+
+ VecSubf(nor, bone->tail, bone->head);
+
+ vec_roll_to_mat3(nor, 0, mat);
+ VECCOPY(up_axis, mat[2]);
+
+ roll = NormalizedVecAngle2(new_up_axis, up_axis);
+
+ Crossf(vec, up_axis, new_up_axis);
+
+ if (Inpf(vec, nor) < 0)
+ {
+ roll = -roll;
+ }
+
+ return roll;
+}
+
/* Sets the roll value of selected bones, depending on the mode
* mode == 0: their z-axes point upwards
* mode == 1: their z-axes point towards 3d-cursor
diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c
index 496d5120bb9..f58eaefc628 100644
--- a/source/blender/src/transform_conversions.c
+++ b/source/blender/src/transform_conversions.c
@@ -1133,6 +1133,14 @@ static void createTransArmatureVerts(TransInfo *t)
Mat3CpyMat3(td->smtx, smtx);
Mat3CpyMat3(td->mtx, mtx);
+ VecSubf(delta, ebo->tail, ebo->head);
+ vec_roll_to_mat3(delta, ebo->roll, td->axismtx);
+
+ if ((ebo->flag & BONE_ROOTSEL) == 0)
+ {
+ td->extra = ebo;
+ }
+
td->ext = NULL;
td->tdi = NULL;
td->val = NULL;
@@ -1150,6 +1158,11 @@ static void createTransArmatureVerts(TransInfo *t)
Mat3CpyMat3(td->smtx, smtx);
Mat3CpyMat3(td->mtx, mtx);
+ VecSubf(delta, ebo->tail, ebo->head);
+ vec_roll_to_mat3(delta, ebo->roll, td->axismtx);
+
+ td->extra = ebo; /* to fix roll */
+
td->ext = NULL;
td->tdi = NULL;
td->val = NULL;
@@ -1863,7 +1876,7 @@ static void VertsToTransData(TransData *td, EditVert *eve)
td->ext = NULL;
td->tdi = NULL;
td->val = NULL;
- td->tdmir = NULL;
+ td->extra = NULL;
if (BIF_GetTransInfo()->mode == TFM_BWEIGHT) {
td->val = &(eve->bweight);
td->ival = eve->bweight;
@@ -2216,7 +2229,7 @@ static void createTransEditVerts(TransInfo *t)
/* Mirror? */
if( (mirror>0 && tob->iloc[0]>0.0f) || (mirror<0 && tob->iloc[0]<0.0f)) {
EditVert *vmir= editmesh_get_x_mirror_vert(G.obedit, tob->iloc); /* initializes octree on first call */
- if(vmir != eve) tob->tdmir = vmir;
+ if(vmir != eve) tob->extra = vmir;
}
tob++;
}
diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c
index 2a91b66ad8e..d8bc2158faa 100644
--- a/source/blender/src/transform_generics.c
+++ b/source/blender/src/transform_generics.c
@@ -254,7 +254,7 @@ static void editmesh_apply_to_mirror(TransInfo *t)
if (td->flag & TD_SKIP)
continue;
- eve = td->tdmir;
+ eve = td->extra;
if(eve) {
eve->co[0]= -td->loc[0];
eve->co[1]= td->loc[1];
@@ -470,6 +470,8 @@ void recalcData(TransInfo *t)
else if(G.obedit->type==OB_ARMATURE){ /* no recalc flag, does pose */
bArmature *arm= G.obedit->data;
EditBone *ebo;
+ TransData *td = t->data;
+ int i;
/* Ensure all bones are correctly adjusted */
for (ebo=G.edbo.first; ebo; ebo=ebo->next){
@@ -506,6 +508,28 @@ void recalcData(TransInfo *t)
ebo->oldlength= ebo->length;
}
}
+
+ /* fix roll */
+ for(i = 0; i < t->total; i++, td++)
+ {
+ if (td->extra)
+ {
+ float vec[3], up_axis[3];
+ float qrot[4];
+
+ ebo = td->extra;
+
+ VecSubf(vec, ebo->tail, ebo->head);
+ Normalize(vec);
+ RotationBetweenVectorsToQuat(qrot, td->axismtx[1], vec);
+
+ VECCOPY(up_axis, td->axismtx[2]);
+ QuatMulVecf(qrot, up_axis);
+
+ ebo->roll = rollBoneToVector(ebo, up_axis);
+ }
+ }
+
if(arm->flag & ARM_MIRROR_EDIT)
transform_armature_mirror_update();