Animato: Groundwork for getting Action Constraint functional again
authorJoshua Leung <aligorith@gmail.com>
Thu, 29 Jan 2009 11:22:34 +0000 (11:22 +0000)
committerJoshua Leung <aligorith@gmail.com>
Thu, 29 Jan 2009 11:22:34 +0000 (11:22 +0000)
Currently this still works really badly, but I'm not sure of the exact cause yet.

source/blender/blenkernel/BKE_action.h
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/anim_sys.c
source/blender/blenkernel/intern/constraint.c

index 9ef91d60e89f34adcae23be0ebda8316a0d712f7..9abacf862c5726a2ae99e1ba5b67d673cd2e1868 100644 (file)
@@ -123,17 +123,8 @@ void update_pose_constraint_flags(struct bPose *pose);
 // XXX to be depreceated for a more general solution in animsys...
 void framechange_poses_clear_unkeyed(void);
 
-/**
- * Set the pose channels from the given action.
- */
-// XXX old crap
-void extract_pose_from_action(struct bPose *pose, struct bAction *act, float ctime);
-
-/**
- * Get the effects of the given action using a workob 
- */
-// XXX old crap, used for action constraint though!
-void what_does_obaction(struct Scene *scene, struct Object *ob, struct Object *workob, struct bAction *act, float cframe);
+/* Used for the Action Constraint */
+void what_does_obaction(struct Scene *scene, struct Object *ob, struct Object *workob, struct bPose *pose, struct bAction *act, float cframe);
 
 /* exported for game engine */
 void blend_poses(struct bPose *dst, struct bPose *src, float srcweight, short mode);
index eb68b1f3a6a6aa9bad816ee8da5f19c4fc97a0ce..3758f9ba0db852bb10037ff2ebe9ae3eaf38bb7a 100644 (file)
@@ -45,6 +45,7 @@
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 
+#include "BKE_animsys.h"
 #include "BKE_action.h"
 #include "BKE_anim.h"
 #include "BKE_armature.h"
@@ -610,46 +611,6 @@ void extract_pose_from_pose(bPose *pose, const bPose *src)
        }
 }
 
-/* Pose should exist, can have any number of channels too (used for constraint) */
-void extract_pose_from_action(bPose *pose, bAction *act, float ctime) 
-{
-#if 0  // XXX old animation system
-       bActionChannel *achan;
-       bPoseChannel    *pchan;
-       Ipo                             *ipo;
-
-       if (!act)
-               return;
-       if (!pose)
-               return;
-       
-       /* Copy the data from the action into the pose */
-       for (pchan= pose->chanbase.first; pchan; pchan=pchan->next) {
-               /* skip this pose channel if it has been tagged as having unkeyed poses */
-               if ((pchan->bone) && (pchan->bone->flag & BONE_UNKEYED)) 
-                       continue;
-               
-               /* get action channel and clear pchan-transform flags */
-               achan= get_action_channel(act, pchan->name);
-               pchan->flag &= ~(POSE_LOC|POSE_ROT|POSE_SIZE);
-               
-               if (achan) {
-                       ipo = achan->ipo;
-                       if (ipo) {
-                               /* Evaluates and sets the internal ipo value */
-                               calc_ipo(ipo, ctime);
-                               /* This call also sets the pchan flags */
-                               execute_action_ipo(achan, pchan);
-                       }
-                       /* 0 = do all ipos, not only drivers */
-                       do_constraint_channels(&pchan->constraints, &achan->constraintChannels, ctime, 0);
-               }
-       }
-#endif // XXX old animation system
-       
-       pose->ctime= ctime;     /* used for cyclic offset matching */
-}
-
 /* for do_all_pose_actions, clears the pose. Now also exported for proxy and tools */
 void rest_pose(bPose *pose)
 {
@@ -708,6 +669,50 @@ void copy_pose_result(bPose *to, bPose *from)
        }
 }
 
+/* For the calculation of the effects of an Action at the given frame on an object 
+ * This is currently only used for the Action Constraint 
+ */
+void what_does_obaction (Scene *scene, Object *ob, Object *workob, bPose *pose, bAction *act, float cframe)
+{
+       AnimData adt;
+       
+       /* clear workob and animdata */
+       clear_workob(workob);
+       memset(&adt, 0, sizeof(AnimData));
+       
+       /* init workob */
+       Mat4CpyMat4(workob->obmat, ob->obmat);
+       Mat4CpyMat4(workob->parentinv, ob->parentinv);
+       Mat4CpyMat4(workob->constinv, ob->constinv);
+       workob->parent= ob->parent;
+       workob->track= ob->track;
+
+       workob->trackflag= ob->trackflag;
+       workob->upflag= ob->upflag;
+       
+       workob->partype= ob->partype;
+       workob->par1= ob->par1;
+       workob->par2= ob->par2;
+       workob->par3= ob->par3;
+
+       workob->constraints.first = ob->constraints.first;
+       workob->constraints.last = ob->constraints.last;
+       
+       workob->pose= pose;     /* need to set pose too, since this is used for both types of Action Constraint */
+
+       strcpy(workob->parsubstr, ob->parsubstr);
+       strcpy(workob->id.name, "OB<ConstrWorkOb>"); /* we don't use real object name, otherwise RNA screws with the real thing */
+       
+       /* init animdata, and attach to workob */
+       workob->adt= &adt;
+       
+       adt.recalc= ADT_RECALC_ANIM;
+       adt.action= act;
+       
+       /* execute effects of Action on to workob (or it's PoseChannels) */
+       BKE_animsys_evaluate_animdata(workob, &adt, cframe, ADT_RECALC_ANIM);
+}
+
 /* ********** NLA with non-poses works with ipo channels ********** */
 
 #if 0 // XXX OLD ANIMATION SYSTEM (TO BE REMOVED)
