Bugfix #4420 + #3975
authorTon Roosendaal <ton@blender.org>
Fri, 23 Jun 2006 12:15:22 +0000 (12:15 +0000)
committerTon Roosendaal <ton@blender.org>
Fri, 23 Jun 2006 12:15:22 +0000 (12:15 +0000)
Found reasonable OK solution for a cyclic dependency that was bothering
a lot of (character) animators. They would like to drive bones with
Objects, but that lagged when you parent these Objects to the
armature, since that's a circular dependency.

Since Driver relations are only looking at local object properties (i.e.
it's local position/rotation) there's a simple way to solve it. In case
such Objects have an Ipo, it reads driver values directly from the
Object Ipo (on correct time) instead of Object values.

source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/ipo.c

index 2a177207a878dfe35f10ac51f60b723b4e516f9d..c3443e524dcd7dd17d2982fdb65a303c4304ab28 100644 (file)
@@ -745,7 +745,7 @@ void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel
                }
                itA = itA->next;
        }
-       /* create new relation and insert at head */
+       /* create new relation and insert at head. MALLOC alert! */
        itA = MEM_mallocN(sizeof(DagAdjList),"DAG adj list");
        itA->node = fob2;
        itA->type = rel;
index 6ea44b4555eb08f36722ceefffe29095cf52fc0d..ba325ee81f38564d6b40fb651f0844cba0f920c8 100644 (file)
@@ -735,7 +735,7 @@ void berekenx(float *f, float *o, int b)
 }
 
 /* has to return a float value */
-static float eval_driver(IpoDriver *driver)
+static float eval_driver(IpoDriver *driver, float ipotime)
 {
        
        if(driver->type == IPO_DRIVER_TYPE_PYTHON) {
@@ -752,6 +752,12 @@ static float eval_driver(IpoDriver *driver)
 
                if(ob==NULL) return 0.0f;
                
+               /* depsgraph failure; ob ipos are calculated in where_is_object, this might get called too late */
+               if(ob->ipo && ob->ctime!=ipotime) {
+                       calc_ipo_spec(ob->ipo, driver->adrcode, &ipotime);
+                       return ipotime;
+               }
+               
                if(driver->blocktype==ID_OB) {
                        switch(driver->adrcode) {
                        case OB_LOC_X:
@@ -837,7 +843,7 @@ float eval_icu(IpoCurve *icu, float ipotime)
        
        if(icu->driver) {
                /* ipotime now serves as input for the curve */
-               ipotime= cvalue= eval_driver(icu->driver);
+               ipotime= cvalue= eval_driver(icu->driver, ipotime);
        }
        if(icu->bezt) {
                prevbezt= icu->bezt;