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)
{
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; i<numVerts; i++) {
MDeformVert *dvert;
float *co = vertexCos[i];
float vec[3];
float contrib=0.0;
@ -707,17 +714,28 @@ void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3],
/* Apply the object's matrix */
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];
for (j=0; j<dvert->totweight; 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);

@ -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) {

@ -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

@ -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;