Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_ipo.h6
-rw-r--r--source/blender/blenkernel/intern/constraint.c2
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c39
-rw-r--r--source/blender/blenkernel/intern/ipo.c164
-rw-r--r--source/blender/blenkernel/intern/key.c2
-rw-r--r--source/blender/blenkernel/intern/object.c39
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;