Camera tracking integration
[blender.git] / source / blender / blenkernel / intern / depsgraph.c
index d39be9d683c6e645b1c53763597d8e38adad2d89..b94891ced4996e4daeba0a90b4d8b0f5530ae951 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id$
- *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
@@ -38,6 +36,7 @@
 
 #include "BLI_winstuff.h"
 #include "BLI_utildefines.h"
+#include "BLI_listbase.h"
 #include "BLI_ghash.h"
 
 #include "DNA_anim_types.h"
@@ -51,6 +50,7 @@
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_windowmanager_types.h"
+#include "DNA_movieclip_types.h"
 
 #include "BKE_animsys.h"
 #include "BKE_action.h"
@@ -301,6 +301,7 @@ static void dag_add_driver_relation(AnimData *adt, DagForest *dag, DagNode *node
        for (fcu= adt->drivers.first; fcu; fcu= fcu->next) {
                ChannelDriver *driver= fcu->driver;
                DriverVar *dvar;
+               int isdata_fcu = isdata || (fcu->rna_path && strstr(fcu->rna_path, "modifiers["));
                
                /* loop over variables to get the target relationships */
                for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
@@ -320,14 +321,14 @@ static void dag_add_driver_relation(AnimData *adt, DagForest *dag, DagNode *node
                                                        ( ((dtar->rna_path) && strstr(dtar->rna_path, "pose.bones[")) || 
                                                          ((dtar->flag & DTAR_FLAG_STRUCT_REF) && (dtar->pchan_name[0])) )) 
                                                {
-                                                       dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Driver");
+                                                       dag_add_relation(dag, node1, node, isdata_fcu?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");
+                                                       dag_add_relation(dag, node1, node, isdata_fcu?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");
+                                                       dag_add_relation(dag, node1, node, isdata_fcu?DAG_RL_OB_DATA:DAG_RL_OB_OB, "Driver");
                                        }
                                }
                        }
@@ -639,7 +640,26 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
                ListBase targets = {NULL, NULL};
                bConstraintTarget *ct;
                
-               if (cti && cti->get_constraint_targets) {
+               if(!cti)
+                       continue;
+
+               /* special case for FollowTrack -- it doesn't use targets to define relations */
+               if(ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER)) {
+                       if(cti->type==CONSTRAINT_TYPE_FOLLOWTRACK) {
+                               bFollowTrackConstraint *data= (bFollowTrackConstraint *)con->data;
+
+                               if((data->clip || data->flag&FOLLOWTRACK_ACTIVECLIP) && data->track[0]) {
+                                       if(scene->camera) {
+                                               node2 = dag_get_node(dag, scene->camera);
+                                               dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB, cti->name);
+                                       }
+                               }
+                       }
+
+                       dag_add_relation(dag,scenenode,node,DAG_RL_SCENE, "Scene Relation");
+                       addtoroot = 0;
+               }
+               else if (cti->get_constraint_targets) {
                        cti->get_constraint_targets(con, &targets);
                        
                        for (ct= targets.first; ct; ct= ct->next) {
@@ -1961,7 +1981,7 @@ static void dag_tag_renderlayers(Scene *sce, unsigned int lay)
                        if(node->id==(ID *)sce) {
                                SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1);
                                if(srl && (srl->lay & lay_changed))
-                                       NodeTagChanged(sce->nodetree, node);
+                                       nodeUpdate(sce->nodetree, node);
                        }
                }
        }
@@ -2027,17 +2047,27 @@ static int object_modifiers_use_time(Object *ob)
        /* check whether any modifiers are animated */
        if (ob->adt) {
                AnimData *adt = ob->adt;
+               FCurve *fcu;
                
                /* action - check for F-Curves with paths containing 'modifiers[' */
                if (adt->action) {
-                       FCurve *fcu;
-                       
                        for (fcu = adt->action->curves.first; fcu; fcu = fcu->next) {
                                if (fcu->rna_path && strstr(fcu->rna_path, "modifiers["))
                                        return 1;
                        }
                }
                
+               /* This here allows modifier properties to get driven and still update properly
+                *
+                * Workaround to get [#26764] (e.g. subsurf levels not updating when animated/driven)
+                * working, without the updating problems ([#28525] [#28690] [#28774] [#28777]) caused
+                * by the RNA updates cache introduced in r.38649
+                */
+               for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
+                       if (fcu->rna_path && strstr(fcu->rna_path, "modifiers["))
+                               return 1;
+               }
+               
                // XXX: also, should check NLA strips, though for now assume that nobody uses
                // that and we can omit that for performance reasons...
        }