@@ -1162,45 +1167,6 @@ static Object *get_parent_path(Object *ob)
 
 /* ************** do the action ************ */
 
-/* For the calculation of the effects of an action at the given frame on an object 
- * This is currently only used for the action constraint 
- */
-void what_does_obaction (Scene *scene, Object *ob, Object *workob, bAction *act, float cframe)
-{
-       ListBase tchanbase= {NULL, NULL};
-       
-       clear_workob(workob);
-       Mat4CpyMat4(workob->obmat, ob->obmat);
-       Mat4CpyMat4(workob->parentinv, ob->parentinv);
-       Mat4CpyMat4(workob->constinv, ob->constinv);
-       workob->parent= ob->parent;
-       workob->track= ob->track;
-
-       workob->trackflag= ob->trackflag;
-       workob->upflag= ob->upflag;
-       
-       workob->partype= ob->partype;
-       workob->par1= ob->par1;
-       workob->par2= ob->par2;
-       workob->par3= ob->par3;
-
-       workob->constraints.first = ob->constraints.first;
-       workob->constraints.last = ob->constraints.last;
-
-       strcpy(workob->parsubstr, ob->parsubstr);
-       strcpy(workob->id.name, ob->id.name);
-       
-       /* extract_ipochannels_from_action needs id's! */
-       workob->action= act;
-       
-       extract_ipochannels_from_action(&tchanbase, &workob->id, act, "Object", bsystem_time(scene, workob, cframe, 0.0));
-       
-       if (tchanbase.first) {
-               execute_ipochannels(&tchanbase);
-               BLI_freelistN(&tchanbase);
-       }
-}
-
 /* ----- nla, etc. --------- */
 
 static void do_nla(Scene *scene, Object *ob, int blocktype)
index a0b329f9bcb3daebaf620e6e6575e55927289638..0029543ff2ee8993eaa68bd6717d9c9be309f336 100644 (file)
@@ -229,6 +229,8 @@ static short animsys_write_rna_setting (PointerRNA *ptr, char *path, int array_i
        }
        else {
                /* failed to get path */
+               // XXX don't tag as failed yet though, as there are some legit situations (Action Constraint) 
+               // where some channels will not exist, but shouldn't lock up Action
                printf("Animato: Invalid path. ID = '%s',  '%s [%d]' \n", 
                        (ptr && ptr->id.data) ? (((ID *)ptr->id.data)->name+2) : "<No ID>", 
                        path, array_index);
index 912bc7ab3bd9e87b5dd4f082f55f59545139bf20..53ea9032087a98349bd32a70618c926c17d7e97a 100644 (file)
@@ -1882,20 +1882,28 @@ static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraint
                CLAMP(s, 0, 1);
                t = ( s * (data->end-data->start)) + data->start;
                
+               // xxx temp debugging string
+               printf("do Action Constraint %s - Ob %s Pchan %s \n", con->name, cob->ob->id.name+2, (cob->pchan)?cob->pchan->name:NULL);
+               
                /* Get the appropriate information from the action */
                if (cob->type == CONSTRAINT_OBTYPE_BONE) {
+                       Object workob;
                        bPose *pose;
                        bPoseChannel *pchan, *tchan;
                        
                        /* make a temporary pose and evaluate using that */
                        pose = MEM_callocN(sizeof(bPose), "pose");
                        
+                       /* make a copy of the bone of interest in the temp pose */
                        pchan = cob->pchan;
                        tchan= verify_pose_channel(pose, pchan->name);
-                       extract_pose_from_action(pose, data->act, t);
                        
-                       chan_calc_mat(tchan);
+                       /* evaluate action using workob (it will only set the PoseChannel in question) */
+                       // XXX we need some flags to prevent evaluation from setting disabled flags on all other settings
+                       what_does_obaction(cob->scene, cob->ob, &workob, pose, data->act, t);
                        
+                       /* convert animation to matrices for use here */
+                       chan_calc_mat(tchan);
                        Mat4CpyMat4(ct->matrix, tchan->chan_mat);
                        
                        /* Clean up */
@@ -1903,8 +1911,9 @@ static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraint
                }
                else if (cob->type == CONSTRAINT_OBTYPE_OBJECT) {
                        Object workob;
+                       
                        /* evaluate using workob */
-                       //what_does_obaction(cob->scene, cob->ob, &workob, data->act, t); // FIXME: missing func...
+                       what_does_obaction(cob->scene, cob->ob, &workob, NULL, data->act, t);
                        object_to_mat4(&workob, ct->matrix);
                }
                else {