small merge needed for testing new animsys in 2.5 BGE, mixing own changes with merge...
[blender.git] / source / blender / blenkernel / intern / depsgraph.c
index 01dd6c0c6578b1391f5d8d2535e75307e3335f4f..dfe3b7ea27943f5d2ca8301c4290a21f683c7709 100644 (file)
 #include "BLI_winstuff.h"
 #endif
 
-//#include "BMF_Api.h"
-
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
 
+#include "DNA_anim_types.h"
 #include "DNA_action_types.h"
 #include "DNA_armature_types.h"
 #include "DNA_curve_types.h"
@@ -54,7 +53,7 @@
 #include "DNA_object_types.h"
 #include "DNA_object_force.h"
 #include "DNA_object_fluidsim.h"
-#include "DNA_oops_types.h"
+#include "DNA_outliner_types.h"
 #include "DNA_particle_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
@@ -302,48 +301,36 @@ DagForest * dag_init()
        return forest;
 }
 
-static void dag_add_driver_relation(Ipo *ipo, DagForest *dag, DagNode *node, int isdata)
+/* isdata = object data... */
+// XXX this needs to be extended to be more flexible (so that not only objects are evaluated via depsgraph)...
+static void dag_add_driver_relation(AnimData *adt, DagForest *dag, DagNode *node, int isdata)
 {
-       IpoCurve *icu;
+       FCurve *fcu;
        DagNode *node1;
        
-       for(icu= ipo->curve.first; icu; icu= icu->next) {
-               if(icu->driver) {
-
-                       if (icu->driver->type == IPO_DRIVER_TYPE_PYTHON) {
-
-                               if ((icu->driver->flag & IPO_DRIVER_FLAG_INVALID) || (icu->driver->name[0] == '\0'))
-                                       continue; /* empty or invalid expression */
-#ifndef DISABLE_PYTHON
-                               else {
-                                       /* now we need refs to all objects mentioned in this
-                                        * pydriver expression, to call 'dag_add_relation'
-                                        * for each of them */
-                                       Object **obarray = BPY_pydriver_get_objects(icu->driver);
-                                       if (obarray) {
-                                               Object *ob, **oba = obarray;
-
-                                               while (*oba) {
-                                                       ob = *oba;
-                                                       node1 = dag_get_node(dag, ob);
-                                                       if (ob->type == OB_ARMATURE)
-                                                               dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Python Ipo Driver");
-                                                       else
-                                                               dag_add_relation(dag, node1, node, isdata?DAG_RL_OB_DATA:DAG_RL_OB_OB, "Python Ipo Driver");
-                                                       oba++;
-                                               }
-
-                                               MEM_freeN(obarray);
-                                       }
+       for (fcu= adt->drivers.first; fcu; fcu= fcu->next) {
+               ChannelDriver *driver= fcu->driver;
+               DriverTarget *dtar;
+               
+               /* loop over targets, adding relationships as appropriate */
+               for (dtar= driver->targets.first; dtar; dtar= dtar->next) {
+                       if (dtar->id) {
+                               if (GS(dtar->id->name)==ID_OB) {
+                                       Object *ob= (Object *)dtar->id;
+                                       
+                                       /* normal channel-drives-channel */
+                                       node1 = dag_get_node(dag, dtar->id);
+                                       
+                                       /* check if bone... */
+                                       if ((ob->type==OB_ARMATURE) && dtar->rna_path && strstr(dtar->rna_path, "pose.pose_channels["))
+                                               dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Driver");
+                                       /* check if ob data */
+                                       else if (dtar->rna_path && strstr(dtar->rna_path, "data."))
+                                               dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Driver");
+                                       /* normal */
+                                       else
+                                               dag_add_relation(dag, node1, node, isdata?DAG_RL_OB_DATA:DAG_RL_OB_OB, "Driver");
                                }
-#endif /* DISABLE_PYTHON */
-                       }
-                       else if (icu->driver->ob) {
-                               node1 = dag_get_node(dag, icu->driver->ob);
-                               if(icu->driver->blocktype==ID_AR)
-                                       dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Ipo Driver");
-                               else
-                                       dag_add_relation(dag, node1, node, isdata?DAG_RL_OB_DATA:DAG_RL_OB_OB, "Ipo Driver");
                        }
                }
        }
@@ -370,7 +357,6 @@ static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Objec
 static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, Object *ob, int mask)
 {
        bConstraint *con;
-       bConstraintChannel *conchan;
        DagNode * node;
        DagNode * node2;
        DagNode * node3;
@@ -425,35 +411,11 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
        }
        
        /* driver dependencies, nla modifiers */
-       if(ob->ipo) 
-               dag_add_driver_relation(ob->ipo, dag, node, 0);
-       
-       key= ob_get_key(ob);
-       if(key && key->ipo)
-               dag_add_driver_relation(key->ipo, dag, node, 1);
-       
-       for (conchan=ob->constraintChannels.first; conchan; conchan=conchan->next)
-               if(conchan->ipo)
-                       dag_add_driver_relation(conchan->ipo, dag, node, 0);
-
-       if(ob->action) {
-               bActionChannel *chan;
-               for (chan = ob->action->chanbase.first; chan; chan=chan->next){
-                       if(chan->ipo)
-                               dag_add_driver_relation(chan->ipo, dag, node, 1);
-                       for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next)
-                               if(conchan->ipo)
-                                       dag_add_driver_relation(conchan->ipo, dag, node, 1);
-               }
-       }
+#if 0 // XXX old animation system
        if(ob->nlastrips.first) {
                bActionStrip *strip;
                bActionChannel *chan;
                for(strip= ob->nlastrips.first; strip; strip= strip->next) {
-                       if(strip->act && strip->act!=ob->action)
-                               for (chan = strip->act->chanbase.first; chan; chan=chan->next)
-                                       if(chan->ipo)
-                                               dag_add_driver_relation(chan->ipo, dag, node, 1);
                        if(strip->modifiers.first) {
                                bActionModifier *amod;
                                for(amod= strip->modifiers.first; amod; amod= amod->next) {
@@ -465,6 +427,14 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
                        }
                }
        }
+#endif // XXX old animation system
+       if (ob->adt)
+               dag_add_driver_relation(ob->adt, dag, node, (ob->type == OB_ARMATURE)); // XXX isdata arg here doesn't give an accurate picture of situation
+               
+       key= ob_get_key(ob);
+       if (key && key->adt)
+               dag_add_driver_relation(key->adt, dag, node, 1);
+
        if (ob->modifiers.first) {
                ModifierData *md;
                
@@ -514,11 +484,12 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
                dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA|DAG_RL_OB_OB, "Proxy");
                /* inverted relation, so addtoroot shouldn't be set to zero */
        }
+       
+
        if (ob->type==OB_CAMERA) {
                Camera *cam = (Camera *)ob->data;
-               if (cam->ipo) {
-                       dag_add_driver_relation(cam->ipo, dag, node, 1);
-               }
+               if (cam->adt)
+                       dag_add_driver_relation(cam->adt, dag, node, 1);
                if (cam->dof_ob) {
                        node2 = dag_get_node(dag, cam->dof_ob);
                        dag_add_relation(dag,node2,node,DAG_RL_OB_OB, "Camera DoF");
@@ -526,10 +497,10 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
        }
        if (ob->type==OB_LAMP) {
                Lamp *la = (Lamp *)ob->data;
-               if (la->ipo) {
-                       dag_add_driver_relation(la->ipo, dag, node, 1);
-               }
+               if (la->adt)
+                       dag_add_driver_relation(la->adt, dag, node, 1);
        }
+       
        if (ob->transflag & OB_DUPLI) {
                if((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) {
                        GroupObject *go;
@@ -565,9 +536,8 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
                        node2 = dag_get_node(dag, cu->taperobj);
                        dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Curve Taper");
                }
-               if(cu->ipo)
-                       dag_add_driver_relation(cu->ipo, dag, node, 1);
-
+               if (cu->adt)
+                       dag_add_driver_relation(cu->adt, dag, node, 1);
        }
        else if(ob->type==OB_FONT) {
                Curve *cu= ob->data;
@@ -1952,25 +1922,28 @@ static int object_modifiers_use_time(Object *ob)
        return 0;
 }
 
-static int exists_channel(Object *ob, char *name)
+static short animdata_use_time(AnimData *adt)
 {
-       bActionStrip *strip;
+       NlaTrack *nlt;
        
-       if(ob->action)
-               if(get_action_channel(ob->action, name))
-                       return 1;
+       if(adt==NULL) return 0;
        
-       for (strip=ob->nlastrips.first; strip; strip=strip->next)
-               if(get_action_channel(strip->act, name))
+       /* check action - only if assigned, and it has anim curves */
+       if (adt->action && adt->action->curves.first)
+               return 1;
+       
+       /* check NLA tracks + strips */
+       for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) {
+               if (nlt->strips.first)
                        return 1;
+       }
+       
        return 0;
 }
 
 static void dag_object_time_update_flags(Object *ob)
 {
-       
-       if(ob->ipo) ob->recalc |= OB_RECALC_OB;
-       else if(ob->constraints.first) {
+       if(ob->constraints.first) {
                bConstraint *con;
                for (con = ob->constraints.first; con; con=con->next) {
                        bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
@@ -2000,14 +1973,9 @@ static void dag_object_time_update_flags(Object *ob)
                if(ob->parent->type==OB_CURVE || ob->parent->type==OB_ARMATURE) ob->recalc |= OB_RECALC_OB;
        }
        
-       if(ob->action || ob->nlastrips.first) {
-               /* since actions now are mixed, we set the recalcs on the safe side */
-               ob->recalc |= OB_RECALC_OB;
-               if(ob->type==OB_ARMATURE)
-                       ob->recalc |= OB_RECALC_DATA;
-               else if(exists_channel(ob, "Shape"))
-                       ob->recalc |= OB_RECALC_DATA;
-               else if(ob->dup_group) {
+#if 0 // XXX old animation system
+       if(ob->nlastrips.first) {
+               if(ob->dup_group) {
                        bActionStrip *strip;
                        /* this case is for groups with nla, whilst nla target has no action or nla */
                        for(strip= ob->nlastrips.first; strip; strip= strip->next) {
@@ -2016,6 +1984,14 @@ static void dag_object_time_update_flags(Object *ob)
                        }
                }
        }
+#endif // XXX old animation system
+       
+       if(animdata_use_time(ob->adt)) {
+               ob->recalc |= OB_RECALC;
+               ob->adt->recalc |= ADT_RECALC_ANIM;
+       }
+       
+       if((ob->adt) && (ob->type==OB_ARMATURE)) ob->recalc |= OB_RECALC_DATA;
        
        if(object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA;
        if((ob->pose) && (ob->pose->flag & POSE_CONSTRAINTS_TIMEDEPEND)) ob->recalc |= OB_RECALC_DATA;
@@ -2291,6 +2267,7 @@ void DAG_pose_sort(Object *ob)
                        ListBase targets = {NULL, NULL};
                        bConstraintTarget *ct;
                        
+#if 0 // XXX old animation system... driver stuff to watch out for
                        if(con->ipo) {
                                IpoCurve *icu;
                                for(icu= con->ipo->curve.first; icu; icu= icu->next) {
@@ -2302,7 +2279,7 @@ void DAG_pose_sort(Object *ob)
                                                if(target) {
                                                        node2 = dag_get_node(dag, target);
                                                        dag_add_relation(dag, node2, node, 0, "Ipo Driver");
-
+                                                       
                                                        /* uncommented this line, results in dependencies
                                                         * not being added properly for this constraint,
                                                         * what is the purpose of this? - brecht */
@@ -2311,6 +2288,7 @@ void DAG_pose_sort(Object *ob)
                                        }
                                }
                        }
+#endif // XXX old animation system... driver stuff to watch out for
                        
                        if (cti && cti->get_constraint_targets) {
                                cti->get_constraint_targets(con, &targets);