Control over Armature deform. Three new options are added for it;

Armature Panel
- "Vertex Groups"
- "Envelope"

Bones Panel
- "Mult"

The logic works as follows;
- Set "Vertex Groups" will enable vertex group based deform (default)
- Set "Envelope" will enable Bone Envelopes to deform
- Set both will apply Envelope deform on vertices without VertexGroups

- Set the per-Bone "Mult" option to have Envelopes work on top of a
  VertexGroup
- The per-Bone "Deform" option (was called "Skinnable") will dis/enable
  the Bone to deform for all situations.

The old convention was that, without any vertex groups, the Bones deformed
with bone-distances. I can't patch that... so you have to enable it by
hand in older files. Not too bad, since this option was unusable before
anyway. :)
This commit is contained in:
Ton Roosendaal 2005-08-21 18:53:12 +00:00
parent a669c9d6d1
commit 6ad0c922af
4 changed files with 73 additions and 43 deletions

@ -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) void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], int numVerts)
{ {
bArmature *arm= armOb->data;
bPoseChannel *pchan, **defnrToPC = NULL; bPoseChannel *pchan, **defnrToPC = NULL;
MDeformVert *dverts; MDeformVert *dverts= NULL;
float obinv[4][4], premat[4][4], postmat[4][4]; float obinv[4][4], premat[4][4], postmat[4][4];
int use_envelope= arm->deformflag & ARM_DEF_ENVELOPE;
int i; int i;
Mat4Invert(obinv, target->obmat); Mat4Invert(obinv, target->obmat);
@ -676,11 +678,13 @@ void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3],
/* initialize B_bone matrices */ /* initialize B_bone matrices */
for(pchan= armOb->pose->chanbase.first; pchan; pchan= pchan->next) { 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) if(pchan->bone->segments>1)
pchan_b_bone_defmats(pchan); pchan_b_bone_defmats(pchan);
} }
/* get a vertex-deform-index to posechannel array */
if(arm->deformflag & ARM_DEF_VGROUP) {
if (target->type==OB_MESH){ if (target->type==OB_MESH){
int numGroups = BLI_countlist(&target->defbase); int numGroups = BLI_countlist(&target->defbase);
bDeformGroup *dg; bDeformGroup *dg;
@ -690,14 +694,17 @@ void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3],
defnrToPC = MEM_callocN(sizeof(*defnrToPC)*numGroups, "defnrToBone"); defnrToPC = MEM_callocN(sizeof(*defnrToPC)*numGroups, "defnrToBone");
for (i=0,dg=target->defbase.first; dg; i++,dg=dg->next) { for (i=0,dg=target->defbase.first; dg; i++,dg=dg->next) {
defnrToPC[i] = get_pose_channel(armOb->pose, dg->name); 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; i<numVerts; i++) { for(i=0; i<numVerts; i++) {
MDeformVert *dvert;
float *co = vertexCos[i]; float *co = vertexCos[i];
float vec[3]; float vec[3];
float contrib=0.0; float contrib=0.0;
@ -708,16 +715,27 @@ void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3],
/* Apply the object's matrix */ /* Apply the object's matrix */
Mat4MulVecfl(premat, co); Mat4MulVecfl(premat, co);
if (dverts) { // use weight groups if(dverts)
dvert= dverts+i;
else
dvert= NULL;
if(dvert) { // use weight groups
MDeformVert *dvert = &dverts[i]; MDeformVert *dvert = &dverts[i];
for (j=0; j<dvert->totweight; j++){ for (j=0; j<dvert->totweight; j++){
pchan = defnrToPC[dvert->dw[j].def_nr]; pchan = defnrToPC[dvert->dw[j].def_nr];
if (pchan) if (pchan) {
pchan_bone_deform(pchan, dvert->dw[j].weight, vec, co, &contrib); 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) { for(pchan= armOb->pose->chanbase.first; pchan; pchan= pchan->next) {
if(pchan->bone->boneclass==BONE_SKINNABLE) if(pchan->bone->boneclass==BONE_SKINNABLE)
contrib+= dist_bone_deform(pchan, vec, co); contrib+= dist_bone_deform(pchan, vec, co);

@ -4882,6 +4882,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
for(arm=main->armature.first; arm; arm= arm->id.next) { for(arm=main->armature.first; arm; arm= arm->id.next) {
bone_version_238(&arm->bonebase); bone_version_238(&arm->bonebase);
arm->deformflag |= ARM_DEF_VGROUP;
} }
for(me=main->mesh.first; me; me= me->id.next) { for(me=main->mesh.first; me; me= me->id.next) {

@ -76,7 +76,7 @@ typedef struct bArmature {
ListBase chainbase; ListBase chainbase;
int flag; int flag;
int drawtype; int drawtype;
int res2; int deformflag;
int res3; int res3;
}bArmature; }bArmature;
@ -96,12 +96,15 @@ typedef struct bArmature {
#define ARM_MIRROR_EDIT 0x0100 #define ARM_MIRROR_EDIT 0x0100
/* armature->drawtype */ /* armature->drawtype */
#define ARM_OCTA 0 #define ARM_OCTA 0
#define ARM_LINE 1 #define ARM_LINE 1
#define ARM_B_BONE 2 #define ARM_B_BONE 2
#define ARM_ENVELOPE 3 #define ARM_ENVELOPE 3
/* armature->deformflag */
#define ARM_DEF_VGROUP 1
#define ARM_DEF_ENVELOPE 2
/* bone->flag */ /* bone->flag */
#define BONE_SELECTED 1 #define BONE_SELECTED 1
@ -121,6 +124,8 @@ typedef struct bArmature {
#define BONE_HINGE 512 #define BONE_HINGE 512
/* hidden Bones when drawing Armature Editmode */ /* 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 */ /* bone->flag bits */
#define BONE_IK_TOPARENTBIT 4 #define BONE_IK_TOPARENTBIT 4

@ -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); 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; 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); uiBlockBeginAlign(block);
uiDefButBitI(block, TOG, ARM_RESTPOS, B_ARM_RECALCDATA, 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");
"Rest Position", 10,180,150,20, &arm->flag, 0, 0, 0, 0, "Disable all animation for this object"); 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);
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"); uiDefBut(block, LABEL, 0, "Display Options", 10,140,150,20, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block); 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, "Octahedron", 10, 120,90,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, "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, 140,70,20, &arm->drawtype, 0, ARM_B_BONE, 0, 0, "Draw bones as boxes, showing subdivision and b-splines"); 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, 140,85,20, &arm->drawtype, 0, ARM_ENVELOPE, 0, 0, "Draw bones as extruded spheres, showing deformation influence volume"); 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");
uiBlockBeginAlign(block); 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_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", 160,100,150,20, &arm->flag, 0, 0, 0, 0, "Draw bone names");
uiDefButBitI(block, TOG, ARM_DRAWNAMES, REDRAWVIEW3D, "Draw Names", 110,110,100,20, &arm->flag, 0, 0, 0, 0, "Draw bone names"); uiBlockEndAlign(block);
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");
uiDefBut(block, LABEL, 0, "Deform Options", 10,80,150,20, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block); 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"); 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");
} }
static void editing_panel_armature_bones(Object *ob, bArmature *arm) 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"); 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 */ /* 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"); 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, "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"); 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");
/* Hide in posemode flag */ 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+223,by-38,110,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in Edit Mode"); 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); uiBlockEndAlign(block);
by-=60; 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"); 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 */ /* 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"); 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, "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"); 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");
/* Hide in posemode flag */ 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+223,by-38,110,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in posemode"); 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); uiBlockEndAlign(block);
by-=60; by-=60;