diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 27e06590670..62c9e2334b8 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -661,9 +661,11 @@ static void pchan_bone_deform(bPoseChannel *pchan, float weight, float *vec, flo void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], int numVerts) { + bArmature *arm= armOb->data; bPoseChannel *pchan, **defnrToPC = NULL; - MDeformVert *dverts; + MDeformVert *dverts= NULL; float obinv[4][4], premat[4][4], postmat[4][4]; + int use_envelope= arm->deformflag & ARM_DEF_ENVELOPE; int i; Mat4Invert(obinv, target->obmat); @@ -676,28 +678,33 @@ void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], /* initialize B_bone matrices */ for(pchan= armOb->pose->chanbase.first; pchan; pchan= pchan->next) { - //if(pchan->bone->boneclass==BONE_SKINNABLE) // not yet... for vgroups this is ignored + if(pchan->bone->boneclass==BONE_SKINNABLE) if(pchan->bone->segments>1) pchan_b_bone_defmats(pchan); } - if (target->type==OB_MESH){ - int numGroups = BLI_countlist(&target->defbase); - bDeformGroup *dg; - - dverts = ((Mesh*)target->data)->dvert; - if(dverts) { - defnrToPC = MEM_callocN(sizeof(*defnrToPC)*numGroups, "defnrToBone"); - for (i=0,dg=target->defbase.first; dg; i++,dg=dg->next) { - defnrToPC[i] = get_pose_channel(armOb->pose, dg->name); + /* get a vertex-deform-index to posechannel array */ + if(arm->deformflag & ARM_DEF_VGROUP) { + if (target->type==OB_MESH){ + int numGroups = BLI_countlist(&target->defbase); + bDeformGroup *dg; + + dverts = ((Mesh*)target->data)->dvert; + if(dverts) { + defnrToPC = MEM_callocN(sizeof(*defnrToPC)*numGroups, "defnrToBone"); + for (i=0,dg=target->defbase.first; dg; i++,dg=dg->next) { + defnrToPC[i] = get_pose_channel(armOb->pose, dg->name); + /* exclude non-skinnable bones */ + if(defnrToPC[i]) + if(defnrToPC[i]->bone->boneclass!=BONE_SKINNABLE) + defnrToPC[i]= NULL; + } } } } - else { - dverts = NULL; - } for(i=0; itotweight; j++){ pchan = defnrToPC[dvert->dw[j].def_nr]; - if (pchan) - pchan_bone_deform(pchan, dvert->dw[j].weight, vec, co, &contrib); + if (pchan) { + float weight= dvert->dw[j].weight; + if(pchan->bone->flag & BONE_MULT_VG_ENV) { + Bone *bone= pchan->bone; + weight*= distfactor_to_bone(co, bone->arm_head, bone->arm_tail, bone->rad_head, bone->rad_tail, bone->dist); + } + pchan_bone_deform(pchan, weight, vec, co, &contrib); + } } } - else { + else if(use_envelope) { for(pchan= armOb->pose->chanbase.first; pchan; pchan= pchan->next) { if(pchan->bone->boneclass==BONE_SKINNABLE) contrib+= dist_bone_deform(pchan, vec, co); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 061bfdb912b..04e63dcfb48 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4882,6 +4882,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) for(arm=main->armature.first; arm; arm= arm->id.next) { bone_version_238(&arm->bonebase); + arm->deformflag |= ARM_DEF_VGROUP; } for(me=main->mesh.first; me; me= me->id.next) { diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h index 013b42876a1..59e68ebe44b 100644 --- a/source/blender/makesdna/DNA_armature_types.h +++ b/source/blender/makesdna/DNA_armature_types.h @@ -76,7 +76,7 @@ typedef struct bArmature { ListBase chainbase; int flag; int drawtype; - int res2; + int deformflag; int res3; }bArmature; @@ -96,12 +96,15 @@ typedef struct bArmature { #define ARM_MIRROR_EDIT 0x0100 /* armature->drawtype */ - #define ARM_OCTA 0 #define ARM_LINE 1 #define ARM_B_BONE 2 #define ARM_ENVELOPE 3 +/* armature->deformflag */ +#define ARM_DEF_VGROUP 1 +#define ARM_DEF_ENVELOPE 2 + /* bone->flag */ #define BONE_SELECTED 1 @@ -120,7 +123,9 @@ typedef struct bArmature { /* No parent rotation or scale */ #define BONE_HINGE 512 /* hidden Bones when drawing Armature Editmode */ -#define BONE_HIDDEN_A 1024 +#define BONE_HIDDEN_A 1024 + /* multiplies vgroup with envelope */ +#define BONE_MULT_VG_ENV 2048 /* bone->flag bits */ #define BONE_IK_TOPARENTBIT 4 diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 9a8b9149053..a2149f2b183 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -2175,24 +2175,30 @@ static void editing_panel_armature_type(Object *ob, bArmature *arm) block= uiNewBlock(&curarea->uiblocks, "editing_panel_armature_type", UI_EMBOSS, UI_HELV, curarea->win); if(uiNewPanel(curarea, block, "Armature", "Editing", 320, 0, 318, 204)==0) return; + uiDefBut(block, LABEL, 0, "Editing Options", 10,180,150,20, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, ARM_RESTPOS, B_ARM_RECALCDATA, - "Rest Position", 10,180,150,20, &arm->flag, 0, 0, 0, 0, "Disable all animation for this object"); + uiDefButBitI(block, TOG, ARM_MIRROR_EDIT, B_DIFF, "X-Axis Mirror Edit", 10, 160,150,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes"); + uiDefButBitC(block, TOG, OB_DRAWXRAY,REDRAWVIEW3D, "X-Ray", 160,160,150,20, &ob->dtx, 0, 0, 0, 0, "Draw armature in front of solid objects"); + uiBlockEndAlign(block); + + uiDefBut(block, LABEL, 0, "Display Options", 10,140,150,20, 0, 0, 0, 0, 0, ""); + uiBlockBeginAlign(block); + uiDefButI(block, ROW, REDRAWVIEW3D, "Octahedron", 10, 120,90,20, &arm->drawtype, 0, ARM_OCTA, 0, 0, "Draw bones as octahedra"); + uiDefButI(block, ROW, REDRAWVIEW3D, "Stick", 100, 120,55,20, &arm->drawtype, 0, ARM_LINE, 0, 0, "Draw bones as simple 2d lines with dots"); + uiDefButI(block, ROW, REDRAWVIEW3D, "B-Bone", 155, 120,70,20, &arm->drawtype, 0, ARM_B_BONE, 0, 0, "Draw bones as boxes, showing subdivision and b-splines"); + uiDefButI(block, ROW, REDRAWVIEW3D, "Envelope", 225, 120,85,20, &arm->drawtype, 0, ARM_ENVELOPE, 0, 0, "Draw bones as extruded spheres, showing deformation influence volume"); - uiDefButBitI(block, TOG, ARM_DELAYDEFORM, REDRAWVIEW3D, "Delay Deform", 160, 180,150,20, &arm->flag, 0, 0, 0, 0, "Don't deform children when manipulating bones in pose mode"); - uiBlockBeginAlign(block); - uiDefButI(block, ROW, REDRAWVIEW3D, "Octahedron", 10, 140,75,20, &arm->drawtype, 0, ARM_OCTA, 0, 0, "Draw bones as octahedra"); - uiDefButI(block, ROW, REDRAWVIEW3D, "Stick", 85, 140,70,20, &arm->drawtype, 0, ARM_LINE, 0, 0, "Draw bones as simple 2d lines with dots"); - uiDefButI(block, ROW, REDRAWVIEW3D, "B-Bone", 155, 140,70,20, &arm->drawtype, 0, ARM_B_BONE, 0, 0, "Draw bones as boxes, showing subdivision and b-splines"); - uiDefButI(block, ROW, REDRAWVIEW3D, "Envelope", 225, 140,85,20, &arm->drawtype, 0, ARM_ENVELOPE, 0, 0, "Draw bones as extruded spheres, showing deformation influence volume"); + uiDefButBitI(block, TOG, ARM_DRAWAXES, REDRAWVIEW3D, "Draw Axes", 10, 100,150,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes"); + uiDefButBitI(block, TOG, ARM_DRAWNAMES, REDRAWVIEW3D, "Draw Names", 160,100,150,20, &arm->flag, 0, 0, 0, 0, "Draw bone names"); + uiBlockEndAlign(block); + uiDefBut(block, LABEL, 0, "Deform Options", 10,80,150,20, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, ARM_DRAWAXES, REDRAWVIEW3D, "Draw Axes", 10, 110,100,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes"); - uiDefButBitI(block, TOG, ARM_DRAWNAMES, REDRAWVIEW3D, "Draw Names", 110,110,100,20, &arm->flag, 0, 0, 0, 0, "Draw bone names"); - uiDefButBitC(block, TOG, OB_DRAWXRAY,REDRAWVIEW3D, "X-Ray", 210,110,100,20, &ob->dtx, 0, 0, 0, 0, "Draw armature in front of solid objects"); + uiDefButBitI(block, TOG, ARM_DEF_VGROUP, B_ARM_RECALCDATA, "Vertex Groups", 10, 60,150,20, &arm->deformflag, 0, 0, 0, 0, "Enable VertexGroups defining deform"); + uiDefButBitI(block, TOG, ARM_DEF_ENVELOPE, B_ARM_RECALCDATA, "Envelopes", 160,60,150,20, &arm->deformflag, 0, 0, 0, 0, "Enable Bone Envelopes defining deform"); + uiDefButBitI(block, TOG, ARM_RESTPOS, B_ARM_RECALCDATA,"Rest Position", 10,40,150,20, &arm->flag, 0, 0, 0, 0, "Show armature rest position, no posing possible"); + uiDefButBitI(block, TOG, ARM_DELAYDEFORM, REDRAWVIEW3D, "Delay Deform", 160,40,150,20, &arm->flag, 0, 0, 0, 0, "Don't deform children when manipulating bones in pose mode"); - uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, ARM_MIRROR_EDIT, B_DIFF, "X-Axis Mirror Edit", 10, 80,150,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes"); } static void editing_panel_armature_bones(Object *ob, bArmature *arm) @@ -2248,10 +2254,10 @@ static void editing_panel_armature_bones(Object *ob, bArmature *arm) uiDefButF(block, NUM,B_ARM_RECALCDATA, "Weight:", bx+223, by-19,110, 18, &curBone->weight, 0.0F, 1000.0F, 10.0F, 0.0F, "Bone deformation weight"); /* bone types */ - uiDefButBitI(block, TOG, BONE_HINGE, B_ARM_RECALCDATA, "Hinge", bx-10,by-38,117,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone"); - uiDefButBitS(block, TOGN, 1,B_ARM_RECALCDATA, "Skinnable", bx+110, by-38, 105, 18, &curBone->boneclass, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone is included in automatic creation of vertex groups"); - /* Hide in posemode flag */ - uiDefButBitI(block, TOG, BONE_HIDDEN_A, REDRAWVIEW3D, "Hide", bx+223,by-38,110,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in Edit Mode"); + uiDefButBitI(block, TOG, BONE_HINGE, B_ARM_RECALCDATA, "Hinge", bx-10,by-38,85,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone"); + uiDefButBitS(block, TOGN, 1, B_ARM_RECALCDATA, "Deform", bx+75, by-38, 85, 18, &curBone->boneclass, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone deforms geometry"); + uiDefButBitI(block, TOG, BONE_MULT_VG_ENV, B_ARM_RECALCDATA, "Mult", bx+160,by-38,85,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Multiply Bone Envelope with VertexGroup"); + uiDefButBitI(block, TOG, BONE_HIDDEN_A, REDRAWVIEW3D, "Hide", bx+245,by-38,88,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in Edit Mode"); uiBlockEndAlign(block); by-=60; @@ -2307,10 +2313,10 @@ static void editing_panel_pose_bones(Object *ob, bArmature *arm) uiDefButF(block, NUM,B_ARM_RECALCDATA, "Out:", bx+220, by-19, 110, 19, &curBone->ease2, 0.0, 2.0, 10.0, 0.0, "Second length of Bezier handle"); /* bone types */ - uiDefButBitI(block, TOG, BONE_HINGE, B_ARM_RECALCDATA, "Hinge", bx-10,by-38,117,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone"); - uiDefButBitS(block, TOGN, 1,B_ARM_RECALCDATA, "Skinnable", bx+110, by-38, 105, 18, &curBone->boneclass, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone is included in automatic creation of vertex groups"); - /* Hide in posemode flag */ - uiDefButBitI(block, TOG, BONE_HIDDEN_P, REDRAWVIEW3D, "Hide", bx+223,by-38,110,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in posemode"); + uiDefButBitI(block, TOG, BONE_HINGE, B_ARM_RECALCDATA, "Hinge", bx-10,by-38,85,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone"); + uiDefButBitS(block, TOGN, 1, B_ARM_RECALCDATA, "Deform", bx+75, by-38, 85, 18, &curBone->boneclass, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone deforms geometry"); + uiDefButBitI(block, TOG, BONE_MULT_VG_ENV, B_ARM_RECALCDATA, "Mult", bx+160,by-38,85,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Multiply Bone Envelope with VertexGroup"); + uiDefButBitI(block, TOG, BONE_HIDDEN_P, REDRAWVIEW3D, "Hide", bx+245,by-38,88,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in Pose Mode"); uiBlockEndAlign(block); by-=60;