diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2007-10-10 13:00:47 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2007-10-10 13:00:47 +0400 |
commit | 87b186e6e74e1f468655aed794edeb32d47c3359 (patch) | |
tree | 8c27dd1366743302db7780c7a7e238e07f6d2170 /source | |
parent | da792a426ad8a842e497d8d9bf3667b95a2f66de (diff) |
Make B-Bones not deform in rest position by default.
B-Bones already deformed the mesh in the armature rest position, which is
unconvenient. For backwards compatibility existing .blend files still have
a button for the old behavior enabled.
(peach feature request)
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_armature.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_blender.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/armature.c | 43 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 15 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_armature_types.h | 1 | ||||
-rw-r--r-- | source/blender/src/buttons_editing.c | 10 | ||||
-rw-r--r-- | source/blender/src/drawarmature.c | 2 |
7 files changed, 55 insertions, 20 deletions
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index 37022d89ac1..0e3857603b6 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -112,7 +112,7 @@ typedef struct Mat4 { float mat[4][4]; } Mat4; -Mat4 *b_bone_spline_setup(struct bPoseChannel *pchan); +Mat4 *b_bone_spline_setup(struct bPoseChannel *pchan, int rest); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index c79076b4e68..328d9775deb 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -44,7 +44,7 @@ struct ListBase; struct MemFile; #define BLENDER_VERSION 245 -#define BLENDER_SUBVERSION 3 +#define BLENDER_SUBVERSION 4 #define BLENDER_MINVERSION 240 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 31a25a984c4..15e45dfd01f 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -404,9 +404,11 @@ static void equalize_bezier(float *data, int desired) /* returns pointer to static array, filled with desired amount of bone->segments elements */ /* this calculation is done within unit bone space */ -Mat4 *b_bone_spline_setup(bPoseChannel *pchan) +Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest) { static Mat4 bbone_array[MAX_BBONE_SUBDIV]; + static Mat4 bbone_rest_array[MAX_BBONE_SUBDIV]; + Mat4 *result_array= (rest)? bbone_rest_array: bbone_array; bPoseChannel *next, *prev; Bone *bone= pchan->bone; float h1[3], h2[3], length, hlength1, hlength2, roll; @@ -430,11 +432,17 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan) first point = (0,0,0) last point = (0, length, 0) */ - Mat4Invert(imat, pchan->pose_mat); + if(rest) + Mat4Invert(imat, pchan->bone->arm_mat); + else + Mat4Invert(imat, pchan->pose_mat); if(prev) { /* transform previous point inside this bone space */ - VECCOPY(h1, prev->pose_head); + if(rest) + VECCOPY(h1, prev->bone->arm_head) + else + VECCOPY(h1, prev->pose_head) Mat4MulVecfl(imat, h1); /* if previous bone is B-bone too, use average handle direction */ if(prev->bone->segments>1) h1[1]-= length; @@ -448,14 +456,20 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan) float difmat[4][4], result[3][3], imat3[3][3]; /* transform next point inside this bone space */ - VECCOPY(h2, next->pose_tail); + if(rest) + VECCOPY(h2, next->bone->arm_tail) + else + VECCOPY(h2, next->pose_tail) Mat4MulVecfl(imat, h2); /* if next bone is B-bone too, use average handle direction */ if(next->bone->segments>1); else h2[1]-= length; /* find the next roll to interpolate as well */ - Mat4MulMat4(difmat, next->pose_mat, imat); + if(rest) + Mat4MulMat4(difmat, next->pose_mat, imat); + else + Mat4MulMat4(difmat, next->bone->arm_mat, imat); Mat3CpyMat4(result, difmat); // the desired rotation at beginning of next bone vec_roll_to_mat3(h2, 0.0f, mat3); // the result of vec_roll without roll @@ -490,19 +504,20 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan) for(a=0, fp= data[0]; a<bone->segments; a++, fp+=4) { VecSubf(h1, fp+4, fp); vec_roll_to_mat3(h1, fp[3], mat3); // fp[3] is roll - Mat4CpyMat3(bbone_array[a].mat, mat3); - VECCOPY(bbone_array[a].mat[3], fp); + Mat4CpyMat3(result_array[a].mat, mat3); + VECCOPY(result_array[a].mat[3], fp); } - return bbone_array; + return result_array; } /* ************ Armature Deform ******************* */ -static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion) +static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion, int rest_def) { Bone *bone= pchan->bone; - Mat4 *b_bone= b_bone_spline_setup(pchan); + Mat4 *b_bone= b_bone_spline_setup(pchan, 0); + Mat4 *b_bone_rest= (rest_def)? NULL: b_bone_spline_setup(pchan, 1); Mat4 *b_bone_mats; DualQuat *b_bone_dual_quats= NULL; float tmat[4][4]; @@ -529,7 +544,10 @@ static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion) Mat4One(tmat); for(a=0; a<bone->segments; a++) { - tmat[3][1] = -a*(bone->length/(float)bone->segments); + if(b_bone_rest) + Mat4Invert(tmat, b_bone_rest[a].mat); + else + tmat[3][1] = -a*(bone->length/(float)bone->segments); Mat4MulSerie(b_bone_mats[a+1].mat, pchan->chan_mat, bone->arm_mat, b_bone[a].mat, tmat, b_bone_mats[0].mat, NULL, NULL, NULL); @@ -726,6 +744,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, float obinv[4][4], premat[4][4], postmat[4][4]; int use_envelope = deformflag & ARM_DEF_ENVELOPE; int use_quaternion = deformflag & ARM_DEF_QUATERNION; + int bbone_rest_def = deformflag & ARM_DEF_B_BONE_REST; int numGroups = 0; /* safety for vertexgroup index overflow */ int i, target_totvert = 0; /* safety for vertexgroup overflow */ int use_dverts = 0; @@ -751,7 +770,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, for(pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next) { if(!(pchan->bone->flag & BONE_NO_DEFORM)) { if(pchan->bone->segments > 1) - pchan_b_bone_defmats(pchan, use_quaternion); + pchan_b_bone_defmats(pchan, use_quaternion, bbone_rest_def); if(use_quaternion) { pchan->dual_quat= &dualquats[totchan++]; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 4f33a90daef..487cce9e44f 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6750,6 +6750,21 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 4)) { + bArmature *arm; + ModifierData *md; + Object *ob; + + for(arm= main->armature.first; arm; arm= arm->id.next) + arm->deformflag |= ARM_DEF_B_BONE_REST; + + for(ob = main->object.first; ob; ob= ob->id.next) + for(md=ob->modifiers.first; md; md=md->next) + if(md->type==eModifierType_Armature) + ((ArmatureModifierData*)md)->deformflag |= ARM_DEF_B_BONE_REST; + } + + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */ diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h index 31a95363802..1fc50f4eec4 100644 --- a/source/blender/makesdna/DNA_armature_types.h +++ b/source/blender/makesdna/DNA_armature_types.h @@ -114,6 +114,7 @@ typedef struct bArmature { #define ARM_DEF_VGROUP 1 #define ARM_DEF_ENVELOPE 2 #define ARM_DEF_QUATERNION 4 +#define ARM_DEF_B_BONE_REST 8 /* armature->pathflag */ #define ARM_PATH_FNUMS 0x001 diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index da60aaef71f..c389c2ddc7e 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -1912,9 +1912,8 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob); uiDefButBitS(block, TOG, ARM_DEF_VGROUP, B_ARM_RECALCDATA, "Vert.Groups", lx,cy-=19,buttonWidth/2,20, &amd->deformflag, 0, 0, 0, 0, "Enable VertexGroups defining deform"); uiDefButBitS(block, TOG, ARM_DEF_ENVELOPE, B_ARM_RECALCDATA, "Envelopes", lx+buttonWidth/2,cy,(buttonWidth + 1)/2,20, &amd->deformflag, 0, 0, 0, 0, "Enable Bone Envelopes defining deform"); - uiDefButBitS(block, TOG, ARM_DEF_QUATERNION, B_ARM_RECALCDATA, "Quaternion", lx,(cy-=19),buttonWidth + 1,20, &amd->deformflag, 0, 0, 0, 0, "Enable deform rotation interpolation with Quaternions"); - - + uiDefButBitS(block, TOG, ARM_DEF_QUATERNION, B_ARM_RECALCDATA, "Quaternion", lx,(cy-=19),buttonWidth/2,20, &amd->deformflag, 0, 0, 0, 0, "Enable deform rotation interpolation with Quaternions"); + uiDefButBitS(block, TOG, ARM_DEF_B_BONE_REST, B_ARM_RECALCDATA, "B-Bone Rest", lx+buttonWidth/2,cy,(buttonWidth + 1)/2,20, &amd->deformflag, 0, 0, 0, 0, "Make B-Bones deform already in rest position"); } else if (md->type==eModifierType_Hook) { HookModifierData *hmd = (HookModifierData*) md; uiDefButF(block, NUM, B_MODIFIER_RECALC, "Falloff: ", lx, (cy-=19), buttonWidth,19, &hmd->falloff, 0.0, 100.0, 100, 0, "If not zero, the distance from hook where influence ends"); @@ -3641,8 +3640,9 @@ static void editing_panel_armature_type(Object *ob, bArmature *arm) uiDefButBitS(block, TOG, ARM_DEF_VGROUP, B_ARM_RECALCDATA, "Vertex Groups", 10, 20,100,20, &arm->deformflag, 0, 0, 0, 0, "Enable VertexGroups defining deform (not for Modifiers)"); uiDefButBitS(block, TOG, ARM_DEF_ENVELOPE, B_ARM_RECALCDATA, "Envelopes", 110,20,100,20, &arm->deformflag, 0, 0, 0, 0, "Enable Bone Envelopes defining deform (not for Modifiers)"); uiDefButBitS(block, TOG, ARM_DEF_QUATERNION, B_ARM_RECALCDATA, "Quaternion", 210,20,100,20, &arm->deformflag, 0, 0, 0, 0, "Enable deform rotation interpolation with Quaternions (not for Modifiers)"); - uiDefButBitI(block, TOG, ARM_RESTPOS, B_ARM_RECALCDATA,"Rest Position", 10,0,150,20, &arm->flag, 0, 0, 0, 0, "Show armature rest position, no posing possible"); - uiDefButBitI(block, TOG, ARM_DELAYDEFORM, REDRAWVIEW3D, "Delay Deform", 160,0,150,20, &arm->flag, 0, 0, 0, 0, "Don't deform children when manipulating bones in pose mode"); + uiDefButBitI(block, TOG, ARM_RESTPOS, B_ARM_RECALCDATA,"Rest Position", 10,0,100,20, &arm->flag, 0, 0, 0, 0, "Show armature rest position, no posing possible"); + uiDefButBitI(block, TOG, ARM_DELAYDEFORM, REDRAWVIEW3D, "Delay Deform", 110,0,100,20, &arm->flag, 0, 0, 0, 0, "Don't deform children when manipulating bones in pose mode"); + uiDefButBitS(block, TOG, ARM_DEF_B_BONE_REST, B_ARM_RECALCDATA,"B-Bone Rest", 210,0,100,20, &arm->deformflag, 0, 0, 0, 0, "Make B-Bones deform already in rest position"); uiBlockEndAlign(block); } diff --git a/source/blender/src/drawarmature.c b/source/blender/src/drawarmature.c index 1592a05aeb3..601a3fdf589 100644 --- a/source/blender/src/drawarmature.c +++ b/source/blender/src/drawarmature.c @@ -888,7 +888,7 @@ static void draw_b_bone_boxes(int dt, bPoseChannel *pchan, float xwidth, float l if(segments>1 && pchan) { float dlen= length/(float)segments; - Mat4 *bbone= b_bone_spline_setup(pchan); + Mat4 *bbone= b_bone_spline_setup(pchan, 0); int a; for(a=0; a<segments; a++, bbone++) { |