@@ -2061,6 +2091,23 @@ static short animdata_use_time(AnimData *adt)
                        return 1;
        }
        
+       /* If we have drivers, more likely than not, on a frame change
+        * they'll need updating because their owner changed
+        * 
+        * This is kindof a hack to get around a whole host of problems
+        * involving drivers using non-object datablock data (which the 
+        * depsgraph currently has no way of representing let alone correctly
+        * dependency sort+tagging). By doing this, at least we ensure that 
+        * some commonly attempted drivers (such as scene -> current frame;
+        * see "Driver updates fail" thread on Bf-committers dated July 2)
+        * will work correctly, and that other non-object datablocks will have
+        * their drivers update at least on frame change.
+        *
+        * -- Aligorith, July 4 2011
+        */
+       if (adt->drivers.first)
+               return 1;
+       
        return 0;
 }
 
@@ -2073,18 +2120,25 @@ static void dag_object_time_update_flags(Object *ob)
                        ListBase targets = {NULL, NULL};
                        bConstraintTarget *ct;
                        
-                       if (cti && cti->get_constraint_targets) {
-                               cti->get_constraint_targets(con, &targets);
-                               
-                               for (ct= targets.first; ct; ct= ct->next) {
-                                       if (ct->tar) {
-                                               ob->recalc |= OB_RECALC_OB;
-                                               break;
+                       if (cti) {
+                               /* special case for FollowTrack -- it doesn't use targets to define relations */
+                               if(ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER)) {
+                                       ob->recalc |= OB_RECALC_OB;
+                               }
+                               else if (cti->get_constraint_targets) {
+                                       cti->get_constraint_targets(con, &targets);
+                                       
+                                       for (ct= targets.first; ct; ct= ct->next) {
+                                               if (ct->tar) {
+                                                       ob->recalc |= OB_RECALC_OB;
+                                                       break;
+                                               }
                                        }
+                                       
+                                       if (cti->flush_constraint_targets)
+                                               cti->flush_constraint_targets(con, &targets, 1);
                                }
                                
-                               if (cti->flush_constraint_targets)
-                                       cti->flush_constraint_targets(con, &targets, 1);
                        }
                }
        }
@@ -2377,7 +2431,7 @@ static void dag_id_flush_update(Scene *sce, ID *id)
        if(id) {
                idtype= GS(id->name);
 
-               if(ELEM7(idtype, ID_ME, ID_CU, ID_MB, ID_LA, ID_LT, ID_CA, ID_AR)) {
+               if(ELEM8(idtype, ID_ME, ID_CU, ID_MB, ID_LA, ID_LT, ID_CA, ID_AR, ID_SPK)) {
                        for(obt=bmain->object.first; obt; obt= obt->id.next) {
                                if(!(ob && obt == ob) && obt->data == id) {
                                        obt->recalc |= OB_RECALC_DATA;
@@ -2442,6 +2496,36 @@ static void dag_id_flush_update(Scene *sce, ID *id)
                                                BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
                }
 
+               if(idtype == ID_MC) {
+                       for(obt=bmain->object.first; obt; obt= obt->id.next){
+                               bConstraint *con;
+                               for (con = obt->constraints.first; con; con=con->next) {
+                                       bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+                                       if(ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER)) {
+                                               obt->recalc |= OB_RECALC_OB;
+                                               break;
+                                       }
+                               }
+                       }
+
+                       if(sce->nodetree) {
+                               bNode *node;
+
+                               for(node= sce->nodetree->nodes.first; node; node= node->next) {
+                                       if(node->id==id) {
+                                               nodeUpdate(sce->nodetree, node);
+                                       }
+                               }
+                       }
+               }
+
+               /* camera's matrix is used to orient reconstructed stuff,
+                  so it should happen tracking-related constraints recalculation
+                  when camera is changing */
+               if(sce->camera && &sce->camera->id == id && sce->clip) {
+                       dag_id_flush_update(sce, &sce->clip->id);
+               }
+
                /* update editors */
                dag_editors_update(bmain, id);
        }