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/intern/ipo.c')
-rw-r--r--source/blender/blenkernel/intern/ipo.c164
1 files changed, 137 insertions, 27 deletions
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);