Revision: 17446
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17446
Author: theeth
Date: 2008-11-13 23:35:40 +0100 (Thu, 13 Nov 2008)
Log Message:
-----------
==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.
Modified Paths:
--------------
trunk/blender/source/blender/include/BIF_editarmature.h
trunk/blender/source/blender/include/transform.h
trunk/blender/source/blender/src/editarmature.c
trunk/blender/source/blender/src/transform_conversions.c
trunk/blender/source/blender/src/transform_generics.c
Modified: trunk/blender/source/blender/include/BIF_editarmature.h
===================================================================
--- trunk/blender/source/blender/include/BIF_editarmature.h 2008-11-13
21:44:32 UTC (rev 17445)
+++ trunk/blender/source/blender/include/BIF_editarmature.h 2008-11-13
22:35:40 UTC (rev 17446)
@@ -68,6 +68,8 @@
} 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);
Modified: trunk/blender/source/blender/include/transform.h
===================================================================
--- trunk/blender/source/blender/include/transform.h 2008-11-13 21:44:32 UTC
(rev 17445)
+++ trunk/blender/source/blender/include/transform.h 2008-11-13 22:35:40 UTC
(rev 17446)
@@ -160,7 +160,7 @@
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*/
Modified: trunk/blender/source/blender/src/editarmature.c
===================================================================
--- trunk/blender/source/blender/src/editarmature.c 2008-11-13 21:44:32 UTC
(rev 17445)
+++ trunk/blender/source/blender/src/editarmature.c 2008-11-13 22:35:40 UTC
(rev 17446)
@@ -1817,6 +1817,31 @@
}
}
+/* 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
Modified: trunk/blender/source/blender/src/transform_conversions.c
===================================================================
--- trunk/blender/source/blender/src/transform_conversions.c 2008-11-13
21:44:32 UTC (rev 17445)
+++ trunk/blender/source/blender/src/transform_conversions.c 2008-11-13
22:35:40 UTC (rev 17446)
@@ -1133,6 +1133,14 @@
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 @@
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 @@
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 @@
/* 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++;
}
Modified: trunk/blender/source/blender/src/transform_generics.c
===================================================================
--- trunk/blender/source/blender/src/transform_generics.c 2008-11-13
21:44:32 UTC (rev 17445)
+++ trunk/blender/source/blender/src/transform_generics.c 2008-11-13
22:35:40 UTC (rev 17446)
@@ -254,7 +254,7 @@
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 @@
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 @@
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();
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs