Hook Modifier - Bone Targets
authorJoshua Leung <aligorith@gmail.com>
Fri, 21 Aug 2009 10:47:27 +0000 (10:47 +0000)
committerJoshua Leung <aligorith@gmail.com>
Fri, 21 Aug 2009 10:47:27 +0000 (10:47 +0000)
Made Hook Modifier be able to use bone targets. However, I haven't been able to verify that everything will work perfectly, since just creating a new Hook Modifier and assigning targets doesn't set hmd->indexar correctly.

release/ui/buttons_data_modifier.py
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/modifier.c
source/blender/editors/object/object_edit.c
source/blender/editors/object/object_modifier.c
source/blender/makesdna/DNA_modifier_types.h
source/blender/makesrna/intern/rna_modifier.c

index cc50256f216ddadff99603fc30998abc824df9be..f5af26f874658f7082a190e939b0ac27def7dbda 100644 (file)
@@ -200,7 +200,11 @@ class DATA_PT_modifiers(DataButtonsPanel):
                layout.itemL(text="See Fluid panel.")
                
        def HOOK(self, layout, ob, md):
-               layout.itemR(md, "object")
+               col = layout.column()
+               col.itemR(md, "object")
+               if md.object and md.object.type == "ARMATURE":
+                       layout.item_pointerR(md, "subtarget", md.object.data, "bones", text="Bone")
+               
                layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 
                split = layout.split()
index f4d4eb1cc9c3109b4a86100f197142b4082440fc..6a39139d2505253ed6bc7054f8f809b9e5c7f851 100644 (file)
@@ -410,8 +410,9 @@ bActionGroup *action_groups_find_named (bAction *act, const char name[])
 bPoseChannel *get_pose_channel(const bPose *pose, const char *name)
 {
        bPoseChannel *chan;
-
-       if (pose==NULL) return NULL;
+       
+       if (ELEM(NULL, pose, name) || (name[0] == 0))
+               return NULL;
        
        for (chan=pose->chanbase.first; chan; chan=chan->next) {
                if (chan->name[0] == name[0]) {
index 37cf427b8972bdc0fe9679c69648989a3f634a61..501638aba0d1d8362cc2fdcb206f340283c3fb14 100644 (file)
@@ -5598,6 +5598,7 @@ static void hookModifier_copyData(ModifierData *md, ModifierData *target)
        thmd->indexar = MEM_dupallocN(hmd->indexar);
        memcpy(thmd->parentinv, hmd->parentinv, sizeof(hmd->parentinv));
        strncpy(thmd->name, hmd->name, 32);
+       strncpy(thmd->subtarget, hmd->subtarget, 32);
 }
 
 CustomDataMask hookModifier_requiredDataMask(Object *ob, ModifierData *md)
@@ -5642,9 +5643,11 @@ static void hookModifier_updateDepgraph(ModifierData *md, DagForest *forest, Sce
 
        if (hmd->object) {
                DagNode *curNode = dag_get_node(forest, hmd->object);
-
-               dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA,
-                       "Hook Modifier");
+               
+               if (hmd->subtarget[0])
+                       dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA|DAG_RL_DATA_DATA, "Hook Modifier");
+               else
+                       dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA, "Hook Modifier");
        }
 }
 
@@ -5653,12 +5656,22 @@ static void hookModifier_deformVerts(
         float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
 {
        HookModifierData *hmd = (HookModifierData*) md;
-       float vec[3], mat[4][4];
+       bPoseChannel *pchan= get_pose_channel(hmd->object->pose, hmd->subtarget);
+       float vec[3], mat[4][4], dmat[4][4], imat[4][4];
        int i;
        DerivedMesh *dm = derivedData;
-
-       Mat4Invert(ob->imat, ob->obmat);
-       Mat4MulSerie(mat, ob->imat, hmd->object->obmat, hmd->parentinv,
+       
+       /* get world-space matrix of target, corrected for the space the verts are in */
+       if (hmd->subtarget[0] && pchan) {
+               /* bone target if there's a matching pose-channel */
+               Mat4MulMat4(dmat, pchan->pose_mat, hmd->object->obmat);
+       }
+       else {
+               /* just object target */
+               Mat4CpyMat4(dmat, hmd->object->obmat);
+       }
+       Mat4Invert(imat, dmat);
+       Mat4MulSerie(mat, imat, dmat, hmd->parentinv,
                     NULL, NULL, NULL, NULL, NULL);
 
        /* vertex indices? */
index 2fb9835f833b59365ec11e3c1a3adf34d6d4bdc0..e1b8858937c389f26c51156e8219c2e7891dca59 100644 (file)
@@ -979,6 +979,9 @@ static void select_editmesh_hook(Object *ob, HookModifierData *hmd)
        EditVert *eve;
        int index=0, nr=0;
        
+       if (hmd->indexar == NULL)
+               return;
+       
        for(eve= em->verts.first; eve; eve= eve->next, nr++) {
                if(nr==hmd->indexar[index]) {
                        eve->f |= SELECT;
@@ -1361,6 +1364,7 @@ void add_hook(Scene *scene, View3D *v3d, int mode)
                        hmd->totindex= tot;
                        BLI_strncpy(hmd->name, name, 32);
                        
+                       // TODO: need to take into account bone targets here too now...
                        if(mode==1 || mode==2) {
                                /* matrix calculus */
                                /* vert x (obmat x hook->imat) x hook->obmat x ob->imat */
index 32a1297aaf44b62f656ae29890087fce1943e360..3785e17f67cdaf527b86165599766daafe2eba36 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "DNA_action_types.h"
 #include "DNA_curve_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
@@ -42,6 +43,7 @@
 #include "BLI_arithb.h"
 #include "BLI_listbase.h"
 
+#include "BKE_action.h"
 #include "BKE_curve.h"
 #include "BKE_context.h"
 #include "BKE_depsgraph.h"
@@ -853,8 +855,21 @@ static int hook_reset_exec(bContext *C, wmOperator *op)
        HookModifierData *hmd= ptr.data;
 
        if(hmd->object) {
-               Mat4Invert(hmd->object->imat, hmd->object->obmat);
-               Mat4MulSerie(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
+               bPoseChannel *pchan= get_pose_channel(hmd->object->pose, hmd->subtarget);
+               
+               if(hmd->subtarget[0] && pchan) {
+                       float imat[4][4], mat[4][4];
+                       
+                       /* calculate the world-space matrix for the pose-channel target first, then carry on as usual */
+                       Mat4MulMat4(mat, pchan->pose_mat, hmd->object->obmat);
+                       
+                       Mat4Invert(imat, mat);
+                       Mat4MulSerie(hmd->parentinv, imat, mat, NULL, NULL, NULL, NULL, NULL, NULL);
+               }
+               else {
+                       Mat4Invert(hmd->object->imat, hmd->object->obmat);
+                       Mat4MulSerie(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
+               }
        }
 
        DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
index 912d11dcc8c88225f34b709bb4db237c9954e536..a4587c34e89aa09ea63e39f0cefa0e29a7bc130e 100644 (file)
@@ -426,6 +426,8 @@ typedef struct HookModifierData {
        ModifierData modifier;
 
        struct Object *object;
+       char subtarget[32];             /* optional name of bone target */
+       
        float parentinv[4][4];  /* matrix making current transform unmodified */
        float cent[3];                  /* visualization of hook */
        float falloff;                  /* if not zero, falloff is distance where influence zero */
index c080b88feafc6913491287c1bd04eef1231c3149..bfd93a4218b331e794d342675e70a5847c5b8e59 100644 (file)
@@ -912,6 +912,11 @@ static void rna_def_modifier_hook(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Object", "Parent Object for hook, also recalculates and clears offset");
        RNA_def_property_flag(prop, PROP_EDITABLE);
        RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update");
+       
+       prop= RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE);
+       RNA_def_property_string_sdna(prop, NULL, "subtarget");
+       RNA_def_property_ui_text(prop, "Sub-Target", "Name of Parent Bone for hook (if applicable), also recalculates and clears offset");
+       RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update");
 
        prop= RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
        RNA_def_property_string_sdna(prop, NULL, "name");