Fix bones moving when changing between editmode and posemode.
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 5 Feb 2011 13:19:14 +0000 (13:19 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 5 Feb 2011 13:19:14 +0000 (13:19 +0000)
Patch #25901 by Tobias Oelgarte.

Bone transformations would be converted back and forth between different
representations when changing modes, which due to numerical errors could
lead to bone transformations slowly changing as you edit the armature.

Now the editmode head, tail and roll values are stored in bones and used
directly when entering edit mode. Head and tail were already there but
now we ensure they are the exact same value, roll was not yet there, so
we have a version patch for it.

The sub version was incremented to 1 for the version patch.

source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/intern/armature.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/armature/editarmature.c
source/blender/makesdna/DNA_armature_types.h

index a4b7d8469e0f687e9123c778927edad526e7bc28..65e7f848ea00e6b4800e907339f5ed3d21122daf 100644 (file)
@@ -45,7 +45,7 @@ struct Scene;
 struct Main;
 
 #define BLENDER_VERSION                        256
-#define BLENDER_SUBVERSION             0
+#define BLENDER_SUBVERSION             1
 
 #define BLENDER_MINVERSION             250
 #define BLENDER_MINSUBVERSION  0
index 1a219939b774c6d845d90e03e6371015b694f6e8..14c4b6f97abf83e354a612ce22d78341ba7799eb 100644 (file)
@@ -1401,13 +1401,6 @@ void where_is_armature_bone(Bone *bone, Bone *prevbone)
                VECCOPY(bone->arm_mat[3], bone->head);
        }
        
-       /* head */
-       VECCOPY(bone->arm_head, bone->arm_mat[3]);
-       /* tail is in current local coord system */
-       VECCOPY(vec, bone->arm_mat[1]);
-       mul_v3_fl(vec, bone->length);
-       add_v3_v3v3(bone->arm_tail, bone->arm_head, vec);
-       
        /* and the kiddies */
        prevbone= bone;
        for(bone= bone->childbase.first; bone; bone= bone->next) {
index 069d85f9bda43012689ff8b2d333f7e86089eafc..085ec92e2090cd23feb706e89bf8d6346854e579 100644 (file)
@@ -5746,6 +5746,23 @@ static int map_223_keybd_code_to_224_keybd_code(int code)
        }
 }
 
+static void do_version_bone_head_tail_237(Bone *bone)
+{
+       Bone *child;
+       float vec[3];
+
+       /* head */
+       copy_v3_v3(bone->arm_head, bone->arm_mat[3]);
+
+       /* tail is in current local coord system */
+       copy_v3_v3(vec, bone->arm_mat[1]);
+       mul_v3_fl(vec, bone->length);
+       add_v3_v3v3(bone->arm_tail, bone->arm_head, vec);
+
+       for(child= bone->childbase.first; child; child= child->next)
+               do_version_bone_head_tail_237(child);
+}
+
 static void bone_version_238(ListBase *lb)
 {
        Bone *bone;
@@ -6655,6 +6672,19 @@ static void do_versions_seq_unique_name_all_strips(
        }
 }
 
