diff options
-rw-r--r-- | source/blender/blenkernel/BKE_lattice.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/armature.c | 25 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 33 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_modifier_types.h | 3 | ||||
-rw-r--r-- | source/blender/src/buttons_editing.c | 4 |
5 files changed, 59 insertions, 10 deletions
diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h index 3dc4b49b52b..bf505fa23d7 100644 --- a/source/blender/blenkernel/BKE_lattice.h +++ b/source/blender/blenkernel/BKE_lattice.h @@ -64,8 +64,8 @@ void lattice_deform_verts(struct Object *laOb, struct Object *target, int numVerts, char *vgroup); void armature_deform_verts(struct Object *armOb, struct Object *target, struct DerivedMesh *dm, float (*vertexCos)[3], - float (*defMats)[3][3], int numVerts, - int deformflag, const char *defgrp_name); + float (*defMats)[3][3], int numVerts, int deformflag, + float (*prevCos)[3], const char *defgrp_name); float (*lattice_getVertexCos(struct Object *ob, int *numVerts_r))[3]; void lattice_applyVertexCos(struct Object *ob, float (*vertexCos)[3]); void lattice_calc_modifiers(struct Object *ob); diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index f688c573bc8..477ee982138 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -790,7 +790,8 @@ static void pchan_bone_deform(bPoseChannel *pchan, float weight, float *vec, Dua void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, float (*vertexCos)[3], float (*defMats)[3][3], - int numVerts, int deformflag, const char *defgrp_name) + int numVerts, int deformflag, + float (*prevCos)[3], const char *defgrp_name) { bPoseChannel *pchan, **defnrToPC = NULL; MDeformVert *dverts = NULL; @@ -881,11 +882,12 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, for(i = 0; i < numVerts; i++) { MDeformVert *dvert; DualQuat sumdq, *dq = NULL; - float *co = vertexCos[i], dco[3]; + float *co, dco[3]; float sumvec[3], summat[3][3]; float *vec = NULL, (*smat)[3] = NULL; float contrib = 0.0f; - float armature_weight = 1.0f; /* default to 1 if no overall def group */ + float armature_weight = 1.0f; /* default to 1 if no overall def group */ + float prevco_weight = 1.0f; /* weight for optional cached vertexcos */ int j; if(use_quaternion) { @@ -917,11 +919,19 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, break; } } + /* hackish: the blending factor can be used for blending with prevCos too */ + if(prevCos) { + prevco_weight= armature_weight; + armature_weight= 1.0f; + } } /* check if there's any point in calculating for this vert */ if(armature_weight == 0.0f) continue; + /* get the coord we work on */ + co= prevCos?prevCos[i]:vertexCos[i]; + /* Apply the object's matrix */ Mat4MulVecfl(premat, co); @@ -1005,6 +1015,15 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, /* always, check above code */ Mat4MulVecfl(postmat, co); + + + /* interpolate with previous modifier position using weight group */ + if(prevCos && prevco_weight!=1.0f) { + float mw= 1.0f - prevco_weight; + vertexCos[i][0]= mw*vertexCos[i][0] + prevco_weight*co[0]; + vertexCos[i][1]= mw*vertexCos[i][1] + prevco_weight*co[1]; + vertexCos[i][2]= mw*vertexCos[i][2] + prevco_weight*co[2]; + } } if(dualquats) MEM_freeN(dualquats); diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index c2f3880ec19..3a6611a2be7 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -238,12 +238,29 @@ static void latticeModifier_updateDepgraph(ModifierData *md, DagForest *forest, } } +static void modifier_vgroup_cache(ModifierData *md, float (*vertexCos)[3]) +{ + md= md->next; + if(md) { + if(md->type==eModifierType_Armature) { + ArmatureModifierData *amd = (ArmatureModifierData*) md; + if(amd->multi) + amd->prevCos= MEM_dupallocN(vertexCos); + } + /* lattice/mesh modifier too */ + } +} + + static void latticeModifier_deformVerts( ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { LatticeModifierData *lmd = (LatticeModifierData*) md; + + modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */ + lattice_deform_verts(lmd->object, ob, derivedData, vertexCos, numVerts, lmd->name); } @@ -4664,8 +4681,16 @@ static void armatureModifier_deformVerts( { ArmatureModifierData *amd = (ArmatureModifierData*) md; + modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */ + armature_deform_verts(amd->object, ob, derivedData, vertexCos, NULL, - numVerts, amd->deformflag, amd->defgrp_name); + numVerts, amd->deformflag, + amd->prevCos, amd->defgrp_name); + /* free cache */ + if(amd->prevCos) { + MEM_freeN(amd->prevCos); + amd->prevCos= NULL; + } } static void armatureModifier_deformVertsEM( @@ -4678,7 +4703,7 @@ static void armatureModifier_deformVertsEM( if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data); armature_deform_verts(amd->object, ob, dm, vertexCos, NULL, numVerts, - amd->deformflag, amd->defgrp_name); + amd->deformflag, NULL, amd->defgrp_name); if(!derivedData) dm->release(dm); } @@ -4694,7 +4719,7 @@ static void armatureModifier_deformMatricesEM( if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data); armature_deform_verts(amd->object, ob, dm, vertexCos, defMats, numVerts, - amd->deformflag, amd->defgrp_name); + amd->deformflag, NULL, amd->defgrp_name); if(!derivedData) dm->release(dm); } @@ -5241,6 +5266,8 @@ static void meshdeformModifier_deformVerts( else dm= derivedData; + modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */ + meshdeformModifier_do(md, ob, dm, vertexCos, numVerts); if(dm != derivedData) diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index c55ae752ffb..0802fbf0e40 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -313,9 +313,10 @@ typedef struct WaveModifierData { typedef struct ArmatureModifierData { ModifierData modifier; - short deformflag, pad1; /* deformflag replaces armature->deformflag */ + short deformflag, multi; /* deformflag replaces armature->deformflag */ int pad2; struct Object *object; + float *prevCos; /* stored input of previous modifier, for vertexgroup blending */ char defgrp_name[32]; } ArmatureModifierData; diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index c6c5668fdbd..9dcd7f9921b 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -1957,8 +1957,10 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco ArmatureModifierData *amd = (ArmatureModifierData*) md; uiDefIDPoinBut(block, modifier_testArmatureObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &amd->object, "Armature object to deform with"); - but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &amd->defgrp_name, 0.0, 31.0, 0, 0, "Vertex Group name to control overall armature influence"); + but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth-40,19, &amd->defgrp_name, 0.0, 31.0, 0, 0, "Vertex Group name to control overall armature influence"); uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob); + uiDefButS(block, TOG, B_ARM_RECALCDATA, "MM", lx+buttonWidth-40,cy, 40, 20, &amd->multi, 0, 0, 0, 0, "MultiModifier: This modifier uses same input as previous modifier, and mixes using this vgroup"); + 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/2,20, &amd->deformflag, 0, 0, 0, 0, "Enable deform rotation interpolation with Quaternions"); |