diff options
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_ipo.h | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/depsgraph.c | 39 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/ipo.c | 164 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/key.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 39 |
6 files changed, 211 insertions, 41 deletions
diff --git a/source/blender/blenkernel/BKE_ipo.h b/source/blender/blenkernel/BKE_ipo.h index c0a5be27bcf..6acbceb8e3f 100644 --- a/source/blender/blenkernel/BKE_ipo.h +++ b/source/blender/blenkernel/BKE_ipo.h @@ -52,7 +52,10 @@ struct ID; /* struct IPO_Channel; */ float frame_to_float(int cfra); + +void free_ipo_curve(struct IpoCurve *icu); void free_ipo(struct Ipo *ipo); + struct Ipo *add_ipo(char *name, int idcode); struct Ipo *copy_ipo(struct Ipo *ipo); void make_local_obipo(struct Ipo *ipo); @@ -79,11 +82,14 @@ void *give_mtex_poin(struct MTex *mtex, int adrcode ); void *get_ipo_poin(struct ID *id, struct IpoCurve *icu, int *type); void set_icu_vars(struct IpoCurve *icu); void execute_ipo(struct ID *id, struct Ipo *ipo); + void do_ipo_nocalc(struct Ipo *ipo); void do_ipo(struct Ipo *ipo); void do_mat_ipo(struct Material *ma); void do_ob_ipo(struct Object *ob); void do_seq_ipo(struct Sequence *seq); +void do_ob_ipodrivers(struct Object *ob, struct Ipo *ipo); + int has_ipo_code(struct Ipo *ipo, int code); void do_all_data_ipos(void); int calc_ipo_spec(struct Ipo *ipo, int adrcode, float *ctime); diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 9c06c2d015d..6fd3cbcfd8b 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -756,7 +756,7 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own if(data->subtarget[0]) { pchan = get_pose_channel(data->tar->pose, data->subtarget); if (pchan) { - float arm_mat[3][3], pose_mat[3][3]; + float arm_mat[3][3], pose_mat[3][3]; /* arm mat should be bone mat! bug... */ Mat3CpyMat4(arm_mat, pchan->bone->arm_mat); Mat3CpyMat4(pose_mat, pchan->pose_mat); diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 61a0ea20a2e..45c9d0b874e 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -47,6 +47,7 @@ #include "DNA_ID.h" #include "DNA_effect_types.h" #include "DNA_lattice_types.h" +#include "DNA_key_types.h" #include "DNA_mesh_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" @@ -289,6 +290,23 @@ DagForest * dag_init() return forest; } +static void dag_add_driver_relation(Ipo *ipo, DagForest *dag, DagNode *node, int isdata) +{ + IpoCurve *icu; + DagNode *node1; + + for(icu= ipo->curve.first; icu; icu= icu->next) { + if(icu->driver && 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); + else + dag_add_relation(dag, node1, node, isdata?DAG_RL_OB_DATA:DAG_RL_OB_OB); + } + } +} + + struct DagForest *build_dag(struct Scene *sce, short mask) { Base *base; @@ -300,6 +318,7 @@ struct DagForest *build_dag(struct Scene *sce, short mask) DagNode * scenenode; DagForest *dag; DagAdjList *itA; + Key *key; dag = sce->theDag; sce->dagisvalid=1; @@ -324,9 +343,8 @@ struct DagForest *build_dag(struct Scene *sce, short mask) dag_add_relation(dag,node,node2,DAG_RL_DATA); node2->first_ancestor = ob; node2->ancestor_count += 1; - - } + if (ob->type == OB_ARMATURE) { if (ob->pose){ bPoseChannel *pchan; @@ -354,6 +372,23 @@ struct DagForest *build_dag(struct Scene *sce, short mask) } } } + + /* driver dependencies */ + 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); + + 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); + } + } + if (ob->modifiers.first) { ModifierData *md; diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index ece3e39ae1e..36f461feaf2 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -42,6 +42,7 @@ #include "MEM_guardedalloc.h" #include "DNA_action_types.h" +#include "DNA_armature_types.h" #include "DNA_curve_types.h" #include "DNA_camera_types.h" #include "DNA_lamp_types.h" @@ -184,17 +185,24 @@ float frame_to_float(int cfra) /* see also bsystem_time in object.c */ return ctime; } +/* includes ipo curve itself */ +void free_ipo_curve(IpoCurve *icu) +{ + if(icu->bezt) MEM_freeN(icu->bezt); + if(icu->bp) MEM_freeN(icu->bp); + if(icu->driver) MEM_freeN(icu->driver); + MEM_freeN(icu); +} + /* do not free ipo itself */ void free_ipo(Ipo *ipo) { IpoCurve *icu; - icu= ipo->curve.first; - while(icu) { - if(icu->bezt) MEM_freeN(icu->bezt); - icu= icu->next; + while( (icu= ipo->curve.first) ) { + BLI_remlink(&ipo->curve, icu); + free_ipo_curve(icu); } - BLI_freelistN(&ipo->curve); } Ipo *add_ipo(char *name, int idcode) @@ -212,7 +220,7 @@ Ipo *copy_ipo(Ipo *ipo) Ipo *ipon; IpoCurve *icu; - if(ipo==0) return 0; + if(ipo==NULL) return 0; ipon= copy_libblock(ipo); @@ -221,6 +229,7 @@ Ipo *copy_ipo(Ipo *ipo) icu= ipon->curve.first; while(icu) { icu->bezt= MEM_dupallocN(icu->bezt); + if(icu->driver) icu->driver= MEM_dupallocN(icu->driver); icu= icu->next; } @@ -247,7 +256,7 @@ void make_local_obipo(Ipo *ipo) ob= ob->id.next; } - if(local && lib==0) { + if(local && lib==NULL) { ipo->id.lib= 0; ipo->id.flag= LIB_LOCAL; new_id(0, (ID *)ipo, 0); @@ -260,7 +269,7 @@ void make_local_obipo(Ipo *ipo) while(ob) { if(ob->ipo==ipo) { - if(ob->id.lib==0) { + if(ob->id.lib==NULL) { ob->ipo= ipon; ipon->id.us++; ipo->id.us--; @@ -291,7 +300,7 @@ void make_local_matipo(Ipo *ipo) ma= ma->id.next; } - if(local && lib==0) { + if(local && lib==NULL) { ipo->id.lib= 0; ipo->id.flag= LIB_LOCAL; new_id(0, (ID *)ipo, 0); @@ -304,7 +313,7 @@ void make_local_matipo(Ipo *ipo) while(ma) { if(ma->ipo==ipo) { - if(ma->id.lib==0) { + if(ma->id.lib==NULL) { ma->ipo= ipon; ipon->id.us++; ipo->id.us--; @@ -335,7 +344,7 @@ void make_local_keyipo(Ipo *ipo) key= key->id.next; } - if(local && lib==0) { + if(local && lib==NULL) { ipo->id.lib= 0; ipo->id.flag= LIB_LOCAL; new_id(0, (ID *)ipo, 0); @@ -348,7 +357,7 @@ void make_local_keyipo(Ipo *ipo) while(key) { if(key->ipo==ipo) { - if(key->id.lib==0) { + if(key->id.lib==NULL) { key->ipo= ipon; ipon->id.us++; ipo->id.us--; @@ -363,7 +372,7 @@ void make_local_keyipo(Ipo *ipo) void make_local_ipo(Ipo *ipo) { - if(ipo->id.lib==0) return; + if(ipo->id.lib==NULL) return; if(ipo->id.us==1) { ipo->id.lib= 0; ipo->id.flag= LIB_LOCAL; @@ -443,7 +452,7 @@ void testhandles_ipocurve(IpoCurve *icu) int flag, a; bezt= icu->bezt; - if(bezt==0) return; + if(bezt==NULL) return; a= icu->totvert; while(a--) { @@ -675,6 +684,86 @@ void berekenx(float *f, float *o, int b) } } +static float eval_driver(IpoDriver *driver) +{ + Object *ob= driver->ob; + + if(ob==NULL) return 0.0f; + + if(driver->blocktype==ID_OB) { + switch(driver->adrcode) { + case OB_LOC_X: + return ob->loc[0]; + case OB_LOC_Y: + return ob->loc[1]; + case OB_LOC_Z: + return ob->loc[2]; + case OB_ROT_X: + return ob->rot[0]/(M_PI_2/9.0); + case OB_ROT_Y: + return ob->rot[1]/(M_PI_2/9.0); + case OB_ROT_Z: + return ob->rot[2]/(M_PI_2/9.0); + case OB_SIZE_X: + return ob->size[0]; + case OB_SIZE_Y: + return ob->size[1]; + case OB_SIZE_Z: + return ob->size[2]; + } + } + else { /* ID_AR */ + bPoseChannel *pchan= get_pose_channel(ob->pose, driver->name); + if(pchan && pchan->bone) { + float pose_mat[3][3]; + float diff_mat[3][3], par_mat[3][3], ipar_mat[3][3]; + float eul[3], size[3]; + + /* we need the local transform = current transform - (parent transform + bone transform) */ + + Mat3CpyMat4(pose_mat, pchan->pose_mat); + + if (pchan->parent) { + Mat3CpyMat4(par_mat, pchan->parent->pose_mat); + Mat3MulMat3(diff_mat, par_mat, pchan->bone->bone_mat); + + Mat3Inv(ipar_mat, diff_mat); + } + else { + Mat3Inv(ipar_mat, pchan->bone->bone_mat); + } + + Mat3MulMat3(diff_mat, ipar_mat, pose_mat); + + Mat3ToEul(diff_mat, eul); + Mat3ToSize(diff_mat, size); + + switch(driver->adrcode) { + case OB_LOC_X: + return pchan->loc[0]; + case OB_LOC_Y: + return pchan->loc[1]; + case OB_LOC_Z: + return pchan->loc[2]; + case OB_ROT_X: + return eul[0]/(M_PI_2/9.0); + case OB_ROT_Y: + return eul[1]/(M_PI_2/9.0); + case OB_ROT_Z: + return eul[2]/(M_PI_2/9.0); + case OB_SIZE_X: + return size[0]; + case OB_SIZE_Y: + return size[1]; + case OB_SIZE_Z: + return size[2]; + } + } + } + + return 0.0f; +} + float eval_icu(IpoCurve *icu, float ipotime) { BezTriple *bezt, *prevbezt; @@ -684,6 +773,10 @@ float eval_icu(IpoCurve *icu, float ipotime) cycyofs= 0.0; + if(icu->driver) { + /* ipotime now serves as input for the curve */ + ipotime= cvalue= eval_driver(icu->driver); + } if(icu->bezt) { prevbezt= icu->bezt; bezt= prevbezt+1; @@ -814,10 +907,12 @@ void calc_ipo(Ipo *ipo, float ctime) { IpoCurve *icu; + if(ipo==NULL) return; + icu= ipo->curve.first; while(icu) { - if( (icu->flag & IPO_LOCK)==0) calc_icu(icu, ctime); + if(icu->driver || (icu->flag & IPO_LOCK)==0) calc_icu(icu, ctime); icu= icu->next; } @@ -1186,7 +1281,7 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type) poin= &(ma->add); break; } - if(poin==0) { + if(poin==NULL) { mtex= 0; if(icu->adrcode & MA_MAP1) mtex= ma->mtex[0]; else if(icu->adrcode & MA_MAP2) mtex= ma->mtex[1]; @@ -1270,7 +1365,7 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type) poin= &(wo->starsize); break; } - if(poin==0) { + if(poin==NULL) { mtex= 0; if(icu->adrcode & MA_MAP1) mtex= wo->mtex[0]; else if(icu->adrcode & MA_MAP2) mtex= wo->mtex[1]; @@ -1315,7 +1410,7 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type) poin= &(la->haint); break; } - if(poin==0) { + if(poin==NULL) { mtex= 0; if(icu->adrcode & MA_MAP1) mtex= la->mtex[0]; else if(icu->adrcode & MA_MAP2) mtex= la->mtex[1]; @@ -1650,7 +1745,7 @@ void execute_ipo(ID *id, Ipo *ipo) void *poin; int type; - if(ipo==0) return; + if(ipo==NULL) return; icu= ipo->curve.first; while(icu) { @@ -1673,7 +1768,7 @@ void do_ipo_nocalc(Ipo *ipo) Camera *ca; bSound *snd; - if(ipo==0) return; + if(ipo==NULL) return; switch(ipo->blocktype) { case ID_OB: @@ -1747,7 +1842,7 @@ void do_mat_ipo(Material *ma) { float ctime; - if(ma==0 || ma->ipo==0) return; + if(ma==NULL || ma->ipo==NULL) return; ctime= frame_to_float(G.scene->r.cfra); /* if(ob->ipoflag & OB_OFFS_OB) ctime-= ob->sf; */ @@ -1762,7 +1857,7 @@ void do_ob_ipo(Object *ob) float ctime; unsigned int lay; - if(ob->ipo==0) return; + if(ob->ipo==NULL) return; /* do not set ob->ctime here: for example when parent in invisible layer */ @@ -1785,6 +1880,21 @@ void do_ob_ipo(Object *ob) } } +void do_ob_ipodrivers(Object *ob, Ipo *ipo) +{ + IpoCurve *icu; + void *poin; + int type; + + for(icu= ipo->curve.first; icu; icu= icu->next) { + if(icu->driver) { + icu->curval= eval_icu(icu, 0.0f); + poin= get_ipo_poin((ID *)ob, icu, &type); + if(poin) write_ipo_poin(poin, type, icu->curval); + } + } +} + void do_seq_ipo(Sequence *seq) { float ctime, div; @@ -1794,7 +1904,7 @@ void do_seq_ipo(Sequence *seq) if(seq->ipo) { ctime= frame_to_float(G.scene->r.cfra - seq->startdisp); div= (seq->enddisp - seq->startdisp)/100.0f; - if(div==0) return; + if(div==0.0) return; /* 2nd field */ calc_ipo(seq->ipo, (ctime+0.5f)/div); @@ -1813,7 +1923,7 @@ int has_ipo_code(Ipo *ipo, int code) { IpoCurve *icu; - if(ipo==0) return 0; + if(ipo==NULL) return 0; icu= ipo->curve.first; while(icu) { @@ -1924,7 +2034,7 @@ int calc_ipo_spec(Ipo *ipo, int adrcode, float *ctime) { IpoCurve *icu; - if(ipo==0) return 0; + if(ipo==NULL) return 0; icu= ipo->curve.first; while(icu) { @@ -1948,11 +2058,11 @@ void clear_delta_obipo(Ipo *ipo) { Object *ob; - if(ipo==0) return; + if(ipo==NULL) return; ob= G.main->object.first; while(ob) { - if(ob->id.lib==0) { + if(ob->id.lib==NULL) { if(ob->ipo==ipo) { memset(&ob->dloc, 0, 12); memset(&ob->drot, 0, 12); diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index c32874f69c5..d0c0b1f9927 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -935,6 +935,8 @@ static int do_mesh_key(Mesh *me) else { ctime= bsystem_time(0, 0, (float)G.scene->r.cfra, 0.0); + calc_ipo(me->key->ipo, ctime); /* also all relative key positions */ + if(calc_ipo_spec(me->key->ipo, KEY_SPEED, &ctime)==0) { ctime /= 100.0; CLAMP(ctime, 0.0, 1.0); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 29bfff8bc66..aa8efe61565 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -237,6 +237,7 @@ void unlink_object(Object *ob) Scene *sce; Curve *cu; Tex *tex; + Ipo *ipo; Group *group; bConstraint *con; int a; @@ -308,7 +309,7 @@ void unlink_object(Object *ob) for(a=0; a<MAX_MTEX; a++) { if(mat->mtex[a] && ob==mat->mtex[a]->object) { /* actually, test for lib here... to do */ - mat->mtex[a]->object= 0; + mat->mtex[a]->object= NULL; } } @@ -319,7 +320,7 @@ void unlink_object(Object *ob) tex= G.main->tex.first; while(tex) { if(tex->env) { - if(tex->env->object == ob) tex->env->object= 0; + if(tex->env->object == ob) tex->env->object= NULL; } tex= tex->id.next; } @@ -333,10 +334,10 @@ void unlink_object(Object *ob) /* worlds */ wrld= G.main->world.first; while(wrld) { - if(wrld->id.lib==0) { + if(wrld->id.lib==NULL) { for(a=0; a<MAX_MTEX; a++) { if(wrld->mtex[a] && ob==wrld->mtex[a]->object) - wrld->mtex[a]->object =0; + wrld->mtex[a]->object= NULL; } } @@ -346,12 +347,23 @@ void unlink_object(Object *ob) /* scenes */ sce= G.main->scene.first; while(sce) { - if(sce->id.lib==0) { - if(sce->camera==ob) sce->camera= 0; + if(sce->id.lib==NULL) { + if(sce->camera==ob) sce->camera= NULL; } sce= sce->id.next; } - /* keys */ + /* ipos */ + ipo= G.main->ipo.first; + while(ipo) { + if(ipo->id.lib==NULL) { + IpoCurve *icu; + for(icu= ipo->curve.first; icu; icu= icu->next) { + if(icu->driver && icu->driver->ob==ob) + icu->driver->ob= NULL; + } + } + ipo= ipo->id.next; + } /* screens */ sc= G.main->screen.first; @@ -365,11 +377,11 @@ void unlink_object(Object *ob) View3D *v3d= (View3D*) sl; if(v3d->camera==ob) { - v3d->camera= 0; + v3d->camera= NULL; if(v3d->persp>1) v3d->persp= 1; } if(v3d->localvd && v3d->localvd->camera==ob ) { - v3d->localvd->camera= 0; + v3d->localvd->camera= NULL; if(v3d->localvd->persp>1) v3d->localvd->persp= 1; } } @@ -1285,8 +1297,9 @@ void where_is_object_time(Object *ob, float ctime) if(ob==NULL) return; + /* this is needed to be able to grab objects with ipos, otherwise it always freezes them */ stime= bsystem_time(ob, 0, ctime, 0.0); - if( stime != ob->ctime) { + if(stime != ob->ctime) { ob->ctime= stime; if(ob->ipo) { @@ -1296,7 +1309,11 @@ void where_is_object_time(Object *ob, float ctime) /* do constraint ipos ... */ do_constraint_channels(&ob->constraints, &ob->constraintChannels, ctime); } - + else { + /* but, the drivers have to be done */ + if(ob->ipo) do_ob_ipodrivers(ob, ob->ipo); + } + if(ob->parent) { par= ob->parent; |