+
+static void do_version_bone_roll_256(Bone *bone)
+{
+       Bone *child;
+       float submat[3][3];
+       
+       copy_m3_m4(submat, bone->arm_mat);
+       mat3_to_vec_roll(submat, 0, &bone->arm_roll);
+       
+       for(child = bone->childbase.first; child; child = child->next)
+               do_version_bone_roll_256(child);
+}
+
 static void do_versions(FileData *fd, Library *lib, Main *main)
 {
        /* WATCH IT!!!: pointers from libdata have not been converted */
@@ -7964,10 +7994,14 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                bArmature *arm;
                bConstraint *con;
                Object *ob;
+               Bone *bone;
                
                // armature recode checks 
                for(arm= main->armature.first; arm; arm= arm->id.next) {
                        where_is_armature(arm);
+
+                       for(bone= arm->bonebase.first; bone; bone= bone->next)
+                               do_version_bone_head_tail_237(bone);
                }
                for(ob= main->object.first; ob; ob= ob->id.next) {
                        if(ob->parent) {
@@ -11285,6 +11319,16 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
        }
        
+       if (main->versionfile < 256 || (main->versionfile == 256 && main->subversionfile < 1)) {
+               /* fix for bones that didn't have arm_roll before */
+               bArmature* arm;
+               Bone* bone;
+
+               for (arm = main->armature.first; arm; arm = arm->id.next)
+                       for (bone = arm->bonebase.first; bone; bone = bone->next)
+                               do_version_bone_roll_256(bone);
+       }
+                               
        /* put compatibility code here until next subversion bump */
        
        {
index 5e54cbf63450891824b18ed9a087eb9d3b0b1707..4fc5064cef026ccaefa08be95bd7e2da681cedba 100644 (file)
@@ -246,11 +246,6 @@ EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone
        EditBone        *eBoneAct= NULL;
        EditBone        *eBoneTest= NULL;
        Bone            *curBone;
-       float delta[3];
-       float premat[3][3];
-       float postmat[3][3];
-       float imat[3][3];
-       float difmat[3][3];
                
        for (curBone=bones->first; curBone; curBone=curBone->next) {
                eBone= MEM_callocN(sizeof(EditBone), "make_editbone");
@@ -291,20 +286,8 @@ EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone
                }
 
                copy_v3_v3(eBone->head, curBone->arm_head);
-               copy_v3_v3(eBone->tail, curBone->arm_tail);             
-               
-               eBone->roll= 0.0f;
-               
-               /* roll fixing */
-               sub_v3_v3v3(delta, eBone->tail, eBone->head);
-               vec_roll_to_mat3(delta, 0.0f, postmat);
-               
-               copy_m3_m4(premat, curBone->arm_mat);
-               
-               invert_m3_m3(imat, postmat);
-               mul_m3_m3m3(difmat, imat, premat);
-               
-               eBone->roll = (float)atan2(difmat[2][0], difmat[2][2]);
+               copy_v3_v3(eBone->tail, curBone->arm_tail);
+               eBone->roll = curBone->arm_roll;
                
                /* rest of stuff copy */
                eBone->length= curBone->length;
@@ -420,8 +403,10 @@ void ED_armature_from_edit(Object *obedit)
                eBone->temp= newBone;   /* Associate the real Bones with the EditBones */
                
                BLI_strncpy(newBone->name, eBone->name, sizeof(newBone->name));
-               memcpy(newBone->head, eBone->head, sizeof(newBone->head));
-               memcpy(newBone->tail, eBone->tail, sizeof(newBone->tail));
+               copy_v3_v3(newBone->arm_head, eBone->head);
+               copy_v3_v3(newBone->arm_tail, eBone->tail);
+               newBone->arm_roll = eBone->roll;
+               
                newBone->flag= eBone->flag;
                
                if (eBone == arm->act_edbone) {
@@ -456,7 +441,6 @@ void ED_armature_from_edit(Object *obedit)
                        BLI_addtail(&newBone->parent->childbase, newBone);
                        
                        {
-                               float M_boneRest[3][3];
                                float M_parentRest[3][3];
                                float iM_parentRest[3][3];
                                float   delta[3];
@@ -465,10 +449,6 @@ void ED_armature_from_edit(Object *obedit)
                                sub_v3_v3v3(delta, eBone->parent->tail, eBone->parent->head);
                                vec_roll_to_mat3(delta, eBone->parent->roll, M_parentRest);
                                
-                               /* Get this bone's  matrix (rotation only) */
-                               sub_v3_v3v3(delta, eBone->tail, eBone->head);
-                               vec_roll_to_mat3(delta, eBone->roll, M_boneRest);
-                               
                                /* Invert the parent matrix */
                                invert_m3_m3(iM_parentRest, M_parentRest);
                                
@@ -481,8 +461,11 @@ void ED_armature_from_edit(Object *obedit)
                        }
                }
                /*      ...otherwise add this bone to the armature's bonebase */
-               else
+               else {
+                       copy_v3_v3(newBone->head, eBone->head);
+                       copy_v3_v3(newBone->tail, eBone->tail);
                        BLI_addtail(&arm->bonebase, newBone);
+               }
        }
        
        /* Make a pass through the new armature to fix rolling */
index 108c0883f15fe2fb009db5560a2ae6dfd9a7e105..89c2d69b8be3ef6da64a8c161cb6f8f1c1ec75ac 100644 (file)
@@ -57,8 +57,9 @@ typedef struct Bone {
        int                             flag;
        
        float                   arm_head[3];            
-       float                   arm_tail[3];    /*      head/tail and roll in Armature Space (rest pos) */
+       float                   arm_tail[3];    /*      head/tail in Armature Space (rest pos) */
        float                   arm_mat[4][4];  /*  matrix: (bonemat(b)+head(b))*arm_mat(b-1), rest pos*/
+       float           arm_roll;        /* roll in Armature Space (rest pos) */
        
        float                   dist, weight;                   /*  dist, weight: for non-deformgroup deforms */
        float                   xwidth, length, zwidth; /*  width: for block bones. keep in this order, transform! */
@@ -68,7 +69,7 @@ typedef struct Bone {
        float                   size[3];                /*  patch for upward compat, UNUSED! */
        int                             layer;                  /* layers that bone appears on */
        short                   segments;               /*  for B-bones */
-       short                   pad[3];
+       short                   pad[1];
 } Bone;
 
 typedef struct bArmature {